Logo Search packages:      
Sourcecode: kdesdk version File versions

linepath.cpp

/***************************************************************************
 *                                                                         *
 *   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 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/
#include <cstdlib>
#include <cmath>

// qt includes
#include <qcanvas.h>
#include <qdatastream.h>
#include <qdom.h>

// kde includes
#include <kdebug.h>

// application includes
#include "associationwidget.h"
#include "activitywidget.h"
#include "umlview.h"
#include "linepath.h"

// using namespace std;  CHECK: strange... it compiles without this for me.

LinePath::Circle::Circle(QCanvas * canvas, int radius /* = 0 */)
  : QCanvasEllipse(radius * 2, radius * 2, canvas) {
}

void LinePath::Circle::setX(int x) {
      QCanvasItem::setX( (double) x );
}

void LinePath::Circle::setY(int y) {
      QCanvasItem::setY( (double) y );
}

void LinePath::Circle::setRadius(int radius) {
      QCanvasEllipse::setSize(radius * 2, radius * 2);
}

int LinePath::Circle::getRadius() const {
      return (QCanvasEllipse::height() / 2);
}

00048 void LinePath::Circle::drawShape(QPainter& p) {
      int diameter = height();
      int radius = diameter / 2;
      p.drawEllipse( (int)x() - radius, (int)y() - radius, diameter, diameter);
}

00054 LinePath::LinePath() {
      m_RectList.setAutoDelete( true );
      m_LineList.setAutoDelete( true );
      m_HeadList.setAutoDelete( true );
      m_ParallelList.setAutoDelete( true );
      m_bSelected = false;
      m_pClearPoly = 0;
      m_pCircle = 0;
      m_PointArray.resize( 4 );
      m_ParallelLines.resize( 4 );
      m_pAssociation = 0;
      m_bHeadCreated = false;
      m_bParallelLineCreated = false;
}

00069 LinePath::~LinePath() {}

00071 void LinePath::setAssociation(AssociationWidget * association ) {
      if( !association )
            return;
      cleanup();
      m_pAssociation = association;
      createHeadLines();
      if( getAssocType() == at_Coll_Message )
            setupParallelLine();
      UMLView * view =  (UMLView *)m_pAssociation -> parent();
      connect( view, SIGNAL( sigLineColorChanged( int ) ), this, SLOT( slotLineColorChanged( int ) ) );
      connect( view, SIGNAL( sigLineWidthChanged( int ) ), this, SLOT( slotLineWidthChanged( int ) ) );
}

00084 QPoint LinePath::getPoint( int pointIndex ) {
      int count = m_LineList.count();
      if( count == 0 || pointIndex > count  || pointIndex < 0)
            return QPoint( -1, -1 );

      if( pointIndex == count ) {
            QCanvasLine * line = m_LineList.last();
            return line -> endPoint();
      }
      QCanvasLine * line = m_LineList.at( pointIndex );
      return line -> startPoint();
}

00097 bool LinePath::setPoint( int pointIndex, QPoint point ) {
      int count = m_LineList.count();
      if( count == 0 || pointIndex > count  || pointIndex < 0)
            return false;

      if( pointIndex == count) {
            QCanvasLine * line = m_LineList.last();
            QPoint p = line -> startPoint();
            line -> setPoints( p.x(), p.y(), point.x(), point.y() );
            moveSelected( pointIndex );
            update();
            return true;
      }
      if( pointIndex == 0 ) {
            QCanvasLine * line = m_LineList.first();
            QPoint p = line -> endPoint();
            line -> setPoints( point.x(), point.y(), p.x(), p.y() );
            moveSelected( pointIndex );
            update();
            return true;
      }
      QCanvasLine * line = m_LineList.at( pointIndex  );
      QPoint p = line -> endPoint();
      line -> setPoints( point.x(), point.y(), p.x(), p.y() );
      line = m_LineList.at( pointIndex - 1 );
      p = line -> startPoint();
      line -> setPoints( p.x(), p.y(), point.x(), point.y() );
      moveSelected( pointIndex );
      update();
      return true;
}

