Salome HOME
Fix problem with table of contents resizing
[modules/superv.git] / src / SUPERVGUI / SUPERVGUI_CanvasView.cxx
index 2f6f04ece4f8c53d22ed57b7cf2a683d9fba079c..48dcf44a5994e04b4ddd9d4d56bb628f0a35ca81 100644 (file)
@@ -1,21 +1,40 @@
 //  SUPERV SUPERVGUI : GUI for Supervisor component
 //
-//  Copyright (C) 2003  CEA/DEN, EDF R&D
-//
-//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library 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 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 //  File   : SUPERVGUI_CanvasView.cxx
 //  Author : Natalia KOPNOVA
 //  Module : SUPERV
 
-using namespace std;
+#include "SUPERVGUI.h"
 #include "SUPERVGUI_CanvasView.h"
 #include "SUPERVGUI_Main.h"
 #include "SUPERVGUI_CanvasNode.h"
 #include "SUPERVGUI_CanvasPort.h"
 #include "SUPERVGUI_CanvasLink.h"
 #include "SUPERVGUI_CanvasNodePrs.h"
-#include "QAD_Config.h"
+#include "SUPERVGUI_Clipboard.h"
+
+#include "SUPERVGUI_ArrayView.h" //for tooltip testing
+
+#include "SUIT_MessageBox.h"
 
 #include <qpixmap.h>
 #include <qcolordialog.h>
