/** * @file ModuleGraphicsItem.cpp * @brief 模块图元的绘制类 * @date 2011-08-17 */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "PaiWorkflowDataModel.h" #include "ModuleGraphicsItem.h" #include "ModuleInformation.h" #include "Module.h" #include "PaiModuleStyle.h" #include "ModuleToolBarGraphicsItem.h" #include "PaiDropEventAnalyser.h" #include "PaiObject.h" #include "PaiSeisData.h" #include "PaiSurvey.h" #include "PaiJobParameterItem.h" #include "GeneralWorkflowScene.h" #include "PaiClearLineEdit.h" #include "ModuleConnectGraphicsItem.h" #include "PaiGrid.h" #include "PaiGeometry.h" #include "PaiStatics.h" #include "PaiVelModel.h" #include "PaiVelPairs.h" #include "ModuleParameterUtil.h" #include "PaiBaseMaster.h" #include "PaiDataMaster.h" #include "PaiTraceEdit.h" #include "PaiFirstArrival.h" #include "PaiMute.h" #include "PaiHorizon.h" #include "WorkflowConst.h" #include "PaiJobParameterItemWidget.h" #include "ModuleMonitorGraphicsItem.h" using namespace pai::objectmodel; using namespace pai::graphics2d; using namespace pai::workflow; using namespace pai::gui; // 画连接虚线的状态 bool g_bSceneLineDrawing = false; void SetSceneLineDrawing(bool drawing) { g_bSceneLineDrawing = drawing; } bool GetSceneLineDrawing() { return g_bSceneLineDrawing; } //////////////////////////////////////////////////////////////////////////////////////////// pai::graphics2d::ModuleGraphicsItemEventAgent ModuleGraphicsItem::m_EventAgent; void ModuleGraphicsItemEventAgent::ModulePortSelectionChanged(pai::graphics2d::ModuleGraphicsItem *pItem, bool selected) { emit PortSelectionChanged(pItem, selected); } void ModuleGraphicsItemEventAgent::ItemNeedCenterOn(pai::graphics2d::ModuleGraphicsItem *pItem) { emit ModuleCenterOn(pItem); } void ModuleGraphicsItemEventAgent::ItemNeedBeDelete(pai::graphics2d::GeneralWorkflowScene *pScene, pai::graphics2d::ModuleGraphicsItem *pItem) { emit DeleteModule(pScene, pItem); } void ModuleGraphicsItemEventAgent::DoubleClickModule(CModuleInformation *pInfo, bool readOnly) { emit DoubleClick(pInfo, readOnly); } void ModuleGraphicsItemEventAgent::ClickModule(CModuleInformation *pModule, bool readOnly) { emit ModuleClicked(pModule, readOnly); } void ModuleGraphicsItemEventAgent::ClickSelectedModule(CModuleInformation *pModule) { emit ClickSelectedItem(pModule); } void ModuleGraphicsItemEventAgent::ItemSetEnabled(pai::graphics2d::ModuleGraphicsItem *pItem , bool enabled) { emit SetEnalbed(pItem, enabled); } void ModuleGraphicsItemEventAgent::ItemSetName(pai::graphics2d::ModuleGraphicsItem *pItem) { emit SetName(pItem); } void ModuleGraphicsItemEventAgent::UpdataModule(pai::graphics2d::ModuleGraphicsItem *pItem) { emit UpdateItem(pItem); } void ModuleGraphicsItemEventAgent::ModulePortHoveringChanged(pai::graphics2d::ModuleGraphicsItem *pItem, bool hovering) { emit PortHoveringChanged(pItem, hovering); } void ModuleGraphicsItemEventAgent::SetMonitoring(pai::graphics2d::ModuleGraphicsItem *pItem, bool monitor) { emit SetModuleMonitoring(pItem,monitor); } void ModuleGraphicsItemEventAgent::ShowColorEditor(pai::graphics2d::ModuleMonitorGraphicsItem *pMonitor) { emit ShowMonitorColorEditor(pMonitor); } void ModuleGraphicsItemEventAgent::UpdateMonitorColor(const QString& color) { emit ChangeMonitorColor(color); } //////////////////////////////////////////////////////////////////////////////////////// ModuleGraphicsItem::ModuleGraphicsItem(CModuleInformation *pModule, pai::graphics2d::PaiModuleStyle *pStyle, bool job, QGraphicsItem *pParent) : QGraphicsItem(pParent), m_pModule(NULL), m_pStyle(pStyle), m_pToolBarItem(NULL), m_pMonitorItem(NULL), m_size(pStyle->GetSize()), m_OnMoving(false), m_OnHovering(false), m_InitialValidated(false), m_monitoring(false), m_job(job), m_pCJobParameterItem(NULL), m_JobType(false) { if(!m_job) { setFlag(QGraphicsItem::ItemIsMovable, true); setFlag(QGraphicsItem::ItemSendsScenePositionChanges, true); setFlag(QGraphicsItem::ItemSendsGeometryChanges, true); } //在作业日志查看中让其模块能进行选择和获取焦点,解决模块Info信息筛选的问题。 setFlag(QGraphicsItem::ItemIsFocusable, true); setFlag(QGraphicsItem::ItemIsSelectable, true); setAcceptDrops(true); setAcceptHoverEvents(true); SetModule(pModule); if (pStyle->GetPosition() != QPointF(0, 0)) { setPos(pStyle->GetPosition()); } InitModuleNameEdit(); InitDropType(); } ModuleGraphicsItem::ModuleGraphicsItem(QGraphicsItem *pParent) : QGraphicsItem(pParent), m_pModule(NULL), m_pStyle(NULL), m_pToolBarItem(NULL), m_pMonitorItem(NULL), m_size(200, 60), m_OnMoving(false), m_OnHovering(false), m_InitialValidated(false), m_monitoring(false), m_pCJobParameterItem(NULL), m_JobType(false) { setFlag(QGraphicsItem::ItemIsSelectable, true); setFlag(QGraphicsItem::ItemIsMovable, true); setFlag(QGraphicsItem::ItemSendsScenePositionChanges, true); setFlag(QGraphicsItem::ItemSendsGeometryChanges, true); setFlag(QGraphicsItem::ItemIsFocusable, true); setAcceptDrops(true); setAcceptHoverEvents(true); InitModuleNameEdit(); InitDropType(); } ModuleGraphicsItem::~ModuleGraphicsItem() { //因为清空场景时,这个widget占用内存虽然被释放了,但是指针没有置空 if(m_pEdit) { m_pEdit = NULL; } } int ModuleGraphicsItem::type() const { return Type; } void ModuleGraphicsItem::InitModuleNameEdit() { //初始化模块名称输入框 m_pEdit = new pai::gui::PaiClearLineEdit(); m_pEdit->resize(180, 22); m_pEdit->setPlaceholderText(QString("Valid module name")); QGraphicsProxyWidget *pProxy = new QGraphicsProxyWidget(this); pProxy->setWidget(m_pEdit); pProxy->hide(); //下拉框 QCompleter *completer = new QCompleter(); //在ModuleItem中添加widget QGraphicsProxyWidget *pPopupProxy = new QGraphicsProxyWidget(this); pPopupProxy->setWidget(completer->popup()); completer->setCaseSensitivity(Qt::CaseInsensitive); m_pEdit->setCompleter(completer); QObject::connect(completer->popup(), SIGNAL(clicked(const QModelIndex &)), m_pEdit, SIGNAL(editingFinished()), Qt::UniqueConnection); QObject::connect(m_pEdit, SIGNAL(editingFinished()), &m_EventAgent, SIGNAL(EditingFinished()), Qt::UniqueConnection); } void ModuleGraphicsItem::InitDropType() { m_SupportedDropType << QUuid(PaiSeisData::GetTypeIDString()) << QUuid(PaiGrid::GetTypeIDString()) << QUuid(PaiGeometry::GetTypeIDString()) << QUuid(PaiStatics::GetTypeIDString()) << QUuid(PaiVelModel::GetTypeIDString()) << QUuid(PaiVelPairs::GetTypeIDString()) << QUuid(PaiTraceEdit::GetTypeIDString()) << QUuid(PaiFirstArrival::GetTypeIDString()) << QUuid(PaiMute::GetTypeIDString()) << QUuid(PaiHorizon::GetTypeIDString()); } QGraphicsView* ModuleGraphicsItem::GetView() const { return scene()->views().at(0); } void ModuleGraphicsItem::SetStyle(pai::graphics2d::PaiModuleStyle *pStyle) { m_pStyle = pStyle; } void ModuleGraphicsItem::SetModule(CModuleInformation *pModule) { qreal dHeight = m_size.height(); qreal dWidth = m_size.width(); qreal dPortDiameter = 14.0; if(m_pStyle) { dPortDiameter = m_pStyle->GetPortDiameter(); } qreal dDefaultPortPadding = dPortDiameter + 20.0; m_pModule = pModule; m_InputPorts.clear(); m_OutputPorts.clear(); if((pModule == NULL) || (pModule->IsBlankModule())) { return; } std::vector < Port > vecInputPorts; if((m_pModule->GetModule()) && (m_pModule->GetModule()->GetMetaData())) { m_pModule->GetModule()->GetMetaData()->GetInputPorts(vecInputPorts); } //////////////////////////////////////////BK改,当输入点为空时,添加新的点 // if(vecInputPorts.empty()) { Port rTop; rTop.type = PORT_INPUT; rTop.order=1; vecInputPorts.push_back(rTop); } ////////////////////////////// qreal dAllPortLength = dDefaultPortPadding * (vecInputPorts.size() - 1); qreal dMaxPortLength = dWidth - dPortDiameter; qreal dPixelStep = dMaxPortLength / (vecInputPorts.size() - 1); if(dPixelStep > dDefaultPortPadding) { dPixelStep = dDefaultPortPadding; } qreal dPixelPortX = -dAllPortLength / 2; if(dPixelPortX < -dMaxPortLength / 2) { dPixelPortX = -dMaxPortLength / 2; } for(std::vector< Port >::const_iterator it = vecInputPorts.begin(); it != vecInputPorts.end(); ++it) { ModulePortGraphicsItem port(m_pStyle, QPointF(dPixelPortX, -dHeight / 2 - 1), dPortDiameter, Top); m_InputPorts.append(port); dPixelPortX += dPixelStep; } std::vector < Port > vecOutputPorts; if((m_pModule->GetModule()) && (m_pModule->GetModule()->GetMetaData())) { m_pModule->GetModule()->GetMetaData()->GetOutputPorts(vecOutputPorts); } ///////////////改 if(vecOutputPorts.empty()) { Port rBottom; rBottom.type = PORT_OUTPUT; rBottom.order=2; vecOutputPorts.push_back(rBottom); } //////////////////////// dAllPortLength = dDefaultPortPadding * (vecOutputPorts.size() - 1); dPixelStep = dMaxPortLength / (vecOutputPorts.size() + 1); if(dPixelStep > dDefaultPortPadding) { dPixelStep = dDefaultPortPadding; } dPixelPortX = -dAllPortLength / 2; if(dPixelPortX < -dMaxPortLength / 2) { dPixelPortX = -(dMaxPortLength) / 2; } for(std::vector< Port >::const_iterator it = vecOutputPorts.begin(); it != vecOutputPorts.end(); ++it) { ModulePortGraphicsItem port(m_pStyle, QPointF(dPixelPortX, dHeight / 2 + 1), dPortDiameter, Bottom); m_OutputPorts.append(port); dPixelPortX += dPixelStep; } update(); } void ModuleGraphicsItem::SetDisable(bool isDisable) { if(m_pStyle) { m_pStyle->SetDisableFlag(isDisable); } if (m_pModule) { m_pModule->SetEnabled(!isDisable); } } bool ModuleGraphicsItem::IsDisable() const { return m_pStyle->IsDisable(); } void ModuleGraphicsItem::SetToolBarItem(pai::graphics2d::ModuleToolBarGraphicsItem *pToolBarItem) { m_pToolBarItem = pToolBarItem; } CModuleInformation* ModuleGraphicsItem::GetModule() const { return m_pModule; } pai::graphics2d::PaiModuleStyle* ModuleGraphicsItem::GetModuleStyle() const { return m_pStyle; } pai::graphics2d::ModuleToolBarGraphicsItem* ModuleGraphicsItem::GetToolBar() const { return m_pToolBarItem; } QRectF ModuleGraphicsItem::boundingRect() const { const int nExposedPortHeight = 10;//圆圈半径7+热区3 const int adjustValue = 2;//四个角的矩形 qreal dWidth = m_size.width() + adjustValue; qreal dHeight = m_size.height(); qreal dPenWidth = 1; return QRectF(-dWidth / 2 - dPenWidth / 2, -dHeight / 2 - dPenWidth / 2 - nExposedPortHeight, dWidth + dPenWidth, dHeight + dPenWidth * 2 + nExposedPortHeight * 2); } void ModuleGraphicsItem::paint(QPainter *pPainter, const QStyleOptionGraphicsItem *pOption, QWidget *pWidget) { const int iHighLightHeight = 14;// 高光的高度为14像素 const qreal EPS = 1e-10; qreal dWidth = m_size.width(); qreal dHeight = m_size.height(); qreal dStop = iHighLightHeight / dHeight; int eStatus = pai::graphics2d::PaiModuleStyle::Normal; if(isSelected())// 选中的优先级最高,无论什么状态,选中的绘制都一样 { eStatus |= pai::graphics2d::PaiModuleStyle::Selected; } if(m_pStyle != NULL) { if(m_pStyle->IsSaved()) { eStatus |= pai::graphics2d::PaiModuleStyle::Saved; } if(m_pStyle->IsError()) { eStatus |= pai::graphics2d::PaiModuleStyle::Error; } if(m_pStyle->IsWarning()) { eStatus |= pai::graphics2d::PaiModuleStyle::Warning; } if(m_pStyle->IsDisable()) { eStatus |= pai::graphics2d::PaiModuleStyle::Disable; } } QRectF rect(-dWidth / 2, -dHeight / 2, dWidth, dHeight); QPainterPath path; path.addRoundedRect(rect, 5.0, 5.0); QLinearGradient linearGrad(QPointF(0, -dHeight / 2), QPointF(0, dHeight / 2)); QColor beginColor; QColor endColor; // 高光部分的渐变 if(m_pStyle != NULL) { m_pStyle->GetHighColor(eStatus, beginColor, endColor); } linearGrad.setColorAt(0, beginColor); linearGrad.setColorAt(dStop, endColor); // 正常光部分的渐变 if(m_pStyle != NULL) { m_pStyle->GetColor(eStatus, beginColor, endColor); } linearGrad.setColorAt(dStop + EPS, beginColor); linearGrad.setColorAt(1, endColor); // 边框 QColor marginColor(Qt::red); if(m_OnHovering) { eStatus |= pai::graphics2d::PaiModuleStyle::MouseOn; } if(m_pStyle != NULL) { m_pStyle->GetMarginColor(eStatus, marginColor); } // 开始绘制 QBrush oldBrush = pPainter->brush(); QPen oldPen = pPainter->pen(); QBrush brush(linearGrad); QPen pen(marginColor); pen.setWidth((isSelected() || m_OnHovering) ? 2.0 : 1.0); pPainter->setPen(pen); pPainter->setBrush(brush); pPainter->drawPath(path); // 外边框 if(!m_OnHovering && !isSelected()) { QColor marginLightColor(Qt::red); m_pStyle->GetMarginColor(eStatus, marginLightColor); rect.adjust(-1, -1, 1, 1); pPainter->setPen(marginLightColor); pPainter->drawRoundedRect(rect, 5.0, 5.0); } pPainter->setPen(oldPen); pPainter->setBrush(oldBrush); // 绘制模块错误图标 if(m_pStyle->IsError()) { QPixmap errorIcon(":/MError.png"); int iIconWidth = errorIcon.width(); qreal dIconPosX = static_cast< qreal > (-iIconWidth / 2); qreal dIconPosY = (m_size.height() / 2 - pPainter->fontMetrics().height() / 2) / 2 - m_size.height() / 2 - iIconWidth / 2; pPainter->drawPixmap(QPointF(dIconPosX, dIconPosY), errorIcon); } // 绘制模块名字 QFont oldFont = pPainter->font(); QFont newFont = QApplication::font(); if(m_pStyle->IsWarning()) { QRectF rectBelowPort; // to avoid the fonts being covered by the port. rectBelowPort.setRect(rect.x(), rect.y() + 7, rect.width(), rect.height() - 7); pPainter->setPen(Qt::red); newFont.setPixelSize(11); pPainter->setFont(newFont); pPainter->drawText(rectBelowPort, Qt::AlignTop | Qt::AlignHCenter, "Parameters incomplete!"); } pPainter->setPen(Qt::black); pPainter->setFont(oldFont); if((m_pModule != NULL) && (!m_pModule->IsBlankModule()) && m_pModule->GetModule() && m_pModule->GetModule()->GetMetaData()) { pPainter->drawText(boundingRect(), Qt::AlignCenter, QString::fromStdString(m_pModule->GetModule()->GetMetaData()->GetName())); } // 绘制端口 QList< ModulePortGraphicsItem >::iterator it; for(it = m_InputPorts.begin(); it != m_InputPorts.end(); ++it) { (*it).paint(pPainter, pOption, pWidget); } for(it = m_OutputPorts.begin(); it != m_OutputPorts.end(); ++it) { (*it).paint(pPainter, pOption, pWidget); } // 画选中的模块的四个角 if(isSelected()) { //获得四个角的矩形区域 int adjustValue = 8 / 2; QColor fillColor("#00A8FF"); QBrush fillBrush(fillColor); QRectF leftTop(-dWidth / 2, -dHeight / 2, 0, 0); leftTop.adjust(-adjustValue, -adjustValue, adjustValue, adjustValue); QRectF rightTop(dWidth / 2, -dHeight / 2, 0, 0); rightTop.adjust(-adjustValue, -adjustValue, adjustValue, adjustValue); QRectF leftBottom(-dWidth / 2, dHeight / 2, 0, 0); leftBottom.adjust(-adjustValue, -adjustValue, adjustValue, adjustValue); QRectF rightBottom(dWidth / 2, dHeight / 2, 0, 0); rightBottom.adjust(-adjustValue, -adjustValue, adjustValue, adjustValue); pPainter->fillRect(leftTop, fillBrush); pPainter->fillRect(rightTop, fillBrush); pPainter->fillRect(leftBottom, fillBrush); pPainter->fillRect(rightBottom, fillBrush); } //画完了ModuleItem以后调整m_pEdit位置,只有显示时才执行 if(!m_pEdit->isHidden()) { m_pEdit->move(rect.center().toPoint() - m_pEdit->graphicsProxyWidget()->rect().center().toPoint()); m_pEdit->completer()->popup()->move(QPoint(-90, 11)); } } QPointF ModuleGraphicsItem::GetPortPostion(PortDirection portDirection, int portIndex) const { if(portDirection == Top) { if((portIndex < 0) || (portIndex >= m_InputPorts.size())) { return QPointF(); } return pos() + m_InputPorts.at(portIndex).m_center; } else { if((portIndex < 0) || (portIndex >= m_OutputPorts.size())) { return QPointF(); } return pos() + m_OutputPorts.at(portIndex).m_center; } } QRectF ModuleGraphicsItem::GetPortBoundingRect(PortDirection portDirection,int portIndex) const { if(portDirection == Top) { if((portIndex < 0) || (portIndex >= m_InputPorts.size())) { return QRectF(); } return m_InputPorts.at(portIndex).boundingRect(); } else { if((portIndex < 0) || (portIndex >= m_OutputPorts.size())) { return QRectF(); } return m_OutputPorts.at(portIndex).boundingRect(); } } QSizeF ModuleGraphicsItem::GetSize() const { return m_size; } void ModuleGraphicsItem::GetHoveringPort(PortDirection& portDirection, int& portIndex) { QList::iterator it; int i = 0; for(it = m_InputPorts.begin(); it != m_InputPorts.end(); ++it) { if(it->m_OnHovering) { portDirection = Top; portIndex = i; return; } ++i; } i = 0; for(it = m_OutputPorts.begin(); it != m_OutputPorts.end(); ++it) { if(it->m_OnHovering) { portDirection = Bottom; portIndex = i; return; } ++i; } portIndex = -1; } void ModuleGraphicsItem::GetSelectedPort(PortDirection& portDirection, int& portIndex) { QList::iterator it; int i = 0; for(it = m_InputPorts.begin(); it != m_InputPorts.end(); ++it) { if(it->m_selected) { portDirection = Top; portIndex = i; return; } ++i; } i = 0; for(it = m_OutputPorts.begin(); it != m_OutputPorts.end(); ++it) { if(it->m_selected) { portDirection = Bottom; portIndex = i; return; } ++i; } portIndex = -1; } bool ModuleGraphicsItem::HasPortSelected() const { QList< ModulePortGraphicsItem >::const_iterator it; for(it = m_InputPorts.begin(); it != m_InputPorts.end(); ++it) { if(it->m_selected) { return true; } } for(it = m_OutputPorts.begin(); it != m_OutputPorts.end(); ++it) { if(it->m_selected) { return true; } } return false; } void ModuleGraphicsItem::CancelPortSelect() { QList< ModulePortGraphicsItem >::iterator it; for(it = m_InputPorts.begin(); it != m_InputPorts.end(); ++it) { if(it->m_selected) { it->m_selected = false; return; } } for(it = m_OutputPorts.begin(); it != m_OutputPorts.end(); ++it) { if(it->m_selected) { it->m_selected = false; return; } } } void ModuleGraphicsItem::SetWorkflow(pai::objectmodel::PaiWorkflowDataModel *pWorkflow) { m_pWorkflow = pWorkflow; } void ModuleGraphicsItem::SetJobType(bool jobType) { m_JobType = jobType; } void ModuleGraphicsItem::UpdateView() { if(this->scene() != NULL) { if(this->scene()->views().count() > 0) { this->scene()->views().at(0)->update(); } } } void ModuleGraphicsItem::hoverEnterEvent(QGraphicsSceneHoverEvent *pEvent) { m_OnHovering = true; if(m_pToolBarItem) { int nCenterWidth = boundingRect().width() / 2 + 2 + m_pToolBarItem->boundingRect().width() / 2; m_pToolBarItem->SetOpacityEffect(true); m_pToolBarItem->setPos(pos() + QPointF(nCenterWidth, 0.0)); m_pToolBarItem->AttachModuleItem(this); m_pToolBarItem->SetToolBarVisible(true); } QGraphicsItem::hoverEnterEvent(pEvent); if(m_job) { if(m_JobType) { if(m_pCJobParameterItem == NULL) { m_pCJobParameterItem = new pai::gui::PaiJobParameterItem(this); } GeneralWorkflowScene *pScene = (GeneralWorkflowScene *) this->scene(); if(pScene != NULL) { m_pCJobParameterItem->GetWidget()->SetParamEditInfo(m_pWorkflow->GetHtmlModuleInfo(m_pModule->GetModule())); //必须使用m_pCJobParameterItem->GetWidget()而不是m_pCJobParameterItem来设置是否显示,因为defect28520 m_pCJobParameterItem->GetWidget()->show(); QPointF point = m_pCJobParameterItem->mapToParent(0, 0); m_pCJobParameterItem->setPos(point); } //让模块信息展示框处于最顶层 setZValue(2); } else { //使流转信息处于顶层 setZValue(1); } } setToolTip(m_error); } void ModuleGraphicsItem::SetPortToolTip(bool isInput, unsigned int index) { std::vector < Port > vecPorts; if(isInput == true) { m_pModule->GetModule()->GetMetaData()->GetInputPorts(vecPorts); } else { m_pModule->GetModule()->GetMetaData()->GetOutputPorts(vecPorts); } if(vecPorts.size() > index) { Port port = vecPorts.at(index); //port order + 1 to assure port order tip shows 1,2,3,4 QString tip = "Order:" + QString::number(port.order + 1) + "\n" + "PortType:" + QString(port.type == PORT_INPUT ? "input" : "output") + "\n" + "Connected Module Type:" + QString::fromStdString(port.connectedModuleType) + "\n" + "Name:" + QString::fromStdString(port.name) + "\n" + "Optional:" + QString(port.optional ? "true" : "false"); setToolTip(tip); } } void ModuleGraphicsItem::hoverMoveEvent(QGraphicsSceneHoverEvent *pEvent) { QList< ModulePortGraphicsItem >::iterator it; bool bFindEnter = false; bool bFindLeave = false; unsigned int indexOfPort = 0; for(it = m_InputPorts.begin(); it != m_InputPorts.end(); ++it) { if(it->boundingRect().contains(pEvent->pos())) { it->hoverEnterEvent(pEvent); if(g_bSceneLineDrawing) { m_EventAgent.ModulePortHoveringChanged(this, true); } update(it->boundingRect()); bFindEnter = true; } else { if(it->m_OnHovering) { it->hoverLeaveEvent(pEvent); update(it->boundingRect()); bFindLeave = true; } } ++indexOfPort; } indexOfPort = 0; if(!bFindEnter || !bFindLeave) { for(it = m_OutputPorts.begin(); it != m_OutputPorts.end(); ++it) { if(it->boundingRect().contains(pEvent->pos())) { it->hoverEnterEvent(pEvent); update(it->boundingRect()); if(g_bSceneLineDrawing) { m_EventAgent.ModulePortHoveringChanged(this, true); } } else { if(it->m_OnHovering) { it->hoverLeaveEvent(pEvent); update(it->boundingRect()); } } ++indexOfPort; } } // 端口状态改变时,刷新视口 UpdateView(); QGraphicsItem::hoverMoveEvent(pEvent); } void ModuleGraphicsItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *pEvent) { if(m_pToolBarItem) { // pEvent->pos().x()为鼠标离开时的x坐标。 // 当鼠标位置在水平方向超出模块图元本身再加上工具条的宽度时,表示鼠标已经完全脱离该图元,此时应该无条件将悬浮状态取消。 if((pEvent->pos().x() < m_size.width() / 2) || (pEvent->pos().x() > m_size.width() / 2 + m_pToolBarItem->boundingRect().width())) { m_pToolBarItem->DetachModuleItem(); this->m_pToolBarItem->SetToolBarVisible(false); m_OnHovering = false; } if(qAbs(pEvent->pos().y()) > (m_size.height() / 2 - 2)) { m_pToolBarItem->DetachModuleItem(); this->m_pToolBarItem->SetToolBarVisible(false); m_OnHovering = false; } } QList< ModulePortGraphicsItem >::iterator it; for(it = m_InputPorts.begin(); it != m_InputPorts.end(); ++it) { it->m_OnHovering = false; } for(it = m_OutputPorts.begin(); it != m_OutputPorts.end(); ++it) { it->m_OnHovering = false; } if(m_job) { if(m_JobType) { GeneralWorkflowScene *pScene = (GeneralWorkflowScene *) this->scene(); if(pScene && m_pCJobParameterItem && m_pCJobParameterItem->GetWidget()) { // 必须使用m_pCJobParameterItem->GetWidget()而不是m_pCJobParameterItem来设置是否显示,因为defect28520 if(!(m_pCJobParameterItem->GetWidget()->GetMouseEnterWidgetFlag())) { if(m_pCJobParameterItem->GetWidget()->GetFixWidgetPosFlag()) { m_pCJobParameterItem->GetWidget()->show(); } else { m_pCJobParameterItem->GetWidget()->hide(); } } } } // 鼠标移出时设置回默认Z值 setZValue(0); } QGraphicsItem::hoverLeaveEvent(pEvent); setToolTip(""); // 鼠标移出后刷新一下视口,防止进度条被模块遮盖 UpdateView(); update(); } bool ModuleGraphicsItem::PortHit(QGraphicsSceneMouseEvent *pEvent) { QList< ModulePortGraphicsItem >::iterator it; bool bFind = false; for(it = m_InputPorts.begin(); it != m_InputPorts.end(); ++it) { if(!bFind && (it->boundingRect().contains(pEvent->pos()))) { it->SetPortSelected(true); update(it->boundingRect()); m_EventAgent.ModulePortSelectionChanged(this, true); bFind = true; } else { if(it->m_selected) { it->SetPortSelected(false); update(it->boundingRect()); } } } for(it = m_OutputPorts.begin(); it != m_OutputPorts.end(); ++it) { if(!bFind && (it->boundingRect().contains(pEvent->pos()))) { it->SetPortSelected(true); update(it->boundingRect()); m_EventAgent.ModulePortSelectionChanged(this, true); bFind = true; } else { if(it->m_selected) { it->SetPortSelected(false); update(it->boundingRect()); } } } return bFind; } void ModuleGraphicsItem::mousePressEvent(QGraphicsSceneMouseEvent *pEvent) { m_PressedOnPort = PortHit(pEvent); bool hasSelection = isSelected(); QGraphicsItem::mousePressEvent(pEvent); m_EventAgent.ClickModule(this->GetModule(), m_job); // 发射点击的信号 if(hasSelection) { // 如果点击前模块已经时被选中状态,发射重复点击信号 m_EventAgent.ClickSelectedModule(this->GetModule()); } update(); } void ModuleGraphicsItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *pEvent) { QGraphicsItem::mouseReleaseEvent(pEvent); setCursor(Qt::ArrowCursor); if(m_OnMoving) { m_OnMoving = false; m_EventAgent.ItemNeedCenterOn(this); } } void ModuleGraphicsItem::mouseMoveEvent(QGraphicsSceneMouseEvent *pEvent) { if(m_PressedOnPort == false) { setCursor(Qt::ClosedHandCursor); } QRectF sceneRect(GetView()->sceneRect()); QGraphicsItem::mouseMoveEvent(pEvent); if(m_pStyle) { QPointF scenePos(pos()); QPointF sceneMarginPos(scenePos.x() + m_size.width() / 2, scenePos.y() + m_size.height() / 2); if(!sceneRect.contains(sceneMarginPos)) { m_OnMoving = true; if(sceneRect.bottom() < sceneMarginPos.y()) { sceneRect.setBottom(sceneMarginPos.y()); GetView()->setSceneRect(sceneRect); } if(sceneRect.right() < sceneMarginPos.x()) { sceneRect.setRight(sceneMarginPos.x()); GetView()->setSceneRect(sceneRect); } } } if(m_pMonitorItem) { if(m_pMonitorItem->GetStyle()) { m_pMonitorItem->GetStyle()->SetPosition(pos() + QPointF(-120, -20)); } m_pMonitorItem->setPos(pos() + QPointF(-120, -20)); } } void ModuleGraphicsItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* /*pEvent*/) { m_EventAgent.DoubleClickModule(this->GetModule(), m_job); // 发射双击的信号 } bool ModuleGraphicsItem::IsDropTypeValid(const QMimeData *pMimeData) { PaiDropEventAnalyser dropAna(pMimeData); // 获取被拖拽的数据 QListdataLst = dropAna.GetDraggedData(); // 查找地震数据 foreach(DraggedData draggedData, dataLst) { if(m_SupportedDropType.contains(QUuid(draggedData.dataType))) { return true; } } return false; } bool ModuleGraphicsItem::AddFileToModuleParameter(pai::objectmodel::PaiObject *pObject) { PaiGeoObject *pGeoObject = dynamic_cast< PaiGeoObject* > (pObject); if(!pGeoObject) { return false; } pai::module::CModuleParameter* pModuleParam = GetModule()->GetModuleParameter(); if(!pModuleParam) { return false; } pai::module::CParameterItem* pParameterItem = NULL; std::vector< pai::module::CParameterItem* > vecLeafItems; pModuleParam->GetRootParameterItem()->GetParameterItemsWithValidInputType(vecLeafItems); bool bFound = false; std::vector< pai::module::CParameterItem* >::const_iterator it; for(it = vecLeafItems.begin(); it != vecLeafItems.end(); ++it) { pParameterItem = *it; QList< QUuid > acceptDropTypes(pai::ModuleParameterUtil::GetAcceptDropTypes(pParameterItem)); for(int i = 0; i < acceptDropTypes.size(); ++i) { if(acceptDropTypes[i] == pObject->GetTypeID()) { bFound = true; break; } } if(bFound) { break; } } if(!bFound) { return false; } std::string oldParamValue = pParameterItem->GetStringValue(); CCompositeParameterItem *pCompositeItem = (CCompositeParameterItem*)(pModuleParam->GetParameterItem("files")); QString dataPath = pGeoObject->GetVisibleFile(); //处理拖拽作业下的地震数据 if((dynamic_cast< PaiSeisData * > (pGeoObject)) && (dynamic_cast< PaiJob * > (pGeoObject->GetParent()))) { //清空dataPath dataPath.clear(); //获取被拖拽地震数据的逻辑路径 dataPath = dynamic_cast< PaiSeisData * > (pGeoObject)->GetPhysicalFile(); PaiSurvey* pSurvey = pGeoObject->GetForebear< PaiSurvey > (); if(pSurvey) { PaiBaseMaster *pMaster = pSurvey->GetMaster(QUuid(pai::objectmodel::PaiDataMaster::GetTypeIDString())); if(pMaster) { dataPath.replace(pGeoObject->GetName(), QString("")); dataPath.append(pMaster->GetName() + QString("/") + pGeoObject->GetName()); } } } if(NULL != pCompositeItem) { int ifiles_num = pCompositeItem->GetChildCount(); pai::module::CParameterItem *pItemNeedSetValue = pCompositeItem->GetParameterItem("files[0].filename"); for(int i = 0; i < ifiles_num; ++i) { std::stringstream stream; stream.str(""); stream << i; string id = "files[" + stream.str() + "]"; pai::module::CParameterItem *pItem = pCompositeItem->GetParameterItem(id + ".filename"); if(pItem == NULL) { continue; } if(pItem->ValueToString().empty()) { pItemNeedSetValue = pItem; break; } } if(pItemNeedSetValue) { oldParamValue = pItemNeedSetValue->GetStringValue(); pItemNeedSetValue->SetDefault(dataPath.toStdString()); pItemNeedSetValue->SetStringValue(pGeoObject->GetPhysicalFile().toStdString()); if(oldParamValue != pItemNeedSetValue->GetStringValue()) { return true; } } } else { pParameterItem->SetDefault(dataPath.toStdString()); pParameterItem->SetStringValue(pGeoObject->GetPhysicalFile().toStdString()); if(oldParamValue != pParameterItem->GetStringValue()) { return true; } } return false; } void ModuleGraphicsItem::dragEnterEvent ( QGraphicsSceneDragDropEvent *pEvent) { QGraphicsItem::dragEnterEvent(pEvent); if(IsDropTypeValid(pEvent->mimeData())) { pEvent->accept(); } else { pEvent->ignore(); } } void ModuleGraphicsItem::dropEvent ( QGraphicsSceneDragDropEvent *pEvent) { QGraphicsItem::dropEvent(pEvent); PaiDropEventAnalyser dropAna(pEvent->mimeData()); //拖拽数据为空 if(!dropAna.IsAvailable()) { pEvent->ignore(); return; } bool addFileSuccess = false; //数据树拖拽来的数据 if((dropAna.GetDataSource() == DRAG_DATATREE) && IsDropTypeValid(pEvent->mimeData())) { QListdataLst = dropAna.GetDraggedData(); foreach(DraggedData draggedData,dataLst) { bool ok; PaiObject *pDragObject = ::GetObjectModelService()->GetObject((draggedData.id).toLongLong(&ok)); if(ok && pDragObject) { //添加输入数据 if(AddFileToModuleParameter(pDragObject)) { addFileSuccess = true; } } } if(addFileSuccess) { m_EventAgent.UpdataModule(this); pEvent->accept(); } } } QVariant ModuleGraphicsItem::itemChange(GraphicsItemChange change, const QVariant & value) { QVariant myValue(value); if(change == QGraphicsItem::ItemPositionChange) { if(m_pToolBarItem && isSelected()) { int nCenterWidth = boundingRect().width() / 2 + 2 + m_pToolBarItem->boundingRect().width() / 2; m_pToolBarItem->setPos(pos() + QPointF(nCenterWidth, 0.0)); } } return QGraphicsItem::itemChange(change, myValue); } int ModuleGraphicsItem::GetInputPortCount() const { return m_InputPorts.count(); } int ModuleGraphicsItem::GetOutputPortCount() const { return m_OutputPorts.count(); } bool ModuleGraphicsItem::GetInitialValidated() const { return m_InitialValidated; } void ModuleGraphicsItem::SetInitialValidated(bool validated) { m_InitialValidated = validated; } void ModuleGraphicsItem::SetErrorString(QString error) { m_error = error; } void ModuleGraphicsItem::HilightPorts(PortDirection portDirection, bool light) { QList< ModulePortGraphicsItem >& lstPortItems = (portDirection == Top) ? m_InputPorts : m_OutputPorts; for(QList< ModulePortGraphicsItem >::iterator it = lstPortItems.begin(); it != lstPortItems.end(); ++it) { it->m_light = light; } update(); } void ModuleGraphicsItem::SetModuleNamePopup(const QList &moduleNameList) { //初始化pupupView QStringListModel *pModel = new QStringListModel(moduleNameList); m_pEdit->completer()->setModel(pModel); m_pEdit->completer()->popup()->setMinimumHeight(m_pEdit->completer()->popup()->sizeHintForRow(0)); } void ModuleGraphicsItem::HideModuleNameEditor() { if(m_pEdit && !(m_pEdit->isHidden())) { m_pEdit->clear(); m_pEdit->graphicsProxyWidget()->hide(); if(m_pEdit->completer()->popup() && !(m_pEdit->completer()->popup()->isHidden())) { m_pEdit->completer()->popup()->hide(); } setZValue(zValue() - MODULE_ZVALUE_STEP); } } void ModuleGraphicsItem::HideNonBlankModuleEditor() { if(m_pEdit && !(m_pEdit->isHidden()) && m_pModule && !(m_pModule->IsBlankModule())) { m_pEdit->clear(); m_pEdit->graphicsProxyWidget()->hide(); if(m_pEdit->completer()->popup() && !(m_pEdit->completer()->popup()->isHidden())) { m_pEdit->completer()->popup()->hide(); } setZValue(zValue() - MODULE_ZVALUE_STEP); } } bool ModuleGraphicsItem::IsEditingModuleName() { if(m_pEdit && !(m_pEdit->isHidden())) { return true; } return false; } QString ModuleGraphicsItem::GetModuleNameEditorText() const { if(m_pEdit && !(m_pEdit->isHidden())) { return m_pEdit->text(); } return ""; } void ModuleGraphicsItem::ShowModuleNameEditor() { if(m_pEdit && (m_pEdit->isHidden())) { m_pEdit->clear(); m_pEdit->show(); m_pEdit->setFocus(); setZValue(zValue() + MODULE_ZVALUE_STEP); } } bool ModuleGraphicsItem::IsModuleReadOnly() const { return m_job; } bool ModuleGraphicsItem::InPortHasBeenLined(int portIndex) const { if(!scene()) { return false; } foreach(QGraphicsItem *pItem, scene()->items()) { if (pItem && (pItem->type() == ModuleConnectGraphicsItem::Type)) { ModuleConnectGraphicsItem* pConnectionItem = dynamic_cast (pItem); if (pConnectionItem && (pConnectionItem->GetEndItem() == this) && (pConnectionItem->GetEndPortIndex() == portIndex)) { return true; } } } return false; } int ModuleGraphicsItem::GetFreeInPortIndex() const { int inportIndex = -1; if(!scene()) { return inportIndex; } //结束模块的输入端口数量 int inputPortCount = GetInputPortCount(); for(int i = 0; i < inputPortCount; ++i) { //判断是否当前端口i被连接 bool connected = false; foreach(QGraphicsItem *pItem, scene()->items()) { if (pItem && (pItem->type() == ModuleConnectGraphicsItem::Type)) { ModuleConnectGraphicsItem* pConnectionItem = dynamic_cast (pItem); if (pConnectionItem && (pConnectionItem->GetEndItem() == this) && (pConnectionItem->GetEndPortIndex() == i)) { connected = true; break; } } } //如果端口i没有被连接,则端口i设置为被连接端口 if(!connected) { inportIndex = i; break; } } return inportIndex; } void ModuleGraphicsItem::SetMonitoring(bool monitor) { m_monitoring = monitor; } bool ModuleGraphicsItem::GetMonitoring() const { return m_monitoring; } void ModuleGraphicsItem::SetMonitorItem(pai::graphics2d::ModuleMonitorGraphicsItem *pMonitor) { m_pMonitorItem = pMonitor; } pai::graphics2d::ModuleMonitorGraphicsItem* ModuleGraphicsItem::GetMonitorItem() const { return m_pMonitorItem; }