00129 bool LinePath::isPoint( int pointIndex, QPoint point, unsigned short delta) {
      /* onLinePath doesn't return the index number we mean */
      pointIndex--;
      int count = m_LineList.count();
      if ( pointIndex >= count )
            return false;

      QCanvasLine * line = m_LineList.at( pointIndex );

      /* check if the given point is the start or end point of the line */
      if ( (
                abs( line -> endPoint().x() - point.x() ) <= delta
                &&
                abs( line -> endPoint().y() - point.y() ) <= delta
            ) || (
                abs( line -> startPoint().x() - point.x() ) <= delta
                &&
                abs( line -> startPoint().y() - point.y() ) <= delta
            ) )
            return true;

      /* check if the given point is the start or end point of the line */
      return false;
}

00154 bool LinePath::insertPoint( int pointIndex, QPoint point ) {
      int count = m_LineList.count();
      if( count == 0 )
            return false;

      if( count == 1 || pointIndex == 1) {
            QCanvasLine * first = m_LineList.first();
            QPoint sp = first -> startPoint();
            QPoint ep = first -> endPoint();
            first -> setPoints( sp.x(), sp.y(), point.x(), point.y() );
            QCanvasLine * line = new QCanvasLine( getCanvas() );
            line -> setZ( -2 );
            line -> setPoints( point.x(), point.y(), ep.x(), ep.y() );
            line -> setPen( getPen() );
            line -> setVisible( true );
            m_LineList.insert( 1, line );
            setupSelected();
            return true;
      }
      if( count + 1 == pointIndex ) {
            QCanvasLine * before = m_LineList.last();
            QPoint sp = before -> startPoint();
            QPoint ep = before -> endPoint();
            before -> setPoints( sp.x(), sp.y(), point.x(), point.y() );
            QCanvasLine * line = new QCanvasLine( getCanvas() );
            line -> setPoints( point.x(), point.y(), ep.x(), ep.y() );
            line -> setZ( -2 );
            line -> setPen( getPen() );
            line -> setVisible( true );
            m_LineList.append( line );
            setupSelected();
            return true;
      }
      QCanvasLine * before = m_LineList.at( pointIndex - 1 );
      QPoint sp = before -> startPoint();
      QPoint ep = before -> endPoint();
      before -> setPoints( sp.x(), sp.y(), point.x(), point.y() );
      QCanvasLine * line = new QCanvasLine(getCanvas() );
      line -> setPoints( point.x(), point.y(), ep.x(), ep.y() );
      line -> setZ( -2 );
      line -> setPen( getPen() );
      line -> setVisible( true );
      m_LineList.insert( pointIndex, line );
      setupSelected();
      return true;
}

00201 bool LinePath::removePoint( int pointIndex, QPoint point, unsigned short delta )
{
      /* get the number of line segments */
      int count = m_LineList.count();

      /* we have to reduce the pointIndex, because it is always 1 too high returned
       * by LinePath::onLinePath */
      if (pointIndex != 0)
            pointIndex--;

      /* we don't know if the user clicked on the start- or endpoint of a
       * line segment */
      QCanvasLine * current_line = m_LineList.at( pointIndex );
      if (abs( current_line -> endPoint().x() - point.x() ) <= delta
          &&
          abs( current_line -> endPoint().y() - point.y() ) <= delta)
      {
            /* the user clicked on the end point of the line;
             * we have to make sure that this isn't the last line segment */
            if (pointIndex >= count - 1)
                  return false;

            /* the next segment will get the starting point from the current one,
             * which is going to be removed */
            QCanvasLine * next_line = m_LineList.at( pointIndex + 1 );
            QPoint startPoint = current_line -> startPoint();
            QPoint endPoint = next_line -> endPoint();
            next_line -> setPoints(startPoint.x(), startPoint.y(),
                                endPoint.x(), endPoint.y());

      } else
      if (abs( current_line -> startPoint().x() - point.x() ) <= delta
          &&
          abs( current_line -> startPoint().y() - point.y() ) <= delta)
      {
            /* the user clicked on the start point of the line;
             * we have to make sure that this isn't the first line segment */
             if (pointIndex < 1)
                  return false;

            /* the previous segment will get the end point from the current one,
             * which is going to be removed */
            QCanvasLine * previous_line = m_LineList.at( pointIndex - 1 );
            QPoint startPoint = previous_line -> startPoint();
            QPoint endPoint = current_line -> endPoint();
            previous_line -> setPoints(startPoint.x(), startPoint.y(),
                                    endPoint.x(), endPoint.y());
      } else {
            /* the user clicked neither on the start- nor on the end point of
             * the line; this really shouldn't happen, but just make sure */
            return false;
      }


      /* remove the segment from the list */
      m_LineList.remove( pointIndex );

      return true;
}

