kivio_group_stencil.cpp
1/*
2 * Kivio - Visual Modelling and Flowcharting
3 * Copyright (C) 2000-2004 theKompany.com & Dave Marotti
4 * Peter Simonsson
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20#include "kivio_group_stencil.h"
21#include "kivio_intra_stencil_data.h"
22#include "kivio_layer.h"
23
24#include <kdebug.h>
25
26#include <KoGlobal.h>
27
28KivioGroupStencil::KivioGroupStencil()
29 : KivioStencil(),
30 m_pGroupList(NULL)
31{
32 m_pGroupList = new TQPtrList<KivioStencil>;
33 m_pGroupList->setAutoDelete(true);
34
35 m_x = m_y = 1000000000000.0f;
36 m_w = m_h = -10000000000.0f;
37 setType(kstGroup);
38}
39
40KivioGroupStencil::~KivioGroupStencil()
41{
42 if( m_pGroupList )
43 {
44 delete m_pGroupList;
45 m_pGroupList = NULL;
46 }
47}
48
49
50void KivioGroupStencil::paint( KivioIntraStencilData *pData )
51{
52 // Draw the group
53 KivioStencil *pStencil = m_pGroupList->first();
54 while( pStencil )
55 {
56 pStencil->paint(pData);
57
58 pStencil = m_pGroupList->next();
59 }
60}
61
62void KivioGroupStencil::paintOutline( KivioIntraStencilData *pData )
63{
64 // Draw the group in outline mode
65 KivioStencil *pStencil = m_pGroupList->first();
66 while( pStencil )
67 {
68 pStencil->paintOutline(pData);
69
70 pStencil = m_pGroupList->next();
71 }
72}
73
74void KivioGroupStencil::paintConnectorTargets( KivioIntraStencilData *pData )
75{
76 // Draw the group in outline mode
77 KivioStencil *pStencil = m_pGroupList->first();
78 while( pStencil )
79 {
80 pStencil->paintConnectorTargets(pData);
81
82 pStencil = m_pGroupList->next();
83 }
84}
85
86void KivioGroupStencil::setFGColor( TQColor c )
87{
88 // Draw the group in outline mode
89 KivioStencil *pStencil = m_pGroupList->first();
90 while( pStencil )
91 {
92 pStencil->setFGColor(c);
93
94 pStencil = m_pGroupList->next();
95 }
96}
97
98void KivioGroupStencil::setBGColor( TQColor c )
99{
100 // Draw the group in outline mode
101 KivioStencil *pStencil = m_pGroupList->first();
102 while( pStencil )
103 {
104 pStencil->setBGColor(c);
105
106 pStencil = m_pGroupList->next();
107 }
108}
109
110void KivioGroupStencil::setLineWidth( double f )
111{
112 // Draw the group in outline mode
113 KivioStencil *pStencil = m_pGroupList->first();
114 while( pStencil )
115 {
116 pStencil->setLineWidth(f);
117
118 pStencil = m_pGroupList->next();
119 }
120}
121
122KivioCollisionType KivioGroupStencil::checkForCollision( KoPoint *p, double threshold )
123{
124 KivioCollisionType colType;
125
126 // Draw the group in outline mode
127 KivioStencil *pStencil = m_pGroupList->last();
128 while( pStencil )
129 {
130 colType = pStencil->checkForCollision( p, threshold );
131 if( colType != kctNone && pStencil->type()!=kstConnector) {
132 return colType;
133 }
134
135 pStencil = m_pGroupList->prev();
136 }
137
138 return kctNone;
139}
140
141void KivioGroupStencil::addToGroup( KivioStencil *pStencil )
142{
143 double left, right, top, bottom;
144
145
146 m_pGroupList->append(pStencil);
147
148 // Special case it
149 if( m_pGroupList->count() == 1 )
150 {
151 m_x = pStencil->x();
152 m_y = pStencil->y();
153 m_w = pStencil->w();
154 m_h = pStencil->h();
155 }
156 else
157 {
158 right = pStencil->x() + pStencil->w();
159 left = pStencil->x();
160 top = pStencil->y();
161 bottom = pStencil->y() + pStencil->h();
162
163 // Adjust the borders to new limits
164 if( left < m_x )
165 {
166 m_w = m_w + (m_x - left);
167 m_x = left;
168 }
169 if( right > m_x + m_w )
170 {
171 m_w = right - m_x;
172 }
173 if( top < m_y )
174 {
175 m_h = m_h + (m_y - top);
176 m_y = top;
177 }
178 if( bottom > m_y + m_h )
179 {
180 m_h = bottom - m_y;
181 }
182 }
183}
184
185KivioStencil *KivioGroupStencil::duplicate()
186{
187 KivioGroupStencil *pGroup;
188 KivioStencil *pStencil;
189
190 pGroup = new KivioGroupStencil();
191
192 pStencil = m_pGroupList->first();
193 while( pStencil )
194 {
195 pGroup->addToGroup( pStencil->duplicate() );
196
197 pStencil = m_pGroupList->next();
198 }
199
200 *(pGroup->protection()) = *m_pProtection;
201
202 return pGroup;
203}
204
205bool KivioGroupStencil::loadXML( const TQDomElement &e, KivioLayer *pLayer )
206{
207 TQDomNode node;
208 KivioStencil *pStencil;
209
210 node = e.firstChild();
211 while( !node.isNull() )
212 {
213 TQString name = node.nodeName();
214
215 if( name == "KivioGroupStencil" )
216 {
217 pStencil = pLayer->loadGroupStencil( node.toElement() );
218 if( pStencil )
219 {
220 addToGroup( pStencil );
221 }
222 else
223 {
224 kdDebug(43000) << "KivioGroupStencil::loadXML() - Error loading group stencil" << endl;
225 }
226 }
227 else if( name == "KivioSMLStencil" || name == "KivioPyStencil" )
228 {
229 pStencil = pLayer->loadSMLStencil( node.toElement() );
230 if( pStencil )
231 {
232 addToGroup( pStencil );
233 }
234 else
235 {
236 kdDebug(43000) << "KivioGroupStencil::loadXML() - Error loading group stencil" << endl;
237 }
238 }
239 else if( name == "KivioPluginStencil" )
240 {
241 KivioStencil *pStencil = pLayer->loadPluginStencil( node.toElement() );
242 if( pStencil )
243 {
244 addToGroup( pStencil );
245 }
246 else
247 {
248 kdDebug(43000) << "KivioGroupStencil::loadXML() - Error loading group stencil" << endl;
249 }
250 }
251
252 node = node.nextSibling();
253 }
254
255 return true;
256}
257
258TQDomElement KivioGroupStencil::saveXML( TQDomDocument &doc )
259{
260 TQDomElement e = doc.createElement("KivioGroupStencil");
261
262 TQDomElement stencilE;
263 KivioStencil *pStencil = m_pGroupList->first();
264 while( pStencil )
265 {
266 stencilE = pStencil->saveXML( doc );
267
268 e.appendChild( stencilE );
269
270 pStencil = m_pGroupList->next();
271 }
272
273 return e;
274}
275
276void KivioGroupStencil::setX( double newX )
277{
278 double dx = newX - m_x;
279
280 m_x = newX;
281 KivioStencil *pStencil = m_pGroupList->first();
282 while( pStencil )
283 {
284 if( pStencil->protection()->at(kpX)==false )
285 {
286 pStencil->setX( pStencil->x() + dx );
287 }
288
289 pStencil = m_pGroupList->next();
290 }
291
292}
293
294void KivioGroupStencil::setY( double newY )
295{
296 double dy = newY - m_y;
297
298 m_y = newY;
299 KivioStencil *pStencil = m_pGroupList->first();
300 while( pStencil )
301 {
302 if( pStencil->protection()->at(kpY)==false )
303 {
304 pStencil->setY( pStencil->y() + dy );
305 }
306
307 pStencil = m_pGroupList->next();
308 }
309
310}
311
312void KivioGroupStencil::setPosition( double newX, double newY )
313{
314 double dx = newX - m_x;
315 double dy = newY - m_y;
316
317 double newX2, newY2;
318
319 m_x = newX;
320 m_y = newY;
321
322 KivioStencil *pStencil = m_pGroupList->first();
323 while( pStencil )
324 {
325 if(((pStencil->type() == kstConnector) && !pStencil->connected()) ||
326 pStencil->type() != kstConnector)
327 {
328 if( pStencil->protection()->at(kpX)==false ) {
329 newX2 = pStencil->x() + dx;
330 } else {
331 newX2 = pStencil->x();
332 }
333
334 if( pStencil->protection()->at(kpY)==false ) {
335 newY2 = pStencil->y() + dy;
336 } else {
337 newY2 = pStencil->y();
338 }
339
340 pStencil->setPosition( newX2, newY2 );
341 }
342
343 pStencil = m_pGroupList->next();
344 }
345
346}
347
348void KivioGroupStencil::setW( double newW )
349{
350 double percInc = newW / m_w;
351
352 if( newW > 0.0f ) {
353 m_w = newW;
354 }
355
356 KivioStencil *pStencil = m_pGroupList->first();
357 while( pStencil )
358 {
359 if(((pStencil->type() == kstConnector) && !pStencil->connected()) ||
360 pStencil->type() != kstConnector)
361 {
362 if( pStencil->protection()->at(kpX)==false ) {
363 pStencil->setX( ((pStencil->x() - m_x) * percInc) + m_x );
364 }
365
366 if( pStencil->protection()->at(kpWidth)==false ) {
367 pStencil->setW( pStencil->w() * percInc );
368 }
369 }
370
371 pStencil = m_pGroupList->next();
372 }
373}
374
375void KivioGroupStencil::setH( double newH )
376{
377 double percInc = newH / m_h;
378
379 if( newH > 0.0f ) {
380 m_h = newH;
381 }
382
383 KivioStencil *pStencil = m_pGroupList->first();
384 while( pStencil )
385 {
386 if(((pStencil->type() == kstConnector) && !pStencil->connected()) ||
387 pStencil->type() != kstConnector)
388 {
389 if( pStencil->protection()->at(kpY)==false ) {
390 pStencil->setY( ((pStencil->y() - m_y) * percInc) + m_y );
391 }
392
393 if( pStencil->protection()->at(kpHeight)==false ) {
394 pStencil->setH( pStencil->h() * percInc );
395 }
396 }
397
398 pStencil = m_pGroupList->next();
399 }
400}
401
402void KivioGroupStencil::setDimensions( double newW, double newH )
403{
404 double percIncX = newW / m_w;
405 double percIncY = newH / m_h;
406
407 if( newW > 0.0f ) {
408 m_w = newW;
409 }
410 if( newH > 0.0f ) {
411 m_h = newH;
412 }
413
414 KivioStencil *pStencil = m_pGroupList->first();
415 while( pStencil )
416 {
417 if(((pStencil->type() == kstConnector) && !pStencil->connected()) ||
418 pStencil->type() != kstConnector)
419 {
420 if( newW > 0.0f ) {
421 if( pStencil->protection()->at(kpX)==false ) {
422 pStencil->setX( ((pStencil->x() - m_x) * percIncX) + m_x );
423 }
424 if( pStencil->protection()->at(kpWidth)==false ) {
425 pStencil->setW( pStencil->w() * percIncX );
426 }
427 }
428
429 if( newH > 0.0f ) {
430 if( pStencil->protection()->at(kpY)==false ) {
431 pStencil->setY( ((pStencil->y() - m_y) * percIncY) + m_y );
432 }
433 if( pStencil->protection()->at(kpHeight)==false ) {
434 pStencil->setH( pStencil->h() * percIncY );
435 }
436 }
437 }
438
439 pStencil = m_pGroupList->next();
440 }
441
442}
443
444int KivioGroupStencil::generateIds( int next )
445{
446 KivioStencil *pStencil = m_pGroupList->first();
447
448 while( pStencil )
449 {
450 next = pStencil->generateIds( next );
451
452 pStencil = m_pGroupList->next();
453 }
454
455 return next;
456}
457
458
459KivioConnectorTarget *KivioGroupStencil::connectToTarget( KivioConnectorPoint *p, double thresh)
460{
461 KivioConnectorTarget *pTarget;
462
463 KivioStencil *pStencil = m_pGroupList->first();
464 while( pStencil )
465 {
466 pTarget = pStencil->connectToTarget( p, thresh );
467 if( pTarget )
468 return pTarget;
469
470 pStencil = m_pGroupList->next();
471 }
472
473 return NULL;
474}
475
476KivioConnectorTarget *KivioGroupStencil::connectToTarget( KivioConnectorPoint *p, int id )
477{
478 KivioConnectorTarget *pTarget;
479
480 KivioStencil *pStencil = m_pGroupList->first();
481 while( pStencil )
482 {
483 pTarget = pStencil->connectToTarget( p, id );
484 if( pTarget )
485 return pTarget;
486
487 pStencil = m_pGroupList->next();
488 }
489
490 return NULL;
491}
492
493void KivioGroupStencil::searchForConnections( KivioPage *p )
494{
495 KivioStencil *pCur = 0;
496 KivioStencil *pStencil = m_pGroupList->first();
497
498 while( pStencil )
499 {
500 // Backup the current list position
501 pCur = pStencil;
502
503 pStencil->searchForConnections( p );
504
505 // Restore it
506 m_pGroupList->find( pCur );
507
508 pStencil = m_pGroupList->next();
509 }
510}
511
512void KivioGroupStencil::setTextColor( TQColor c )
513{
514 KivioStencil *pStencil = m_pGroupList->first();
515 while( pStencil )
516 {
517 pStencil->setTextColor(c);
518
519 pStencil = m_pGroupList->next();
520 }
521}
522
523void KivioGroupStencil::setText( const TQString &text )
524{
525 KivioStencil *pStencil = m_pGroupList->first();
526 while( pStencil )
527 {
528 pStencil->setText(text);
529
530 pStencil = m_pGroupList->next();
531 }
532}
533
534TQString KivioGroupStencil::text()
535{
536 KivioStencil *pStencil = m_pGroupList->first();
537
538 if( !pStencil )
539 return TQString("");
540
541 return pStencil->text();
542}
543
544void KivioGroupStencil::setHTextAlign( int a )
545{
546 KivioStencil *pStencil = m_pGroupList->first();
547 while( pStencil )
548 {
549 pStencil->setHTextAlign(a);
550
551 pStencil = m_pGroupList->next();
552 }
553}
554
555int KivioGroupStencil::hTextAlign()
556{
557 KivioStencil *pStencil = m_pGroupList->first();
558
559 if( !pStencil )
560 return TQt::AlignHCenter;
561
562 return pStencil->hTextAlign();
563}
564
565void KivioGroupStencil::setVTextAlign( int a )
566{
567 KivioStencil *pStencil = m_pGroupList->first();
568 while( pStencil )
569 {
570 pStencil->setVTextAlign(a);
571
572 pStencil = m_pGroupList->next();
573 }
574}
575
576int KivioGroupStencil::vTextAlign()
577{
578 KivioStencil *pStencil = m_pGroupList->first();
579
580 if( !pStencil )
581 return TQt::AlignVCenter;
582
583 return pStencil->vTextAlign();
584}
585
586void KivioGroupStencil::setTextFont( const TQFont &f )
587{
588 KivioStencil *pStencil = m_pGroupList->first();
589 while( pStencil )
590 {
591 pStencil->setTextFont(f);
592
593 pStencil = m_pGroupList->next();
594 }
595}
596
597TQFont KivioGroupStencil::textFont()
598{
599 KivioStencil *pStencil = m_pGroupList->first();
600
601 if( !pStencil )
602 return KoGlobal::defaultFont();
603
604 return pStencil->textFont();
605}
606
607TQColor KivioGroupStencil::textColor()
608{
609 KivioStencil *pStencil = m_pGroupList->first();
610
611 if( !pStencil )
612 return TQColor(0, 0, 0);
613
614 return pStencil->textColor();
615}
616
617int KivioGroupStencil::resizeHandlePositions()
618{
619 return KIVIO_RESIZE_HANDLE_POSITION_ALL;
620}
621
622TQString KivioGroupStencil::getTextBoxName(const KoPoint& p)
623{
624 int id = checkForCollision(p);
625
626 if(id < 0) {
627 return TQString();
628 }
629
630 KivioStencil* pStencil = m_pGroupList->at(id);
631 TQString name = TQString::number(id) + "-" + pStencil->getTextBoxName(p);
632 return name;
633}
634
635void KivioGroupStencil::setText(const TQString& text, const TQString& name)
636{
637 int id = name.section("-", 0, 0).toInt();
638 TQString n = name.section("-", 1);
639
640 m_pGroupList->at(id)->setText(text, n);
641}
642
643TQString KivioGroupStencil::text(const TQString& name)
644{
645 int id = name.section("-", 0, 0).toInt();
646 TQString n = name.section("-", 1);
647
648 return m_pGroupList->at(id)->text(n);
649}
650
651int KivioGroupStencil::checkForCollision(const KoPoint& p)
652{
653 KivioStencil *pStencil = m_pGroupList->first();
654 KoPoint pos = p;
655 int id = 0;
656
657 while(pStencil)
658 {
659 if(pStencil->checkForCollision(&pos, 4.0) != kctNone) {
660 return id;
661 }
662
663 pStencil = m_pGroupList->next();
664 id++;
665 }
666
667 return -1;
668}
669
670bool KivioGroupStencil::hasTextBox() const
671{
672 KivioStencil *pStencil = m_pGroupList->first();
673
674 while(pStencil)
675 {
676 if(pStencil->hasTextBox()) {
677 return true;
678 }
679
680 pStencil = m_pGroupList->next();
681 }
682
683 return false;
684}
685
686TQColor KivioGroupStencil::textColor(const TQString& textBoxName)
687{
688 int id = textBoxName.section("-", 0, 0).toInt();
689 TQString n = textBoxName.section("-", 1);
690
691 return m_pGroupList->at(id)->textColor(n);
692}
693
694void KivioGroupStencil::setTextColor(const TQString& textBoxName, const TQColor& color)
695{
696 int id = textBoxName.section("-", 0, 0).toInt();
697 TQString n = textBoxName.section("-", 1);
698
699 m_pGroupList->at(id)->setTextColor(n, color);
700}
701
702TQFont KivioGroupStencil::textFont(const TQString& textBoxName)
703{
704 int id = textBoxName.section("-", 0, 0).toInt();
705 TQString n = textBoxName.section("-", 1);
706
707 return m_pGroupList->at(id)->textFont(n);
708}
709
710void KivioGroupStencil::setTextFont(const TQString& textBoxName, const TQFont& font)
711{
712 int id = textBoxName.section("-", 0, 0).toInt();
713 TQString n = textBoxName.section("-", 1);
714
715 m_pGroupList->at(id)->setTextFont(n, font);
716}
717
718int KivioGroupStencil::hTextAlign(const TQString& textBoxName)
719{
720 int id = textBoxName.section("-", 0, 0).toInt();
721 TQString n = textBoxName.section("-", 1);
722
723 return m_pGroupList->at(id)->hTextAlign(n);
724}
725
726int KivioGroupStencil::vTextAlign(const TQString& textBoxName)
727{
728 int id = textBoxName.section("-", 0, 0).toInt();
729 TQString n = textBoxName.section("-", 1);
730
731 return m_pGroupList->at(id)->vTextAlign(n);
732}
733
734void KivioGroupStencil::setHTextAlign(const TQString& textBoxName, int align)
735{
736 int id = textBoxName.section("-", 0, 0).toInt();
737 TQString n = textBoxName.section("-", 1);
738
739 m_pGroupList->at(id)->setHTextAlign(n, align);
740}
741
742void KivioGroupStencil::setVTextAlign(const TQString& textBoxName, int align)
743{
744 int id = textBoxName.section("-", 0, 0).toInt();
745 TQString n = textBoxName.section("-", 1);
746
747 m_pGroupList->at(id)->setVTextAlign(n, align);
748}