kivio

kivio_layer.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 "kivio_common.h"
20#include "kivio_connector_point.h"
21#include "kivio_connector_target.h"
22#include "kivio_group_stencil.h"
23#include "kivio_intra_stencil_data.h"
24#include "kivio_layer.h"
25#include "kivio_painter.h"
26#include "kivio_stencil.h"
27#include "kivio_stencil_spawner.h"
28#include "kivio_stencil_spawner_info.h"
29#include "kivio_stencil_spawner_set.h"
30#include "KIvioLayerIface.h"
31#include "kivio_doc.h"
32#include "kivio_page.h"
33
34#include <tqdom.h>
35
36#include <tdelocale.h>
37#include <kdebug.h>
38#include <KoZoomHandler.h>
39#include <KoPoint.h>
40#include <KoStore.h>
41#include <KoXmlWriter.h>
42
43KivioLayer::KivioLayer( KivioPage *pPage )
44 :m_pStencilList(NULL)
45{
46 m_pPage = pPage;
47 m_name = i18n("Untitled Layer");
48
49 m_pStencilList = new TQPtrList<KivioStencil>;
50 m_pStencilList->setAutoDelete(true);
51
52 m_pDeletedStencilList = new TQPtrList<KivioStencil>;
53 m_pDeletedStencilList->setAutoDelete(true);
54
55 m_flags = 0;
56 m_dcop = 0;
57 setVisible(true);
58 setConnectable(false);
59 setEditable(true);
60 setPrintable(true);
61}
62
63DCOPObject* KivioLayer::dcopObject()
64{
65 if ( !m_dcop )
66 m_dcop = new KIvioLayerIface( this );
67 return m_dcop;
68}
69
70KivioLayer::~KivioLayer()
71{
72 kdDebug(43000)<<"KivioLayer::~KivioLayer()***************:"<<this<<endl;
73 if( m_pStencilList )
74 {
75 delete m_pStencilList;
76 m_pStencilList = NULL;
77 }
78 delete m_pDeletedStencilList;
79 delete m_dcop;
80}
81
82bool KivioLayer::addStencil( KivioStencil *pStencil )
83{
84 int pos = m_pDeletedStencilList->findRef(pStencil);
85 if ( pos != -1 )
86 m_pDeletedStencilList->take( pos);
87
88 m_pStencilList->append( pStencil );
89
90 return true;
91}
92
93void KivioLayer::takeStencilFromList( KivioStencil *pStencil )
94{
95 int pos=m_pStencilList->findRef(pStencil);
96 m_pStencilList->take( pos );
97 m_pDeletedStencilList->append( pStencil );
98}
99
100void KivioLayer::insertStencil( KivioStencil *pStencil )
101{
102 int pos=m_pDeletedStencilList->findRef(pStencil);
103 if ( pos != -1 )
104 m_pDeletedStencilList->take( pos);
105
106 m_pStencilList->append( pStencil );
107}
108
109bool KivioLayer::removeStencil( KivioStencil *pStencil )
110{
111 return m_pStencilList->remove( pStencil );
112}
113
114
127KivioStencil *KivioLayer::loadSMLStencil( const TQDomElement &stencilE )
128{
129 TQString setId, _id;
130
131 kdDebug(43000) << "KivioLayer::loadSMLStencil() " << setId << " " << _id << endl;
132
133 setId = XmlReadString( stencilE, "setId", "" );
134 _id = XmlReadString( stencilE, "id", "" );
135
136
137 if( setId.length() == 0 ||
138 _id.length() == 0 )
139 {
140 return NULL;
141 }
142
143
144 // Locate the spawner set
145 KivioStencilSpawner *pSpawner = m_pPage->doc()->findStencilSpawner(setId,_id);
146 if( pSpawner )
147 {
148 KivioStencil *pStencil = pSpawner->newStencil();
149 pStencil->loadXML( stencilE );
150
151 return pStencil;
152 }
153
154 return NULL;
155}
156
169KivioStencil *KivioLayer::loadGroupStencil( const TQDomElement &stencilE )
170{
171 kdDebug(43000) << "KivioLayer::loadGroupStencil()" << endl;
172
173 KivioGroupStencil *pStencil = new KivioGroupStencil();
174
175 if(pStencil->loadXML( stencilE, this )==false)
176 {
177 delete pStencil;
178 return NULL;
179 }
180
181 return pStencil;
182}
183
184KivioStencil *KivioLayer::loadPluginStencil( const TQDomElement &stencilE )
185{
186 TQString setId, _id;
187
188 kdDebug(43000) << "KivioLayer::loadPluginStencil() " << setId.ascii() << " / " << _id << endl;
189
190
191 setId = XmlReadString( stencilE, "setId", "" );
192 _id = XmlReadString( stencilE, "id", "" );
193
194
195 if( setId.length() == 0 ||
196 _id.length() == 0 )
197 return NULL;
198
199
200 // Locate the spawner set
201 KivioStencilSpawner *pSpawner = m_pPage->doc()->findStencilSpawner(setId, _id);
202 if( pSpawner )
203 {
204 KivioStencil *pStencil = pSpawner->newStencil();
205 pStencil->loadXML( stencilE );
206
207 return pStencil;
208 }
209
210 return NULL;
211}
212
213bool KivioLayer::loadXML( const TQDomElement &layerE )
214{
215 m_flags = XmlReadInt( layerE, "flags", 1 );
216 kdDebug(43000) << "Flags: " << m_flags << endl;
217 m_name = XmlReadString( layerE, "name", "layerX" );
218
219 TQDomNode node;
220 node = layerE.firstChild();
221 while( !node.isNull() )
222 {
223 TQString name = node.nodeName();
224 if( name == "KivioSMLStencil" || name == "KivioPyStencil" )
225 {
226 KivioStencil *pStencil = loadSMLStencil( node.toElement() );
227 if( pStencil )
228 {
229 pStencil->updateGeometry();
230 m_pStencilList->append( pStencil );
231 }
232 else
233 {
234 kdWarning(43000) << "KivioLayer::loadXML() - Unknown KivioSMLStencil (id=" <<
235 XmlReadString( node.toElement(), "id", "" ) << " set=" <<
236 XmlReadString( node.toElement(), "setId", "" ) << ") found." << endl;
237 }
238 }
239 else if( name == "KivioGroupStencil" )
240 {
241 KivioStencil *pStencil = loadGroupStencil( node.toElement() );
242 if( pStencil )
243 {
244 m_pStencilList->append(pStencil);
245 }
246 else
247 {
248 kdWarning(43000) << "KivioLayer::loadXML() - Unable to load KivioGroupStencil" << endl;
249 }
250 }
251 else if( name == "KivioPluginStencil" )
252 {
253 KivioStencil *pStencil = loadPluginStencil( node.toElement() );
254 if( pStencil )
255 {
256 m_pStencilList->append(pStencil);
257 }
258 else
259 {
260 kdWarning(43000) << "KivioLayer - Unable to load KivioPluginStencil" << endl;
261 kdWarning(43000) << "KivioLayer::loadXML() - Unable to load KivioPluginStencil (id=" <<
262 XmlReadString( node.toElement(), "id", "" ) << " set=" <<
263 XmlReadString( node.toElement(), "setId", "" ) << ") found." << endl;
264 }
265 }
266
267 node = node.nextSibling();
268 }
269
270 return true;
271}
272
273void KivioLayer::loadOasis(const TQDomElement& layer)
274{
275 m_name = layer.attribute("draw:name");
276 // TODO OASIS Load flags
277}
278
279
280TQDomElement KivioLayer::saveXML( TQDomDocument &doc )
281{
282 TQDomElement e = doc.createElement("KivioLayer");
283
284 XmlWriteInt( e, "flags", m_flags );
285 XmlWriteString( e, "name", m_name );
286
287 KivioStencil *pStencil = m_pStencilList->first();
288 while( pStencil )
289 {
290 e.appendChild( pStencil->saveXML( doc ) );
291
292 pStencil = m_pStencilList->next();
293 }
294
295 return e;
296}
297
298void KivioLayer::saveOasis(KoXmlWriter* layerWriter)
299{
300 layerWriter->startElement("draw:layer");
301 layerWriter->addAttribute("draw:name", m_name);
302 // TODO OASIS Save flags
303 layerWriter->endElement(); // draw:layer
304}
305
306void KivioLayer::paintContent( KivioPainter& painter, const TQRect&, bool, TQPoint,
307 KoZoomHandler* zoom )
308{
309 if(!visible()) {
310 return;
311 }
312
313 KivioStencil *pStencil = m_pStencilList->first();
314 KivioIntraStencilData data;
315
316 painter.setFGColor( TQColor(0,0,0) );
317
318 data.painter = &painter;
319 data.zoomHandler = zoom;
320
321 while( pStencil )
322 {
323 if(!pStencil->hidden()) {
324 pStencil->paint( &data );
325 }
326
327 pStencil = m_pStencilList->next();
328 }
329}
330
331void KivioLayer::printContent( KivioPainter& painter, int xdpi, int ydpi )
332{
333 if(!printable() || !visible())
334 return;
335
336 if(!xdpi) {
337 xdpi = KoGlobal::dpiX();
338 }
339
340 if(!ydpi) {
341 ydpi = KoGlobal::dpiY();
342 }
343
344 KivioStencil *pStencil = m_pStencilList->first();
345 KivioIntraStencilData data;
346 KoZoomHandler zoomHandler;
347 zoomHandler.setZoomAndResolution(100, xdpi, ydpi);
348
349 painter.setFGColor( TQColor(0,0,0) );
350
351 data.painter = &painter;
352 data.zoomHandler = &zoomHandler;
353 data.printing = true;
354
355 while( pStencil )
356 {
357 pStencil->paint( &data );
358
359 pStencil = m_pStencilList->next();
360 }
361}
362
363void KivioLayer::printContent(KivioPainter& painter, KoZoomHandler* zoomHandler)
364{
365 if(!printable() || !visible())
366 return;
367
368 KivioStencil *pStencil = m_pStencilList->first();
369 KivioIntraStencilData data;
370
371 painter.setFGColor( TQColor(0,0,0) );
372
373 data.painter = &painter;
374 data.zoomHandler = zoomHandler;
375 data.printing = true;
376
377 while( pStencil )
378 {
379 pStencil->paint( &data );
380
381 pStencil = m_pStencilList->next();
382 }
383}
384
385void KivioLayer::paintConnectorTargets( KivioPainter& painter, const TQRect&, bool, TQPoint,
386 KoZoomHandler* zoom )
387{
388 if(!visible()) {
389 return;
390 }
391
392 KivioIntraStencilData data;
393
394 painter.setFGColor( TQColor(0,0,0) );
395
396 data.painter = &painter;
397 data.zoomHandler = zoom;
398
399 KivioStencil *pStencil = m_pStencilList->first();
400 while( pStencil )
401 {
402 if(!pStencil->hidden()) {
403 pStencil->paintConnectorTargets( &data );
404 }
405
406 pStencil = m_pStencilList->next();
407 }
408}
409
410void KivioLayer::paintSelectionHandles( KivioPainter& painter, const TQRect&, bool, TQPoint, KoZoomHandler* zoom )
411{
412 if(!visible()) {
413 return;
414 }
415
416 KivioIntraStencilData data;
417
418 painter.setFGColor( TQColor(0,0,0) );
419
420 data.painter = &painter;
421 data.zoomHandler = zoom;
422
423 KivioStencil *pStencil = m_pStencilList->first();
424 while( pStencil )
425 {
426 if( pStencil->isSelected() && !pStencil->hidden() )
427 pStencil->paintSelectionHandles( &data );
428
429 pStencil = m_pStencilList->next();
430 }
431}
432
433KivioStencil *KivioLayer::checkForStencil( KoPoint *pPoint, int *collisionType, float threshold, bool selectedOnly )
434{
435 KivioStencil *pStencil;
436 int colType;
437
438 if(editable()) {
439 pStencil = m_pStencilList->last();
440 while( pStencil )
441 {
442 // If we are only supposed to check the selected stencils, then only do that. Otherwise
443 // check them all.
444 if( (selectedOnly==true && pStencil->isSelected()==true) ||
445 (selectedOnly==false) )
446 {
447 if( (colType = pStencil->checkForCollision( pPoint, threshold )) != kctNone )
448 {
449 // Assign the collision type and return
450 *collisionType = colType;
451 return pStencil;
452 }
453 }
454
455 pStencil = m_pStencilList->prev();
456 }
457 }
458
459 *collisionType = kctNone;
460
461 return NULL;
462}
463
464void KivioLayer::setVisible( bool f )
465{
466 if( f==true )
467 {
468 m_flags = m_flags | FLOW_LAYER_VISIBLE;
469 }
470 else
471 {
472 m_flags = m_flags & (~FLOW_LAYER_VISIBLE);
473 }
474}
475
476void KivioLayer::setConnectable( bool f )
477{
478 if( f==true )
479 {
480 m_flags = m_flags | FLOW_LAYER_CONNECTABLE;
481 }
482 else
483 {
484 m_flags = m_flags & (~FLOW_LAYER_CONNECTABLE);
485 }
486}
487
488void KivioLayer::setEditable(bool f)
489{
490 if(f) {
491 m_flags = m_flags & (~FLOW_LAYER_NOT_EDITABLE);
492 } else {
493 m_flags = m_flags | FLOW_LAYER_NOT_EDITABLE;
494 }
495}
496
497void KivioLayer::setPrintable(bool f)
498{
499 if(f) {
500 m_flags = m_flags & (~FLOW_LAYER_NOT_PRINTABLE);
501 } else {
502 m_flags = m_flags | FLOW_LAYER_NOT_PRINTABLE;
503 }
504}
505
506int KivioLayer::generateStencilIds( int next )
507{
508 KivioStencil *pStencil;
509
510 pStencil = m_pStencilList->first();
511 while( pStencil )
512 {
513 next = pStencil->generateIds( next );
514
515 pStencil = m_pStencilList->next();
516 }
517
518 return next;
519}
520
521void KivioLayer::searchForConnections( KivioPage *p )
522{
523 KivioStencil *pStencil;
524 KivioStencil *pCur;
525
526 pStencil = m_pStencilList->first();
527 while( pStencil )
528 {
529 // Backup the current list position
530 pCur = pStencil;
531
532 pStencil->searchForConnections( p );
533
534 // Restore it
535 m_pStencilList->find( pCur );
536
537 pStencil = m_pStencilList->next();
538 }
539}
540
541KivioStencil *KivioLayer::takeStencil( KivioStencil *p )
542{
543 m_pStencilList->find( p );
544
545 return m_pStencilList->take();
546}
547
548
556KivioConnectorTarget *KivioLayer::connectPointToTarget( KivioConnectorPoint *p, float thresh )
557{
558 KivioConnectorTarget *pTarget;
559
560 KivioStencil *pStencil = m_pStencilList->last();
561 while( pStencil )
562 {
563 // Don't allow the connector point to connect to the stencil that owns it
564 if( pStencil != p->stencil() )
565 {
566 pTarget = pStencil->connectToTarget(p, thresh);
567 if( pTarget )
568 {
569 return pTarget;
570 }
571 }
572
573 pStencil = m_pStencilList->prev();
574 }
575
576 return NULL;
577}
578
579KoPoint KivioLayer::snapToTarget( const KoPoint& p, double thresh, bool& hit )
580{
581 KoPoint retVal = p;
582 KivioStencil *pStencil = m_pStencilList->last();
583
584 while( pStencil && !hit)
585 {
586 retVal = pStencil->snapToTarget(p, thresh, hit);
587 pStencil = m_pStencilList->prev();
588 }
589
590 return retVal;
591}