00261 bool LinePath::setStartEndPoints( QPoint start, QPoint end ) {
      int count = m_LineList.count();

      if( count == 0 ) {
            QCanvasLine * line = new QCanvasLine(getCanvas() );
            line -> setPoints( start.x(), start.y(), end.x(), end.y() );
            line -> setZ( -2 );
            line -> setPen( getPen() );
            line -> setVisible( true );
            m_LineList.append( line );
            return true;
      }
      bool status = setPoint( 0, start );
      if( status)
            return setPoint( count , end );
      return false;
}

00279 int LinePath::count() {
      return m_LineList.count() + 1;
}

00283 int LinePath::onLinePath( QPoint position ) {
      typedef QCanvasItemList ItemList;
      ItemList list = getCanvas() -> collisions( position );
      ItemList::iterator item_it;
      int index = 0;
      for( item_it = list.begin(); item_it != list.end(); ++item_it ) {
            if( ( index = m_LineList.findRef( (QCanvasLine*)*item_it ) ) != -1 )
                  return index + 1;
      }//end for
      return -1;
}

00295 void LinePath::setSelected( bool select ) {
      if(select)
            setupSelected();
      else if( m_RectList.count() > 0 )
            m_RectList.clear();
}

00302 void LinePath::setAssocType( Uml::Association_Type type ) {
      LineListIt it( m_LineList );
      QCanvasLine * line = 0;
      while( ( line = it.current() ) ) {
            line -> setPen( getPen() );
            ++it;
      }
      if( m_pClearPoly ) {
            delete m_pClearPoly;
            m_pClearPoly = 0;
      }
      createHeadLines();
      if( type == at_Coll_Message )
            setupParallelLine();
      update();
}

00319 void LinePath::update() {
      if( m_bHeadCreated ) {
            calculateHead();
            updateHead();
      } else {
            createHeadLines();
      }

      if( getAssocType() == at_Coll_Message ) {
            if( m_bParallelLineCreated ) {
                  calculateParallelLine();
                  updateParallelLine();
            } else
                  setupParallelLine();

      }
}

00337 void LinePath::slotLineColorChanged( int viewID ) {
      if(m_pAssociation->getUMLView()->getID() != viewID) {
            return;
      }
      setLineColor( m_pAssociation->getUMLView()->getLineColor() );
}


00345 void LinePath::setLineColor( QColor color ) {
      QCanvasLine * line = 0;
      uint linewidth = 0;
      LineListIt it( m_LineList );
      while( ( line = it.current() ) ) {
            linewidth = line->pen().width();
            line -> setPen( QPen( color, linewidth ) );
            ++it;
      }
      LineListIt hit( m_HeadList );
      while( ( line = hit.current() ) ) {
            linewidth = line->pen().width();
            line -> setPen( QPen( color, linewidth ) );
            ++hit;
      }
      LineListIt pit( m_ParallelList );
      while( ( line = pit.current() ) ) {
            linewidth = line->pen().width();
            line -> setPen( QPen( color, linewidth ) );
            ++pit;
      }

      if( getAssocType() == at_Aggregation )
            if (m_pClearPoly) m_pClearPoly -> setBrush( QBrush( white ) );
      else if( getAssocType() == at_Composition )
            if (m_pClearPoly) m_pClearPoly -> setBrush( QBrush( color ) );

      if( m_pCircle ) {
            linewidth = m_pCircle->pen().width();
            m_pCircle->setPen( QPen(color, linewidth) );
      }
}

00378 void LinePath::slotLineWidthChanged( int viewID ) {
      if(m_pAssociation->getUMLView()->getID() != viewID) {
            return;
      }
      setLineWidth( m_pAssociation->getUMLView()->getLineWidth() );
}