@@ -64,6 +83,7 @@ const char* imageZoomCursor[] = {
 
 QPixmap zoomPix(imageZoomCursor);
 QCursor zoom2Cursor(zoomPix);
+QCursor handCursor(Qt::PointingHandCursor);
 
 #if QT_VERSION >= 0x030005
 QCursor pan2Cursor(Qt::SizeAllCursor);
@@ -77,11 +97,14 @@ SUPERVGUI_CanvasView::SUPERVGUI_CanvasView(SUPERVGUI_Canvas* theCanvas, SUPERVGU
 {
   setName("CanvasView");
 
+  myIsPanBtnClicked = false;
   myIsPanActivated = false;
+  myIsFitWRActivated = false;
   myIsZoomActivated = false;
   myIsLinkCreating = false;
 
   myAddStudyItem = 0;
+  mySelectedRect = 0;
   myCursor = cursor();
 
   myTimer = new QTimer(this);
@@ -89,19 +112,22 @@ SUPERVGUI_CanvasView::SUPERVGUI_CanvasView(SUPERVGUI_Canvas* theCanvas, SUPERVGU
 
   myPopup = new QPopupMenu(viewport());
 
-  if (myMain->isEditable()) {
+  const bool isEdit = myMain->isEditable();
+  if (isEdit) {
     myPopup->insertItem(tr("MSG_ADD_NODE"), myMain, SLOT(addNode()));
+
+    // Paste Node functionality
+    SUPERVGUI_Clipboard* aCB = SUPERVGUI_Clipboard::getClipboard();
+    myPasteNodeItem = myPopup->insertItem(tr("ITM_PASTE_NODE"), aCB, SLOT(pasteNode()));
+
     myPopup->insertItem(tr("MSG_INS_FILE"), myMain, SLOT(insertFile()));
     myPopup->insertSeparator();
   }
 
   QPopupMenu* aViewPopup = new QPopupMenu(viewport());
-  //  aViewPopup->insertItem(tr("POP_FULLVIEW"), myMain, SLOT(showFullGraph()));
   aViewPopup->insertItem(tr("POP_FULLVIEW"), myMain, SLOT(showCanvas()));
   aViewPopup->insertItem(tr("POP_CONTROLVIEW"), myMain, SLOT(showContolFlow()));
-  aViewPopup->insertItem(tr("POP_TABLEVIEW"), myMain, SLOT(showTable()));
-  //  aViewPopup->insertItem("Previous Full View", myMain, SLOT(showFullGraph()));
-  //  aViewPopup->insertItem(tr("POP_CANVASVIEW"), myMain, SLOT(showCanvas()));
+  aViewPopup->insertItem(tr("POP_TABLEVIEW"), myMain, SLOT(showCanvasTable()));
 
   myPopup->insertItem(tr("POP_VIEW"), aViewPopup);
   myPopup->insertSeparator();
@@ -111,13 +137,17 @@ SUPERVGUI_CanvasView::SUPERVGUI_CanvasView(SUPERVGUI_Canvas* theCanvas, SUPERVGU
   aZoomPopup->insertItem("100%", this, SLOT(zoomReset()));
   aZoomPopup->insertItem("50%", this, SLOT(zoomOut()));
   aZoomPopup->insertSeparator();
-  aZoomPopup->insertItem("Fit All", this, SLOT(fitAll()));
+  //mkr: "Fit within rectangle" functionality
+  aZoomPopup->insertItem(tr("POP_FITWITHINRECT"), this, SLOT(fitWithinRect()));
+  aZoomPopup->insertSeparator();
+  aZoomPopup->insertItem(tr("POP_FITALL"), this, SLOT(fitAll()));
+  
 
-  myPopup->insertItem("Zoom", aZoomPopup);
+  myPopup->insertItem(tr("POP_ZOOM"), aZoomPopup);
   myPopup->insertSeparator();
 
-  myAddStudyItem = myPopup->insertItem(tr("MSG_ADD_STUDY"), this, SLOT(addToStudy()));
-  myPopup->insertItem(tr("MSG_CHANGE_INFO"), myMain, SLOT(changeInformation()));
+  myAddStudyItem = myPopup->insertItem(tr("MSG_ADD_STUDY"), myMain, SLOT(addDataflowToStudy()));
+  myPopup->insertItem(tr(isEdit ? "MSG_CHANGE_INFO" : "MSG_INFO"), myMain, SLOT(changeInformation()));
   myPopup->insertSeparator();
 
   myPopup->insertItem(tr("MSG_COPY_DATAFLOW"), myMain, SLOT(copy()));
@@ -134,16 +164,30 @@ SUPERVGUI_CanvasView::SUPERVGUI_CanvasView(SUPERVGUI_Canvas* theCanvas, SUPERVGU
   myDelPntItem = mySketchPopup->insertItem(tr("MSG_DEL_LAST_PNT"), this, SLOT(deletePoint()));
   mySketchPopup->insertItem(tr("MSG_DEL_LINK"), this, SLOT(cancelSketch()));
   myOrtoItem = mySketchPopup->insertItem(tr("MSG_ORTHO_LINE"), this, SLOT(setOrthoMode()));
+
+  
+  // add "change dataflow parameters" popup item
+  myPopup->insertSeparator();
+  myDSParamsItem = myPopup->insertItem( tr( "MSG_SET_GRAPHPARAMS" ), myMain, SLOT( changeDSGraphParameters() ) );
+
+  SUPERVGraph_ViewFrame* anActiveVF = (SUPERVGraph_ViewFrame*)myMain->parent();
+  if ( anActiveVF ) {
+    myPopup->insertSeparator();
+    myShowToolBarItem = myPopup->insertItem( tr( "MEN_SHOW_TOOLBAR" ), myMain, SLOT( onShowToolbar() ) );
+  }
+
+  // mkr : PAL8237
+  connect(this, SIGNAL(objectCreated()), myMain, SLOT(onObjectCreatedDeleted()));
 }
  
 
 SUPERVGUI_CanvasView::~SUPERVGUI_CanvasView()
 {
+  SUPERVGUI_Clipboard::setNullClipboard();
 }
 
 void SUPERVGUI_CanvasView::contentsMousePressEvent(QMouseEvent* theEvent) 
 {
-  //  cout << "===> SUPERVGUI_CanvasView::contentsMousePressEvent(...) "   << endl;
   myPoint = inverseWorldMatrix().map(theEvent->pos());
   myGlobalPoint = theEvent->globalPos();
   myCurrentItem = 0;
@@ -153,7 +197,7 @@ void SUPERVGUI_CanvasView::contentsMousePressEvent(QMouseEvent* theEvent)
 
   if (((theEvent->button() == Qt::MidButton) &&
        (theEvent->state() == Qt::ControlButton)) || 
-      myIsPanActivated) {
+      myIsPanBtnClicked) {
     myIsPanActivated = true;
     myCursor = cursor();
     setCursor(pan2Cursor);
@@ -207,46 +251,56 @@ void SUPERVGUI_CanvasView::contentsMousePressEvent(QMouseEvent* theEvent)
       }
     }
        
-    myPopup->setItemEnabled(myAddStudyItem, !myMain->isFromStudy());
+    myPopup->setItemEnabled(myAddStudyItem, !myMain->isDataflowInStudy());
+    // Paste Node functionality
+    SUPERVGUI_Clipboard* aCB = SUPERVGUI_Clipboard::getClipboard(); 
+    myPopup->setItemEnabled(myPasteNodeItem, aCB->isCopyNode() );
+       
+    myPopup->setItemEnabled( myDSParamsItem, isHavingStreamPort()/*myMain->getDataflow()->IsStreamGraph()*/ );
+
+    myPopup->setItemEnabled( myShowToolBarItem, !((SUPERVGraph_ViewFrame*)myMain->parent())->getToolBar()->isVisible() );
+
     myMain->showPopup(myPopup, theEvent);
     return;
   }
 
   if (theEvent->button() == Qt::LeftButton) {
-    QCanvasItemList l = canvas()->collisions(myPoint);
-    if (myIsLinkCreating) {
-      for (QCanvasItemList::Iterator it = l.begin(); it != l.end(); ++it) {
-       if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_Node) {
-         SUPERVGUI_CanvasNodePrs* aNodePrs = (SUPERVGUI_CanvasNodePrs*) (*it);
-         QObject* anObj = aNodePrs->getObject(myPoint);
-         if (anObj->inherits("SUPERVGUI_CanvasPort")) {
-           endSketch((SUPERVGUI_CanvasPort*)anObj);
-           return;
+    if (!myIsFitWRActivated) {//not moving items if fit within rectangle 
+                              //functionality is enable
+      QCanvasItemList l = canvas()->collisions(myPoint);
+      if (myIsLinkCreating) {
+       for (QCanvasItemList::Iterator it = l.begin(); it != l.end(); ++it) {
+         if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_Node) {
+           SUPERVGUI_CanvasNodePrs* aNodePrs = (SUPERVGUI_CanvasNodePrs*) (*it);
+           QObject* anObj = aNodePrs->getObject(myPoint);
+           if (anObj->inherits("SUPERVGUI_CanvasPort")) {
+             endSketch((SUPERVGUI_CanvasPort*)anObj);
+             return;
+           }
+           else {
+             myCurrentItem = *it;
+             ((SUPERVGUI_CanvasNodePrs*)myCurrentItem)->setZ(2);
+             ((SUPERVGUI_CanvasNodePrs*)myCurrentItem)->setMoving(true);
+             return;
+           }
          }
-         else {
-           myCurrentItem = *it;
-           ((SUPERVGUI_CanvasNodePrs*)myCurrentItem)->setZ(2);
-           ((SUPERVGUI_CanvasNodePrs*)myCurrentItem)->setMoving(true);
-           return;
+         if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_Hook) {
+           SUPERVGUI_CanvasHookPrs* aHookPrs = (SUPERVGUI_CanvasHookPrs*) (*it);
+           QObject* anObj = aHookPrs->getObject();
+           if (anObj->inherits("SUPERVGUI_CanvasPort")) {
+             endSketch((SUPERVGUI_CanvasPort*)anObj);
+             return;
+           }
          }
        }
-       if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_Hook) {
-         SUPERVGUI_CanvasHookPrs* aHookPrs = (SUPERVGUI_CanvasHookPrs*) (*it);
-         QObject* anObj = aHookPrs->getObject();
-         if (anObj->inherits("SUPERVGUI_CanvasPort")) {
-           endSketch((SUPERVGUI_CanvasPort*)anObj);
-           return;
-         }
+       if (myLinkBuilder) {
+         myLinkBuilder->addNextPoint(myPoint, mySketchPopup->isItemChecked(myOrtoItem));
+         canvas()->update();
+         mySketchPopup->setItemEnabled(myDelPntItem, true);
+         return;
        }
       }
-      if (myLinkBuilder) {
-       myLinkBuilder->addNextPoint(myPoint, mySketchPopup->isItemChecked(myOrtoItem));
-       canvas()->update();
-       mySketchPopup->setItemEnabled(myDelPntItem, true);
-       return;
-      }
-    }
-
+      
 //  if (myMain->isEditable()) { // allow to move nodes and link point on imported graph
       for (QCanvasItemList::Iterator it = l.begin(); it != l.end(); ++it) {
        if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_Node) {
@@ -263,8 +317,25 @@ void SUPERVGUI_CanvasView::contentsMousePressEvent(QMouseEvent* theEvent)
            return;
          }
        }
+       if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_LinkEdge) {
+         //mkr: for moving segment of link
+         SUPERVGUI_CanvasEdgePrs* aPrs = (SUPERVGUI_CanvasEdgePrs*) (*it);
+         if (aPrs->getLink()->getInputPort()->getConnectionPoint() == aPrs->startPoint()
+             ||
+           aPrs->getLink()->getInputPort()->getConnectionPoint() == aPrs->endPoint()
+             ||
+             aPrs->getLink()->getOutputPort()->getConnectionPoint() == aPrs->startPoint()
+             ||
+             aPrs->getLink()->getOutputPort()->getConnectionPoint() == aPrs->endPoint()) {
+           return;
+         }
+         myCurrentItem = *it;
+         aPrs->setMoving(true);
+         return;
+       }
       }
 //  }
+    } 
   }
 }
 
@@ -284,13 +355,16 @@ void SUPERVGUI_CanvasView::contentsMouseMoveEvent(QMouseEvent* theEvent)
     myLinkBuilder->setFloatPoint(p);
     canvas()->update();
   }
-      
+   
   if (myCurrentItem) {
     //    setHilighted(0);
-    double cx = myCurrentItem->x() - myPoint.x();
-    double cy = myCurrentItem->y() - myPoint.y();
-    if (p.x()+cx < 0) p.setX(-(int)cx);
-    if (p.y()+cy < 0) p.setY(-(int)cy);
+    if (myCurrentItem->x() && myCurrentItem->y()) {
+      double cx = myCurrentItem->x() - myPoint.x();
+      double cy = myCurrentItem->y() - myPoint.y();
+      
+      if (p.x()+cx < 0) p.setX(-(int)cx);
+      if (p.y()+cy < 0) p.setY(-(int)cy);
+    }
     myCurrentItem->moveBy(p.x() - myPoint.x(), 
                          p.y() - myPoint.y());
     myPoint = p;
@@ -337,6 +411,30 @@ void SUPERVGUI_CanvasView::contentsMouseMoveEvent(QMouseEvent* theEvent)
     return;
   }
 
+  //mkr: "Fit within rectangle" functionality
+  if (myIsFitWRActivated) {
+    int aLX, aTY; //left x and top y
+    if (myPoint.x() < p.x()) aLX = myPoint.x();
+    else aLX = p.x();
+    if (myPoint.y() < p.y()) aTY = myPoint.y();
+    else aTY = p.y();
+    QRect aRect(aLX, aTY, abs(myPoint.x()-p.x()), abs(myPoint.y()-p.y()));
+    QCanvasRectangle* aRect1 = new QCanvasRectangle(aRect, canvas());
+
+    //hide old selected rectangle
+    if (mySelectedRect)
+      mySelectedRect->hide();
+    //draw new selected rectangle
+    QPen pen(Qt::SolidLine);
+    pen.setWidth(1);
+    aRect1->setPen(pen);
+    aRect1->setZ(3);
+    aRect1->show();
+
+    mySelectedRect = aRect1;
+    canvas()->update();
+  }
+  
   if (!myIsLinkCreating && myMain->isEditable() &&
       !myMain->getCanvas()->isControlView()) {
     // compute collision rectangle
@@ -359,12 +457,15 @@ void SUPERVGUI_CanvasView::contentsMouseMoveEvent(QMouseEvent* theEvent)
     setHilighted(0);
   }
 
+  // QToolTip for title and label for SUPERVGUI_CanvasNode
+  SUPERVGUI_ToolTip* aTT = new SUPERVGUI_ToolTip(this);
+  aTT->maybeTip(p);
+
   busy = false;
 }
 
 void SUPERVGUI_CanvasView::contentsMouseReleaseEvent(QMouseEvent* theEvent) 
 {
-  //  cout << "===> SUPERVGUI_CanvasView::contentsMouseReleaseEvent(...) "   << endl;
   if (myTimer->isActive()) myTimer->stop();
 
   if (myCurrentItem) {
@@ -381,6 +482,7 @@ void SUPERVGUI_CanvasView::contentsMouseReleaseEvent(QMouseEvent* theEvent)
 
   if (myIsPanActivated) {
     myIsPanActivated = false;
+    myIsPanBtnClicked = false;
     setCursor(myCursor);
   }
 
@@ -388,15 +490,47 @@ void SUPERVGUI_CanvasView::contentsMouseReleaseEvent(QMouseEvent* theEvent)
     myIsZoomActivated = false;
     setCursor(myCursor);
   }
+
+  //mkr: "Fit within rectangle" functionality
+  if (myIsFitWRActivated) {
+    if (mySelectedRect) {
+      mySelectedRect->hide();
+      mySelectedRect = 0;
+      canvas()->update();
+    }
+
+    //myPoint is the start point for selecting rectangle now
+    QPoint anEndPoint = inverseWorldMatrix().map(theEvent->pos());
+    int aLX, aTY; //left x and top y
+    if (myPoint.x() < anEndPoint.x()) aLX = myPoint.x();
+    else aLX = anEndPoint.x();
+    if (myPoint.y() < anEndPoint.y()) aTY = myPoint.y();
+    else aTY = anEndPoint.y();
+
+    //calculate width and height for new view and new zoom factor
+    double aXzoom = ((double)visibleWidth())/((double)(abs(myPoint.x()-anEndPoint.x())));
+    double aYzoom = ((double)visibleHeight())/((double)(abs(myPoint.y()-anEndPoint.y())));
+    if (aXzoom > aYzoom) aXzoom = aYzoom;
+    
+    QWMatrix m;
+    m.scale(aXzoom, aXzoom);
+    setWorldMatrix(m);
+    setContentsPos((int)(aLX*aXzoom), (int)(aTY*aYzoom));
+
+    canvas()->update();
+    
+    myIsFitWRActivated = false;
+    viewport()->setMouseTracking(true);
+    setCursor(myCursor);
+  }
 }
 
 void SUPERVGUI_CanvasView::contentsMouseDoubleClickEvent(QMouseEvent* theEvent)
 {
-  //  cout << "===> SUPERVGUI_CanvasView::contentsMouseDoubleClickEvent(...) "   << endl;
   QPoint p = inverseWorldMatrix().map(theEvent->pos());
 
   // compute collision rectangle
-  QRect aSel(p.x()-MARGIN, p.y()-MARGIN, 1+2*MARGIN, 1+2*MARGIN);
+  //QRect aSel(p.x()-MARGIN, p.y()-MARGIN, 1+2*MARGIN, 1+2*MARGIN);
 
   if (theEvent->button() == Qt::LeftButton) {
     QCanvasItemList l = canvas()->collisions(p);
@@ -454,14 +588,27 @@ void SUPERVGUI_CanvasView::changeBackground()
 {
   QColor aColor = QColorDialog::getColor(canvas()->backgroundColor(), this );
   if ( aColor.isValid() ) {
+    // change background color for canvas view
     canvas()->setBackgroundColor(aColor);
     setPaletteBackgroundColor(aColor.light(120));
+    // change background color for array view
+    getMain()->getArrayView()->canvas()->setBackgroundColor(aColor);
+    getMain()->getArrayView()->setPaletteBackgroundColor(aColor.light(120));
+
+    // mkr : IPAL10825 -->
+    SUPERVGUI* aSupMod = SUPERVGUI::Supervision();
+    if ( !aSupMod ) {
+      MESSAGE("NULL Supervision module!");
+      return;
+    }
+    aSupMod->setIVFBackgroundColor(aColor); 
+    // <--
   }
 }
 
 void SUPERVGUI_CanvasView::ActivatePanning()
 {
-  myIsPanActivated = true;
+  myIsPanBtnClicked = true;
 }
 
 void SUPERVGUI_CanvasView::ResetView()
@@ -482,7 +629,6 @@ void SUPERVGUI_CanvasView::startSketch(SUPERVGUI_CanvasPort* thePort)
 
 void SUPERVGUI_CanvasView::endSketch(SUPERVGUI_CanvasPort* thePort)
 {
-  //  cout << "===> SUPERVGUI_CanvasView::endSketch(" << thePort->name() << ")"  << endl;
   if (!myIsLinkCreating) return;
 
   if (myLinkBuilder && myLinkBuilder->canCreateEngine(thePort)) {
@@ -507,7 +653,43 @@ void SUPERVGUI_CanvasView::endSketch(SUPERVGUI_CanvasPort* thePort)
       SUPERVGUI_CanvasPort* aOutPort = (input ? myLinkBuilder->getStartPort() : thePort);
       aLinkEngine = myMain->getDataflow()->Link(aOutPort->getEngine(), aInPort->getEngine());
     }
-    if (SUPERV_isNull(aLinkEngine)) return;
+    if (SUPERV_isNull(aLinkEngine)) 
+      return;    
+
+    // here, in fact, aLinkEngine may NOT be a newly created link.  If a link already existed between the
+    // the 2 given ports - it will be return (NOT created again).
+    // this should be checked and new presentation should NOT be created for existing link.
+    // Solution 1: NOT to allow creation of a link if it already exists between the ports in 
+    //             myLinkBuilder->canCreateEngine()
+    // Solution 2: check here if aLinkEngine is "new" or "old"
+    // Implement 2nd solution, because canCreateEngine() checks for types of ports, etc.. - it's another thing
+    // THE CHECK:
+    QObjectList* canvasLinks = canvas()->queryList("SUPERVGUI_CanvasLink");
+    SUPERVGUI_CanvasLink* canvasLink = 0;
+    QObjectListIt it(*canvasLinks);
+    bool prsAlreadyExists = false;
+    while ( (canvasLink=(SUPERVGUI_CanvasLink*)it.current()) ) {
+      ++it;
+      SUPERV_Link existingLinkWithPrs = canvasLink->getEngine();
+      if ( !SUPERV_isNull( existingLinkWithPrs ) ) {
+       if ( existingLinkWithPrs->IsEqual( aLinkEngine ) ) {
+         prsAlreadyExists = true;
+         break;
+       }       
+      }
+    }
+    delete canvasLinks;
+    if ( prsAlreadyExists ) { // aLinkEngine is already bound with a SUPERVGUI_CanvasLink object
+      //return;  // -> if return here, than the old CanvasLink is kept
+
+      // we want to delete old and create a new CanvasLink for this Link
+      delete canvasLink;
+      canvasLink = 0;
+      // clear old corrdinates in Engine link
+      for ( int i = 1; i <= aLinkEngine->CoordsSize(); i++ )
+       aLinkEngine->RemoveCoord( i );
+      // now we are ready to set coords for a link and create a new CanvasLink presentation that will use them.
+    }
 
     myLinkBuilder->setCoords(aLinkEngine.in());
 
@@ -517,8 +699,20 @@ void SUPERVGUI_CanvasView::endSketch(SUPERVGUI_CanvasPort* thePort)
     SUPERVGUI_CanvasLink* aLink = new SUPERVGUI_CanvasLink(canvas(), myMain, aLinkEngine);
     aLink->show();
 
+    emit objectCreated(); // mkr : PAL8237
+
     canvas()->update();
     myIsLinkCreating = false;
+
+    // asv : 13.12.04 : introducing a check for ports' types compatibility (Bugs and Improvements p.1.16, PAL7380)
+    if ( !aLinkEngine->IsValid() ) { 
+      const int id = SUIT_MessageBox::warn2( this, tr( "TLT_INVALID_LINK" ), 
+                                            tr( "MSG_INVALID_LINK" ) + QString(" : ") + QString(myMain->getDataflow()->Messages()), 
+                                            tr( "Keep" ), tr( "Remove" ), 0, 1, 0 );
+      if ( id == 1 ) { // "Remove" was selected in Message Box
+       aLink->remove(); // the new link did not live long...
+      }
+    }
   }
 }
 
@@ -547,12 +741,6 @@ void SUPERVGUI_CanvasView::setOrthoMode()
   mySketchPopup->setItemChecked(myOrtoItem, aIsOrtho);
 }
 
