1 // SUPERV SUPERVGUI : GUI for Supervisor component
3 // Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
24 // File : SUPERVGUI_Graph.cxx
25 // Author : Francis KLOSS
29 #include "SUPERVGUI_Def.h"
30 #include "SUPERVGUI_Graph.h"
31 #include "SUPERVGUI_Main.h"
32 #include "SUPERVGUI_ComputeNode.h"
33 #include "SUPERVGUI_ControlNode.h"
34 #include "SUPERVGUI.h"
36 #include <qapplication.h>
38 #include <qgroupbox.h>
44 #include <sys/timeb.h>
48 #define UPDATECONTROLNODES(NodesName) \
49 n = nodes->NodesName.length(); \
50 for (int i=0; i<n; i++) { \
51 SUPERV_CNode aCNode = SUPERV::CNode::_narrow(nodes->NodesName[i]); \
52 SUPERV_CNode aCNodeEnd = SUPERV::CNode::_narrow(nodes->NodesName[i]->Coupled()); \
53 ihmNode = (SUPERVGUI_Node *)child(aCNode->Name(), "SUPERVGUI_Node"); \
54 if (ihmNode == NULL) { \
55 main->addControlNode(aCNode, aCNodeEnd, false); \
57 ResizeGraph(ihmNode, aCNode->X(), aCNode->Y()); \
58 moveChild(ihmNode, aCNode->X(), aCNode->Y()); \
59 ihmList->removeRef(ihmNode); \
61 aEndNodePrs = (SUPERVGUI_EndControlNode*)child(aCNodeEnd->Name(), "SUPERVGUI_EndControlNode"); \
62 ResizeGraph(aEndNodePrs, aCNodeEnd->X(), aCNodeEnd->Y()); \
63 moveChild(aEndNodePrs, aCNodeEnd->X(), aCNodeEnd->Y()); \
64 ihmList->removeRef(aEndNodePrs); \
65 aEndNodePrs->sync(); \
70 #define UPDATENODES(NodesName, FuncName) \
71 n = nodes->NodesName.length(); \
72 for (int i=0; i<n; i++) { \
73 SUPERV_CNode aCNode = SUPERV::CNode::_narrow(nodes->NodesName[i]); \
74 ihmNode = (SUPERVGUI_Node *)child(aCNode->Name(), "SUPERVGUI_Node"); \
75 if (ihmNode == NULL) { \
76 main->FuncName(aCNode); \
78 ResizeGraph(ihmNode, aCNode->X(), aCNode->Y()); \
79 moveChild(ihmNode, aCNode->X(), aCNode->Y()); \
80 ihmList->removeRef(ihmNode); \
86 SUPERVGUI_Graph::SUPERVGUI_Graph(SUPERVGUI_Main* m):
90 Trace("SUPERVGUI_Graph::SUPERVGUI_Graph");
91 myIsControlView = false;
92 myLinksList.setAutoDelete(true);
93 viewport()->setMouseTracking(true);
95 resizeContents(GRAPH_WIDTH, GRAPH_HEIGHT);
97 if (SUPERV_isNull(main->getDataflow())) return;
100 //create sketching popup menu
101 mySketchPopup = new QPopupMenu(viewport());
102 if (!mySketchPopup->isCheckable())
103 mySketchPopup->setCheckable(true);
104 myDelPntItem = mySketchPopup->insertItem(tr("MSG_DEL_LAST_PNT"), this, SLOT(delLastPnt()));
105 mySketchPopup->insertItem(tr("MSG_DEL_LINK"), this, SLOT(delCreatingLink()));
106 myOrtoItem = mySketchPopup->insertItem(tr("MSG_ORTHO_LINE"), this, SLOT(setOrtho()));
108 //create link popup menu
109 myLinkPopup = new QPopupMenu(viewport());
110 myDelLinkItem = myLinkPopup->insertItem(tr("MSG_DELLINK"), this, SLOT(deleteLink()));
111 myAddLinkPntItem = myLinkPopup->insertItem(tr("MSG_ADD_POINT"), this, SLOT(addPoint()));
112 myDelLinkPntItem = myLinkPopup->insertItem(tr("MSG_DEL_POINT"), this, SLOT(deletePoint()));
117 SUPERVGUI_Graph::~SUPERVGUI_Graph() {
121 * Synchronizes Graph presentation with internal graph structure
123 void SUPERVGUI_Graph::sync() {
124 if (SUPERV_isNull(main->getDataflow())) return;
128 SUPERVGUI_Node* ihmNode;
129 QObjectList* ihmList = queryList("SUPERVGUI_Node");
130 SUPERV_Nodes nodes = main->getDataflow()->Nodes();
132 MESSAGE("CNodes="<<nodes->CNodes.length());
133 MESSAGE("FNodes="<<nodes->FNodes.length());
134 MESSAGE("INodes="<<nodes->INodes.length());
135 MESSAGE("GNodes="<<nodes->GNodes.length());
136 MESSAGE("LNodes="<<nodes->LNodes.length());
137 MESSAGE("SNodes="<<nodes->SNodes.length());
140 UPDATENODES(CNodes, addComputeNode);
141 UPDATENODES(FNodes, addComputeNode);
142 UPDATENODES(INodes, addComputeNode);
143 UPDATENODES(GNodes, addGOTONode);
145 SUPERVGUI_EndControlNode* aEndNodePrs;
146 UPDATECONTROLNODES(LNodes);
147 UPDATECONTROLNODES(SNodes);
149 QObjectListIt i(*ihmList);
150 while ((ihmNode=(SUPERVGUI_Node*)i.current()) != 0) {
152 ihmNode->close(true);
156 ihmList = queryList("SUPERVGUI_GraphNode");
158 SUPERVGUI_GraphNode* aGraphNode;
159 while ((aGraphNode=(SUPERVGUI_GraphNode*)i.current()) != 0) {
161 aGraphNode->updateLinksPrs();
170 * Reimplemented for repainting links
172 bool SUPERVGUI_Graph::eventFilter(QObject* object, QEvent* event) {
173 if (event->type() == QEvent::Paint) {
177 return QScrollView::eventFilter(object, event);
182 * Clears content of Graph (links)
184 void SUPERVGUI_Graph::clearView() {
185 QPainter aPainter(viewport());
186 aPainter.eraseRect(viewport()->rect());
191 * Draws links using off screen buffer
193 void SUPERVGUI_Graph::draw() {
198 if (myLinksList.count() == 0) {
201 int aWidth = viewport()->width();
202 int aHeight = viewport()->height();
203 QPixmap aPixmap(aWidth, aHeight);
204 aPixmap.setOptimization(QPixmap::BestOptim);
205 aPixmap.fill(viewport()->paletteBackgroundColor());
207 QPainter aPainter(&aPixmap);
208 QPoint aPos = viewportToContents(viewport()->pos());
210 if (myIsControlView) {
211 SUPERVGUI_CtrlLink* aLink;
212 QMap<QString, SUPERVGUI_CtrlLink>::Iterator it;
213 for ( it = myCtrlLinks.begin(); it != myCtrlLinks.end(); ++it ) {
214 it.data().paint(&aPainter, false);
217 SUPERVGUI_Link* aLink;
218 for (aLink = myLinksList.first(); aLink; aLink = myLinksList.next()) {
219 aLink->isInRect(aPos.x(), aPos.y(), aWidth, aHeight);
220 if (aLink->isInRect(aPos.x(), aPos.y(), aWidth, aHeight)) {
221 aLink->paint(&aPainter, false);
225 bitBlt(viewport(), 0, 0,
226 &aPixmap, 0, 0, aWidth, aHeight,
230 myNewLink->repaintSketch();
235 ulong aTm = 1000*(aTm2.time-aTm1.time)+(aTm2.millitm-aTm1.millitm);
236 //cout<<"### Time="<<aTm<<endl;
241 void SUPERVGUI_Graph::contentsMousePressEvent(QMouseEvent* e) {
242 Trace("SUPERVGUI_Graph::contentsMousePressEvent");
243 if ( e->button() == Qt::RightButton) {
245 main->showPopup(mySketchPopup, e);
247 SUPERVGUI_Link* aLink = SUPERVGUI_Link::getSelectedLink();
248 if (aLink && main->isEditable()) {
249 myLinkPopup->setItemEnabled(myAddLinkPntItem,
250 !aLink->haveSelectedPoint());
251 myLinkPopup->setItemEnabled(myDelLinkPntItem,
252 aLink->haveSelectedPoint());
255 if (!aLink->isESInputPort()) {
256 SUPERV::KindOfPort aOutType = aLink->getOutputPort()->getPort()->Kind();
257 SUPERV::KindOfPort aInType = aLink->getInputPort()->getPort()->Kind();
258 myLinkPopup->setItemEnabled(myDelLinkItem,
259 ((aOutType != SUPERV::LoopParameter)
261 (aInType != SUPERV::LoopParameter)));
264 myMousePos = e->pos();
265 mySelectedLink = aLink;
266 mySelectedPoint = mySelectedLink->getSelectedPoint();
267 main->showPopup(myLinkPopup, e);
271 main->showPopup(myPopup, e);
275 emit mousePressed(e);
277 SUPERVGUI_View::contentsMousePressEvent(e);
281 void SUPERVGUI_Graph::contentsMouseReleaseEvent(QMouseEvent* e) {
282 Trace("SUPERVGUI_Graph::contentsMouseReleaseEvent");
283 if (myNewLink && (e->button() == Qt::LeftButton)) {
284 myNewLink->addTmpPoint(e->pos());
285 mySketchPopup->setItemEnabled(myDelPntItem, true);
287 emit mouseReleased(e);
288 SUPERVGUI_View::contentsMouseReleaseEvent(e);
292 void SUPERVGUI_Graph::contentsMouseMoveEvent(QMouseEvent* e) {
293 Trace("SUPERVGUI_Graph::contentsMouseMoveEvent");
295 myNewLink->drawTo(e->pos());
298 SUPERVGUI_View::contentsMouseMoveEvent(e);
302 void SUPERVGUI_Graph::addPoint() {
303 mySelectedLink->addPoint(myMousePos.x(), myMousePos.y());
307 void SUPERVGUI_Graph::deletePoint() {
308 mySelectedLink->removePoint(mySelectedPoint);
312 void SUPERVGUI_Graph::deleteLink() {
314 if (mySelectedLink->isESInputPort())
315 aName = mySelectedLink->getInputPortES()->getPort()->Name();
317 aName = mySelectedLink->getInputPort()->getPort()->Name();
319 if (aName != "Default") {
320 deleteLink(mySelectedLink);
327 void SUPERVGUI_Graph::deleteLink(SUPERVGUI_Link* theLink) {
328 if (getMain()->getDataflow()->IsDone()) {
329 //update values of input ports of theLink if theLink is deleted and dataflow has been executed any times
330 SUPERVGUI_PortIn* aInPort = theLink->getInputPort();
333 QString aPortValue = QString(aInPort->getPort()->ToString());
334 if ( (aInPort->getPort()->IsParam() || aInPort->getPort()->IsInLine())
336 !aPortValue.isNull()) {
337 //gives a value to an input port
338 theLink->destroyEngine();
339 aInPort->getPort()->Input( Supervision.getEngine()->StringValue( aPortValue ) );
343 theLink->destroyEngine();
346 theLink->destroyEngine();
349 theLink->destroyEngine();
351 myLinksList.removeRef(theLink);
352 if (myLinksList.count() == 0) clearView();
356 void SUPERVGUI_Graph::setAsFromStudy(bool theToStudy) {
357 SUPERVGUI_View::setAsFromStudy(theToStudy);
358 if (theToStudy) return;
360 SUPERVGUI_PortOut* aPortOut;
361 QObjectList* aPortsList = queryList("SUPERVGUI_PortOut");
362 QObjectListIt aPortIt(*aPortsList);
363 while ((aPortOut=(SUPERVGUI_PortOut*)aPortIt.current()) != 0) {
365 if (aPortOut->isInStudy()) {
366 aPortOut->setStudyState(false);
375 * Begins Link sketching
377 void SUPERVGUI_Graph::sketchBegin(SUPERVGUI_Port* thePort) {
378 if (thePort == 0) return;
380 SUPERV_Port aPort = thePort->getPort();
381 myNewLink = new SUPERVGUI_Link(this);
382 mySketchPopup->setItemEnabled(myDelPntItem, false);
383 mySketchPopup->setItemChecked(myOrtoItem, myNewLink->isOrthoMode());
385 myNewLink->setBeginPort(thePort);
387 if (aPort->IsInput()) {
388 if (aPort->Kind() == SUPERV::EndSwitchParameter
390 aPort->Node()->Kind() == SUPERV::EndSwitchNode) {
391 myNewLink->setInputPortES(dynamic_cast<SUPERVGUI_PortInESNode*>(thePort));
394 myNewLink->setInputPort(dynamic_cast<SUPERVGUI_PortIn*>(thePort));
397 myNewLink->setOutputPort(dynamic_cast<SUPERVGUI_PortOut*>(thePort));
401 void SUPERVGUI_Graph::sketchEnd(SUPERVGUI_Port* thePort) {
402 if (!myNewLink) return;
404 bool aIsInput = myNewLink->getBeginPort()->getPort()->IsInput();
405 if (aIsInput && thePort->getPort()->IsInput()
407 !aIsInput && !thePort->getPort()->IsInput()) {
412 SUPERV_Port aPort = thePort->getPort();
413 if (aPort->IsInput()) {
415 int aKind = myNewLink->getOutputPort()->getPort()->Kind();
417 if ((aPort->Kind() == SUPERV::EndSwitchParameter
419 aPort->Node()->Kind() == SUPERV::EndSwitchNode)
421 (aKind == SUPERV::InLineParameter || aKind == SUPERV::ServiceParameter))
423 QString aName(aPort->Name());
424 if (aName != "Default")
425 myNewLink->setInputPortES(dynamic_cast<SUPERVGUI_PortInESNode*>(thePort));
427 else if (aPort->Kind() == SUPERV::DataStreamParameter){
428 myNewLink->setInputPort(dynamic_cast<SUPERVGUI_StreamPortIn*>(thePort));
430 if (aPort->IsLinked()) return;
432 if (aKind == SUPERV::GateParameter || aPort->Kind() == SUPERV::GateParameter) {
433 if (aKind != aPort->Kind() && aKind != SUPERV::InLineParameter
434 && aPort->Kind() != SUPERV::InLineParameter) {
437 else { //connection like Gate <--> Gate
438 myNewLink->setInputPort(dynamic_cast<SUPERVGUI_PortIn*>(thePort));
441 myNewLink->setInputPort(dynamic_cast<SUPERVGUI_PortIn*>(thePort));
446 if (myNewLink->isESInputPort()) {
447 if(aPort->Kind() == SUPERV::InLineParameter || aPort->Kind() == SUPERV::ServiceParameter)
449 myNewLink->setOutputPort(dynamic_cast<SUPERVGUI_PortOut*>(thePort));
454 int aKind = myNewLink->getInputPort()->getPort()->Kind();
456 if (aKind == SUPERV::GateParameter || aPort->Kind() == SUPERV::GateParameter) {
457 if (aKind != aPort->Kind() &&
458 aKind != SUPERV::InLineParameter &&
459 aPort->Kind() != SUPERV::InLineParameter) {
461 } else //connection like Gate <--> Gate
462 myNewLink->setOutputPort(dynamic_cast<SUPERVGUI_PortOut*>(thePort));
463 } else if (aPort->Kind() == SUPERV::DataStreamParameter){
464 myNewLink->setOutputPort(dynamic_cast<SUPERVGUI_StreamPortOut*>(thePort));
466 myNewLink->setOutputPort(dynamic_cast<SUPERVGUI_PortOut*>(thePort));
470 if (myNewLink->isCreationComplete()) { // if everything is defined
471 if (myNewLink->createEngine()) {
472 myLinksList.append(myNewLink);
475 QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_CANT_CREATE_LINK"));
483 * Returns true if presentation of link exists
485 bool SUPERVGUI_Graph::isLinkPrsExists(SUPERV_Link theLink) {
486 SUPERVGUI_Link* aTmpLink;
487 for (aTmpLink = myLinksList.first(); aTmpLink; aTmpLink = myLinksList.next()) {
488 SUPERVGUI_PortOut* aOutPort = aTmpLink->getOutputPort();
489 if (strcmp(aOutPort->getPort()->Node()->Name(),
490 theLink->OutPort()->Node()->Name()) == 0) {
491 QString aName(theLink->OutPort()->Name());
493 if (aOutPort->name() == aName) {
503 * Creates link presentation from link engine
504 * Returns false if fails
506 bool SUPERVGUI_Graph::createLinkPrs(SUPERV_Link theLink) {
507 SUPERVGUI_Link* aNewLink = new SUPERVGUI_Link(this, theLink);
510 SUPERVGUI_Node* aOutNode = (SUPERVGUI_Node*)
511 child(theLink->OutPort()->Node()->Name(), "SUPERVGUI_Node");
513 QString aName(theLink->OutPort()->Name());
515 SUPERVGUI_PortOut* aOutPort = (SUPERVGUI_PortOut*)
516 aOutNode->child(aName, "SUPERVGUI_PortOut");
518 aNewLink->setOutputPort(aOutPort);
528 SUPERVGUI_Node* aInNode = (SUPERVGUI_Node*)
529 child(theLink->InPort()->Node()->Name(), "SUPERVGUI_Node");
531 QString aName(theLink->InPort()->Name());
533 if (theLink->InPort()->Kind() == SUPERV::EndSwitchParameter) {
534 //If input port is EndSwitchParameter
535 SUPERVGUI_PortInESNode* aInPortES =(SUPERVGUI_PortInESNode*)
536 aInNode->child(aName, "SUPERVGUI_PortInESNode"); //returns null
538 aNewLink->setInputPortES(aInPortES);
544 SUPERVGUI_PortIn* aInPort =(SUPERVGUI_PortIn*)
545 aInNode->child(aName, "SUPERVGUI_PortIn");
547 aNewLink->setInputPort(aInPort);
557 aNewLink->setVisible(!myIsControlView);
558 myLinksList.append(aNewLink);
563 void SUPERVGUI_Graph::delLastPnt() {
565 myNewLink->delLastTmpPoint();
569 void SUPERVGUI_Graph::delCreatingLink() {
570 myNewLink->abortCreation();
576 void SUPERVGUI_Graph::setOrtho() {
578 bool aIsOrtho = !mySketchPopup->isItemChecked(myOrtoItem);
579 myNewLink->setOrthoMode(aIsOrtho);
580 mySketchPopup->setItemChecked(myOrtoItem, aIsOrtho);
586 void SUPERVGUI_Graph::setFullView() {
587 QObjectList* aNodeList = queryList("SUPERVGUI_Node");
588 QObjectListIt aIt(*aNodeList);
589 SUPERVGUI_Node* aNode;
590 while ((aNode=(SUPERVGUI_Node*)aIt.current()) != 0) {
597 SUPERVGUI_Link* aLink;
598 for (aLink = myLinksList.first(); aLink; aLink = myLinksList.next()) {
599 aLink->setVisible(true);
602 myIsControlView = false;
606 void SUPERVGUI_Graph::setControlView() {
607 QObjectList* aNodeList = queryList("SUPERVGUI_Node");
608 QObjectListIt aIt(*aNodeList);
609 SUPERVGUI_Node* aNode;
610 while ((aNode=(SUPERVGUI_Node*)aIt.current()) != 0) {
616 SUPERVGUI_Link* aLink;
617 for (aLink = myLinksList.first(); aLink; aLink = myLinksList.next()) {
618 aLink->setVisible(false);
620 QString aOutName(aLink->getEngineLink()->OutPort()->Node()->Name());
621 QString aInName(aLink->getEngineLink()->InPort()->Node()->Name());
622 QString aKey = aOutName + aInName;
624 if (!myCtrlLinks.contains(aKey)) {
625 SUPERVGUI_GraphNode* aOutNode = (SUPERVGUI_GraphNode*)
626 child(aOutName, "SUPERVGUI_GraphNode");
627 if (!aOutNode) continue;
628 SUPERVGUI_GraphNode* aInNode = (SUPERVGUI_GraphNode*)
629 child(aInName, "SUPERVGUI_GraphNode");
630 if (!aInNode) continue;
632 myCtrlLinks[aKey] = SUPERVGUI_CtrlLink(this, aOutNode, aInNode);
636 myIsControlView = true;
640 void SUPERVGUI_Graph::deleteNode(SUPERVGUI_Node* theNode) {
641 theNode->close(true);