00385 void LinePath::setLineWidth( uint width ) {
      QCanvasLine * line = 0;
      QColor linecolor;
      LineListIt it( m_LineList );
      while( ( line = it.current() ) ) {
            linecolor = line->pen().color();
            line -> setPen( QPen( linecolor, width ) );
            ++it;
      }
      LineListIt hit( m_HeadList );
      while( ( line = hit.current() ) ) {
            linecolor = line->pen().color();
            line -> setPen( QPen( linecolor, width ) );
            ++hit;
      }
      LineListIt pit( m_ParallelList );
      while( ( line = pit.current() ) ) {
            linecolor = line->pen().color();
            line -> setPen( QPen( linecolor, width ) );
            ++pit;
      }

      if( m_pCircle ) {
            linecolor = m_pCircle->pen().color();
            m_pCircle->setPen( QPen(linecolor, width) );
      }
}

00413 void LinePath::moveSelected( int pointIndex ) {
      int lineCount = m_LineList.count();
      if( !m_bSelected ) {
            m_RectList.clear();
            return;
      }
      if( (int)m_RectList.count() + 1 != lineCount )
            setupSelected();
      QCanvasRectangle * rect = 0;
      QCanvasLine * line = 0;
      if( pointIndex == lineCount || lineCount == 1) {
            line = m_LineList.last();
            QPoint p = line -> endPoint();
            rect = m_RectList.last();
            rect -> setX( p.x() );
            rect -> setY( p.y() );
            rect -> setZ( 4 );
            return;
      }
      line = m_LineList.at( pointIndex );
      QPoint p = line -> startPoint();
      rect = m_RectList.at( pointIndex );
      rect -> setX( p.x() );
      rect -> setY( p.y() );
      rect -> setZ( 4 );
}

00440 void LinePath::setupSelected() {
      m_RectList.clear();
      const int SIZE = 4;
      QCanvasLine * line = 0;
      LineListIt it( m_LineList );
      while( ( line = it.current() ) ) {
            QPoint sp = line -> startPoint();
            QCanvasRectangle * rect = new QCanvasRectangle( sp.x() - SIZE / 2, sp.y() - SIZE / 2, SIZE, SIZE, getCanvas() );
            rect -> setBrush( QBrush( blue ) );
            rect -> setPen( QPen( blue ) );
            rect -> setVisible( true );
            m_RectList.append( rect );
            ++it;
      }
      //special case for last point
      line = m_LineList.last();
      QPoint p = line -> endPoint();
      QCanvasRectangle * rect = new QCanvasRectangle( p.x() - SIZE / 2, p.y() - SIZE / 2, SIZE, SIZE, getCanvas() );
      rect -> setBrush( QBrush( blue ) );
      rect -> setPen( QPen( blue ) );
      rect -> setVisible( true );
      m_RectList.append( rect );
}

00464 QPen LinePath::getPen() {
      Uml::Association_Type type = getAssocType();
      if( type == at_Dependency || type == at_Realization || type == at_Anchor )
            return QPen( getLineColor(), getLineWidth(), DashLine );
      return QPen( getLineColor(), getLineWidth() );
}

#ifdef DEBUG_ASSOCLINES
extern int calls_to_calc_head;
#endif

