kivio

kivio_page.cpp

00001 /*
00002  * Kivio - Visual Modelling and Flowcharting
00003  * Copyright (C) 2000-2001 theKompany.com & Dave Marotti
00004  *
00005  * This program is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU General Public License
00007  * as published by the Free Software Foundation; either version 2
00008  * of the License, or (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software
00017  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00018  */
00019 #include <stdlib.h>
00020 #include <stdio.h>
00021 #include <ctype.h>
00022 #include <math.h>
00023 
00024 #include <qpainter.h>
00025 #include <qdrawutil.h>
00026 #include <qkeycode.h>
00027 #include <qregexp.h>
00028 #include <qpoint.h>
00029 #include <qcursor.h>
00030 #include <qptrstack.h>
00031 #include <qbuffer.h>
00032 #include <qmessagebox.h>
00033 #include <qclipboard.h>
00034 #include <qpicture.h>
00035 #include <qdom.h>
00036 #include <qtextstream.h>
00037 #include <qdragobject.h>
00038 #include <qmime.h>
00039 #include <qsortedlist.h>
00040 #include <qvaluelist.h>
00041 
00042 #include <kdebug.h>
00043 #include <klocale.h>
00044 #include <kglobal.h>
00045 #include <kmessagebox.h>
00046 #include <KoUnit.h>
00047 #include <KoPoint.h>
00048 #include <KoRect.h>
00049 #include <KoZoomHandler.h>
00050 #include <kapplication.h>
00051 #include <KoXmlWriter.h>
00052 #include <KoXmlNS.h>
00053 #include <KoDom.h>
00054 #include <KoStore.h>
00055 #include <KoOasisStyles.h>
00056 #include <KoGenStyles.h>
00057 
00058 #include "kivio_page.h"
00059 #include "kivio_map.h"
00060 #include "kivio_doc.h"
00061 #include "kivio_canvas.h"
00062 #include "kivio_view.h"
00063 #include "kivio_config.h"
00064 
00065 #include "kivio_common.h"
00066 #include "kivio_connector_point.h"
00067 #include "kivio_group_stencil.h"
00068 #include "kivio_intra_stencil_data.h"
00069 #include "kivio_layer.h"
00070 #include "kivio_painter.h"
00071 #include "kivio_stencil.h"
00072 #include "kivio_1d_stencil.h"
00073 #include "KIvioPageIface.h"
00074 #include "kivio_command.h"
00075 #include "kivioglobal.h"
00076 #include "kiviodragobject.h"
00077 
00078 #include <fixx11h.h> // for None
00079 
00080 int KivioPage::s_id = 0L;
00081 QIntDict<KivioPage>* KivioPage::s_mapPages;
00082 
00083 KivioPage::KivioPage( KivioMap *_map, const QString &pageName, const char *_name )
00084 : QObject( _map, _name ),
00085   m_pCurLayer(NULL)
00086 {
00087   if ( s_mapPages == 0L )
00088     s_mapPages = new QIntDict<KivioPage>;
00089   m_id = s_id++;
00090   s_mapPages->insert( m_id, this );
00091 
00092   m_dcop = 0;
00093 
00094   m_pMap = _map;
00095   m_pDoc = _map->doc();
00096 
00097   // Make sure the layers auto-delete themselves
00098   m_pCurLayer = new KivioLayer(this);
00099   m_pCurLayer->setName(i18n("Layer 1"));
00100   m_lstLayers.append( m_pCurLayer );
00101   m_lstLayers.setAutoDelete(true);
00102 
00103   m_lstSelection.setAutoDelete(false);
00104 
00105   m_strName = pageName;
00106 
00107   setHidden(false);
00108   // Get a unique name so that we can offer scripting
00109   if ( !_name ) {
00110     QCString s;
00111     s.sprintf("Page%i", s_id );
00112     setName( s.data() );
00113   }
00114 
00115   m_pPageLayout = Kivio::Config::defaultPageLayout();
00116 }
00117 
00118 DCOPObject* KivioPage::dcopObject()
00119 {
00120     if ( !m_dcop )
00121         m_dcop = new KIvioPageIface( this );
00122     return m_dcop;
00123 }
00124 
00125 
00126 KivioPage::~KivioPage()
00127 {
00128   kdDebug(43000)<<" KivioPage::~KivioPage()************ :"<<this<<endl;
00129   s_mapPages->remove(m_id);
00130   delete m_dcop;
00131 }
00132 
00133 KivioPage* KivioPage::find( int _id )
00134 {
00135   if ( !s_mapPages )
00136     return 0L;
00137 
00138   return (*s_mapPages)[ _id ];
00139 }
00140 
00141 void KivioPage::print( QPainter &/*painter*/, KPrinter */*_printer*/ )
00142 {
00143 }
00144 
00145 void KivioPage::printPage( QPainter &/*_painter*/, const QRect& /*page_range*/, const QRect& /*view*/ )
00146 {
00147 }
00148 
00149 QDomElement KivioPage::save( QDomDocument& doc )
00150 {
00151     // Write the name and 'hide' flag first as attributes
00152     QDomElement page = doc.createElement( "KivioPage" );
00153     page.setAttribute( "name", m_strName );
00154     page.setAttribute( "hide", (int)m_bPageHide );
00155 
00156     // Create a child element for the page layout
00157     QDomElement layoutE = saveLayout( doc );
00158     page.appendChild( layoutE );
00159 
00160     // Save guides
00161     QDomElement guidesElement = doc.createElement("GuidesLayout");
00162     page.appendChild(guidesElement);
00163     saveGuideLines(guidesElement);
00164 
00165     // Iterate through all layers saving them as child elements
00166     KivioLayer *pLayer = m_lstLayers.first();
00167     while( pLayer )
00168     {
00169         QDomElement layerE = pLayer->saveXML(doc);
00170         if( layerE.isNull() )
00171         {
00172        kdDebug(43000) << "KivioPage::save() - Oh shit.  KivioLayer::saveXML() returned a bad element!" << endl;
00173         }
00174     else
00175     {
00176        page.appendChild( layerE );
00177     }
00178 
00179         pLayer = m_lstLayers.next();
00180     }
00181 
00182     return page;
00183 }
00184 
00185 void KivioPage::saveOasis(KoStore* /*store*/, KoXmlWriter* docWriter, KoGenStyles* styles)
00186 {
00187   docWriter->startElement("draw:page");
00188   docWriter->addAttribute("draw:name", m_strName);
00189 
00190   if(m_pPageLayout == Kivio::Config::defaultPageLayout()) {
00191     docWriter->addAttribute("draw:master-page-name", "Standard");
00192   } else {
00193     KoGenStyle pageLayout = m_pPageLayout.saveOasis();
00194     QString layoutName = styles->lookup(pageLayout, "PL");
00195 
00196     KoGenStyle masterPage(KoGenStyle::STYLE_MASTER);
00197     masterPage.addAttribute("style:page-layout-name", layoutName);
00198     QString masterName = styles->lookup(masterPage, "MP");
00199 
00200     docWriter->addAttribute("draw:master-page-name", masterName);
00201   }
00202 
00203   // TODO OASIS: Save guidelines!
00204 
00205   QBuffer layerBuffer;
00206   layerBuffer.open(IO_WriteOnly);
00207   KoXmlWriter layerWriter(&layerBuffer);
00208   layerWriter.startElement("draw:layer-set");
00209 
00210   // Iterate through all layers
00211   KivioLayer* layer = m_lstLayers.first();
00212 
00213   while(layer) {
00214     layer->saveOasis(&layerWriter);
00215     layer = m_lstLayers.next();
00216   }
00217 
00218   layerWriter.endElement(); // draw:layer-set
00219   QString layerSet = QString::fromUtf8(layerBuffer.buffer(), layerBuffer.buffer().size());
00220   KoGenStyle pageStyle(Kivio::STYLE_PAGE, "drawing-page");
00221   pageStyle.addChildElement("draw:layer-set", layerSet);
00222   QString styleName = styles->lookup(pageStyle, "PS");
00223   docWriter->addAttribute("draw:style-name", styleName);
00224 
00225   docWriter->endElement(); // draw:page
00226 }
00227 
00228 QDomElement KivioPage::saveLayout( QDomDocument &doc )
00229 {
00230     QDomElement e = doc.createElement("PageLayout");
00231     Kivio::savePageLayout(e, m_pPageLayout);
00232 
00233     return e;
00234 }
00235 
00236 bool KivioPage::loadLayout( const QDomElement &e )
00237 {
00238     m_pPageLayout = Kivio::loadPageLayout(e);
00239     return true;
00240 }
00241 
00242 bool KivioPage::isLoading()
00243 {
00244   return m_pDoc->isLoading();
00245 }
00246 
00247 bool KivioPage::loadXML( const QDomElement& pageE )
00248 {
00249     m_strName = pageE.attribute("name");
00250     if (m_strName.isEmpty())
00251         return false;
00252 
00253 
00254     m_bPageHide = (int)pageE.attribute("hide").toInt();
00255 
00256     // Clear the layer list
00257     KivioLayer *pLayer;
00258     m_lstLayers.clear();
00259 
00260     QDomNode node = pageE.firstChild();
00261     while( !node.isNull() )
00262     {
00263        if( node.nodeName() == "KivioLayer" )
00264        {
00265       pLayer = new KivioLayer(this);
00266       if( pLayer->loadXML( node.toElement() )==false )
00267       {
00268          delete pLayer;
00269          pLayer = NULL;
00270       }
00271       else
00272       {
00273          m_lstLayers.append( pLayer );
00274          pLayer = NULL;
00275       }
00276        }
00277        else if( node.nodeName() == "PageLayout" )
00278        {
00279       loadLayout( node.toElement() );
00280        }
00281        else if ( node.nodeName() == "GuidesLayout" ) {
00282       loadGuideLines(node.toElement());
00283        }
00284        else
00285        {
00286       kdDebug(43000) << "KivioLayer::loadXML() - unknown node found, " <<  node.nodeName() << endl;
00287        }
00288 
00289        node = node.nextSibling();
00290     }
00291 
00292     m_pCurLayer = m_lstLayers.first();
00293     if( !m_pCurLayer )
00294     {
00295        kdDebug(43000) << "KivioLayer::loadXML() - No layers loaded!! BIGGGGG PROBLEMS!" << endl;
00296     }
00297 
00298     // Now that we are done loading, fix all the connections
00299     KivioLayer *pLayerBak;
00300 
00301     pLayer = m_lstLayers.first();
00302     while( pLayer )
00303     {
00304        pLayerBak = pLayer;
00305 
00306        kdDebug(43000) << "KivioLayer::loadXML() - loading layer connections" << endl;
00307        pLayer->searchForConnections(this);
00308 
00309        m_lstLayers.find( pLayerBak );
00310 
00311        pLayer = m_lstLayers.next();
00312     }
00313 
00314   return true;
00315 }
00316 
00317 bool KivioPage::loadOasis(const QDomElement& page, KoOasisStyles& oasisStyles)
00318 {
00319   m_strName = page.attributeNS( KoXmlNS::draw, "name", QString::null);
00320   QDomElement* masterPage = oasisStyles.masterPages()[page.attributeNS( KoXmlNS::draw, "master-page-name", QString::null)];
00321 
00322   if(!masterPage) {
00323     kdDebug(430000) << "Couldn't find the master page! " << page.attributeNS( KoXmlNS::draw, "master-page-name", QString::null) << endl;
00324     return false;
00325   }
00326 
00327   const QDomElement *pageLayout = oasisStyles.findStyle(masterPage->attributeNS( KoXmlNS::style, "page-layout-name", QString::null ) );
00328 
00329   if(!pageLayout) {
00330     kdDebug(430000) << "Couldn't find the pagelayout!" << endl;
00331     return false;
00332   }
00333 
00334   m_pPageLayout.loadOasis(*pageLayout);
00335 
00336   if(m_pPageLayout.ptWidth <= 1e-13 || m_pPageLayout.ptHeight <= 1e-13) {
00337     kdDebug(430000) << "Non valid pagelayout!" << endl;
00338     return false;
00339   }
00340 
00341   const QDomElement* style = oasisStyles.findStyle(page.attributeNS( KoXmlNS::draw, "style-name", QString::null) ); // Find the page style
00342 
00343   if(!style) {
00344     return false;
00345   }
00346 
00347   QDomNode styleNode = KoDom::namedItemNS( *style, KoXmlNS::style, "properties");
00348   styleNode = KoDom::namedItemNS( styleNode, KoXmlNS::draw, "layer-set");
00349   QDomNode currentNode = styleNode.firstChild();
00350 
00351   // Load the layers
00352   while(!currentNode.isNull()) {
00353     if(currentNode.nodeName() == "draw:layer") {
00354       KivioLayer* layer = new KivioLayer(this);
00355       layer->loadOasis(currentNode.toElement());
00356       m_lstLayers.append(layer);
00357     }
00358 
00359     currentNode = currentNode.nextSibling();
00360   }
00361 
00362   return true;
00363 }
00364 
00365 void KivioPage::update()
00366 {
00367 }
00368 
00369 KivioPage* KivioPage::findPage( const QString& name )
00370 {
00371   if (!m_pMap)
00372     return 0L;
00373 
00374   return m_pMap->findPage(name);
00375 }
00376 
00377 bool KivioPage::setPageName( const QString& name, bool init )
00378 {
00379   if ( map()->findPage( name ) )
00380     return false;
00381 
00382   if ( m_strName == name )
00383     return true;
00384 
00385   QString old_name = m_strName;
00386   m_strName = name;
00387 
00388   if (init)
00389     return true;
00390 
00391   emit m_pDoc->sig_pageNameChanged(this, old_name);
00392 
00393   return true;
00394 }
00395 
00402 void KivioPage::paintContent( KivioPainter& painter, const QRect& rect, bool transparent,
00403   QPoint p0, KoZoomHandler* zoom, bool drawConnectorTargets, bool drawSelection )
00404 {
00405   KivioLayer *pLayer = m_lstLayers.first();
00406   while( pLayer )
00407   {
00408       if( pLayer->visible() )
00409       {
00410           pLayer->paintContent( painter, rect, transparent, p0, zoom );
00411       }
00412 
00413       pLayer = m_lstLayers.next();
00414   }
00415 
00416   // Now the second iteration - connection targets
00417   // Only draw targets if the zoom is higher than a certain value
00418   if(zoom->zoom() >= 50) {
00419     if(drawConnectorTargets) {
00420       m_pCurLayer->paintConnectorTargets( painter, rect, transparent, p0, zoom );
00421       pLayer = m_lstLayers.first();
00422 
00423       while(pLayer) {
00424         if(pLayer->connectable() && (pLayer != m_pCurLayer)) {
00425           pLayer->paintConnectorTargets( painter, rect, transparent, p0, zoom );
00426         }
00427 
00428         pLayer = m_lstLayers.next();
00429       }
00430     }
00431   }
00432 
00433   // Now the third iteration - selection handles
00434   if(drawSelection) {
00435     m_pCurLayer->paintSelectionHandles( painter, rect, transparent, p0, zoom );
00436   }
00437 }
00438 
00439 void KivioPage::printContent( KivioPainter& painter, int xdpi, int ydpi )
00440 {
00441   if(!xdpi) {
00442     xdpi = KoGlobal::dpiX();
00443   }
00444 
00445   if(!ydpi) {
00446     ydpi = KoGlobal::dpiY();
00447   }
00448 
00449   KivioLayer *pLayer = m_lstLayers.first();
00450 
00451   while( pLayer )
00452   {
00453       if( pLayer->visible() )
00454       {
00455           pLayer->printContent( painter, xdpi, ydpi );
00456       }
00457 
00458       pLayer = m_lstLayers.next();
00459   }
00460 }
00461 
00462 void KivioPage::printContent(KivioPainter& painter, KoZoomHandler* zoomHandler)
00463 {
00464   KivioLayer *pLayer = m_lstLayers.first();
00465 
00466   while( pLayer )
00467   {
00468     if(pLayer->visible())
00469     {
00470       pLayer->printContent(painter, zoomHandler);
00471     }
00472 
00473     pLayer = m_lstLayers.next();
00474   }
00475 }
00476 
00477 void KivioPage::printSelected( KivioPainter& painter, int xdpi, int ydpi )
00478 {
00479   if(!xdpi) {
00480     xdpi = KoGlobal::dpiX();
00481   }
00482 
00483   if(!ydpi) {
00484     ydpi = KoGlobal::dpiY();
00485   }
00486 
00487   KivioStencil *pStencil;
00488   KivioIntraStencilData data;
00489   KoZoomHandler zoomHandler;
00490   zoomHandler.setZoomAndResolution(100, xdpi, ydpi);
00491 
00492   data.painter = &painter;
00493   data.zoomHandler = &zoomHandler;
00494   data.printing = true;
00495 
00496   KivioLayer *pLayer = m_lstLayers.first();
00497 
00498   while( pLayer )
00499   {
00500     if( pLayer->visible()==true )
00501     {
00502       pStencil = pLayer->firstStencil();
00503 
00504       while( pStencil )
00505       {
00506         if(pStencil->isSelected())
00507         {
00508           pStencil->paint(&data);
00509         }
00510 
00511         pStencil = pLayer->nextStencil();
00512       }
00513     }
00514 
00515     pLayer = m_lstLayers.next();
00516   }
00517 }
00518 
00519 
00520 bool KivioPage::addStencil( KivioStencil *pStencil )
00521 {
00522   if(!pStencil) {
00523     kdDebug(43000) << "KivioPage::addStencil() - Null stencil passed" << endl;
00524     return false;
00525   }
00526 
00527   if(!m_pCurLayer) {
00528     kdDebug(43000) << "KivioPage::addStencil() - NULL current layer" << endl;
00529     return false;
00530   }
00531 
00532   KivioAddStencilCommand *cmd = new KivioAddStencilCommand(i18n("Add Stencil"), this, m_pCurLayer, pStencil );
00533   m_pDoc->addCommand(cmd);
00534 
00535   return m_pCurLayer->addStencil( pStencil );
00536 }
00537 
00538 void KivioPage::selectStencils( double x, double y, double w, double h )
00539 {
00540   // Iterate through all stencils of this layer
00541   KivioStencil *pStencil = m_pCurLayer->stencilList()->first();
00542 
00543   while(pStencil) {
00544     // Is it in the rectangle?
00545     if(pStencil->isInRect(KoRect(x, y, w, h))) {
00546       selectStencil( pStencil );
00547     }
00548 
00549     pStencil = m_pCurLayer->stencilList()->next();
00550   }
00551 
00552   m_pDoc->slotSelectionChanged();
00553 }
00554 
00555 void KivioPage::selectStencil( KivioStencil *pStencil )
00556 {
00557   if(!pStencil) {
00558     kdDebug(43000) << "KivioPage::selectStencil - AHHHH! NULL STENCIL!" << endl;
00559     return;
00560   }
00561 
00562   // Don't allow reselection
00563   if(m_lstSelection.findRef(pStencil) != -1) {
00564     return;
00565   }
00566 
00567   kdDebug(43000) <<"KivioPage::selectStencil - Selecting stencil" << endl;
00568   pStencil->select();
00569   m_lstSelection.append(pStencil);
00570   m_pDoc->slotSelectionChanged();
00571 }
00572 
00573 bool KivioPage::unselectStencil( KivioStencil *pStencil )
00574 {
00575     pStencil->unselect();
00576     m_pDoc->slotSelectionChanged();
00577     return m_lstSelection.removeRef( pStencil );
00578 }
00579 
00580 void KivioPage::selectAllStencils()
00581 {
00582   unselectAllStencils();
00583   KivioStencil* pStencil = m_pCurLayer->stencilList()->first();
00584 
00585   while(pStencil) {
00586     pStencil->select();
00587     m_lstSelection.append(pStencil);
00588     pStencil = m_pCurLayer->stencilList()->next();
00589   }
00590 
00591 
00592     /*
00593      * The following code is commented out because selections must
00594      * remain in the current layer.
00595     */
00596 /*
00597     KivioLayer* pLayer = m_lstLayers.first();
00598     while( pLayer )
00599     {
00600         if( pLayer->visible() )
00601         {
00602             pStencil = pLayer->stencilList()->first();
00603             while( pStencil )
00604             {
00605                 pStencil->select();
00606                 m_lstSelection.append(pStencil);
00607 
00608                 pStencil = pLayer->stencilList()->next();
00609             }
00610         }
00611 
00612         pLayer = m_lstLayers.next();
00613     }
00614 */
00615   m_pDoc->slotSelectionChanged();
00616 }
00617 
00618 void KivioPage::unselectAllStencils()
00619 {
00620   KivioStencil* pStencil = m_lstSelection.first();
00621 
00622   while(pStencil)
00623   {
00624     pStencil->unselect();
00625     pStencil = m_lstSelection.next();
00626   }
00627 
00628   m_lstSelection.clear();
00629   m_pDoc->slotSelectionChanged();
00630 }
00631 
00632 bool KivioPage::isStencilSelected(KivioStencil *pStencil)
00633 {
00634   return m_lstSelection.findRef( pStencil ) == -1;
00635 }
00636 
00646 KivioStencil *KivioPage::checkForStencil( KoPoint *pPoint, int *collisionType, double threshold, bool selectedOnly )
00647 {
00648     KivioStencil *pStencil;
00649     int colType;
00650 
00651 
00652     /*
00653      * This code is commented out because selecting a stencil should only take place
00654      * on the current layer.  The following code searches all layers.
00655     */
00656     // Start with the last layer since it is the top
00657     /*
00658     KivioLayer* pLayer = m_lstLayers.last();
00659     while( pLayer )
00660     {
00661         pStencil = pLayer->checkForStencil( pPoint, &colType );
00662         if( pStencil )
00663         {
00664             *collisionType = colType;
00665             return pStencil;
00666         }
00667 
00668         pLayer = m_lstLayers.prev();
00669     }
00670     */
00671 
00672     pStencil = m_pCurLayer->checkForStencil( pPoint, &colType, threshold, selectedOnly );
00673     if( pStencil )
00674     {
00675         *collisionType = colType;
00676         return pStencil;
00677     }
00678 
00679 
00680     *collisionType = kctNone;
00681     return NULL;
00682 }
00683 
00684 void KivioPage::deleteSelectedStencils()
00685 {
00686   // Make sure none of them have deletion protection
00687   KivioStencil* pStencil = m_lstSelection.first();
00688 
00689   while(pStencil) {
00690     if(pStencil->protection()->at(kpDeletion)) {
00691       KMessageBox::information(NULL, i18n("One of the selected stencils has protection from deletion and cannot be deleted."),
00692                                 i18n("Protection From Deletion") );
00693       return;
00694     }
00695 
00696     pStencil = m_lstSelection.next();
00697   }
00698 
00699   // Iterate through all items in the selection list
00700   m_lstSelection.first();
00701   pStencil = m_lstSelection.take();
00702   KMacroCommand *macro = new KMacroCommand( i18n("Remove Stencil"));
00703   bool createMacro = false;
00704 
00705   while(pStencil) {
00706     KivioRemoveStencilCommand *cmd =new KivioRemoveStencilCommand(i18n("Remove Stencil"), this,  m_pCurLayer , pStencil );
00707     createMacro = true;
00708     macro->addCommand(cmd);
00709 
00710     if(pStencil->type() == kstConnector) {
00711       static_cast<Kivio1DStencil*>(pStencil)->disconnectFromTargets();
00712     }
00713 
00714     pStencil = m_lstSelection.take();
00715   }
00716 
00717   if (createMacro) {
00718     macro->execute();
00719     m_pDoc->addCommand( macro );
00720   } else {
00721     delete macro;
00722   }
00723 }
00724 
00725 void KivioPage::groupSelectedStencils()
00726 {
00727   // Can't group 0 or 1 stencils
00728   if(!m_pCurLayer || (m_lstSelection.count() <= 1)) {
00729     return;
00730   }
00731 
00732   KivioGroupStencil* pGroup = new KivioGroupStencil();
00733 
00734   // Iterate through all items in the selection list, taking them from the layer, then adding
00735   // them to the group
00736 
00737   KivioStencil* pStencil = m_pCurLayer->firstStencil();
00738   KivioStencil* pTake = 0;
00739 
00740   while(pStencil) {
00741     if(pStencil->isSelected()) {
00742       // Take the stencil out of it's layer
00743       pTake = m_pCurLayer->takeStencil(pStencil);
00744 
00745       if(!pTake) {
00746         kdDebug(43000) << "KivioPage::groupSelectedStencil() - Failed to take() one of the selected stencils. CRAP!" << endl;
00747       } else {
00748         // Add it to the group
00749         pGroup->addToGroup(pTake);
00750         pStencil = m_pCurLayer->currentStencil();
00751       }
00752     } else {
00753       pStencil = m_pCurLayer->nextStencil();
00754     }
00755   }
00756 
00757   // Unselect the old ones
00758   unselectAllStencils();
00759 
00760   // Add the group as the selected stencil
00761   m_pCurLayer->addStencil(pGroup);
00762 
00763   selectStencil(pGroup);
00764 
00765   KivioGroupCommand* cmd = new KivioGroupCommand(i18n("Group Selection"), this, m_pCurLayer, pGroup);
00766   doc()->addCommand(cmd);
00767 }
00768 
00769 void KivioPage::ungroupSelectedStencils()
00770 {
00771   KivioStencil *pSelStencil, *pStencil;
00772   QPtrList<KivioStencil> *pList;
00773   QPtrList<KivioStencil> *pSelectThese = new QPtrList<KivioStencil>;
00774   KMacroCommand* macro = new KMacroCommand(i18n("Ungroup"));
00775   bool ungrouped = false;
00776 
00777   pSelectThese->setAutoDelete(false);
00778 
00779   // Iterate through all selected stencils
00780   pSelStencil = m_lstSelection.first();
00781   while( pSelStencil )
00782   {
00783     // If there is a list, it is a group stencil
00784     pList = pSelStencil->groupList();
00785     if(pList)
00786     {
00787       pList->first();
00788       pStencil = pList->first();
00789 
00790       while( pStencil )
00791       {
00792         m_pCurLayer->addStencil( pStencil );
00793         pSelectThese->append( pStencil );
00794 
00795         pStencil = pList->next();
00796       }
00797 
00798       // Remove the current stencil from the selection list(the group we just disassembled)
00799       m_lstSelection.take();
00800 
00801       // Remove it permanently from the layer
00802       if(!m_pCurLayer->takeStencil(pSelStencil))
00803       {
00804         kdDebug(43000) << "KivioPage::ungroupSelectedStencil() - Failed to locate the group shell for deletion"
00805           << endl;
00806       }
00807 
00808       KivioUnGroupCommand* cmd = new KivioUnGroupCommand(i18n("Ungroup"), this, m_pCurLayer,
00809           static_cast<KivioGroupStencil*>(pSelStencil));
00810       macro->addCommand(cmd);
00811       ungrouped = true;
00812     }
00813 
00814     pSelStencil = m_lstSelection.next();
00815   }
00816 
00817   // Now iterate through the selectThese list and select
00818   // those stencils
00819   pStencil = pSelectThese->first();
00820   while( pStencil )
00821   {
00822     selectStencil( pStencil );
00823 
00824     if(pStencil->type() == kstConnector) {
00825       pStencil->searchForConnections(this, 4.0);
00826     }
00827 
00828     pStencil = pSelectThese->next();
00829   }
00830 
00831   delete pSelectThese;
00832 
00833   if(ungrouped) {
00834     doc()->addCommand(macro);
00835   } else {
00836     delete macro;
00837   }
00838 }
00839 
00840 void KivioPage::bringToFront()
00841 {
00842     KivioStencil *pStencil, *pMove;
00843     KivioLayer *pLayer;
00844 
00845     QPtrList <KivioStencil> newList;
00846 
00847     pLayer = m_pCurLayer;
00848 
00849     newList.setAutoDelete(false);
00850 
00851     /*
00852      * We iterate through all stencils since order must be maintained
00853      * amongst the selection during the move.
00854      */
00855     pStencil = pLayer->firstStencil();
00856     while( pStencil )
00857     {
00858         if( isStencilSelected( pStencil )==true )
00859         {
00860             pMove = pLayer->takeStencil();
00861             if( pMove )
00862             {
00863                 newList.append(pMove);
00864                 pStencil = pLayer->currentStencil();
00865             }
00866             else  // In the case of error, the outside else won't execute
00867             {
00868                 pStencil = pLayer->nextStencil();
00869             }
00870         }
00871         else
00872         {
00873             pStencil = pLayer->nextStencil();
00874         }
00875     }
00876 
00877     // push them back in, in reverse order
00878     pStencil = newList.last();
00879     while( pStencil )
00880     {
00881         pLayer->stencilList()->insert(0, pStencil);
00882 
00883         pStencil = newList.prev();
00884     }
00885 }
00886 
00887 void KivioPage::sendToBack()
00888 {
00889     KivioStencil *pStencil, *pMove;
00890     KivioLayer *pLayer;
00891 
00892     QPtrList <KivioStencil> newList;
00893 
00894     pLayer = m_pCurLayer;
00895 
00896     newList.setAutoDelete(false);
00897 
00898     /*
00899      * We iterate through all stencils since order must be maintained
00900      * amongst the selection during the move.
00901      */
00902     pStencil = pLayer->firstStencil();
00903     while( pStencil )
00904     {
00905         if( isStencilSelected( pStencil )==true )
00906         {
00907             pMove = pLayer->takeStencil();
00908             if( pMove )
00909             {
00910                 newList.append(pMove);
00911                 pStencil = pLayer->currentStencil();
00912             }
00913             else  // In the case of error, the outside else won't execute
00914             {
00915                 pStencil = pLayer->nextStencil();
00916             }
00917         }
00918         else
00919         {
00920             pStencil = pLayer->nextStencil();
00921         }
00922     }
00923 
00924     // push them back in, in reverse order
00925     pStencil = newList.first();
00926     while( pStencil )
00927     {
00928         pLayer->stencilList()->append(pStencil);
00929 
00930         pStencil = newList.next();
00931     }
00932 }
00933 
00934 void KivioPage::copy()
00935 {
00936   if(m_lstSelection.count() <= 0) {
00937     return;
00938   }
00939 
00940   // push to clipbaord
00941   KivioDragObject* kdo = new KivioDragObject();
00942   kdo->setStencilList(m_lstSelection);
00943   kdo->setStencilRect(getRectForAllSelectedStencils());
00944   QApplication::clipboard()->setData(kdo, QClipboard::Clipboard);
00945 }
00946 
00947 void KivioPage::cut()
00948 {
00949   KivioStencil *pStencil;
00950   KivioLayer *pLayer;
00951   bool safe=true;
00952 
00953   if( m_lstSelection.count() <= 0 )
00954       return;
00955 
00956   pLayer = m_pCurLayer;
00957 
00958   // Make sure none of them are protected from deletion
00959   pStencil = pLayer->firstStencil();
00960   while( pStencil )
00961   {
00962     if( isStencilSelected( pStencil )==true )
00963     {
00964       if( pStencil->protection()->at(kpDeletion)==true )
00965       {
00966     safe=false;
00967       }
00968     }
00969 
00970     pStencil = pLayer->nextStencil();
00971   }
00972 
00973   if( safe==false )
00974   {
00975     KMessageBox::information(NULL, i18n("One of the stencils has protection from deletion. You cannot cut or delete this stencil."), i18n("Protection From Delete") );
00976 
00977     return;
00978   }
00979 
00980   copy();
00981   deleteSelectedStencils();
00982 }
00983 
00984 void KivioPage::paste(KivioView* view)
00985 {
00986   QPtrList<KivioStencil> list;
00987   list.setAutoDelete(false);
00988   KivioDragObject kdo;
00989 
00990   if(kdo.decode(QApplication::clipboard()->data(QClipboard::Clipboard), list, this)) {
00991     unselectAllStencils();
00992     KivioStencil* stencil = list.first();
00993 
00994     while(stencil) {
00995       addStencil(stencil);
00996       selectStencil(stencil);
00997       stencil = list.next();
00998     }
00999 
01000     view->canvasWidget()->startPasteMoving();
01001   }
01002 }
01003 
01004 int KivioPage::generateStencilIds(int next)
01005 {
01006     KivioLayer *pLayer;
01007 
01008     pLayer = m_lstLayers.first();
01009     while( pLayer )
01010     {
01011 
01012         next = pLayer->generateStencilIds( next );
01013 
01014         pLayer = m_lstLayers.next();
01015     }
01016 
01017     return next;
01018 }
01019 
01020 KivioLayer *KivioPage::firstLayer()
01021 {
01022     return m_lstLayers.first();
01023 }
01024 
01025 KivioLayer *KivioPage::nextLayer()
01026 {
01027     return m_lstLayers.next();
01028 }
01029 
01030 KivioLayer *KivioPage::prevLayer()
01031 {
01032     return m_lstLayers.prev();
01033 }
01034 
01035 KivioLayer *KivioPage::lastLayer()
01036 {
01037     return m_lstLayers.last();
01038 }
01039 
01040 bool KivioPage::removeCurrentLayer()
01041 {
01042     KivioLayer *pLayer;
01043 
01044     // NOOOOOOO!
01045     if( m_lstLayers.count() <= 1 )
01046         return false;
01047 
01048     pLayer = m_lstLayers.first();
01049 
01050     if( pLayer != m_pCurLayer )
01051     {
01052         if( m_lstLayers.find( m_pCurLayer )==false )
01053         {
01054        kdDebug(43000) << "KivioLayer::removeCurrentLayer() - Couldn't find current layer in the list. Bad!" << endl;
01055             return false;
01056         }
01057     }
01058 
01059     pLayer = m_lstLayers.next();
01060     if( !pLayer )
01061     {
01062         (void)m_lstLayers.last();
01063         pLayer = m_lstLayers.prev();
01064     }
01065 
01066     if( !pLayer )
01067     {
01068        kdDebug(43000) << "KivioLayer::removeCurrentLayer() - Couldn't find a next layer." << endl;
01069         return false;
01070     }
01071 
01072     KivioRemoveLayerCommand * cmd = new KivioRemoveLayerCommand( i18n("Remove Layer"), this , m_pCurLayer , m_lstLayers.findRef(m_pCurLayer) );
01073     doc()->addCommand( cmd );
01074     takeLayer( m_pCurLayer );
01075 /*
01076     if( m_lstLayers.remove( m_pCurLayer )==false )
01077     {
01078        kdDebug(43000) << "KivioLayer::removeCurrentLayer() - Couldn't find current layer in the list. Bad!" << endl;
01079         return false;
01080     }
01081 */
01082     m_pCurLayer = pLayer;
01083 
01084 
01085     return true;
01086 }
01087 
01088 void KivioPage::takeLayer( KivioLayer *pLayer )
01089 {
01090     int pos=m_lstLayers.findRef(pLayer);
01091     m_lstLayers.take( pos );
01092 }
01093 
01094 void KivioPage::addLayer( KivioLayer *pLayer )
01095 {
01096     m_lstLayers.append( pLayer );
01097 }
01098 
01099 void KivioPage::insertLayer( int position, KivioLayer *pLayer )
01100 {
01101     m_lstLayers.insert( position, pLayer );
01102 }
01103 
01104 KivioLayer *KivioPage::layerAt( int pos )
01105 {
01106     return m_lstLayers.at(pos);
01107 }
01108 
01109 void KivioPage::alignStencils(AlignData d)
01110 {
01111     KivioStencil* pStencil = m_lstSelection.first();
01112 
01113     if(!pStencil)
01114         return;
01115 
01116     if (d.v != AlignData::None || d.h != AlignData::None) {
01117         KMacroCommand *macro = new KMacroCommand(i18n("Move Stencil"));
01118         double x = pStencil->x();
01119         double y = pStencil->y();
01120         double w = pStencil->w();
01121         double h = pStencil->h();
01122 
01123         while( pStencil )
01124         {
01125             KoRect oldRect = pStencil->rect();
01126 
01127             switch (d.v) {
01128                 case AlignData::Top:
01129                   pStencil->setY(y);
01130                   break;
01131                 case AlignData::Center:
01132                   pStencil->setY(y+h/2-pStencil->h()/2);
01133                   break;
01134                 case AlignData::Bottom:
01135                   pStencil->setY(y+h-pStencil->h());
01136                   break;
01137                 default:
01138                   break;
01139             }
01140             switch (d.h) {
01141                 case AlignData::Left:
01142                   pStencil->setX(x);
01143                   break;
01144                 case AlignData::Center:
01145                   pStencil->setX(x+w/2-pStencil->w()/2);
01146                   break;
01147                 case AlignData::Right:
01148                   pStencil->setX(x+w-pStencil->w());
01149                   break;
01150                 default:
01151                   break;
01152             }
01153 
01154             KivioMoveStencilCommand * cmd = new KivioMoveStencilCommand( i18n("Move Stencil"),
01155               pStencil, oldRect, pStencil->rect(), this);
01156             macro->addCommand(cmd);
01157             pStencil = m_lstSelection.next();
01158         }
01159 
01160         m_pDoc->addCommand(macro);
01161     }
01162 
01163     if (d.centerOfPage) {
01164         KMacroCommand *macro = new KMacroCommand(i18n("Move Stencil"));
01165         double w = m_pPageLayout.ptWidth;
01166         double h = m_pPageLayout.ptHeight;
01167         KoRect r = getRectForAllSelectedStencils();
01168         double dx = ((w - r.width()) / 2.0) - r.x();
01169         double dy = ((h - r.height()) / 2.0) - r.y();
01170         pStencil = m_lstSelection.first();
01171 
01172         while( pStencil )
01173         {
01174             KoRect oldRect = pStencil->rect();
01175             pStencil->setPosition(pStencil->x() + dx, pStencil->y() + dy);
01176             KivioMoveStencilCommand * cmd = new KivioMoveStencilCommand( i18n("Move Stencil"),
01177               pStencil, oldRect, pStencil->rect(), this);
01178             macro->addCommand(cmd);
01179             pStencil = m_lstSelection.next();
01180         }
01181 
01182         m_pDoc->addCommand(macro);
01183     }
01184 }
01185 
01186 class XYSortedStencilList : public QPtrList<KivioStencil>
01187 {
01188 public:
01189   XYSortedStencilList(bool sortX) :xsort(sortX) {};
01190 
01191 protected:
01192   int compareItems(QPtrCollection::Item i1, QPtrCollection::Item i2)
01193   {
01194     KivioStencil* s1 = (KivioStencil*)i1;
01195     KivioStencil* s2 = (KivioStencil*)i2;
01196     if (xsort) {
01197       if (s1->x() > s2->x())
01198         return 1;
01199       if (s1->x() < s2->x())
01200         return -1;
01201       return 0;
01202     }
01203     if (s1->y() > s2->y())
01204       return 1;
01205     if (s1->y() < s2->y())
01206       return -1;
01207     return 0;
01208   }
01209 
01210 private:
01211   bool xsort;
01212 };
01213 
01214 
01215 void KivioPage::distributeStencils(DistributeData d)
01216 {
01217   double x  = 0.0;
01218   double y  = 0.0;
01219   double x1 = 0.0;
01220   double y1 = 0.0;
01221 
01222   KivioStencil* pStencil = m_lstSelection.first();
01223   if (!pStencil)
01224     return;
01225 
01226   XYSortedStencilList xSortList(true);
01227   XYSortedStencilList ySortList(false);
01228   QValueList<KoRect> oldRects;
01229 
01230   while( pStencil )
01231   {
01232       xSortList.append(pStencil);
01233       ySortList.append(pStencil);
01234       oldRects.append(pStencil->rect());
01235       pStencil = m_lstSelection.next();
01236   }
01237   xSortList.sort();
01238   ySortList.sort();
01239 
01240   switch (d.extent) {
01241     case DistributeData::Page:
01242       x = m_pPageLayout.ptLeft;
01243       y = m_pPageLayout.ptTop;
01244       x1 = m_pPageLayout.ptWidth - m_pPageLayout.ptRight;
01245       y1 = m_pPageLayout.ptHeight - m_pPageLayout.ptBottom;
01246       break;
01247     case DistributeData::Selection:
01248       pStencil = m_lstSelection.first();
01249       x = pStencil->x();
01250       y = pStencil->x();
01251       x1 = x + pStencil->w();
01252       y1 = y + pStencil->h();
01253       while( pStencil )
01254       {
01255           x = QMIN(x,pStencil->x());
01256           y = QMIN(y,pStencil->y());
01257           x1 = QMAX(x1,pStencil->x() + pStencil->w());
01258           y1 = QMAX(y1,pStencil->y() + pStencil->h());
01259           pStencil = m_lstSelection.next();
01260       }
01261       break;
01262     default:
01263       break;
01264   }
01265 
01266   /*****************************************************/
01267   KivioStencil* firstx = xSortList.first();
01268   KivioStencil* lastx = xSortList.last();
01269   double countx = (double)(xSortList.count()-1);
01270   double distx = 0.0;
01271   switch (d.h) {
01272     case DistributeData::Left:
01273       x1 = x1 - lastx->w();
01274       distx = (x1 - x)/countx;
01275       break;
01276     case DistributeData::Center:
01277       x = x + firstx->w()/2;
01278       x1 = x1 - lastx->w()/2;
01279       distx = (x1 - x)/countx;
01280       break;
01281     case DistributeData::Spacing: {
01282       double allw = 0.0;
01283       pStencil = xSortList.first();
01284       while( pStencil )
01285       {
01286           allw = allw + pStencil->w();
01287           pStencil = xSortList.next();
01288       }
01289       distx = (x1-x-allw)/countx;
01290       break; }
01291     case DistributeData::Right:
01292       x = x + firstx->w();
01293       distx = (x1 - x)/countx;
01294       break;
01295     default:
01296       break;
01297   }
01298 
01299   double xx = x;
01300   switch (d.h) {
01301     case DistributeData::Center:
01302       pStencil = xSortList.first();
01303       while( pStencil )
01304       {
01305           pStencil->setX(xx - pStencil->w()/2);
01306           xx = xx + distx;
01307           pStencil = xSortList.next();
01308       }
01309       break;
01310     case DistributeData::Right:
01311       pStencil = xSortList.first();
01312       while( pStencil )
01313       {
01314           pStencil->setX(xx - pStencil->w());
01315           xx = xx + distx;
01316           pStencil = xSortList.next();
01317       }
01318       break;
01319     case DistributeData::Left:
01320       pStencil = xSortList.first();
01321       while( pStencil )
01322       {
01323           pStencil->setX(xx);
01324           xx = xx + distx;
01325           pStencil = xSortList.next();
01326       }
01327       break;
01328     case DistributeData::Spacing:
01329       pStencil = xSortList.first();
01330       while( pStencil )
01331       {
01332           pStencil->setX(xx);
01333           xx = xx + pStencil->w() + distx;
01334           pStencil = xSortList.next();
01335       }
01336       break;
01337     default:
01338       break;
01339   }
01340   /*****************************************************/
01341   KivioStencil* firsty = ySortList.first();
01342   KivioStencil* lasty = ySortList.last();
01343   double county = (double)(ySortList.count()-1);
01344   double disty = 0.0;
01345   switch (d.v) {
01346     case DistributeData::Top:
01347       y1 = y1 - lasty->h();
01348       disty = (y1 - y)/county;
01349       break;
01350     case DistributeData::Center:
01351       y = y + firsty->h()/2;
01352       y1 = y1 - lasty->h()/2;
01353       disty = (y1 - y)/countx;
01354       break;
01355     case DistributeData::Spacing: {
01356       double allh = 0.0;
01357       pStencil = ySortList.first();
01358       while( pStencil )
01359       {
01360           allh = allh + pStencil->h();
01361           pStencil = ySortList.next();
01362       }
01363       disty = (y1-y-allh)/county;
01364       break; }
01365     case DistributeData::Bottom:
01366       y = y + firsty->h();
01367       disty = (y1 - y)/county;
01368       break;
01369     default:
01370       break;
01371   }
01372 
01373   double yy = y;
01374   switch (d.v) {
01375     case DistributeData::Center:
01376       pStencil = ySortList.first();
01377       while( pStencil )
01378       {
01379           pStencil->setY(yy - pStencil->h()/2);
01380           yy = yy + disty;
01381           pStencil = ySortList.next();
01382       }
01383       break;
01384     case DistributeData::Bottom:
01385       pStencil = ySortList.first();
01386       while( pStencil )
01387       {
01388           pStencil->setY(yy - pStencil->h());
01389           yy = yy + disty;
01390           pStencil = ySortList.next();
01391       }
01392       break;
01393     case DistributeData::Top:
01394       pStencil = ySortList.first();
01395       while( pStencil )
01396       {
01397           pStencil->setY(yy);
01398           yy = yy + disty;
01399           pStencil = ySortList.next();
01400       }
01401       break;
01402     case DistributeData::Spacing:
01403       pStencil = ySortList.first();
01404       while( pStencil )
01405       {
01406           pStencil->setY(yy);
01407           yy = yy + pStencil->h() + disty;
01408           pStencil = ySortList.next();
01409       }
01410       break;
01411     default:
01412       break;
01413   }
01414 
01415   if(d.v != DistributeData::None || d.h != DistributeData::None) {
01416     KMacroCommand *macro = new KMacroCommand(i18n("Move Stencil"));
01417     QValueListIterator<KoRect> it;
01418     pStencil = m_lstSelection.first();
01419 
01420     for(it = oldRects.begin(); it != oldRects.end(); ++it) {
01421       KivioMoveStencilCommand * cmd = new KivioMoveStencilCommand(i18n("Move Stencil"),
01422         pStencil, (*it), pStencil->rect(), this);
01423       macro->addCommand( cmd);
01424       pStencil = m_lstSelection.next();
01425     }
01426 
01427     m_pDoc->addCommand( macro );
01428   }
01429 }
01430 
01431 
01435 KoRect KivioPage::getRectForAllSelectedStencils()
01436 {
01437     KoRect rTotal, r;
01438 
01439     KivioStencil *pStencil = m_lstSelection.first();
01440 
01441     // Get the rect of the first selected stencil
01442     if( pStencil )
01443     {
01444         rTotal = pStencil->rect();
01445 
01446         pStencil = m_lstSelection.next();
01447     }
01448 
01449     // iterate through all the stencils uniting the rectangles
01450     while( pStencil )
01451     {
01452         r = pStencil->rect();
01453 
01454         rTotal = rTotal.unite( r );
01455 
01456         pStencil = m_lstSelection.next();
01457     }
01458 
01459     return rTotal;
01460 }
01461 
01465 KoRect KivioPage::getRectForAllStencils()
01466 {
01467     KoRect rTotal, r;
01468 
01469     bool firstTime = true;
01470 
01471     KivioLayer *pLayer;
01472     KivioStencil *pStencil;
01473 
01474     pLayer = m_lstLayers.first();
01475     while( pLayer )
01476     {
01477         pStencil = pLayer->firstStencil();
01478         while( pStencil )
01479         {
01480             if( firstTime==true )
01481             {
01482                 rTotal = pStencil->rect();
01483                 firstTime = false;
01484             }
01485             else
01486             {
01487                 r = pStencil->rect();
01488                 rTotal = rTotal.unite( r );
01489             }
01490 
01491             pStencil = pLayer->nextStencil();
01492         }
01493 
01494         pLayer = m_lstLayers.next();
01495     }
01496 
01497 
01498     return rTotal;
01499 }
01500 
01501 void KivioPage::setPaperLayout(const KoPageLayout &l)
01502 {
01503   m_pPageLayout = l;
01504   doc()->updateView(this);
01505   emit sig_pageLayoutChanged(m_pPageLayout);
01506 }
01507 
01508 KivioConnectorTarget *KivioPage::connectPointToTarget( KivioConnectorPoint *p, double /*thresh*/)
01509 {
01510    double oldX, oldY;
01511    KivioLayer *pLayer, *pCurLayer;
01512    bool doneSearching = false;
01513    KivioConnectorTarget *pTarget;
01514 
01515    if( !p )
01516       return NULL;
01517 
01518    if( p->connectable()==false )
01519       return NULL;
01520 
01521    oldX = p->x();
01522    oldY = p->y();
01523 
01524    pCurLayer = curLayer();
01525    pLayer = firstLayer();
01526 
01527    while( pLayer && doneSearching==false )
01528    {
01529       if( pLayer != pCurLayer )
01530       {
01531      if( pLayer->connectable()==false || pLayer->visible()==false )
01532      {
01533         pLayer = nextLayer();
01534         continue;
01535      }
01536       }
01537 
01538       if( (pTarget=pLayer->connectPointToTarget(p, 8.0f )) )
01539       {
01540      return pTarget;
01541       }
01542 
01543       pLayer = nextLayer();
01544    }
01545 
01546    return NULL;
01547 }
01548 
01549 KoPoint KivioPage::snapToTarget( const KoPoint& p, double thresh, bool& hit )
01550 {
01551    KivioLayer *pLayer, *pCurLayer;
01552    KoPoint retVal = p;
01553 
01554    pCurLayer = curLayer();
01555    pLayer = firstLayer();
01556 
01557    while( pLayer && !hit )
01558    {
01559       if( pLayer != pCurLayer )
01560       {
01561           if( pLayer->connectable()==false || pLayer->visible()==false )
01562           {
01563             pLayer = nextLayer();
01564             continue;
01565           }
01566       }
01567 
01568       retVal = pLayer->snapToTarget(p, thresh, hit);
01569 
01570       pLayer = nextLayer();
01571    }
01572 
01573    return retVal;
01574 }
01575 
01576 void KivioPage::setHidePage(bool _hide)
01577 {
01578     setHidden(_hide);
01579     if(_hide)
01580         emit sig_PageHidden(this);
01581     else
01582         emit sig_PageShown(this);
01583 }
01584 
01585 void KivioPage::setPaintSelected(bool paint)
01586 {
01587   KivioStencil *pStencil = m_lstSelection.first();
01588 
01589   while( pStencil )
01590   {
01591     pStencil->setHidden(!paint);
01592     pStencil = m_lstSelection.next();
01593   }
01594 }
01595 
01596 bool KivioPage::checkForStencilTypeInSelection(KivioStencilType type)
01597 {
01598   KivioStencil *pStencil = m_lstSelection.first();
01599 
01600   while( pStencil )
01601   {
01602     if(pStencil->type() == type) {
01603       return true;
01604     }
01605 
01606     pStencil = m_lstSelection.next();
01607   }
01608 
01609   return false;
01610 }
01611 
01612 bool KivioPage::checkForTextBoxesInSelection()
01613 {
01614   KivioStencil *pStencil = m_lstSelection.first();
01615 
01616   while(pStencil) {
01617     if(pStencil->hasTextBox()) {
01618       return true;
01619     }
01620 
01621     pStencil = m_lstSelection.next();
01622   }
01623 
01624   return false;
01625 }
01626 
01627 void KivioPage::setGuideLines(const QValueList<double> hGuideLines, const QValueList<double> vGuideLines)
01628 {
01629   m_hGuideLines = hGuideLines;
01630   m_vGuideLines = vGuideLines;
01631 }
01632 
01633 void KivioPage::saveGuideLines(QDomElement& element)
01634 {
01635   QValueList<double>::iterator it;
01636   QValueList<double>::iterator itEnd = m_hGuideLines.end();
01637 
01638   for(it = m_hGuideLines.begin(); it != itEnd; ++it) {
01639     QDomElement e = element.ownerDocument().createElement("Guideline");
01640     element.appendChild(e);
01641     XmlWriteDouble(e, "pos", *it);
01642     XmlWriteInt(e, "orient", (int)Qt::Horizontal);
01643   }
01644 
01645   itEnd = m_vGuideLines.end();
01646 
01647   for(it = m_vGuideLines.begin(); it != itEnd; ++it) {
01648     QDomElement e = element.ownerDocument().createElement("Guideline");
01649     element.appendChild(e);
01650     XmlWriteDouble(e, "pos", *it);
01651     XmlWriteInt(e, "orient", (int)Qt::Vertical);
01652   }
01653 }
01654 
01655 void KivioPage::loadGuideLines(const QDomElement& element)
01656 {
01657   m_hGuideLines.clear();
01658   m_vGuideLines.clear();
01659 
01660   QDomElement e = element.firstChild().toElement();
01661 
01662   for( ; !e.isNull(); e = e.nextSibling().toElement() )
01663   {
01664     double pos = XmlReadDouble(e, "pos", 0.0);
01665     Qt::Orientation orient = (Qt::Orientation)XmlReadInt(e, "orient", 0);
01666     addGuideLine(orient, pos);
01667   }
01668 }
01669 
01670 void KivioPage::addGuideLine(Qt::Orientation orientation, double position)
01671 {
01672   if(orientation == Qt::Horizontal) {
01673     m_hGuideLines.append(position);
01674   } else {
01675     m_vGuideLines.append(position);
01676   }
01677 }
01678 
01679 #include "kivio_page.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys