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"
39 #include <sys/timeb.h>
43 #define UPDATECONTROLNODES(NodesName) \
44 n = nodes->NodesName.length(); \
45 for (int i=0; i<n; i++) { \
46 SUPERV_CNode aCNode = SUPERV::CNode::_narrow(nodes->NodesName[i]); \
47 SUPERV_CNode aCNodeEnd = SUPERV::CNode::_narrow(nodes->NodesName[i]->Coupled()); \
48 ihmNode = (SUPERVGUI_Node *)child(aCNode->Name(), "SUPERVGUI_Node"); \
49 if (ihmNode == NULL) { \
50 main->addControlNode(aCNode, aCNodeEnd, false); \
52 ResizeGraph(ihmNode, aCNode->X(), aCNode->Y()); \
53 moveChild(ihmNode, aCNode->X(), aCNode->Y()); \
54 ihmList->removeRef(ihmNode); \
56 aEndNodePrs = (SUPERVGUI_EndControlNode*)child(aCNodeEnd->Name(), "SUPERVGUI_EndControlNode"); \
57 ResizeGraph(aEndNodePrs, aCNodeEnd->X(), aCNodeEnd->Y()); \
58 moveChild(aEndNodePrs, aCNodeEnd->X(), aCNodeEnd->Y()); \
59 ihmList->removeRef(aEndNodePrs); \
60 aEndNodePrs->sync(); \
65 #define UPDATENODES(NodesName, FuncName) \
66 n = nodes->NodesName.length(); \
67 for (int i=0; i<n; i++) { \
68 SUPERV_CNode aCNode = SUPERV::CNode::_narrow(nodes->NodesName[i]); \
69 ihmNode = (SUPERVGUI_Node *)child(aCNode->Name(), "SUPERVGUI_Node"); \
70 if (ihmNode == NULL) { \
71 main->FuncName(aCNode); \
73 ResizeGraph(ihmNode, aCNode->X(), aCNode->Y()); \
74 moveChild(ihmNode, aCNode->X(), aCNode->Y()); \
75 ihmList->removeRef(ihmNode); \
81 SUPERVGUI_Graph::SUPERVGUI_Graph(SUPERVGUI_Main* m):
85 Trace("SUPERVGUI_Graph::SUPERVGUI_Graph");
86 myIsControlView = false;
87 myLinksList.setAutoDelete(true);
88 viewport()->setMouseTracking(true);
90 resizeContents(GRAPH_WIDTH, GRAPH_HEIGHT);
92 if (SUPERV_isNull(main->getDataflow())) return;
95 //create sketching popup menu
96 mySketchPopup = new QPopupMenu(viewport());
97 if (!mySketchPopup->isCheckable())
98 mySketchPopup->setCheckable(true);
99 myDelPntItem = mySketchPopup->insertItem(tr("MSG_DEL_LAST_PNT"), this, SLOT(delLastPnt()));
100 mySketchPopup->insertItem(tr("MSG_DEL_LINK"), this, SLOT(delCreatingLink()));
101 myOrtoItem = mySketchPopup->insertItem(tr("MSG_ORTHO_LINE"), this, SLOT(setOrtho()));
103 //create link popup menu
104 myLinkPopup = new QPopupMenu(viewport());
105 myDelLinkItem = myLinkPopup->insertItem(tr("MSG_DELLINK"), this, SLOT(deleteLink()));
106 myAddLinkPntItem = myLinkPopup->insertItem(tr("MSG_ADD_POINT"), this, SLOT(addPoint()));
107 myDelLinkPntItem = myLinkPopup->insertItem(tr("MSG_DEL_POINT"), this, SLOT(deletePoint()));
112 SUPERVGUI_Graph::~SUPERVGUI_Graph() {
116 * Synchronizes Graph presentation with internal graph structure
118 void SUPERVGUI_Graph::sync() {
119 if (SUPERV_isNull(main->getDataflow())) return;
123 SUPERVGUI_Node* ihmNode;
124 QObjectList* ihmList = queryList("SUPERVGUI_Node");
125 SUPERV_Nodes nodes = main->getDataflow()->Nodes();
127 MESSAGE("CNodes="<<nodes->CNodes.length());
128 MESSAGE("FNodes="<<nodes->FNodes.length());
129 MESSAGE("INodes="<<nodes->INodes.length());
130 MESSAGE("GNodes="<<nodes->GNodes.length());
131 MESSAGE("LNodes="<<nodes->LNodes.length());
132 MESSAGE("SNodes="<<nodes->SNodes.length());
135 UPDATENODES(CNodes, addComputeNode);
136 UPDATENODES(FNodes, addComputeNode);
137 UPDATENODES(INodes, addComputeNode);
138 UPDATENODES(GNodes, addGOTONode);
140 SUPERVGUI_EndControlNode* aEndNodePrs;
141 UPDATECONTROLNODES(LNodes);
142 UPDATECONTROLNODES(SNodes);
144 QObjectListIt i(*ihmList);
145 while ((ihmNode=(SUPERVGUI_Node*)i.current()) != 0) {
147 ihmNode->close(true);
151 ihmList = queryList("SUPERVGUI_GraphNode");
153 SUPERVGUI_GraphNode* aGraphNode;
154 while ((aGraphNode=(SUPERVGUI_GraphNode*)i.current()) != 0) {
156 aGraphNode->updateLinksPrs();
165 * Reimplemented for repainting links
167 bool SUPERVGUI_Graph::eventFilter(QObject* object, QEvent* event) {
168 if (event->type() == QEvent::Paint) {
172 return QScrollView::eventFilter(object, event);
177 * Clears content of Graph (links)
179 void SUPERVGUI_Graph::clearView() {
180 QPainter aPainter(viewport());
181 aPainter.eraseRect(viewport()->rect());
186 * Draws links using off screen buffer
188 void SUPERVGUI_Graph::draw() {
193 if (myLinksList.count() == 0) {
196 int aWidth = viewport()->width();
197 int aHeight = viewport()->height();
198 QPixmap aPixmap(aWidth, aHeight);
199 aPixmap.setOptimization(QPixmap::BestOptim);
200 aPixmap.fill(viewport()->paletteBackgroundColor());
202 QPainter aPainter(&aPixmap);
203 QPoint aPos = viewportToContents(viewport()->pos());
205 if (myIsControlView) {
206 SUPERVGUI_CtrlLink* aLink;
207 QMap<QString, SUPERVGUI_CtrlLink>::Iterator it;
208 for ( it = myCtrlLinks.begin(); it != myCtrlLinks.end(); ++it ) {
209 it.data().paint(&aPainter, false);
212 SUPERVGUI_Link* aLink;
213 for (aLink = myLinksList.first(); aLink; aLink = myLinksList.next()) {
214 aLink->isInRect(aPos.x(), aPos.y(), aWidth, aHeight);
215 if (aLink->isInRect(aPos.x(), aPos.y(), aWidth, aHeight)) {
216 aLink->paint(&aPainter, false);
220 bitBlt(viewport(), 0, 0,
221 &aPixmap, 0, 0, aWidth, aHeight,
225 myNewLink->repaintSketch();
230 ulong aTm = 1000*(aTm2.time-aTm1.time)+(aTm2.millitm-aTm1.millitm);
231 cout<<"### Time="<<aTm<<endl;
236 void SUPERVGUI_Graph::contentsMousePressEvent(QMouseEvent* e) {
237 Trace("SUPERVGUI_Graph::contentsMousePressEvent");
238 if ( e->button() == Qt::RightButton) {
240 main->showPopup(mySketchPopup, e);
242 SUPERVGUI_Link* aLink = SUPERVGUI_Link::getSelectedLink();
243 if (aLink && main->isEditable()) {
244 myLinkPopup->setItemEnabled(myAddLinkPntItem,
245 !aLink->haveSelectedPoint());
246 myLinkPopup->setItemEnabled(myDelLinkPntItem,
247 aLink->haveSelectedPoint());
250 if (!aLink->isESInputPort()) {
251 SUPERV::KindOfPort aOutType = aLink->getOutputPort()->getPort()->Kind();
252 SUPERV::KindOfPort aInType = aLink->getInputPort()->getPort()->Kind();
253 myLinkPopup->setItemEnabled(myDelLinkItem,
254 ((aOutType != SUPERV::LoopParameter)
256 (aInType != SUPERV::LoopParameter)));
259 myMousePos = e->pos();
260 mySelectedLink = aLink;
261 mySelectedPoint = mySelectedLink->getSelectedPoint();
262 main->showPopup(myLinkPopup, e);
265 main->showPopup(myPopup, e);
269 emit mousePressed(e);
271 SUPERVGUI_View::contentsMousePressEvent(e);
275 void SUPERVGUI_Graph::contentsMouseReleaseEvent(QMouseEvent* e) {
276 Trace("SUPERVGUI_Graph::contentsMouseReleaseEvent");
277 if (myNewLink && (e->button() == Qt::LeftButton)) {
278 myNewLink->addTmpPoint(e->pos());
279 mySketchPopup->setItemEnabled(myDelPntItem, true);
281 emit mouseReleased(e);
282 SUPERVGUI_View::contentsMouseReleaseEvent(e);
286 void SUPERVGUI_Graph::contentsMouseMoveEvent(QMouseEvent* e) {
287 Trace("SUPERVGUI_Graph::contentsMouseMoveEvent");
289 myNewLink->drawTo(e->pos());
292 SUPERVGUI_View::contentsMouseMoveEvent(e);
296 void SUPERVGUI_Graph::addPoint() {
297 mySelectedLink->addPoint(myMousePos.x(), myMousePos.y());
301 void SUPERVGUI_Graph::deletePoint() {
302 mySelectedLink->removePoint(mySelectedPoint);
306 void SUPERVGUI_Graph::deleteLink() {
308 if (mySelectedLink->isESInputPort())
309 aName = mySelectedLink->getInputPortES()->getPort()->Name();
311 aName = mySelectedLink->getInputPort()->getPort()->Name();
313 if (aName != "Default") {
314 deleteLink(mySelectedLink);
321 void SUPERVGUI_Graph::deleteLink(SUPERVGUI_Link* theLink) {
322 theLink->destroyEngine();
323 myLinksList.removeRef(theLink);
324 if (myLinksList.count() == 0) clearView();
328 void SUPERVGUI_Graph::setAsFromStudy(bool theToStudy) {
329 SUPERVGUI_View::setAsFromStudy(theToStudy);
330 if (theToStudy) return;
332 SUPERVGUI_PortOut* aPortOut;
333 QObjectList* aPortsList = queryList("SUPERVGUI_PortOut");
334 QObjectListIt aPortIt(*aPortsList);
335 while ((aPortOut=(SUPERVGUI_PortOut*)aPortIt.current()) != 0) {
337 if (aPortOut->isInStudy()) {
338 aPortOut->setStudyState(false);
347 * Begins Link sketching
349 void SUPERVGUI_Graph::sketchBegin(SUPERVGUI_Port* thePort) {
350 if (thePort == 0) return;
352 SUPERV_Port aPort = thePort->getPort();
353 myNewLink = new SUPERVGUI_Link(this);
354 mySketchPopup->setItemEnabled(myDelPntItem, false);
355 mySketchPopup->setItemChecked(myOrtoItem, myNewLink->isOrthoMode());
357 myNewLink->setBeginPort(thePort);
359 if (aPort->IsInput()) {
360 if (aPort->Kind() == SUPERV::EndSwitchParameter
362 aPort->Node()->Kind() == SUPERV::EndSwitchNode) {
363 myNewLink->setInputPortES(dynamic_cast<SUPERVGUI_PortInESNode*>(thePort));
366 myNewLink->setInputPort(dynamic_cast<SUPERVGUI_PortIn*>(thePort));
369 myNewLink->setOutputPort(dynamic_cast<SUPERVGUI_PortOut*>(thePort));
373 void SUPERVGUI_Graph::sketchEnd(SUPERVGUI_Port* thePort) {
374 if (!myNewLink) return;
376 bool aIsInput = myNewLink->getBeginPort()->getPort()->IsInput();
377 if (aIsInput && thePort->getPort()->IsInput()
379 !aIsInput && !thePort->getPort()->IsInput()) {
384 SUPERV_Port aPort = thePort->getPort();
385 if (aPort->IsInput()) {
387 int aKind = myNewLink->getOutputPort()->getPort()->Kind();
389 if ((aPort->Kind() == SUPERV::EndSwitchParameter
391 aPort->Node()->Kind() == SUPERV::EndSwitchNode)
393 (aKind == SUPERV::InLineParameter || aKind == SUPERV::ServiceParameter))
395 QString aName(aPort->Name());
396 if (aName != "Default")
397 myNewLink->setInputPortES(dynamic_cast<SUPERVGUI_PortInESNode*>(thePort));
400 if (aPort->IsLinked()) return;
402 if (aKind == SUPERV::GateParameter || aPort->Kind() == SUPERV::GateParameter) {
403 if (aKind != aPort->Kind() && aKind != SUPERV::InLineParameter
404 && aPort->Kind() != SUPERV::InLineParameter) {
407 else { //connection like Gate <--> Gate
408 myNewLink->setInputPort(dynamic_cast<SUPERVGUI_PortIn*>(thePort));
411 myNewLink->setInputPort(dynamic_cast<SUPERVGUI_PortIn*>(thePort));
416 if (myNewLink->isESInputPort()) {
417 if(aPort->Kind() == SUPERV::InLineParameter || aPort->Kind() == SUPERV::ServiceParameter)
419 myNewLink->setOutputPort(dynamic_cast<SUPERVGUI_PortOut*>(thePort));
425 int aKind = myNewLink->getInputPort()->getPort()->Kind();
427 if (aKind == SUPERV::GateParameter || aPort->Kind() == SUPERV::GateParameter) {
428 if (aKind != aPort->Kind() && aKind != SUPERV::InLineParameter
429 && aPort->Kind() != SUPERV::InLineParameter) {
432 else //connection like Gate <--> Gate
433 myNewLink->setOutputPort(dynamic_cast<SUPERVGUI_PortOut*>(thePort));
435 myNewLink->setOutputPort(dynamic_cast<SUPERVGUI_PortOut*>(thePort));
439 if (myNewLink->isCreationComplete()) { // if everything is defined
440 if (myNewLink->createEngine()) {
441 myLinksList.append(myNewLink);
444 QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_CANT_CREATE_LINK"));
452 * Returns true if presentation of link exists
454 bool SUPERVGUI_Graph::isLinkPrsExists(SUPERV_Link theLink) {
455 SUPERVGUI_Link* aTmpLink;
456 for (aTmpLink = myLinksList.first(); aTmpLink; aTmpLink = myLinksList.next()) {
457 SUPERVGUI_PortOut* aOutPort = aTmpLink->getOutputPort();
458 if (strcmp(aOutPort->getPort()->Node()->Name(),
459 theLink->OutPort()->Node()->Name()) == 0) {
460 QString aName(theLink->OutPort()->Name());
462 if (aOutPort->name() == aName) {
472 * Creates link presentation from link engine
473 * Returns false if fails
475 bool SUPERVGUI_Graph::createLinkPrs(SUPERV_Link theLink) {
476 SUPERVGUI_Link* aNewLink = new SUPERVGUI_Link(this, theLink);
479 SUPERVGUI_Node* aOutNode = (SUPERVGUI_Node*)
480 child(theLink->OutPort()->Node()->Name(), "SUPERVGUI_Node");
482 QString aName(theLink->OutPort()->Name());
484 SUPERVGUI_PortOut* aOutPort = (SUPERVGUI_PortOut*)
485 aOutNode->child(aName, "SUPERVGUI_PortOut");
487 aNewLink->setOutputPort(aOutPort);
497 SUPERVGUI_Node* aInNode = (SUPERVGUI_Node*)
498 child(theLink->InPort()->Node()->Name(), "SUPERVGUI_Node");
500 QString aName(theLink->InPort()->Name());
502 if (theLink->InPort()->Kind() == SUPERV::EndSwitchParameter) {
503 //If input port is EndSwitchParameter
504 SUPERVGUI_PortInESNode* aInPortES =(SUPERVGUI_PortInESNode*)
505 aInNode->child(aName, "SUPERVGUI_PortInESNode"); //returns null
507 aNewLink->setInputPortES(aInPortES);
513 SUPERVGUI_PortIn* aInPort =(SUPERVGUI_PortIn*)
514 aInNode->child(aName, "SUPERVGUI_PortIn");
516 aNewLink->setInputPort(aInPort);
526 aNewLink->setVisible(!myIsControlView);
527 myLinksList.append(aNewLink);
532 void SUPERVGUI_Graph::delLastPnt() {
534 myNewLink->delLastTmpPoint();
538 void SUPERVGUI_Graph::delCreatingLink() {
539 myNewLink->abortCreation();
545 void SUPERVGUI_Graph::setOrtho() {
547 bool aIsOrtho = !mySketchPopup->isItemChecked(myOrtoItem);
548 myNewLink->setOrthoMode(aIsOrtho);
549 mySketchPopup->setItemChecked(myOrtoItem, aIsOrtho);
555 void SUPERVGUI_Graph::setFullView() {
556 QObjectList* aNodeList = queryList("SUPERVGUI_Node");
557 QObjectListIt aIt(*aNodeList);
558 SUPERVGUI_Node* aNode;
559 while ((aNode=(SUPERVGUI_Node*)aIt.current()) != 0) {
566 SUPERVGUI_Link* aLink;
567 for (aLink = myLinksList.first(); aLink; aLink = myLinksList.next()) {
568 aLink->setVisible(true);
571 myIsControlView = false;
575 void SUPERVGUI_Graph::setControlView() {
576 QObjectList* aNodeList = queryList("SUPERVGUI_Node");
577 QObjectListIt aIt(*aNodeList);
578 SUPERVGUI_Node* aNode;
579 while ((aNode=(SUPERVGUI_Node*)aIt.current()) != 0) {
585 SUPERVGUI_Link* aLink;
586 for (aLink = myLinksList.first(); aLink; aLink = myLinksList.next()) {
587 aLink->setVisible(false);
589 QString aOutName(aLink->getEngineLink()->OutPort()->Node()->Name());
590 QString aInName(aLink->getEngineLink()->InPort()->Node()->Name());
591 QString aKey = aOutName + aInName;
593 if (!myCtrlLinks.contains(aKey)) {
594 SUPERVGUI_GraphNode* aOutNode = (SUPERVGUI_GraphNode*)
595 child(aOutName, "SUPERVGUI_GraphNode");
596 if (!aOutNode) continue;
597 SUPERVGUI_GraphNode* aInNode = (SUPERVGUI_GraphNode*)
598 child(aInName, "SUPERVGUI_GraphNode");
599 if (!aInNode) continue;
601 myCtrlLinks[aKey] = SUPERVGUI_CtrlLink(this, aOutNode, aInNode);
605 myIsControlView = true;
609 void SUPERVGUI_Graph::deleteNode(SUPERVGUI_Node* theNode) {
610 theNode->close(true);