00475 void LinePath::calculateHead() {
#ifdef DEBUG_ASSOCLINES
      calls_to_calc_head++;
#endif
      uint size = m_LineList.count();
      QPoint farPoint;
      int halfLength = 10;
      double arrowAngle = 0.2618;   // 0.5 * atan(sqrt(3.0) / 3.0) = 0.2618
      Association_Type at = getAssocType();
      bool diamond = (at == at_Aggregation || at == at_Composition);
      if (diamond || at == at_Containment) {
            farPoint = getPoint(1);
            m_EgdePoint = getPoint(0);
            if (diamond) {
                  arrowAngle *= 1.5;      // wider
                  halfLength += 1;  // longer
            } else {
                  // Containment has a circle-plus symbol at the
                  // containing object.  What we are tweaking here
                  // is the perpendicular line through the circle
                  // (i.e. the horizontal line of the plus sign if
                  // the objects are oriented north/south)
                  arrowAngle *= 2.5;      // wider
                  halfLength -= 4;  // shorter
            }
      } else {
            farPoint = getPoint(size - 1);
            m_EgdePoint = getPoint(size);
            // We have an arrow.
            arrowAngle *= 2.0;      // wider
            halfLength += 3;  // longer
      }
      int xa = farPoint.x();
      int ya = farPoint.y();
      int xb = m_EgdePoint.x();
      int yb = m_EgdePoint.y();
      double deltaX = xb - xa;
      double deltaY = yb - ya;
      double hypotenuse = sqrt(deltaX*deltaX + deltaY*deltaY); // the length
      double slope = atan2(deltaY, deltaX);     //slope of line
      double arrowSlope = slope + arrowAngle;
      double cosx, siny;
      if (hypotenuse < 1.0e-6) {
            cosx = 1.0;
            siny = 0.0;
      } else {
            cosx = halfLength * deltaX/hypotenuse;
            siny = halfLength * deltaY/hypotenuse;
      }

      m_ArrowPointA.setX( (int)rint(xb - halfLength * cos(arrowSlope)) );
      m_ArrowPointA.setY( (int)rint(yb - halfLength * sin(arrowSlope)) );
      arrowSlope = slope - arrowAngle;
      m_ArrowPointB.setX( (int)rint(xb - halfLength * cos(arrowSlope)) );
      m_ArrowPointB.setY( (int)rint(yb - halfLength * sin(arrowSlope)) );

      if(xa > xb)
            cosx = cosx > 0 ? cosx : cosx * -1;
      else
            cosx = cosx > 0 ? cosx * -1: cosx;

      if(ya > yb)
            siny = siny > 0 ? siny : siny * -1;
      else
            siny = siny > 0 ? siny * -1 : siny;

      m_MidPoint.setX( (int)rint(xb + cosx) );
      m_MidPoint.setY( (int)rint(yb + siny) );

      m_PointArray.setPoint(0, m_EgdePoint);
      m_PointArray.setPoint(1, m_ArrowPointA);
      if( getAssocType() == at_Realization ||
          getAssocType() == at_Generalization ) {
            m_PointArray.setPoint( 2, m_ArrowPointB );
            m_PointArray.setPoint( 3, m_EgdePoint );
      } else {
            QPoint diamondFarPoint;
            diamondFarPoint.setX( (int)rint(xb + cosx * 2) );
            diamondFarPoint.setY( (int)rint(yb + siny * 2) );
            m_PointArray.setPoint(2, diamondFarPoint);
            m_PointArray.setPoint(3, m_ArrowPointB);
      }
}

00559 void LinePath::updateHead() {
      int count = m_HeadList.count();
      QCanvasLine * line = 0;
      switch( getAssocType() ) {
            case at_State:
            case at_Activity:
            case at_UniAssociation:
            case at_Dependency:
                  if( count < 2)
                        return;
                  line = m_HeadList.at( 0 );
                  line -> setPoints( m_EgdePoint.x(), m_EgdePoint.y(), m_ArrowPointA.x(), m_ArrowPointA.y() );

                  line = m_HeadList.at( 1 );
                  line -> setPoints( m_EgdePoint.x(), m_EgdePoint.y(), m_ArrowPointB.x(), m_ArrowPointB.y() );
                  break;

            case at_Generalization:
            case at_Realization:
                  if( count < 3)
                        return;
                  line = m_HeadList.at( 0 );
                  line -> setPoints( m_EgdePoint.x(), m_EgdePoint.y(), m_ArrowPointA.x(), m_ArrowPointA.y() );

                  line = m_HeadList.at( 1 );
                  line -> setPoints( m_EgdePoint.x(), m_EgdePoint.y(), m_ArrowPointB.x(), m_ArrowPointB.y() );

                  line = m_HeadList.at( 2 );
                  line -> setPoints( m_ArrowPointA.x(), m_ArrowPointA.y(), m_ArrowPointB.x(), m_ArrowPointB.y() );
                  m_pClearPoly -> setPoints( m_PointArray );
                  break;

            case at_Composition:
            case at_Aggregation:
                  if( count < 4)
                        return;
                  line = m_HeadList.at( 0 );
                  line -> setPoints( m_PointArray[ 0 ].x(), m_PointArray[ 0 ].y(), m_PointArray[ 1 ].x(), m_PointArray[ 1 ].y() );

                  line = m_HeadList.at( 1 );
                  line -> setPoints( m_PointArray[ 1 ].x(), m_PointArray[ 1 ].y(), m_PointArray[ 2 ].x(), m_PointArray[ 2 ].y() );

                  line = m_HeadList.at( 2 );
                  line -> setPoints( m_PointArray[ 2 ].x(), m_PointArray[ 2 ].y(), m_PointArray[ 3 ].x(), m_PointArray[ 3 ].y() );

                  line = m_HeadList.at( 3 );
                  line -> setPoints( m_PointArray[ 3 ].x(), m_PointArray[ 3 ].y(), m_PointArray[ 0 ].x(), m_PointArray[ 0 ].y() );
                  m_pClearPoly -> setPoints( m_PointArray );
                  break;

            case at_Containment:
                  if (count < 1)
                        return;
                  line = m_HeadList.at( 0 );
                  line->setPoints( m_PointArray[ 1 ].x(), m_PointArray[ 1 ].y(),
                               m_PointArray[ 3 ].x(), m_PointArray[ 3 ].y() );
                  m_pCircle -> setX( m_MidPoint.x() );
                  m_pCircle -> setY( m_MidPoint.y() );
                  break;
            default:
                  break;
      }
}

