kivio

kivio_page.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 <stdlib.h>
20#include <stdio.h>
21#include <ctype.h>
22#include <math.h>
23
24#include <tqpainter.h>
25#include <tqdrawutil.h>
26#include <tqkeycode.h>
27#include <tqregexp.h>
28#include <tqpoint.h>
29#include <tqcursor.h>
30#include <tqptrstack.h>
31#include <tqbuffer.h>
32#include <tqmessagebox.h>
33#include <tqclipboard.h>
34#include <tqpicture.h>
35#include <tqdom.h>
36#include <tqtextstream.h>
37#include <tqdragobject.h>
38#include <tqmime.h>
39#include <tqsortedlist.h>
40#include <tqvaluelist.h>
41
42#include <kdebug.h>
43#include <tdelocale.h>
44#include <tdeglobal.h>
45#include <tdemessagebox.h>
46#include <KoUnit.h>
47#include <KoPoint.h>
48#include <KoRect.h>
49#include <KoZoomHandler.h>
50#include <tdeapplication.h>
51#include <KoXmlWriter.h>
52#include <KoXmlNS.h>
53#include <KoDom.h>
54#include <KoStore.h>
55#include <KoOasisStyles.h>
56#include <KoGenStyles.h>
57
58#include "kivio_page.h"
59#include "kivio_map.h"
60#include "kivio_doc.h"
61#include "kivio_canvas.h"
62#include "kivio_view.h"
63#include "kivio_config.h"
64
65#include "kivio_common.h"
66#include "kivio_connector_point.h"
67#include "kivio_group_stencil.h"
68#include "kivio_intra_stencil_data.h"
69#include "kivio_layer.h"
70#include "kivio_painter.h"
71#include "kivio_stencil.h"
72#include "kivio_1d_stencil.h"
73#include "KIvioPageIface.h"
74#include "kivio_command.h"
75#include "kivioglobal.h"
76#include "kiviodragobject.h"
77
78#include <fixx11h.h> // for None
79
80int KivioPage::s_id = 0L;
81TQIntDict<KivioPage>* KivioPage::s_mapPages;
82
83KivioPage::KivioPage( KivioMap *_map, const TQString &pageName, const char *_name )
84: TQObject( _map, _name ),
85 m_pCurLayer(NULL)
86{
87 if ( s_mapPages == 0L )
88 s_mapPages = new TQIntDict<KivioPage>;
89 m_id = s_id++;
90 s_mapPages->insert( m_id, this );
91
92 m_dcop = 0;
93
94 m_pMap = _map;
95 m_pDoc = _map->doc();
96
97 // Make sure the layers auto-delete themselves
98 m_pCurLayer = new KivioLayer(this);
99 m_pCurLayer->setName(i18n("Layer 1"));
100 m_lstLayers.append( m_pCurLayer );
101 m_lstLayers.setAutoDelete(true);
102
103 m_lstSelection.setAutoDelete(false);
104
105 m_strName = pageName;
106
107 setHidden(false);
108 // Get a unique name so that we can offer scripting
109 if ( !_name ) {
110 TQCString s;
111 s.sprintf("Page%i", s_id );
112 setName( s.data() );
113 }
114
115 m_pPageLayout = Kivio::Config::defaultPageLayout();
116}
117
118DCOPObject* KivioPage::dcopObject()
119{
120 if ( !m_dcop )
121 m_dcop = new KIvioPageIface( this );
122 return m_dcop;
123}
124
125
126KivioPage::~KivioPage()
127{
128 kdDebug(43000)<<" KivioPage::~KivioPage()************ :"<<this<<endl;
129 s_mapPages->remove(m_id);
130 delete m_dcop;
131}
132
133KivioPage* KivioPage::find( int _id )
134{
135 if ( !s_mapPages )
136 return 0L;
137
138 return (*s_mapPages)[ _id ];
139}
140
141void KivioPage::print( TQPainter &/*painter*/, KPrinter */*_printer*/ )
142{
143}
144
145void KivioPage::printPage( TQPainter &/*_painter*/, const TQRect& /*page_range*/, const TQRect& /*view*/ )
146{
147}
148
149TQDomElement KivioPage::save( TQDomDocument& doc )
150{
151 // Write the name and 'hide' flag first as attributes
152 TQDomElement page = doc.createElement( "KivioPage" );
153 page.setAttribute( "name", m_strName );
154 page.setAttribute( "hide", (int)m_bPageHide );
155
156 // Create a child element for the page layout
157 TQDomElement layoutE = saveLayout( doc );
158 page.appendChild( layoutE );
159
160 // Save guides
161 TQDomElement guidesElement = doc.createElement("GuidesLayout");
162 page.appendChild(guidesElement);
163 saveGuideLines(guidesElement);
164
165 // Iterate through all layers saving them as child elements
166 KivioLayer *pLayer = m_lstLayers.first();
167 while( pLayer )
168 {
169 TQDomElement layerE = pLayer->saveXML(doc);
170 if( layerE.isNull() )
171 {
172 kdDebug(43000) << "KivioPage::save() - Oh shit. KivioLayer::saveXML() returned a bad element!" << endl;
173 }
174 else
175 {
176 page.appendChild( layerE );
177 }
178
179 pLayer = m_lstLayers.next();
180 }
181
182 return page;
183}
184
185void KivioPage::saveOasis(KoStore* /*store*/, KoXmlWriter* docWriter, KoGenStyles* styles)
186{
187 docWriter->startElement("draw:page");
188 docWriter->addAttribute("draw:name", m_strName);
189
190 if(m_pPageLayout == Kivio::Config::defaultPageLayout()) {
191 docWriter->addAttribute("draw:master-page-name", "Standard");
192 } else {
193 KoGenStyle pageLayout = m_pPageLayout.saveOasis();
194 TQString layoutName = styles->lookup(pageLayout, "PL");
195
196 KoGenStyle masterPage(KoGenStyle::STYLE_MASTER);
197 masterPage.addAttribute("style:page-layout-name", layoutName);
198 TQString masterName = styles->lookup(masterPage, "MP");
199
200 docWriter->addAttribute("draw:master-page-name", masterName);
201 }
202
203 // TODO OASIS: Save guidelines!
204
205 TQBuffer layerBuffer;
206 layerBuffer.open(IO_WriteOnly);
207 KoXmlWriter layerWriter(&layerBuffer);
208 layerWriter.startElement("draw:layer-set");
209
210 // Iterate through all layers
211 KivioLayer* layer = m_lstLayers.first();
212
213 while(layer) {
214 layer->saveOasis(&layerWriter);
215 layer = m_lstLayers.next();
216 }
217
218 layerWriter.endElement(); // draw:layer-set
219 TQString layerSet = TQString::fromUtf8(layerBuffer.buffer(), layerBuffer.buffer().size());
220 KoGenStyle pageStyle(Kivio::STYLE_PAGE, "drawing-page");
221 pageStyle.addChildElement("draw:layer-set", layerSet);
222 TQString styleName = styles->lookup(pageStyle, "PS");
223 docWriter->addAttribute("draw:style-name", styleName);
224
225 docWriter->endElement(); // draw:page
226}
227
228TQDomElement KivioPage::saveLayout( TQDomDocument &doc )
229{
230 TQDomElement e = doc.createElement("PageLayout");
231 Kivio::savePageLayout(e, m_pPageLayout);
232
233 return e;
234}
235
236bool KivioPage::loadLayout( const TQDomElement &e )
237{
238 m_pPageLayout = Kivio::loadPageLayout(e);
239 return true;
240}
241
242bool KivioPage::isLoading()
243{
244 return m_pDoc->isLoading();
245}
246
247bool KivioPage::loadXML( const TQDomElement& pageE )
248{
249 m_strName = pageE.attribute("name");
250 if (m_strName.isEmpty())
251 return false;
252
253
254 m_bPageHide = (int)pageE.attribute("hide").toInt();
255
256 // Clear the layer list
257 KivioLayer *pLayer;
258 m_lstLayers.clear();
259
260 TQDomNode node = pageE.firstChild();
261 while( !node.isNull() )
262 {
263 if( node.nodeName() == "KivioLayer" )
264 {
265 pLayer = new KivioLayer(this);
266 if( pLayer->loadXML( node.toElement() )==false )
267 {
268 delete pLayer;
269 pLayer = NULL;
270 }
271 else
272 {
273 m_lstLayers.append( pLayer );
274 pLayer = NULL;
275 }
276 }
277 else if( node.nodeName() == "PageLayout" )
278 {
279 loadLayout( node.toElement() );
280 }
281 else if ( node.nodeName() == "GuidesLayout" ) {
282 loadGuideLines(node.toElement());
283 }
284 else
285 {
286 kdDebug(43000) << "KivioLayer::loadXML() - unknown node found, " << node.nodeName() << endl;
287 }
288
289 node = node.nextSibling();
290 }
291
292 m_pCurLayer = m_lstLayers.first();
293 if( !m_pCurLayer )
294 {
295 kdDebug(43000) << "KivioLayer::loadXML() - No layers loaded!! BIGGGGG PROBLEMS!" << endl;
296 }
297
298 // Now that we are done loading, fix all the connections
299 KivioLayer *pLayerBak;
300
301 pLayer = m_lstLayers.first();
302 while( pLayer )
303 {
304 pLayerBak = pLayer;
305
306 kdDebug(43000) << "KivioLayer::loadXML() - loading layer connections" << endl;
307 pLayer->searchForConnections(this);
308
309 m_lstLayers.find( pLayerBak );
310
311 pLayer = m_lstLayers.next();
312 }
313
314 return true;
315}
316
317bool KivioPage::loadOasis(const TQDomElement& page, KoOasisStyles& oasisStyles)
318{
319 m_strName = page.attributeNS( KoXmlNS::draw, "name", TQString());
320 TQDomElement* masterPage = oasisStyles.masterPages()[page.attributeNS( KoXmlNS::draw, "master-page-name", TQString())];
321
322 if(!masterPage) {
323 kdDebug(430000) << "Couldn't find the master page! " << page.attributeNS( KoXmlNS::draw, "master-page-name", TQString()) << endl;
324 return false;
325 }
326
327 const TQDomElement *pageLayout = oasisStyles.findStyle(masterPage->attributeNS( KoXmlNS::style, "page-layout-name", TQString() ) );
328
329 if(!pageLayout) {
330 kdDebug(430000) << "Couldn't find the pagelayout!" << endl;
331 return false;
332 }
333
334 m_pPageLayout.loadOasis(*pageLayout);
335
336 if(m_pPageLayout.ptWidth <= 1e-13 || m_pPageLayout.ptHeight <= 1e-13) {
337 kdDebug(430000) << "Non valid pagelayout!" << endl;
338 return false;
339 }
340
341 const TQDomElement* style = oasisStyles.findStyle(page.attributeNS( KoXmlNS::draw, "style-name", TQString()) ); // Find the page style
342
343 if(!style) {
344 return false;
345 }
346
347 TQDomNode styleNode = KoDom::namedItemNS( *style, KoXmlNS::style, "properties");
348 styleNode = KoDom::namedItemNS( styleNode, KoXmlNS::draw, "layer-set");
349 TQDomNode currentNode = styleNode.firstChild();
350
351 // Load the layers
352 while(!currentNode.isNull()) {
353 if(currentNode.nodeName() == "draw:layer") {
354 KivioLayer* layer = new KivioLayer(this);
355 layer->loadOasis(currentNode.toElement());
356 m_lstLayers.append(layer);
357 }
358
359 currentNode = currentNode.nextSibling();
360 }
361
362 return true;
363}
364
365void KivioPage::update()
366{
367}
368
369KivioPage* KivioPage::findPage( const TQString& name )
370{
371 if (!m_pMap)
372 return 0L;
373
374 return m_pMap->findPage(name);
375}
376
377bool KivioPage::setPageName( const TQString& name, bool init )
378{
379 if ( map()->findPage( name ) )
380 return false;
381
382 if ( m_strName == name )
383 return true;
384
385 TQString old_name = m_strName;
386 m_strName = name;
387
388 if (init)
389 return true;
390
391 emit m_pDoc->sig_pageNameChanged(this, old_name);
392
393 return true;
394}
395
402void KivioPage::paintContent( KivioPainter& painter, const TQRect& rect, bool transparent,
403 TQPoint p0, KoZoomHandler* zoom, bool drawConnectorTargets, bool drawSelection )
404{
405 KivioLayer *pLayer = m_lstLayers.first();
406 while( pLayer )
407 {
408 if( pLayer->visible() )
409 {
410 pLayer->paintContent( painter, rect, transparent, p0, zoom );
411 }
412
413 pLayer = m_lstLayers.next();
414 }
415
416 // Now the second iteration - connection targets
417 // Only draw targets if the zoom is higher than a certain value
418 if(zoom->zoom() >= 50) {
419 if(drawConnectorTargets) {
420 m_pCurLayer->paintConnectorTargets( painter, rect, transparent, p0, zoom );
421 pLayer = m_lstLayers.first();
422
423 while(pLayer) {
424 if(pLayer->connectable() && (pLayer != m_pCurLayer)) {
425 pLayer->paintConnectorTargets( painter, rect, transparent, p0, zoom );
426 }
427
428 pLayer = m_lstLayers.next();
429 }
430 }
431 }
432
433 // Now the third iteration - selection handles
434 if(drawSelection) {
435 m_pCurLayer->paintSelectionHandles( painter, rect, transparent, p0, zoom );
436 }
437}
438
439void KivioPage::printContent( KivioPainter& painter, int xdpi, int ydpi )
440{
441 if(!xdpi) {
442 xdpi = KoGlobal::dpiX();
443 }
444
445 if(!ydpi) {
446 ydpi = KoGlobal::dpiY();
447 }
448
449 KivioLayer *pLayer = m_lstLayers.first();
450
451 while( pLayer )
452 {
453 if( pLayer->visible() )
454 {
455 pLayer->printContent( painter, xdpi, ydpi );
456 }
457
458 pLayer = m_lstLayers.next();
459 }
460}
461
462void KivioPage::printContent(KivioPainter& painter, KoZoomHandler* zoomHandler)
463{
464 KivioLayer *pLayer = m_lstLayers.first();
465
466 while( pLayer )
467 {
468 if(pLayer->visible())
469 {
470 pLayer->printContent(painter, zoomHandler);
471 }
472
473 pLayer = m_lstLayers.next();
474 }
475}
476
477void KivioPage::printSelected( KivioPainter& painter, int xdpi, int ydpi )
478{
479 if(!xdpi) {
480 xdpi = KoGlobal::dpiX();
481 }
482
483 if(!ydpi) {
484 ydpi = KoGlobal::dpiY();
485 }
486
487 KivioStencil *pStencil;
488 KivioIntraStencilData data;
489 KoZoomHandler zoomHandler;
490 zoomHandler.setZoomAndResolution(100, xdpi, ydpi);
491
492 data.painter = &painter;
493 data.zoomHandler = &zoomHandler;
494 data.printing = true;
495
496 KivioLayer *pLayer = m_lstLayers.first();
497
498 while( pLayer )
499 {
500 if( pLayer->visible()==true )
501 {
502 pStencil = pLayer->firstStencil();
503
504 while( pStencil )
505 {
506 if(pStencil->isSelected())
507 {
508 pStencil->paint(&data);
509 }
510
511 pStencil = pLayer->nextStencil();
512 }
513 }
514
515 pLayer = m_lstLayers.next();
516 }
517}
518
519
520bool KivioPage::addStencil( KivioStencil *pStencil )
521{
522 if(!pStencil) {
523 kdDebug(43000) << "KivioPage::addStencil() - Null stencil passed" << endl;
524 return false;
525 }
526
527 if(!m_pCurLayer) {
528 kdDebug(43000) << "KivioPage::addStencil() - NULL current layer" << endl;
529 return false;
530 }
531
532 KivioAddStencilCommand *cmd = new KivioAddStencilCommand(i18n("Add Stencil"), this, m_pCurLayer, pStencil );
533 m_pDoc->addCommand(cmd);
534
535 return m_pCurLayer->addStencil( pStencil );
536}
537
538void KivioPage::selectStencils( double x, double y, double w, double h )
539{
540 // Iterate through all stencils of this layer
541 KivioStencil *pStencil = m_pCurLayer->stencilList()->first();
542
543 while(pStencil) {
544 // Is it in the rectangle?
545 if(pStencil->isInRect(KoRect(x, y, w, h))) {
546 selectStencil( pStencil );
547 }
548
549 pStencil = m_pCurLayer->stencilList()->next();
550 }
551
552 m_pDoc->slotSelectionChanged();
553}
554
555void KivioPage::selectStencil( KivioStencil *pStencil )
556{
557 if(!pStencil) {
558 kdDebug(43000) << "KivioPage::selectStencil - AHHHH! NULL STENCIL!" << endl;
559 return;
560 }
561
562 // Don't allow reselection
563 if(m_lstSelection.findRef(pStencil) != -1) {
564 return;
565 }
566
567 kdDebug(43000) <<"KivioPage::selectStencil - Selecting stencil" << endl;
568 pStencil->select();
569 m_lstSelection.append(pStencil);
570 m_pDoc->slotSelectionChanged();
571}
572
573bool KivioPage::unselectStencil( KivioStencil *pStencil )
574{
575 pStencil->unselect();
576 m_pDoc->slotSelectionChanged();
577 return m_lstSelection.removeRef( pStencil );
578}
579
580void KivioPage::selectAllStencils()
581{
582 unselectAllStencils();
583 KivioStencil* pStencil = m_pCurLayer->stencilList()->first();
584
585 while(pStencil) {
586 pStencil->select();
587 m_lstSelection.append(pStencil);
588 pStencil = m_pCurLayer->stencilList()->next();
589 }
590
591
592 /*
593 * The following code is commented out because selections must
594 * remain in the current layer.
595 */
596/*
597 KivioLayer* pLayer = m_lstLayers.first();
598 while( pLayer )
599 {
600 if( pLayer->visible() )
601 {
602 pStencil = pLayer->stencilList()->first();
603 while( pStencil )
604 {
605 pStencil->select();
606 m_lstSelection.append(pStencil);
607
608 pStencil = pLayer->stencilList()->next();
609 }
610 }
611
612 pLayer = m_lstLayers.next();
613 }
614*/
615 m_pDoc->slotSelectionChanged();
616}
617
618void KivioPage::unselectAllStencils()
619{
620 KivioStencil* pStencil = m_lstSelection.first();
621
622 while(pStencil)
623 {
624 pStencil->unselect();
625 pStencil = m_lstSelection.next();
626 }
627
628 m_lstSelection.clear();
629 m_pDoc->slotSelectionChanged();
630}
631
632bool KivioPage::isStencilSelected(KivioStencil *pStencil)
633{
634 return m_lstSelection.findRef( pStencil ) == -1;
635}
636
646KivioStencil *KivioPage::checkForStencil( KoPoint *pPoint, int *collisionType, double threshold, bool selectedOnly )
647{
648 KivioStencil *pStencil;
649 int colType;
650
651
652 /*
653 * This code is commented out because selecting a stencil should only take place
654 * on the current layer. The following code searches all layers.
655 */
656 // Start with the last layer since it is the top
657 /*
658 KivioLayer* pLayer = m_lstLayers.last();
659 while( pLayer )
660 {
661 pStencil = pLayer->checkForStencil( pPoint, &colType );
662 if( pStencil )
663 {
664 *collisionType = colType;
665 return pStencil;
666 }
667
668 pLayer = m_lstLayers.prev();
669 }
670 */
671
672 pStencil = m_pCurLayer->checkForStencil( pPoint, &colType, threshold, selectedOnly );
673 if( pStencil )
674 {
675 *collisionType = colType;
676 return pStencil;
677 }
678
679
680 *collisionType = kctNone;
681 return NULL;
682}
683
684void KivioPage::deleteSelectedStencils()
685{
686 // Make sure none of them have deletion protection
687 KivioStencil* pStencil = m_lstSelection.first();
688
689 while(pStencil) {
690 if(pStencil->protection()->at(kpDeletion)) {
691 KMessageBox::information(NULL, i18n("One of the selected stencils has protection from deletion and cannot be deleted."),
692 i18n("Protection From Deletion") );
693 return;
694 }
695
696 pStencil = m_lstSelection.next();
697 }
698
699 // Iterate through all items in the selection list
700 m_lstSelection.first();
701 pStencil = m_lstSelection.take();
702 KMacroCommand *macro = new KMacroCommand( i18n("Remove Stencil"));
703 bool createMacro = false;
704
705 while(pStencil) {
706 KivioRemoveStencilCommand *cmd =new KivioRemoveStencilCommand(i18n("Remove Stencil"), this, m_pCurLayer , pStencil );
707 createMacro = true;
708 macro->addCommand(cmd);
709
710 if(pStencil->type() == kstConnector) {
711 static_cast<Kivio1DStencil*>(pStencil)->disconnectFromTargets();
712 }
713
714 pStencil = m_lstSelection.take();
715 }
716
717 if (createMacro) {
718 macro->execute();
719 m_pDoc->addCommand( macro );
720 } else {
721 delete macro;
722 }
723}
724
725void KivioPage::groupSelectedStencils()
726{
727 // Can't group 0 or 1 stencils
728 if(!m_pCurLayer || (m_lstSelection.count() <= 1)) {
729 return;
730 }
731
732 KivioGroupStencil* pGroup = new KivioGroupStencil();
733
734 // Iterate through all items in the selection list, taking them from the layer, then adding
735 // them to the group
736
737 KivioStencil* pStencil = m_pCurLayer->firstStencil();
738 KivioStencil* pTake = 0;
739
740 while(pStencil) {
741 if(pStencil->isSelected()) {
742 // Take the stencil out of it's layer
743 pTake = m_pCurLayer->takeStencil(pStencil);
744
745 if(!pTake) {
746 kdDebug(43000) << "KivioPage::groupSelectedStencil() - Failed to take() one of the selected stencils. CRAP!" << endl;
747 } else {
748 // Add it to the group
749 pGroup->addToGroup(pTake);
750 pStencil = m_pCurLayer->currentStencil();
751 }
752 } else {
753 pStencil = m_pCurLayer->nextStencil();
754 }
755 }
756
757 // Unselect the old ones
758 unselectAllStencils();
759
760 // Add the group as the selected stencil
761 m_pCurLayer->addStencil(pGroup);
762
763 selectStencil(pGroup);
764
765 KivioGroupCommand* cmd = new KivioGroupCommand(i18n("Group Selection"), this, m_pCurLayer, pGroup);
766 doc()->addCommand(cmd);
767}
768
769void KivioPage::ungroupSelectedStencils()
770{
771 KivioStencil *pSelStencil, *pStencil;
772 TQPtrList<KivioStencil> *pList;
773 TQPtrList<KivioStencil> *pSelectThese = new TQPtrList<KivioStencil>;
774 KMacroCommand* macro = new KMacroCommand(i18n("Ungroup"));
775 bool ungrouped = false;
776
777 pSelectThese->setAutoDelete(false);
778
779 // Iterate through all selected stencils
780 pSelStencil = m_lstSelection.first();
781 while( pSelStencil )
782 {
783 // If there is a list, it is a group stencil
784 pList = pSelStencil->groupList();
785 if(pList)
786 {
787 pList->first();
788 pStencil = pList->first();
789
790 while( pStencil )
791 {
792 m_pCurLayer->addStencil( pStencil );
793 pSelectThese->append( pStencil );
794
795 pStencil = pList->next();
796 }
797
798 // Remove the current stencil from the selection list(the group we just disassembled)
799 m_lstSelection.take();
800
801 // Remove it permanently from the layer
802 if(!m_pCurLayer->takeStencil(pSelStencil))
803 {
804 kdDebug(43000) << "KivioPage::ungroupSelectedStencil() - Failed to locate the group shell for deletion"
805 << endl;
806 }
807
808 KivioUnGroupCommand* cmd = new KivioUnGroupCommand(i18n("Ungroup"), this, m_pCurLayer,
809 static_cast<KivioGroupStencil*>(pSelStencil));
810 macro->addCommand(cmd);
811 ungrouped = true;
812 }
813
814 pSelStencil = m_lstSelection.next();
815 }
816
817 // Now iterate through the selectThese list and select
818 // those stencils
819 pStencil = pSelectThese->first();
820 while( pStencil )
821 {
822 selectStencil( pStencil );
823
824 if(pStencil->type() == kstConnector) {
825 pStencil->searchForConnections(this, 4.0);
826 }
827
828 pStencil = pSelectThese->next();
829 }
830
831 delete pSelectThese;
832
833 if(ungrouped) {
834 doc()->addCommand(macro);
835 } else {
836 delete macro;
837 }
838}
839
840void KivioPage::bringToFront()
841{
842 KivioStencil *pStencil, *pMove;
843 KivioLayer *pLayer;
844
845 TQPtrList <KivioStencil> newList;
846
847 pLayer = m_pCurLayer;
848
849 newList.setAutoDelete(false);
850
851 /*
852 * We iterate through all stencils since order must be maintained
853 * amongst the selection during the move.
854 */
855 pStencil = pLayer->firstStencil();
856 while( pStencil )
857 {
858 if( isStencilSelected( pStencil )==true )
859 {
860 pMove = pLayer->takeStencil();
861 if( pMove )
862 {
863 newList.append(pMove);
864 pStencil = pLayer->currentStencil();
865 }
866 else // In the case of error, the outside else won't execute
867 {
868 pStencil = pLayer->nextStencil();
869 }
870 }
871 else
872 {
873 pStencil = pLayer->nextStencil();
874 }
875 }
876
877 // push them back in, in reverse order
878 pStencil = newList.last();
879 while( pStencil )
880 {
881 pLayer->stencilList()->insert(0, pStencil);
882
883 pStencil = newList.prev();
884 }
885}
886
887void KivioPage::sendToBack()
888{
889 KivioStencil *pStencil, *pMove;
890 KivioLayer *pLayer;
891
892 TQPtrList <KivioStencil> newList;
893
894 pLayer = m_pCurLayer;
895
896 newList.setAutoDelete(false);
897
898 /*
899 * We iterate through all stencils since order must be maintained
900 * amongst the selection during the move.
901 */
902 pStencil = pLayer->firstStencil();
903 while( pStencil )
904 {
905 if( isStencilSelected( pStencil )==true )
906 {
907 pMove = pLayer->takeStencil();
908 if( pMove )
909 {
910 newList.append(pMove);
911 pStencil = pLayer->currentStencil();
912 }
913 else // In the case of error, the outside else won't execute
914 {
915 pStencil = pLayer->nextStencil();
916 }
917 }
918 else
919 {
920 pStencil = pLayer->nextStencil();
921 }
922 }
923
924 // push them back in, in reverse order
925 pStencil = newList.first();
926 while( pStencil )
927 {
928 pLayer->stencilList()->append(pStencil);
929
930 pStencil = newList.next();
931 }
932}
933
934void KivioPage::copy()
935{
936 if(m_lstSelection.count() <= 0) {
937 return;
938 }
939
940 // push to clipbaord
941 KivioDragObject* kdo = new KivioDragObject();
942 kdo->setStencilList(m_lstSelection);
943 kdo->setStencilRect(getRectForAllSelectedStencils());
944 TQApplication::clipboard()->setData(kdo, TQClipboard::Clipboard);
945}
946
947void KivioPage::cut()
948{
949 KivioStencil *pStencil;
950 KivioLayer *pLayer;
951 bool safe=true;
952
953 if( m_lstSelection.count() <= 0 )
954 return;
955
956 pLayer = m_pCurLayer;
957
958 // Make sure none of them are protected from deletion
959 pStencil = pLayer->firstStencil();
960 while( pStencil )
961 {
962 if( isStencilSelected( pStencil )==true )
963 {
964 if( pStencil->protection()->at(kpDeletion)==true )
965 {
966 safe=false;
967 }
968 }
969
970 pStencil = pLayer->nextStencil();
971 }
972
973 if( safe==false )
974 {
975 KMessageBox::information(NULL, i18n("One of the stencils has protection from deletion. You cannot cut or delete this stencil."), i18n("Protection From Delete") );
976
977 return;
978 }
979
980 copy();
981 deleteSelectedStencils();
982}
983
984void KivioPage::paste(KivioView* view)
985{
986 TQPtrList<KivioStencil> list;
987 list.setAutoDelete(false);
988 KivioDragObject kdo;
989
990 if(kdo.decode(TQApplication::clipboard()->data(TQClipboard::Clipboard), list, this)) {
991 unselectAllStencils();
992 KivioStencil* stencil = list.first();
993
994 while(stencil) {
995 addStencil(stencil);
996 selectStencil(stencil);
997 stencil = list.next();
998 }
999
1000 view->canvasWidget()->startPasteMoving();
1001 }
1002}
1003
1004int KivioPage::generateStencilIds(int next)
1005{
1006 KivioLayer *pLayer;
1007
1008 pLayer = m_lstLayers.first();
1009 while( pLayer )
1010 {
1011
1012 next = pLayer->generateStencilIds( next );
1013
1014 pLayer = m_lstLayers.next();
1015 }
1016
1017 return next;
1018}
1019
1020KivioLayer *KivioPage::firstLayer()
1021{
1022 return m_lstLayers.first();
1023}
1024
1025KivioLayer *KivioPage::nextLayer()
1026{
1027 return m_lstLayers.next();
1028}
1029
1030KivioLayer *KivioPage::prevLayer()
1031{
1032 return m_lstLayers.prev();
1033}
1034
1035KivioLayer *KivioPage::lastLayer()
1036{
1037 return m_lstLayers.last();
1038}
1039
1040bool KivioPage::removeCurrentLayer()
1041{
1042 KivioLayer *pLayer;
1043
1044 // NOOOOOOO!
1045 if( m_lstLayers.count() <= 1 )
1046 return false;
1047
1048 pLayer = m_lstLayers.first();
1049
1050 if( pLayer != m_pCurLayer )
1051 {
1052 if( m_lstLayers.find( m_pCurLayer )==false )
1053 {
1054 kdDebug(43000) << "KivioLayer::removeCurrentLayer() - Couldn't find current layer in the list. Bad!" << endl;
1055 return false;
1056 }
1057 }
1058
1059 pLayer = m_lstLayers.next();
1060 if( !pLayer )
1061 {
1062 (void)m_lstLayers.last();
1063 pLayer = m_lstLayers.prev();
1064 }
1065
1066 if( !pLayer )
1067 {
1068 kdDebug(43000) << "KivioLayer::removeCurrentLayer() - Couldn't find a next layer." << endl;
1069 return false;
1070 }
1071
1072 KivioRemoveLayerCommand * cmd = new KivioRemoveLayerCommand( i18n("Remove Layer"), this , m_pCurLayer , m_lstLayers.findRef(m_pCurLayer) );
1073 doc()->addCommand( cmd );
1074 takeLayer( m_pCurLayer );
1075/*
1076 if( m_lstLayers.remove( m_pCurLayer )==false )
1077 {
1078 kdDebug(43000) << "KivioLayer::removeCurrentLayer() - Couldn't find current layer in the list. Bad!" << endl;
1079 return false;
1080 }
1081*/
1082 m_pCurLayer = pLayer;
1083
1084
1085 return true;
1086}
1087
1088void KivioPage::takeLayer( KivioLayer *pLayer )
1089{
1090 int pos=m_lstLayers.findRef(pLayer);
1091 m_lstLayers.take( pos );
1092}
1093
1094void KivioPage::addLayer( KivioLayer *pLayer )
1095{
1096 m_lstLayers.append( pLayer );
1097}
1098
1099void KivioPage::insertLayer( int position, KivioLayer *pLayer )
1100{
1101 m_lstLayers.insert( position, pLayer );
1102}
1103
1104KivioLayer *KivioPage::layerAt( int pos )
1105{
1106 return m_lstLayers.at(pos);
1107}
1108
1109void KivioPage::alignStencils(AlignData d)
1110{
1111 KivioStencil* pStencil = m_lstSelection.first();
1112
1113 if(!pStencil)
1114 return;
1115
1116 if (d.v != AlignData::None || d.h != AlignData::None) {
1117 KMacroCommand *macro = new KMacroCommand(i18n("Move Stencil"));
1118 double x = pStencil->x();
1119 double y = pStencil->y();
1120 double w = pStencil->w();
1121 double h = pStencil->h();
1122
1123 while( pStencil )
1124 {
1125 KoRect oldRect = pStencil->rect();
1126
1127 switch (d.v) {
1128 case AlignData::Top:
1129 pStencil->setY(y);
1130 break;
1131 case AlignData::Center:
1132 pStencil->setY(y+h/2-pStencil->h()/2);
1133 break;
1134 case AlignData::Bottom:
1135 pStencil->setY(y+h-pStencil->h());
1136 break;
1137 default:
1138 break;
1139 }
1140 switch (d.h) {
1141 case AlignData::Left:
1142 pStencil->setX(x);
1143 break;
1144 case AlignData::Center:
1145 pStencil->setX(x+w/2-pStencil->w()/2);
1146 break;
1147 case AlignData::Right:
1148 pStencil->setX(x+w-pStencil->w());
1149 break;
1150 default:
1151 break;
1152 }
1153
1154 KivioMoveStencilCommand * cmd = new KivioMoveStencilCommand( i18n("Move Stencil"),
1155 pStencil, oldRect, pStencil->rect(), this);
1156 macro->addCommand(cmd);
1157 pStencil = m_lstSelection.next();
1158 }
1159
1160 m_pDoc->addCommand(macro);
1161 }
1162
1163 if (d.centerOfPage) {
1164 KMacroCommand *macro = new KMacroCommand(i18n("Move Stencil"));
1165 double w = m_pPageLayout.ptWidth;
1166 double h = m_pPageLayout.ptHeight;
1167 KoRect r = getRectForAllSelectedStencils();
1168 double dx = ((w - r.width()) / 2.0) - r.x();
1169 double dy = ((h - r.height()) / 2.0) - r.y();
1170 pStencil = m_lstSelection.first();
1171
1172 while( pStencil )
1173 {
1174 KoRect oldRect = pStencil->rect();
1175 pStencil->setPosition(pStencil->x() + dx, pStencil->y() + dy);
1176 KivioMoveStencilCommand * cmd = new KivioMoveStencilCommand( i18n("Move Stencil"),
1177 pStencil, oldRect, pStencil->rect(), this);
1178 macro->addCommand(cmd);
1179 pStencil = m_lstSelection.next();
1180 }
1181
1182 m_pDoc->addCommand(macro);
1183 }
1184}
1185
1186class XYSortedStencilList : public TQPtrList<KivioStencil>
1187{
1188public:
1189 XYSortedStencilList(bool sortX) :xsort(sortX) {};
1190
1191protected:
1192 int compareItems(TQPtrCollection::Item i1, TQPtrCollection::Item i2)
1193 {
1194 KivioStencil* s1 = (KivioStencil*)i1;
1195 KivioStencil* s2 = (KivioStencil*)i2;
1196 if (xsort) {
1197 if (s1->x() > s2->x())
1198 return 1;
1199 if (s1->x() < s2->x())
1200 return -1;
1201 return 0;
1202 }
1203 if (s1->y() > s2->y())
1204 return 1;
1205 if (s1->y() < s2->y())
1206 return -1;
1207 return 0;
1208 }
1209
1210private:
1211 bool xsort;
1212};
1213
1214
1215void KivioPage::distributeStencils(DistributeData d)
1216{
1217 double x = 0.0;
1218 double y = 0.0;
1219 double x1 = 0.0;
1220 double y1 = 0.0;
1221
1222 KivioStencil* pStencil = m_lstSelection.first();
1223 if (!pStencil)
1224 return;
1225
1226 XYSortedStencilList xSortList(true);
1227 XYSortedStencilList ySortList(false);
1228 TQValueList<KoRect> oldRects;
1229
1230 while( pStencil )
1231 {
1232 xSortList.append(pStencil);
1233 ySortList.append(pStencil);
1234 oldRects.append(pStencil->rect());
1235 pStencil = m_lstSelection.next();
1236 }
1237 xSortList.sort();
1238 ySortList.sort();
1239
1240 switch (d.extent) {
1241 case DistributeData::Page:
1242 x = m_pPageLayout.ptLeft;
1243 y = m_pPageLayout.ptTop;
1244 x1 = m_pPageLayout.ptWidth - m_pPageLayout.ptRight;
1245 y1 = m_pPageLayout.ptHeight - m_pPageLayout.ptBottom;
1246 break;
1247 case DistributeData::Selection:
1248 pStencil = m_lstSelection.first();
1249 x = pStencil->x();
1250 y = pStencil->x();
1251 x1 = x + pStencil->w();
1252 y1 = y + pStencil->h();
1253 while( pStencil )
1254 {
1255 x = TQMIN(x,pStencil->x());
1256 y = TQMIN(y,pStencil->y());
1257 x1 = TQMAX(x1,pStencil->x() + pStencil->w());
1258 y1 = TQMAX(y1,pStencil->y() + pStencil->h());
1259 pStencil = m_lstSelection.next();
1260 }
1261 break;
1262 default:
1263 break;
1264 }
1265
1266 /*****************************************************/
1267 KivioStencil* firstx = xSortList.first();
1268 KivioStencil* lastx = xSortList.last();
1269 double countx = (double)(xSortList.count()-1);
1270 double distx = 0.0;
1271 switch (d.h) {
1272 case DistributeData::Left:
1273 x1 = x1 - lastx->w();
1274 distx = (x1 - x)/countx;
1275 break;
1276 case DistributeData::Center:
1277 x = x + firstx->w()/2;
1278 x1 = x1 - lastx->w()/2;
1279 distx = (x1 - x)/countx;
1280 break;
1281 case DistributeData::Spacing: {
1282 double allw = 0.0;
1283 pStencil = xSortList.first();
1284 while( pStencil )
1285 {
1286 allw = allw + pStencil->w();
1287 pStencil = xSortList.next();
1288 }
1289 distx = (x1-x-allw)/countx;
1290 break; }
1291 case DistributeData::Right:
1292 x = x + firstx->w();
1293 distx = (x1 - x)/countx;
1294 break;
1295 default:
1296 break;
1297 }
1298
1299 double xx = x;
1300 switch (d.h) {
1301 case DistributeData::Center:
1302 pStencil = xSortList.first();
1303 while( pStencil )
1304 {
1305 pStencil->setX(xx - pStencil->w()/2);
1306 xx = xx + distx;
1307 pStencil = xSortList.next();
1308 }
1309 break;
1310 case DistributeData::Right:
1311 pStencil = xSortList.first();
1312 while( pStencil )
1313 {
1314 pStencil->setX(xx - pStencil->w());
1315 xx = xx + distx;
1316 pStencil = xSortList.next();
1317 }
1318 break;
1319 case DistributeData::Left:
1320 pStencil = xSortList.first();
1321 while( pStencil )
1322 {
1323 pStencil->setX(xx);
1324 xx = xx + distx;
1325 pStencil = xSortList.next();
1326 }
1327 break;
1328 case DistributeData::Spacing:
1329 pStencil = xSortList.first();
1330 while( pStencil )
1331 {
1332 pStencil->setX(xx);
1333 xx = xx + pStencil->w() + distx;
1334 pStencil = xSortList.next();
1335 }
1336 break;
1337 default:
1338 break;
1339 }
1340 /*****************************************************/
1341 KivioStencil* firsty = ySortList.first();
1342 KivioStencil* lasty = ySortList.last();
1343 double county = (double)(ySortList.count()-1);
1344 double disty = 0.0;
1345 switch (d.v) {
1346 case DistributeData::Top:
1347 y1 = y1 - lasty->h();
1348 disty = (y1 - y)/county;
1349 break;
1350 case DistributeData::Center:
1351 y = y + firsty->h()/2;
1352 y1 = y1 - lasty->h()/2;
1353 disty = (y1 - y)/countx;
1354 break;
1355 case DistributeData::Spacing: {
1356 double allh = 0.0;
1357 pStencil = ySortList.first();
1358 while( pStencil )
1359 {
1360 allh = allh + pStencil->h();
1361 pStencil = ySortList.next();
1362 }
1363 disty = (y1-y-allh)/county;
1364 break; }
1365 case DistributeData::Bottom:
1366 y = y + firsty->h();
1367 disty = (y1 - y)/county;
1368 break;
1369 default:
1370 break;
1371 }
1372
1373 double yy = y;
1374 switch (d.v) {
1375 case DistributeData::Center:
1376 pStencil = ySortList.first();
1377 while( pStencil )
1378 {
1379 pStencil->setY(yy - pStencil->h()/2);
1380 yy = yy + disty;
1381 pStencil = ySortList.next();
1382 }
1383 break;
1384 case DistributeData::Bottom:
1385 pStencil = ySortList.first();
1386 while( pStencil )
1387 {
1388 pStencil->setY(yy - pStencil->h());
1389 yy = yy + disty;
1390 pStencil = ySortList.next();
1391 }
1392 break;
1393 case DistributeData::Top:
1394 pStencil = ySortList.first();
1395 while( pStencil )
1396 {
1397 pStencil->setY(yy);
1398 yy = yy + disty;
1399 pStencil = ySortList.next();
1400 }
1401 break;
1402 case DistributeData::Spacing:
1403 pStencil = ySortList.first();
1404 while( pStencil )
1405 {
1406 pStencil->setY(yy);
1407 yy = yy + pStencil->h() + disty;
1408 pStencil = ySortList.next();
1409 }
1410 break;
1411 default:
1412 break;
1413 }
1414
1415 if(d.v != DistributeData::None || d.h != DistributeData::None) {
1416 KMacroCommand *macro = new KMacroCommand(i18n("Move Stencil"));
1417 TQValueListIterator<KoRect> it;
1418 pStencil = m_lstSelection.first();
1419
1420 for(it = oldRects.begin(); it != oldRects.end(); ++it) {
1421 KivioMoveStencilCommand * cmd = new KivioMoveStencilCommand(i18n("Move Stencil"),
1422 pStencil, (*it), pStencil->rect(), this);
1423 macro->addCommand( cmd);
1424 pStencil = m_lstSelection.next();
1425 }
1426
1427 m_pDoc->addCommand( macro );
1428 }
1429}
1430
1431
1435KoRect KivioPage::getRectForAllSelectedStencils()
1436{
1437 KoRect rTotal, r;
1438
1439 KivioStencil *pStencil = m_lstSelection.first();
1440
1441 // Get the rect of the first selected stencil
1442 if( pStencil )
1443 {
1444 rTotal = pStencil->rect();
1445
1446 pStencil = m_lstSelection.next();
1447 }
1448
1449 // iterate through all the stencils uniting the rectangles
1450 while( pStencil )
1451 {
1452 r = pStencil->rect();
1453
1454 rTotal = rTotal.unite( r );
1455
1456 pStencil = m_lstSelection.next();
1457 }
1458
1459 return rTotal;
1460}
1461
1465KoRect KivioPage::getRectForAllStencils()
1466{
1467 KoRect rTotal, r;
1468
1469 bool firstTime = true;
1470
1471 KivioLayer *pLayer;
1472 KivioStencil *pStencil;
1473
1474 pLayer = m_lstLayers.first();
1475 while( pLayer )
1476 {
1477 pStencil = pLayer->firstStencil();
1478 while( pStencil )
1479 {
1480 if( firstTime==true )
1481 {
1482 rTotal = pStencil->rect();
1483 firstTime = false;
1484 }
1485 else
1486 {
1487 r = pStencil->rect();
1488 rTotal = rTotal.unite( r );
1489 }
1490
1491 pStencil = pLayer->nextStencil();
1492 }
1493
1494 pLayer = m_lstLayers.next();
1495 }
1496
1497
1498 return rTotal;
1499}
1500
1501void KivioPage::setPaperLayout(const KoPageLayout &l)
1502{
1503 m_pPageLayout = l;
1504 doc()->updateView(this);
1505 emit sig_pageLayoutChanged(m_pPageLayout);
1506}
1507
1508KivioConnectorTarget *KivioPage::connectPointToTarget( KivioConnectorPoint *p, double /*thresh*/)
1509{
1510 double oldX, oldY;
1511 KivioLayer *pLayer, *pCurLayer;
1512 bool doneSearching = false;
1513 KivioConnectorTarget *pTarget;
1514
1515 if( !p )
1516 return NULL;
1517
1518 if( p->connectable()==false )
1519 return NULL;
1520
1521 oldX = p->x();
1522 oldY = p->y();
1523
1524 pCurLayer = curLayer();
1525 pLayer = firstLayer();
1526
1527 while( pLayer && doneSearching==false )
1528 {
1529 if( pLayer != pCurLayer )
1530 {
1531 if( pLayer->connectable()==false || pLayer->visible()==false )
1532 {
1533 pLayer = nextLayer();
1534 continue;
1535 }
1536 }
1537
1538 if( (pTarget=pLayer->connectPointToTarget(p, 8.0f )) )
1539 {
1540 return pTarget;
1541 }
1542
1543 pLayer = nextLayer();
1544 }
1545
1546 return NULL;
1547}
1548
1549KoPoint KivioPage::snapToTarget( const KoPoint& p, double thresh, bool& hit )
1550{
1551 KivioLayer *pLayer, *pCurLayer;
1552 KoPoint retVal = p;
1553
1554 pCurLayer = curLayer();
1555 pLayer = firstLayer();
1556
1557 while( pLayer && !hit )
1558 {
1559 if( pLayer != pCurLayer )
1560 {
1561 if( pLayer->connectable()==false || pLayer->visible()==false )
1562 {
1563 pLayer = nextLayer();
1564 continue;
1565 }
1566 }
1567
1568 retVal = pLayer->snapToTarget(p, thresh, hit);
1569
1570 pLayer = nextLayer();
1571 }
1572
1573 return retVal;
1574}
1575
1576void KivioPage::setHidePage(bool _hide)
1577{
1578 setHidden(_hide);
1579 if(_hide)
1580 emit sig_PageHidden(this);
1581 else
1582 emit sig_PageShown(this);
1583}
1584
1585void KivioPage::setPaintSelected(bool paint)
1586{
1587 KivioStencil *pStencil = m_lstSelection.first();
1588
1589 while( pStencil )
1590 {
1591 pStencil->setHidden(!paint);
1592 pStencil = m_lstSelection.next();
1593 }
1594}
1595
1596bool KivioPage::checkForStencilTypeInSelection(KivioStencilType type)
1597{
1598 KivioStencil *pStencil = m_lstSelection.first();
1599
1600 while( pStencil )
1601 {
1602 if(pStencil->type() == type) {
1603 return true;
1604 }
1605
1606 pStencil = m_lstSelection.next();
1607 }
1608
1609 return false;
1610}
1611
1612bool KivioPage::checkForTextBoxesInSelection()
1613{
1614 KivioStencil *pStencil = m_lstSelection.first();
1615
1616 while(pStencil) {
1617 if(pStencil->hasTextBox()) {
1618 return true;
1619 }
1620
1621 pStencil = m_lstSelection.next();
1622 }
1623
1624 return false;
1625}
1626
1627void KivioPage::setGuideLines(const TQValueList<double> hGuideLines, const TQValueList<double> vGuideLines)
1628{
1629 m_hGuideLines = hGuideLines;
1630 m_vGuideLines = vGuideLines;
1631}
1632
1633void KivioPage::saveGuideLines(TQDomElement& element)
1634{
1635 TQValueList<double>::iterator it;
1636 TQValueList<double>::iterator itEnd = m_hGuideLines.end();
1637
1638 for(it = m_hGuideLines.begin(); it != itEnd; ++it) {
1639 TQDomElement e = element.ownerDocument().createElement("Guideline");
1640 element.appendChild(e);
1641 XmlWriteDouble(e, "pos", *it);
1642 XmlWriteInt(e, "orient", (int)TQt::Horizontal);
1643 }
1644
1645 itEnd = m_vGuideLines.end();
1646
1647 for(it = m_vGuideLines.begin(); it != itEnd; ++it) {
1648 TQDomElement e = element.ownerDocument().createElement("Guideline");
1649 element.appendChild(e);
1650 XmlWriteDouble(e, "pos", *it);
1651 XmlWriteInt(e, "orient", (int)TQt::Vertical);
1652 }
1653}
1654
1655void KivioPage::loadGuideLines(const TQDomElement& element)
1656{
1657 m_hGuideLines.clear();
1658 m_vGuideLines.clear();
1659
1660 TQDomElement e = element.firstChild().toElement();
1661
1662 for( ; !e.isNull(); e = e.nextSibling().toElement() )
1663 {
1664 double pos = XmlReadDouble(e, "pos", 0.0);
1665 TQt::Orientation orient = (TQt::Orientation)XmlReadInt(e, "orient", 0);
1666 addGuideLine(orient, pos);
1667 }
1668}
1669
1670void KivioPage::addGuideLine(TQt::Orientation orientation, double position)
1671{
1672 if(orientation == TQt::Horizontal) {
1673 m_hGuideLines.append(position);
1674 } else {
1675 m_vGuideLines.append(position);
1676 }
1677}
1678
1679#include "kivio_page.moc"
static KoPageLayout defaultPageLayout()
Get the default page layout.