/*************************************************************************** * * * 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. * * * * copyright (C) 2002-2007 * * Umbrello UML Modeller Authors * ***************************************************************************/ // own header #include "linepath.h" // system includes #include #include // qt includes #include #include #include // kde includes #include // application includes #include "associationwidget.h" #include "activitywidget.h" #include "widget_utils.h" #include "umlview.h" #include "umldoc.h" #include "uml.h" LinePath::Circle::Circle(TQCanvas * canvas, int radius /* = 0 */) : TQCanvasEllipse(radius * 2, radius * 2, canvas) { } void LinePath::Circle::setX(int x) { TQCanvasItem::setX( (double) x ); } void LinePath::Circle::setY(int y) { TQCanvasItem::setY( (double) y ); } void LinePath::Circle::setRadius(int radius) { TQCanvasEllipse::setSize(radius * 2, radius * 2); } int LinePath::Circle::getRadius() const { return (TQCanvasEllipse::height() / 2); } void LinePath::Circle::drawShape(TQPainter& p) { int diameter = height(); int radius = diameter / 2; p.drawEllipse( (int)x() - radius, (int)y() - radius, diameter, diameter); } 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; m_DockRegion = TopBottom; } LinePath::~LinePath() {} void LinePath::setAssociation(AssociationWidget * association ) { if( !association ) return; cleanup(); m_pAssociation = association; createHeadLines(); if( getAssocType() == Uml::at_Coll_Message ) setupParallelLine(); UMLView * view = (UMLView *)m_pAssociation -> tqparent(); connect( view, TQT_SIGNAL( sigColorChanged( Uml::IDType ) ), this, TQT_SLOT( slotLineColorChanged( Uml::IDType ) ) ); connect( view, TQT_SIGNAL( sigLineWidthChanged( Uml::IDType ) ), this, TQT_SLOT( slotLineWidthChanged( Uml::IDType ) ) ); } TQPoint LinePath::getPoint( int pointIndex ) { int count = m_LineList.count(); if( count == 0 || pointIndex > count || pointIndex < 0) return TQPoint( -1, -1 ); if( pointIndex == count ) { TQCanvasLine * line = m_LineList.last(); return line -> endPoint(); } TQCanvasLine * line = m_LineList.at( pointIndex ); return line -> startPoint(); } bool LinePath::setPoint( int pointIndex, const TQPoint &point ) { int count = m_LineList.count(); if( count == 0 || pointIndex > count || pointIndex < 0) return false; if (point.x() == 0 && point.y() == 0) { kError() << "LinePath::setPoint:ignoring request for (0,0)" << endl; return false; } if( pointIndex == count) { TQCanvasLine * line = m_LineList.last(); TQPoint p = line -> startPoint(); line -> setPoints( p.x(), p.y(), point.x(), point.y() ); moveSelected( pointIndex ); update(); return true; } if( pointIndex == 0 ) { TQCanvasLine * line = m_LineList.first(); TQPoint p = line -> endPoint(); line -> setPoints( point.x(), point.y(), p.x(), p.y() ); moveSelected( pointIndex ); update(); return true; } TQCanvasLine * line = m_LineList.at( pointIndex ); TQPoint 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; } bool LinePath::isPoint( int pointIndex, const TQPoint &point, unsigned short delta) { int count = m_LineList.count(); if ( pointIndex >= count ) return false; TQCanvasLine * 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; } bool LinePath::insertPoint( int pointIndex, const TQPoint &point ) { int count = m_LineList.count(); if( count == 0 ) return false; const bool bLoading = UMLApp::app()->getDocument()->loading(); if( count == 1 || pointIndex == 1) { TQCanvasLine * first = m_LineList.first(); TQPoint sp = first -> startPoint(); TQPoint ep = first -> endPoint(); first -> setPoints( sp.x(), sp.y(), point.x(), point.y() ); TQCanvasLine * line = new TQCanvasLine( getCanvas() ); line -> setZ( -2 ); line -> setPoints( point.x(), point.y(), ep.x(), ep.y() ); line -> setPen( getPen() ); line -> tqsetVisible( true ); m_LineList.insert( 1, line ); if (!bLoading) setupSelected(); return true; } if( count + 1 == pointIndex ) { TQCanvasLine * before = m_LineList.last(); TQPoint sp = before -> startPoint(); TQPoint ep = before -> endPoint(); before -> setPoints( sp.x(), sp.y(), point.x(), point.y() ); TQCanvasLine * line = new TQCanvasLine( getCanvas() ); line -> setPoints( point.x(), point.y(), ep.x(), ep.y() ); line -> setZ( -2 ); line -> setPen( getPen() ); line -> tqsetVisible( true ); m_LineList.append( line ); if (!bLoading) setupSelected(); return true; } TQCanvasLine * before = m_LineList.at( pointIndex - 1 ); TQPoint sp = before -> startPoint(); TQPoint ep = before -> endPoint(); before -> setPoints( sp.x(), sp.y(), point.x(), point.y() ); TQCanvasLine * line = new TQCanvasLine(getCanvas() ); line -> setPoints( point.x(), point.y(), ep.x(), ep.y() ); line -> setZ( -2 ); line -> setPen( getPen() ); line -> tqsetVisible( true ); m_LineList.insert( pointIndex, line ); if (!bLoading) setupSelected(); return true; } bool LinePath::removePoint( int pointIndex, const TQPoint &point, unsigned short delta ) { /* get the number of line segments */ int count = m_LineList.count(); if ( pointIndex >= count ) return false; /* we don't know if the user clicked on the start- or endpoint of a * line segment */ TQCanvasLine * 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 */ TQCanvasLine * next_line = m_LineList.at( pointIndex + 1 ); TQPoint startPoint = current_line -> startPoint(); TQPoint 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 */ TQCanvasLine * previous_line = m_LineList.at( pointIndex - 1 ); TQPoint startPoint = previous_line -> startPoint(); TQPoint 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; } bool LinePath::setStartEndPoints( const TQPoint &start, const TQPoint &end ) { int count = m_LineList.count(); if( count == 0 ) { TQCanvasLine * line = new TQCanvasLine(getCanvas() ); line -> setPoints( start.x(), start.y(), end.x(), end.y() ); line -> setZ( -2 ); line -> setPen( getPen() ); line -> tqsetVisible( true ); m_LineList.append( line ); return true; } bool status = setPoint( 0, start ); if( status) return setPoint( count , end ); return false; } int LinePath::count() { return m_LineList.count() + 1; } int LinePath::onLinePath( const TQPoint &position ) { TQCanvasItemList list = getCanvas() -> collisions( position ); int index = -1; TQCanvasItemList::iterator end(list.end()); for(TQCanvasItemList::iterator item_it(list.begin()); item_it != end; ++item_it ) { if( ( index = m_LineList.tqfindRef( (TQCanvasLine*)*item_it ) ) != -1 ) break; }//end for return index; } void LinePath::setSelected( bool select ) { if(select) setupSelected(); else if( m_RectList.count() > 0 ) m_RectList.clear(); } void LinePath::setAssocType( Uml::Association_Type type ) { LineListIt it( m_LineList ); TQCanvasLine * line = 0; while( ( line = it.current() ) ) { line -> setPen( getPen() ); ++it; } if( m_pClearPoly ) { delete m_pClearPoly; m_pClearPoly = 0; } if( type == Uml::at_Coll_Message ) setupParallelLine(); else createHeadLines(); update(); } void LinePath::update() { if (getAssocType() == Uml::at_Coll_Message) { if (m_bParallelLineCreated) { calculateParallelLine(); updateParallelLine(); } else setupParallelLine(); } else if (m_bHeadCreated) { calculateHead(); updateHead(); } else { createHeadLines(); } } void LinePath::slotLineColorChanged( Uml::IDType viewID ) { if(m_pAssociation->getUMLView()->getID() != viewID) { return; } setLineColor( m_pAssociation->getUMLView()->getLineColor() ); } void LinePath::setLineColor( const TQColor &color ) { TQCanvasLine * line = 0; uint linewidth = 0; LineListIt it( m_LineList ); while( ( line = it.current() ) ) { linewidth = line->pen().width(); line -> setPen( TQPen( color, linewidth ) ); ++it; } LineListIt hit( m_HeadList ); while( ( line = hit.current() ) ) { linewidth = line->pen().width(); line -> setPen( TQPen( color, linewidth ) ); ++hit; } LineListIt pit( m_ParallelList ); while( ( line = pit.current() ) ) { linewidth = line->pen().width(); line -> setPen( TQPen( color, linewidth ) ); ++pit; } if( getAssocType() == Uml::at_Aggregation ) if (m_pClearPoly) m_pClearPoly -> setBrush( TQBrush( TQt::white ) ); else if( getAssocType() == Uml::at_Composition ) if (m_pClearPoly) m_pClearPoly -> setBrush( TQBrush( color ) ); if( m_pCircle ) { linewidth = m_pCircle->pen().width(); m_pCircle->setPen( TQPen(color, linewidth) ); } } void LinePath::slotLineWidthChanged( Uml::IDType viewID ) { if(m_pAssociation->getUMLView()->getID() != viewID) { return; } setLineWidth( m_pAssociation->getUMLView()->getLineWidth() ); } void LinePath::setLineWidth( uint width ) { TQCanvasLine * line = 0; TQColor linecolor; LineListIt it( m_LineList ); while( ( line = it.current() ) ) { linecolor = line->pen().color(); line -> setPen( TQPen( linecolor, width ) ); ++it; } LineListIt hit( m_HeadList ); while( ( line = hit.current() ) ) { linecolor = line->pen().color(); line -> setPen( TQPen( linecolor, width ) ); ++hit; } LineListIt pit( m_ParallelList ); while( ( line = pit.current() ) ) { linecolor = line->pen().color(); line -> setPen( TQPen( linecolor, width ) ); ++pit; } if( m_pCircle ) { linecolor = m_pCircle->pen().color(); m_pCircle->setPen( TQPen(linecolor, width) ); } } 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(); TQCanvasRectangle * rect = 0; TQCanvasLine * line = 0; if( pointIndex == lineCount || lineCount == 1) { line = m_LineList.last(); TQPoint p = line -> endPoint(); rect = m_RectList.last(); rect -> setX( p.x() ); rect -> setY( p.y() ); rect -> setZ( 4 ); return; } line = m_LineList.at( pointIndex ); TQPoint p = line -> startPoint(); rect = m_RectList.at( pointIndex ); rect -> setX( p.x() ); rect -> setY( p.y() ); rect -> setZ( 4 ); } void LinePath::setupSelected() { m_RectList.clear(); TQCanvasLine * line = 0; LineListIt it( m_LineList ); while( ( line = it.current() ) ) { TQPoint sp = line -> startPoint(); TQCanvasRectangle *rect = Widget_Utils::decoratePoint(sp); m_RectList.append( rect ); ++it; } //special case for last point line = m_LineList.last(); TQPoint p = line -> endPoint(); TQCanvasRectangle *rect = Widget_Utils::decoratePoint(p); m_RectList.append( rect ); update(); } TQPen LinePath::getPen() { Uml::Association_Type type = getAssocType(); if( type == Uml::at_Dependency || type == Uml::at_Realization || type == Uml::at_Anchor ) return TQPen( getLineColor(), getLineWidth(), TQt::DashLine ); return TQPen( getLineColor(), getLineWidth() ); } void LinePath::calculateHead() { uint size = m_LineList.count(); TQPoint farPoint; int halfLength = 10; double arrowAngle = 0.2618; // 0.5 * atan(sqrt(3.0) / 3.0) = 0.2618 Uml::Association_Type at = getAssocType(); bool diamond = (at == Uml::at_Aggregation || at == Uml::at_Composition); if (diamond || at == Uml::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() == Uml::at_Realization || getAssocType() == Uml::at_Generalization ) { m_PointArray.setPoint( 2, m_ArrowPointB ); m_PointArray.setPoint( 3, m_EgdePoint ); } else { TQPoint 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); } } void LinePath::updateHead() { int count = m_HeadList.count(); TQCanvasLine * line = 0; switch( getAssocType() ) { case Uml::at_State: case Uml::at_Activity: case Uml::at_UniAssociation: case Uml::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 Uml::at_Relationship: if (count < 2) { return; } { int xoffset = 0; int yoffset = 0; if( m_DockRegion == TopBottom ) xoffset = 8; else yoffset = 8; line = m_HeadList.at( 0 ); line->setPoints( m_PointArray[2].x(), m_PointArray[2].y(), m_PointArray[0].x()-xoffset, m_PointArray[0].y()-yoffset ); line = m_HeadList.at( 1 ); line->setPoints( m_PointArray[2].x(), m_PointArray[2].y(), m_PointArray[0].x()+xoffset, m_PointArray[0].y()+yoffset ); } case Uml::at_Generalization: case Uml::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 Uml::at_Composition: case Uml::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 Uml::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; } } void LinePath::growList(LineList &list, int by) { TQPen pen( getLineColor(), getLineWidth() ); for (int i = 0; i < by; i++) { TQCanvasLine * line = new TQCanvasLine( getCanvas() ); line -> setZ( 0 ); line -> setPen( pen ); line -> tqsetVisible( true ); list.append( line ); } } void LinePath::createHeadLines() { m_HeadList.clear(); TQCanvas * canvas = getCanvas(); switch( getAssocType() ) { case Uml::at_Activity: case Uml::at_State: case Uml::at_Dependency: case Uml::at_UniAssociation: case Uml::at_Relationship: growList(m_HeadList, 2); break; case Uml::at_Generalization: case Uml::at_Realization: growList(m_HeadList, 3); m_pClearPoly = new TQCanvasPolygon( canvas ); m_pClearPoly -> tqsetVisible( true ); m_pClearPoly -> setBrush( TQBrush( TQt::white ) ); m_pClearPoly -> setZ( -1 ); break; case Uml::at_Composition: case Uml::at_Aggregation: growList(m_HeadList, 4); m_pClearPoly = new TQCanvasPolygon( canvas ); m_pClearPoly -> tqsetVisible( true ); if( getAssocType() == Uml::at_Aggregation ) m_pClearPoly -> setBrush( TQBrush( TQt::white ) ); else m_pClearPoly -> setBrush( TQBrush( getLineColor() ) ); m_pClearPoly -> setZ( -1 ); break; case Uml::at_Containment: growList(m_HeadList, 1); if (!m_pCircle) { m_pCircle = new Circle( canvas, 6 ); m_pCircle->show(); m_pCircle->setPen( TQPen( getLineColor(), getLineWidth() ) ); } break; default: break; } m_bHeadCreated = true; } void LinePath::calculateParallelLine() { int midCount = count() / 2; double ATAN = atan(1.0); int lineDist = 10; //get 1/8(M) and 7/8(T) point TQPoint a = getPoint( midCount - 1 ); TQPoint 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; TQPoint 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; TQPoint 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 ] = TQPoint( pointT.x() - (int)cosx, pointT.y() - (int)siny ); arrowSlope = angle - ATAN; cosx = ( cos( arrowSlope ) ) * arrowDist; siny = ( sin( arrowSlope ) ) * arrowDist; m_ParallelLines[ 3 ] = TQPoint( pointT.x() - (int)cosx, pointT.y() - (int)siny ); } void LinePath::setupParallelLine() { m_ParallelList.clear(); growList(m_ParallelList, 3); m_bParallelLineCreated = true; } void LinePath::updateParallelLine() { if( !m_bParallelLineCreated ) return; TQCanvasLine * line = 0; TQPoint common = m_ParallelLines.at( 0 ); TQPoint 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() ); } 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; } 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; } TQCanvas * LinePath::getCanvas() { if( !m_pAssociation ) return 0; const UMLView * view = m_pAssociation->getUMLView(); return view -> canvas(); } Uml::Association_Type LinePath::getAssocType() { if( m_pAssociation ) return m_pAssociation -> getAssocType(); return Uml::at_Association; } TQColor LinePath::getLineColor() { if( !m_pAssociation ) return TQt::black; return m_pAssociation -> getLineColor(); } uint LinePath::getLineWidth() { if( !m_pAssociation ) return 0; int viewLineWidth = m_pAssociation -> getLineWidth(); if ( viewLineWidth >= 0 && viewLineWidth <= 10 ) return viewLineWidth; else { kWarning() << "Ignore wrong LineWidth of " << viewLineWidth << " in LinePath::getLineWidth" << endl; return 0; } } 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 -> tqparent(); if(view) { disconnect( view, TQT_SIGNAL( sigColorChanged( Uml::IDType ) ), this, TQT_SLOT( slotLineColorChanged( Uml::IDType ) ) ); disconnect( view, TQT_SIGNAL( sigLineWidthChanged( Uml::IDType ) ), this, TQT_SLOT( slotLineWidthChanged( Uml::IDType ) ) ); } m_pAssociation = NULL; } } void LinePath::setDockRegion( Region region ) { m_DockRegion = region; } 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++ ) { TQPoint point = getPoint( i ); kDebug()<<" * point x:"< setCanvas( canvas ); line -> setPen( getPen() ); } } #include "linepath.moc"