00623 void LinePath::growHeadList(int by) {
      QPen pen( getLineColor(), getLineWidth() );
      for (int i = 0; i < by; i++) {
            QCanvasLine * line = new QCanvasLine( getCanvas() );
            line -> setZ( 0 );
            line -> setPen( pen );
            line -> setVisible( true );
            m_HeadList.append( line );
      }
}

00634 void LinePath::createHeadLines() {
      m_HeadList.clear();
      QCanvas * canvas = getCanvas();
      switch( getAssocType() ) {
            case at_Activity:
            case at_State:
            case at_Dependency:
            case at_UniAssociation:
                  growHeadList( 2 );
                  break;

            case at_Generalization:
            case at_Realization:
                  growHeadList( 3 );
                  m_pClearPoly = new QCanvasPolygon( canvas );
                  m_pClearPoly -> setVisible( true );
                  m_pClearPoly -> setBrush( QBrush( white ) );
                  m_pClearPoly -> setZ( -1 );
                  break;

            case at_Composition:
            case at_Aggregation:
                  growHeadList( 4 );
                  m_pClearPoly = new QCanvasPolygon( canvas );
                  m_pClearPoly -> setVisible( true );
                  if( getAssocType() == at_Aggregation )
                        m_pClearPoly -> setBrush( QBrush( white ) );
                  else
                        m_pClearPoly -> setBrush( QBrush( getLineColor() ) );
                  m_pClearPoly -> setZ( -1 );
                  break;

            case at_Containment:
                  growHeadList( 1 );
                  if (!m_pCircle) {
                        m_pCircle = new Circle( canvas, 6 );
                        m_pCircle->show();
                        m_pCircle->setPen( QPen( getLineColor(), getLineWidth() ) );
                  }
                  break;
            default:
                  break;
      }
      m_bHeadCreated = true;
}

00680 void LinePath::calculateParallelLine() {
      int midCount = count() / 2;
      double ATAN = atan(1.0);
      int lineDist = 10;
      //get  1/8(M) and 7/8(T) point
      QPoint a = getPoint( midCount - 1 );
      QPoint b = getPoint( midCount );
      int mx = ( a.x() + b.x() ) / 2;
      int my = ( a.y() + b.y() ) / 2;
      int tx = ( mx + b.x() ) / 2;
      int ty = ( my + b.y() ) / 2;
      //find dist between M and T points
      int distX = ( mx - tx );
      distX *= distX;
      int distY = ( my - ty );
      distY *= distY;
      double dist = sqrt( double(distX + distY) );
      double angle = atan2( double(ty - my), double(tx - mx) ) + ( ATAN * 2 );
      //find point from M to start line from.
      double cosx = cos( angle ) * lineDist;
      double siny = sin( angle ) * lineDist;
      QPoint pointM( mx + (int)cosx, my + (int)siny );
      //find dist between P(xb, yb)
      distX = ( tx - b.x() );
      distX *= distX;
      distY = ( ty - b.y() );
      distY *= distY;
      dist = sqrt( double(distX + distY) );
      //find point from T to end line
      cosx = cos( angle ) * lineDist;
      siny = sin( angle ) * lineDist;
      QPoint pointT( tx + (int)cosx, ty + (int)siny );
      m_ParallelLines[ 1 ] = pointM;
      m_ParallelLines[ 0 ] = pointT;

      int arrowDist = 5;
      angle = atan2( double(pointT.y() - pointM.y()),
                                    double(pointT.x() - pointM.x()) );
      double arrowSlope = angle + ATAN;
      cosx = ( cos( arrowSlope ) ) * arrowDist;
      siny = ( sin( arrowSlope ) ) * arrowDist;
      m_ParallelLines[ 2 ] = QPoint( pointT.x() - (int)cosx, pointT.y() - (int)siny );
      arrowSlope = angle - ATAN;
      cosx = ( cos( arrowSlope )  ) * arrowDist;
      siny = ( sin( arrowSlope ) ) * arrowDist;
      m_ParallelLines[ 3 ] = QPoint( pointT.x() - (int)cosx, pointT.y() - (int)siny );
}