-
-void SUPERVGUI_CanvasView::addToStudy() 
-{
-  if (myMain->addStudy()) myMain->setAsFromStudy(true);
-}
-
 void SUPERVGUI_CanvasView::zoomIn() 
 {
   QWMatrix m;
@@ -597,3 +785,67 @@ void SUPERVGUI_CanvasView::fitAll()
   setWorldMatrix(m);
   canvas()->update();
 }
+
+void SUPERVGUI_CanvasView::fitWithinRect() 
+{
+  //mkr: "Fit within rectangle" functionality
+  myIsFitWRActivated = true;
+  viewport()->setMouseTracking(false);
+  myCursor = cursor();
+  setCursor(handCursor);
+}
+
+bool SUPERVGUI_CanvasView::isHavingStreamPort() const
+{
+  SUPERV::ListOfNodes* aNodesList = myMain->getDataflow()->Nodes();
+
+  //Computing Nodes
+  for ( int i = 0 ; i < (int) aNodesList->CNodes.length() ; i++ ) {
+    SUPERV::ListOfStreamPorts aStrPortsList = *( (aNodesList->CNodes)[i]->StreamPorts() );
+    if ((int) aStrPortsList.length() > 0) {
+      return true;
+    }
+  }
+   
+  //FactoryNodes
+  for ( int i = 0 ; i < (int) aNodesList->FNodes.length() ; i++ ) {
+    SUPERV::ListOfStreamPorts aStrPortsList = *( (aNodesList->FNodes)[i]->StreamPorts() );
+    if ((int) aStrPortsList.length() > 0) {
+      return true;
+    }
+  }
+       
+  //InLineNodes
+  for ( int i = 0 ; i < (int) aNodesList->INodes.length() ; i++ ) {
+    SUPERV::ListOfStreamPorts aStrPortsList = *( (aNodesList->INodes)[i]->StreamPorts() );
+    if ((int) aStrPortsList.length() > 0) {
+      return true;
+    }
+  }
+       
+  //GOTONodes
+  for ( int i = 0 ; i < (int) aNodesList->GNodes.length() ; i++ ) {
+    SUPERV::ListOfStreamPorts aStrPortsList = *( (aNodesList->GNodes)[i]->StreamPorts() );
+    if ((int) aStrPortsList.length() > 0) {
+      return true;
+    }
+  }
+       
+  //LoopNodes
+  for ( int i = 0 ; i < (int) aNodesList->LNodes.length() ; i++ ) {
+    SUPERV::ListOfStreamPorts aStrPortsList = *( (aNodesList->LNodes)[i]->StreamPorts() );
+    if ((int) aStrPortsList.length() > 0) {
+     return true;
+    }
+  }
+       
+  //SwitchNodes
+  for ( int i = 0 ; i < (int) aNodesList->SNodes.length() ; i++ ) {
+    SUPERV::ListOfStreamPorts aStrPortsList = *( (aNodesList->SNodes)[i]->StreamPorts() );
+    if ((int) aStrPortsList.length() > 0) {
+      return true;
+    }
+  }
+       
+  return false;
+}