kivio

sml_connector.cpp
1/*
2* Kivio - Visual Modelling and Flowcharting
3* Copyright (C) 2000-2001 theKompany.com & Dave Marotti
4*
5* This program is free software; you can redistribute it and/or
6* modify it under the terms of the GNU General Public License
7* as published by the Free Software Foundation; either version 2
8* of the License, or (at your option) any later version.
9*
10* This program is distributed in the hope that it will be useful,
11* but WITHOUT ANY WARRANTY; without even the implied warranty of
12* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13* GNU General Public License for more details.
14*
15* You should have received a copy of the GNU General Public License
16* along with this program; if not, write to the Free Software
17* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18*/
19#include <stdio.h>
20#include <math.h>
21#include "sml_connector.h"
22
23#include "kivio_common.h"
24#include "kivio_connector_target.h"
25#include "kivio_layer.h"
26#include "kivio_line_style.h"
27#include "kivio_page.h"
28#include "kivio_painter.h"
29#include "kivio_stencil.h"
30#include "kivio_stencil_spawner.h"
31#include "kivio_stencil_spawner_info.h"
32#include "kivio_stencil_spawner_set.h"
33#include "kivio_text_style.h"
34#include "kivio_shape.h"
35#include "kivio_shape_data.h"
36#include "kivio_point.h"
37
38#include "tkmath.h"
39
40#include <tqcolor.h>
41#include <tqpixmap.h>
42#include <kdebug.h>
43#include <KoZoomHandler.h>
44#include <kiconloader.h>
45
46static KivioStencilSpawnerInfo sinfo = KivioStencilSpawnerInfo( "Ian Reinhart Geiser", "SML Connector", "SML Connector", "SML Based Connector", "0.1", "http://localhost/", "", "off" );
47#include <kgenericfactory.h>
48
49K_EXPORT_COMPONENT_FACTORY( sml_connector, KGenericFactory<KivioSMLConnectorFactory>( "KivioSMLConnectorFactory" ) )
50
51KivioSMLConnectorFactory::KivioSMLConnectorFactory( TQObject *parent, const char* name, const TQStringList& args ) :
52 KivioStencilFactory( parent, name, args )
53{
54 kdDebug(43000) << "new sml stencil factory: " << endl;
55}
56
57KivioStencil *KivioSMLConnectorFactory::NewStencil( const TQString& name )
58{
59 return new KivioSMLConnector( name );
60}
61
62KivioStencil *KivioSMLConnectorFactory::NewStencil()
63{
64 return new KivioSMLConnector( "basic_line" );
65}
66
67
68TQPixmap *KivioSMLConnectorFactory::GetIcon()
69{
70 return & BarIcon( "SML_conn" );
71}
72
73KivioStencilSpawnerInfo *KivioSMLConnectorFactory::GetSpawnerInfo()
74{
75 return & sinfo;
76}
77
78KivioSMLConnector::KivioSMLConnector( const TQString &name )
79 : Kivio1DStencil(), m_name( name )
80{
81
82 m_pStart->setPosition( 0.0f, 0.0f, false );
83 m_pEnd->setPosition( 72.0f, 72.0f, false );
84
85 m_startAH = new KivioArrowHead();
86 m_endAH = new KivioArrowHead();
87 m_needsWidth = false;
88 m_needsText = true;
89
90 m_pCanProtect->clearBit( kpAspect );
91 m_pCanProtect->clearBit( kpWidth );
92 m_pCanProtect->clearBit( kpHeight );
93 m_pCanProtect->clearBit( kpX );
94 m_pCanProtect->clearBit( kpY );
95
96 // This is a stencil of type connector
97 setType( kstConnector );
98
99 // We only have one shape, an open path.
100 //m_shape = new KivioShape();
101 //m_shape->shapeData() ->setShapeType( KivioShapeData::kstOpenPath );
102 loadPath( name );
103}
104
105KivioSMLConnector::~KivioSMLConnector()
106{
107 delete m_startAH;
108 delete m_endAH;
109}
110
111void KivioSMLConnector::setStartPoint( double x, double y )
112{
113 m_pStart->setPosition( x, y, false );
114 m_pStart->disconnect();
115
116 if ( m_needsText )
117 {
118 m_pTextConn->setPosition( ( m_pEnd->x() + m_pStart->x() ) / 2.0f,
119 ( m_pEnd->y() + m_pStart->y() ) / 2.0f,
120 false );
121 }
122
123 // Set list end point
124 m_pConnectorPoints ->first() ->setX( x );
125 m_pConnectorPoints ->first() ->setY( y );
126
127}
128
129void KivioSMLConnector::setEndPoint( double x, double y )
130{
131 m_pEnd->setPosition( x, y, false );
132 m_pEnd->disconnect();
133 m_pConnectorPoints ->last() ->setX( x );
134 m_pConnectorPoints ->last() ->setY( y );
135}
136
137KivioCollisionType KivioSMLConnector::checkForCollision( KivioPoint *p, double threshold )
138{
139 const double end_thresh = 4.0f;
140
141 double px = p->x();
142 double py = p->y();
143
144 KivioConnectorPoint *pPoint;
145
146 int i = kctCustom + 1;
147 pPoint = m_pConnectorPoints->first();
148 while ( pPoint )
149 {
150 if ( px >= pPoint->x() - end_thresh &&
151 px <= pPoint->x() + end_thresh &&
152 py >= pPoint->y() - end_thresh &&
153 py <= pPoint->y() + end_thresh )
154 {
155 return ( KivioCollisionType ) i;
156 }
157
158 i++;
159 pPoint = m_pConnectorPoints->next();
160 }
161
162
163 if ( collisionLine( m_pStart->x(), m_pStart->y(),
164 m_pEnd->x(), m_pEnd->y(),
165 px, py,
166 threshold ) )
167 {
168 return kctBody;
169 }
170
171 return kctNone;
172}
173
174KivioStencil *KivioSMLConnector::duplicate()
175{
176 KivioSMLConnector * pStencil = new KivioSMLConnector( m_name );
177
178
179 // TODO: Copy internal pointlist information?
180
181 // Copy the arrow head information
182 pStencil->setStartAHType( m_startAH->type() );
183 pStencil->setStartAHWidth( m_startAH->width() );
184 pStencil->setStartAHLength( m_startAH->length() );
185
186 pStencil->setEndAHType( m_endAH->type() );
187 pStencil->setEndAHWidth( m_endAH->width() );
188 pStencil->setEndAHLength( m_endAH->length() );
189
190 *( pStencil->protection() ) = *m_pProtection;
191 *( pStencil->canProtect() ) = *m_pCanProtect;
192
193 return pStencil;
194}
195/*
196void KivioSMLConnector::drawOpenPath( KivioShape *pShape, KivioIntraStencilData *pData )
197{
198 KivioPainter * painter;
199 KivioShapeData *pShapeData = pShape->shapeData();
200 KivioPoint *pPoint, *pNewPoint;
201 TQPtrList <KivioPoint> *pPointList = pShapeData->pointList();
202
203 TQPtrList <KivioPoint> *pNewPoints = new TQPtrList<KivioPoint>;
204 pNewPoints->setAutoDelete( true );
205
206 pPoint = pPointList->first();
207 while ( pPoint )
208 {
209 pNewPoint = new KivioPoint( pData->zoomHandler->zoomItX( pPoint->x() ),
210 pData->zoomHandler->zoomItY( pPoint->y() ),
211 pPoint->pointType() );
212 pNewPoints->append( pNewPoint );
213
214 pPoint = pPointList->next();
215 }
216
217 painter = pData->painter;
218 double lineWidth = pShapeData->lineStyle() ->width();
219 painter->setLineWidth( pData->zoomHandler->zoomItY( lineWidth ) );
220 painter->setFGColor( pShapeData->lineStyle() ->color() );
221
222 painter->drawOpenPath( pNewPoints );
223 delete pNewPoints;
224}
225*/
226void KivioSMLConnector::paint( KivioIntraStencilData *pData )
227{
228 KivioPainter * painter = pData->painter;
229 KoZoomHandler* zoomHandler = pData->zoomHandler;
230 double x1, y1, x2, y2;
231 double vecX, vecY;
232 double len;
233
234
235 painter->setFGColor( m_pLineStyle->color() );
236 painter->setLineWidth( zoomHandler->zoomItY( m_pLineStyle->width() ) );
237
238 x1 = zoomHandler->zoomItX( m_pStart->x() );
239 x2 = zoomHandler->zoomItX( m_pEnd->x() );
240
241 y1 = zoomHandler->zoomItY( m_pStart->y() );
242 y2 = zoomHandler->zoomItY( m_pEnd->y() );
243
244
245 // Calculate the direction vector from start -> end
246 vecX = m_pEnd->x() - m_pStart->x();
247 vecY = m_pEnd->y() - m_pStart->y();
248
249 // Normalize the vector
250 len = sqrt( vecX * vecX + vecY * vecY );
251 if ( len )
252 {
253 vecX /= len;
254 vecY /= len;
255
256 // Move the endpoints by the cuts
257 x1 += vecX * zoomHandler->zoomItX( m_startAH->cut() );
258 y1 += vecY * zoomHandler->zoomItY( m_startAH->cut() );
259
260 x2 -= vecX * zoomHandler->zoomItX( m_endAH->cut() );
261 y2 -= vecY * zoomHandler->zoomItY( m_endAH->cut() );
262 }
263
264
265 // Build shape up from m_pConnectorPoints
266
267
268 TQPtrList <KivioPoint> *pNewPoints = new TQPtrList<KivioPoint>;
269 pNewPoints->setAutoDelete( true );
270
271 pNewPoints->append(new KivioPoint( zoomHandler->zoomItX( m_pStart->x() ),
272 zoomHandler->zoomItY( m_pStart->y() )));
273
274 KivioConnectorPoint *pPoint = m_PointList.first();
275 while ( pPoint )
276 {
277 KivioPoint *pNewPoint = new KivioPoint( zoomHandler->zoomItX( pPoint->x() ),
278 zoomHandler->zoomItY( pPoint->y() ));
279 pNewPoints->append( pNewPoint );
280
281 pPoint = m_PointList.next();
282 }
283
284 pNewPoints->append(new KivioPoint( zoomHandler->zoomItX( m_pEnd->x() ),
285 zoomHandler->zoomItY( m_pEnd->y() )));
286 painter = pData->painter;
287 double lineWidth = m_pLineStyle ->width();
288 painter->setLineWidth( zoomHandler->zoomItY( lineWidth ) );
289 painter->setFGColor( m_pLineStyle ->color() );
290
291 painter->drawOpenPath( pNewPoints );
292 delete pNewPoints;
293
294 // Now draw the arrow heads
295 if ( len )
296 {
297 painter->setBGColor( m_pFillStyle->color() );
298
299 m_startAH->paint( painter, m_pStart->x(), m_pStart->y(), -vecX, -vecY, zoomHandler );
300 m_endAH->paint( painter, m_pEnd->x(), m_pEnd->y(), vecX, vecY, zoomHandler );
301 }
302
303 // TODO: Text
304 drawText( pData );
305}
306
307void KivioSMLConnector::paintOutline( KivioIntraStencilData *pData )
308{
309 paint( pData );
310}
311
312bool KivioSMLConnector::saveCustom( TQDomElement &e, TQDomDocument &doc )
313{
314 kdDebug(43000) << "Save custom " << endl;
315 e.appendChild( saveArrowHeads( doc ) );
316
317 //TQDomElement type = m_shape->saveXML(doc);
318 KivioConnectorPoint *p = m_PointList.first();
319 while ( p )
320 {
321 TQDomElement pt = p->saveXML( doc );
322 e.appendChild( pt );
323 p = m_PointList.next();
324 }
325 return true;
326}
327
328bool KivioSMLConnector::loadCustom( const TQDomElement &e )
329{
330 kdDebug(43000) << "Load custom " << endl;
331 TQDomNode node;
332 TQString name;
333
334 node = e.firstChild();
335 while ( !node.isNull() )
336 {
337 name = node.nodeName();
338 if ( name == "KivioArrowHeads" )
339 {
340 loadArrowHeads( node.toElement() );
341 }
342 else if ( name == "KivioShape" )
343 {
344 //m_shape->loadXML(node.toElement());
345 TQDomNode pts = node.firstChild();
346 while ( !pts.isNull() )
347 {
348 KivioConnectorPoint * pt = new KivioConnectorPoint();
349 pt->loadXML( pts.toElement() );
350 m_pConnectorPoints->append( pt );
351 m_PointList.append( pt );
352 pts = pts.nextSibling();
353 }
354 }
355 node = node.nextSibling();
356 }
357
358 updateGeometry();
359
360 return true;
361}
362
363TQDomElement KivioSMLConnector::saveArrowHeads( TQDomDocument &doc )
364{
365 TQDomElement e = doc.createElement( "KivioArrowHeads" );
366
367 e.appendChild( m_startAH->saveXML( doc ) );
368 e.appendChild( m_endAH->saveXML( doc ) );
369
370 return e;
371}
372
373bool KivioSMLConnector::loadArrowHeads( const TQDomElement &e )
374{
375 TQDomNode node;
376 TQString nodeName;
377 TQDomElement arrowE;
378 bool first = true;
379
380 node = e.firstChild();
381 while ( !node.isNull() )
382 {
383 nodeName = node.nodeName();
384 arrowE = node.toElement();
385
386 if ( nodeName == "KivioArrowHead" )
387 {
388 if ( first == true )
389 {
390 m_startAH->loadXML( arrowE );
391
392 first = false;
393 }
394 else
395 {
396 m_endAH->loadXML( arrowE );
397 }
398 }
399
400 node = node.nextSibling();
401 }
402
403 return true;
404}
405
406
407bool KivioSMLConnector::loadPath( const TQString &file )
408{
409 kdDebug(43000) << "Loading :" << file << endl;
410
411 m_PointList.clear();
412 m_PointList.append(m_pStart);
413
414 KivioConnectorPoint *pt = new KivioConnectorPoint(this,false);
415 pt->setPosition(m_pStart->x()+10,m_pStart->y()+10,false);
416// m_PointList.append( pt );
417 m_pConnectorPoints->append(pt);
418
419 pt = new KivioConnectorPoint(this,false);
420 pt->setPosition(m_pStart->x()+20,m_pStart->y()+20,false);
421 m_PointList.append( pt );
422 m_pConnectorPoints->append(pt);
423
424 pt = new KivioConnectorPoint(this,false);
425 pt->setPosition(m_pStart->x()+30,m_pStart->y()+30,false);
426 m_PointList.append( pt );
427 m_pConnectorPoints->append(pt);
428
429// m_PointList.append(m_pEnd);
430 m_name = file;
431 return true;
432}
433
434#include "sml_connector.moc"