00728 void LinePath::setupParallelLine() {
      m_ParallelList.clear();
      QCanvas * canvas = getCanvas();
      QPen pen( getLineColor(), getLineWidth() );
      QCanvasLine * line = new QCanvasLine( canvas );
      line -> setZ( 0 );
      line -> setPen( pen );
      line -> setVisible( true );
      m_ParallelList.append( line );

      line = new QCanvasLine( canvas );
      line -> setZ( 0 );
      line -> setPen( pen );
      line -> setVisible( true );
      m_ParallelList.append( line );

      line = new QCanvasLine( canvas );
      line -> setZ( 0 );
      line -> setPen( pen );
      line -> setVisible( true );
      m_ParallelList.append( line );
      m_bParallelLineCreated = true;
}

00752 void LinePath::updateParallelLine() {
      if( !m_bParallelLineCreated )
            return;
      QCanvasLine * line = 0;
      QPoint common = m_ParallelLines.at( 0 );
      QPoint p = m_ParallelLines.at( 1 );
      line = m_ParallelList.at( 0 );
      line -> setPoints( common.x(), common.y(), p.x(), p.y() );

      p = m_ParallelLines.at( 2 );
      line = m_ParallelList.at( 1 );
      line -> setPoints( common.x(), common.y(), p.x(), p.y() );

      p = m_ParallelLines.at( 3 );
      line = m_ParallelList.at( 2 );
      line -> setPoints( common.x(), common.y(), p.x(), p.y() );
}

00770 bool LinePath::operator==( LinePath & rhs ) {
      if( this -> m_LineList.count() != rhs.m_LineList.count() )
            return false;

      //Check to see if all points at the same position
      for( int i = 0; i< rhs.count() ; i++ ) {
            if( this -> getPoint( i ) != rhs.getPoint( i ) )
                  return false;
      }
      return true;
}

00782 LinePath & LinePath::operator=( LinePath & rhs ) {
      if( this == &rhs )
            return *this;
      //clear out the old canvas objects
      this -> m_LineList.clear();
      this -> m_ParallelList.clear();
      this -> m_RectList.clear();
      this -> m_HeadList.clear();
      int count = rhs.m_LineList.count();
      //setup start end points
      this -> setStartEndPoints( rhs.getPoint( 0 ), rhs.getPoint( count) );
      //now insert the rest
      for( int i = 1; i < count ; i++ ) {
            this -> insertPoint( i, rhs.getPoint ( i ) );
      }
      this -> setAssocType( rhs.getAssocType() );

      return *this;
}

00802 QCanvas * LinePath::getCanvas() {
      if( !m_pAssociation )
            return 0;
      UMLView * view =  (UMLView *)m_pAssociation -> parent();
      return view -> canvas();
}

00809 Uml::Association_Type LinePath::getAssocType() {
      if( m_pAssociation )
            return m_pAssociation -> getAssocType();
      return Uml::at_Association;
}

00815 QColor LinePath::getLineColor() {
      if( !m_pAssociation )
            return black;
      UMLView * view =  (UMLView *)m_pAssociation -> parent();
      return view -> getLineColor();
}

00822 uint LinePath::getLineWidth() {
      if( !m_pAssociation )
            return 0;
      UMLView * view =  (UMLView *)m_pAssociation -> parent();
      int viewLineWidth = view->getLineWidth();
      if ( viewLineWidth >= 0 && viewLineWidth <= 10 )
            return viewLineWidth;
      else {
            kdWarning() << "Ignore wrong LineWidth of " << viewLineWidth
                      << " in LinePath::getLineWidth" << endl;
            return 0;
      }
}

00836 void LinePath::cleanup() {
      if (m_pAssociation)
            m_LineList.clear();
      m_HeadList.clear();
      m_RectList.clear();
      m_ParallelList.clear();

      if( m_pClearPoly )
            delete m_pClearPoly;
      if( m_pCircle )
            delete m_pCircle;
      m_pCircle = 0;
      m_pClearPoly = 0;
      m_bHeadCreated = m_bParallelLineCreated = false;
      if( m_pAssociation ) {
            UMLView * view =  (UMLView *)m_pAssociation -> parent();
            if(view) {
                  disconnect( view, SIGNAL( sigLineColorChanged( int ) ), this, SLOT( slotLineColorChanged( int ) ) );
                  disconnect( view, SIGNAL( sigLineWidthChanged( int ) ), this, SLOT( slotLineWidthChanged( int ) ) );
            }
            m_pAssociation = NULL;
      }
}

bool LinePath::hasPoints () {
      int count = m_LineList.count();
      if (count>1)
            return true;
      return false;
}
void LinePath::dumpPoints () {
      int count = m_LineList.count();
      for( int i = 1; i < count; i++ ) {
            QPoint point = getPoint( i );
            kdDebug()<<" * point x:"<<point.x()<<" y:"<<point.y()<<endl;
      }
}

void LinePath::saveToXMI( QDomDocument & qDoc, QDomElement & qElement ) {
      int count = m_LineList.count();
      QPoint point = getPoint( 0 );
      QDomElement lineElement = qDoc.createElement( "linepath" );
      QDomElement startElement = qDoc.createElement( "startpoint" );
      startElement.setAttribute( "startx", point.x() );
      startElement.setAttribute( "starty", point.y() );
      lineElement.appendChild( startElement );
      QDomElement endElement = qDoc.createElement( "endpoint" );
      point = getPoint( count );
      endElement.setAttribute( "endx", point.x() );
      endElement.setAttribute( "endy", point.y() );
      lineElement.appendChild( endElement );
      for( int i = 1; i < count; i++ ) {
            QDomElement pointElement = qDoc.createElement( "point" );
            point = getPoint( i );
            pointElement.setAttribute( "x", point.x() );
            pointElement.setAttribute( "y", point.y() );
            lineElement.appendChild( pointElement );
      }
      qElement.appendChild( lineElement );
}

bool LinePath::loadFromXMI( QDomElement & qElement ) {
      QDomNode node = qElement.firstChild();
      QDomElement startElement = node.toElement();
      if( startElement.isNull() || startElement.tagName() != "startpoint" )
            return false;
      QString x = startElement.attribute( "startx", "0" );
      int nX = x.toInt();
      QString y = startElement.attribute( "starty", "0" );
      int nY = y.toInt();
      QPoint startPoint( nX, nY );

      node = startElement.nextSibling();
      QDomElement endElement = node.toElement();
      if( endElement.isNull() || endElement.tagName() != "endpoint" )
            return false;
      x = endElement.attribute( "endx", "0" );
      nX = x.toInt();
      y = endElement.attribute( "endy", "0" );
      nY = y.toInt();
      QPoint endPoint( nX, nY );
      setStartEndPoints( startPoint, endPoint );
      QPoint point;
      node = endElement.nextSibling();
      QDomElement element = node.toElement();
      int i = 1;
      while( !element.isNull() ) {
            if( element.tagName() == "point" ) {
                  x = element.attribute( "x", "0" );
                  y = element.attribute( "y", "0" );
                  point.setX( x.toInt() );
                  point.setY( y.toInt() );
                  insertPoint( i++, point );
            }
            node = element.nextSibling();
            element = node.toElement();
      }

      return true;
}


00938 void LinePath::activate() {
      int count = m_LineList.count();
      if (count == 0)
            return;
      QCanvas * canvas = getCanvas();
      if (canvas == NULL)
            return;
      for (int i = 0; i < count ; i++) {
            QCanvasLine *line = m_LineList.at(i);
            line -> setCanvas( canvas );
            line -> setPen( getPen() );
      }
}



#include "linepath.moc"

Generated by  Doxygen 1.6.0   Back to index