kpresenter

KPrDocument.cpp

00001 /* This file is part of the KDE project
00002    Copyright (C) 1998, 1999 Reginald Stadlbauer <reggie@kde.org>
00003    Copyright (C) 2005-2006 Thorsten Zachmann <zachmann@kde.org>
00004 
00005    This library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Library General Public
00007    License as published by the Free Software Foundation; either
00008    version 2 of the License, or (at your option) any later version.
00009 
00010    This library 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 GNU
00013    Library General Public License for more details.
00014 
00015    You should have received a copy of the GNU Library General Public License
00016    along with this library; see the file COPYING.LIB.  If not, write to
00017    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018  * Boston, MA 02110-1301, USA.
00019 */
00020 
00021 #include "KPrDocument.h"
00022 #include "KPrView.h"
00023 #include "KPrCanvas.h"
00024 #include "KPrPage.h"
00025 #include "KPrObject.h"
00026 #include "KPrLineObject.h"
00027 #include "KPrRectObject.h"
00028 #include "KPrEllipseObject.h"
00029 #include "KPrAutoformObject.h"
00030 #include "KPrTextObject.h"
00031 #include "KPrTextDocument.h"
00032 #include "KPrPixmapObject.h"
00033 #include "KPrPieObject.h"
00034 #include "KPrPartObject.h"
00035 #include "KPrGroupObject.h"
00036 #include "KPrCommand.h"
00037 #include "insertpagedia.h"
00038 #include "KPrFreehandObject.h"
00039 #include "KPrPolylineObject.h"
00040 #include "KPrBezierCurveObject.h"
00041 #include "KPrPolygonObject.h"
00042 #include "KPrClosedLineObject.h"
00043 #include "KPrSVGPathParser.h"
00044 
00045 #include <qpopupmenu.h>
00046 #include <qclipboard.h>
00047 #include <qregexp.h>
00048 #include <qfileinfo.h>
00049 #include <qdom.h>
00050 #include <qdict.h>
00051 
00052 #include <KoDom.h>
00053 #include <KoXmlNS.h>
00054 
00055 #include <kurl.h>
00056 #include <kdebug.h>
00057 #include <KoGlobal.h>
00058 #include <kapplication.h>
00059 #include <kurldrag.h>
00060 #include <ktempfile.h>
00061 #include <klocale.h>
00062 #include <kfiledialog.h>
00063 #include <kglobal.h>
00064 #include <kstandarddirs.h>
00065 #include <kmessagebox.h>
00066 #include <kprocess.h>
00067 #include <kio/netaccess.h>
00068 
00069 #include <KoTemplateChooseDia.h>
00070 #include <KoRuler.h>
00071 #include <KoGenStyles.h>
00072 #include <KoFilterManager.h>
00073 #include <KoStore.h>
00074 #include <KoStoreDevice.h>
00075 #include <KoQueryTrader.h>
00076 #include <KoXmlWriter.h>
00077 #include <KoOasisSettings.h>
00078 #include <KoMainWindow.h>
00079 
00080 #include <stdlib.h>
00081 #include <stdio.h>
00082 #include <math.h>
00083 #include <unistd.h>
00084 #include <config.h>
00085 
00086 #include <KoRichText.h>
00087 #include <KoTextObject.h>
00088 #include <KoTextZoomHandler.h>
00089 #include <KoStyleCollection.h>
00090 #include <kcommand.h>
00091 #include "KPrDocumentIface.h"
00092 
00093 #include <kspell2/settings.h>
00094 
00095 #include <KoVariable.h>
00096 #include <KoAutoFormat.h>
00097 #include <KoDocumentInfo.h>
00098 #include "KPrVariableCollection.h"
00099 #include "KPrBackground.h"
00100 #include "KPrNoteBar.h"
00101 #include "KPrBgSpellCheck.h"
00102 #include <kglobalsettings.h>
00103 #include <KoCommandHistory.h>
00104 #include "KoApplication.h"
00105 #include <KoOasisStyles.h>
00106 #include <KoOasisContext.h>
00107 
00108 #include "KPrLoadingInfo.h"
00109 
00110 using namespace std;
00111 
00112 static const int CURRENT_SYNTAX_VERSION = 2;
00113 // Make sure an appropriate DTD is available in www/koffice/DTD if changing this value
00114 static const char * CURRENT_DTD_VERSION = "1.2";
00115 
00116 KPrChild::KPrChild( KPrDocument *_kpr, KoDocument* _doc, const QRect& _rect )
00117     : KoDocumentChild( _kpr, _doc, _rect )
00118 {
00119     m_parent = _kpr;
00120 }
00121 
00122 KPrChild::KPrChild( KPrDocument *_kpr ) :
00123     KoDocumentChild( _kpr )
00124 {
00125     m_parent = _kpr;
00126 }
00127 
00128 KPrChild::~KPrChild()
00129 {
00130 }
00131 
00132 KoDocument *KPrChild::hitTest( const QPoint &, const QWMatrix & )
00133 {
00134     // hitTest functionality is disabled because kpresenter handles activation
00135     // of embedded parts by itself. See KPrPartObject::activate().
00136     return 0;
00137 }
00138 
00139 KPrDocument::KPrDocument( QWidget *parentWidget, const char *widgetName, QObject* parent, const char* name,
00140                               bool singleViewMode )
00141     : KoDocument( parentWidget,widgetName, parent, name, singleViewMode ),
00142       _gradientCollection(), m_customListTest( 0L ),
00143       m_childCountBeforeInsert( 0 )
00144 {
00145     setInstance( KPrFactory::global() );
00146     setTemplateType( "kpresenter_template" );
00147     //Necessary to define page where we load object otherwise copy-duplicate page doesn't work.
00148     m_pageWhereLoadObject=0L;
00149     m_loadingInfo=0L;
00150     m_tabStop = MM_TO_POINT( 15.0 );
00151     m_styleColl=new KoStyleCollection();
00152     m_insertFilePage = 0;
00153     m_picturePath= KGlobalSettings::documentPath();
00154     m_globalLanguage = KGlobal::locale()->language();
00155     m_bGlobalHyphenation = false;
00156     _duplicatePage=false;
00157 
00158     KoParagStyle* m_standardStyle = new KoParagStyle( "Standard" );
00159     m_styleColl->addStyle( m_standardStyle );
00160 
00161     KConfig *config = KPrFactory::global()->config();
00162     config->setGroup("Document defaults" );
00163     QString defaultFontname=config->readEntry("DefaultFont");
00164     if ( !defaultFontname.isEmpty() )
00165         m_defaultFont.fromString( defaultFontname );
00166     // If not found, we automatically fallback to the application font (the one from KControl's font module)
00167 
00168     // Try to force a scalable font.
00169     m_defaultFont.setStyleStrategy( QFont::ForceOutline );
00170     //kdDebug(33001) << "Default font: requested family: " << m_defaultFont.family() << endl;
00171     //kdDebug(33001) << "Default font: real family: " << QFontInfo(m_defaultFont).family() << endl;
00172 
00173     int ptSize = m_defaultFont.pointSize();
00174     if ( ptSize == -1 ) // specified with a pixel size ?
00175         ptSize = QFontInfo(m_defaultFont).pointSize();
00176     //kdDebug(33001) << "KPrDocument::KPrDocument[2] ptSize=" << ptSize << endl;
00177     // Ok, this is KPresenter. A default font of 10 makes no sense. Let's go for 20.
00178     ptSize = QMAX( 20, ptSize );
00179 
00180     m_standardStyle->format().setFont( m_defaultFont );
00181 
00183     m_standardStyle->format().setColor( Qt::black );
00184 
00185     if( config->hasGroup("Interface") ) {
00186         config->setGroup( "Interface" );
00187         m_globalLanguage=config->readEntry("language", KGlobal::locale()->language());
00188         m_bGlobalHyphenation=config->readBoolEntry("hyphenation", false);
00189     }
00190 
00191     m_standardStyle->format().setLanguage( m_globalLanguage);
00192 
00193     m_zoomHandler = new KoTextZoomHandler;
00194 
00195     m_varFormatCollection = new KoVariableFormatCollection;
00196     m_varColl = new KPrVariableCollection( new KoVariableSettings(), m_varFormatCollection );
00197     m_bgSpellCheck = new KPrBgSpellCheck(this);
00198     dcop = 0;
00199     m_initialActivePage=0;
00200     m_bShowStatusBar = true;
00201     m_autoFormat = new KoAutoFormat(this,m_varColl,m_varFormatCollection);
00202     _clean = true;
00203     _spInfiniteLoop = false;
00204     _spShowEndOfPresentationSlide = true;
00205     _spManualSwitch = true;
00206     _showPresentationDuration = false;
00207     tmpSoundFileList = QPtrList<KTempFile>();
00208     _xRnd = 20;
00209     _yRnd = 20;
00210     _txtBackCol = lightGray;
00211     _otxtBackCol = lightGray;
00212 
00213     m_bShowRuler=true;
00214     m_bAllowAutoFormat = true;
00215 
00216     m_bViewFormattingChars = false;
00217     m_bShowGuideLines = true;
00218 
00219     m_bShowGrid = true;
00220 
00221     m_bSnapToGrid = true;
00222 
00223     m_cursorInProtectectedArea=true;
00224 
00225     usedSoundFile = QStringList();
00226     haveNotOwnDiskSoundFile = QStringList();
00227 
00228     m_zoomHandler->setZoomAndResolution( 100, KoGlobal::dpiX(), KoGlobal::dpiY() );
00229     newZoomAndResolution(false,false);
00230 
00231     //   _pageLayout.format = PG_SCREEN;
00232     //   _pageLayout.orientation = PG_PORTRAIT;
00233     //   _pageLayout.width = PG_SCREEN_WIDTH;
00234     //   _pageLayout.height = PG_SCREEN_HEIGHT;
00235     //   _pageLayout.left = 0;
00236     //   _pageLayout.right = 0;
00237     //   _pageLayout.top = 0;
00238     //   _pageLayout.bottom = 0;
00239     //   _pageLayout.ptWidth = cMM_TO_POINT( PG_SCREEN_WIDTH );
00240     //   _pageLayout.ptHeight = cMM_TO_POINT( PG_SCREEN_HEIGHT );
00241     //   _pageLayout.ptLeft = 0;
00242     //   _pageLayout.ptRight = 0;
00243     //   _pageLayout.ptTop = 0;
00244     //   _pageLayout.ptBottom = 0;
00245 
00246     m_indent = MM_TO_POINT( 10.0 );
00247     m_gridX = MM_TO_POINT( 5.0 );
00248     m_gridY = MM_TO_POINT( 5.0 );
00249 
00250     oldGridX = m_gridX;
00251     oldGridY = m_gridY;
00252 
00253     m_masterPage=new KPrPage(this);
00254     KPrPage *newpage = new KPrPage( this, m_masterPage );
00255     m_pageList.insert( 0,newpage);
00256     m_bInsertDirectCursor = false;
00257 
00258     objStartY = 0;
00259     _presPen = QPen( red, 3, SolidLine );
00260     ignoreSticky = TRUE;
00261 
00262     m_gridColor=Qt::black;
00263 
00264     _header = new KPrTextObject( this );
00265     _header->setDrawEditRect( false );
00266     _header->setDrawEmpty( false );
00267 
00268     _footer = new KPrTextObject( this );
00269     _footer->setDrawEditRect( false );
00270     _footer->setDrawEmpty( false );
00271 
00272     saveOnlyPage = -1;
00273     m_maxRecentFiles = 10;
00274 
00275     connect( QApplication::clipboard(), SIGNAL( dataChanged() ),
00276              this, SLOT( clipboardDataChanged() ) );
00277 
00278     m_commandHistory = new KoCommandHistory( actionCollection(),  true ) ;
00279     initConfig();
00280 
00281     connect( m_commandHistory, SIGNAL( documentRestored() ), this, SLOT( slotDocumentRestored() ) );
00282     connect( m_commandHistory, SIGNAL( commandExecuted() ), this, SLOT( slotCommandExecuted() ) );
00283 
00284     dcopObject();
00285 }
00286 
00287 void KPrDocument::refreshMenuCustomVariable()
00288 {
00289     emit sig_refreshMenuCustomVariable();
00290 }
00291 
00292 void KPrDocument::slotDocumentRestored()
00293 {
00294     setModified( false );
00295 }
00296 
00297 void KPrDocument::slotCommandExecuted()
00298 {
00299     setModified( true );
00300 }
00301 
00302 void KPrDocument::saveConfig()
00303 {
00304     if ( !isReadWrite())
00305         return;
00306     KConfigGroup group( KoGlobal::kofficeConfig(), "Spelling" );
00307     group.writeEntry( "PersonalDict", m_spellCheckPersonalDict );
00308     if ( !isEmbedded() )
00309     {
00310         KConfig *config = KPrFactory::global()->config();
00311         config->setGroup( "Interface" );
00312         config->writeEntry( "Zoom", m_zoomHandler->zoom() );
00313         config->writeEntry( "AllowAutoFormat" , m_bAllowAutoFormat );
00314         config->writeEntry( "ViewFormattingChars", m_bViewFormattingChars );
00315         config->writeEntry( "ShowGrid" , m_bShowGrid );
00316         config->writeEntry( "SnapToGrid" , m_bSnapToGrid );
00317         config->writeEntry( "ResolutionX", m_gridX );
00318         config->writeEntry( "ResolutionY", m_gridY );
00319     }
00320 }
00321 
00322 void KPrDocument::initConfig()
00323 {
00324     int zoom;
00325     KConfig* config = KPrFactory::global()->config();
00326     if( config->hasGroup("Interface") ) {
00327         config->setGroup( "Interface" );
00328         setAutoSave( config->readNumEntry( "AutoSave", defaultAutoSave()/60 ) * 60 );
00329         setBackupFile( config->readBoolEntry("BackupFile", true));
00330         setCursorInProtectedArea( config->readBoolEntry( "cursorInProtectArea", true ));
00331 
00332         // Config-file value in mm, default 10 pt
00333         double indent =  config->readDoubleNumEntry("Indent", MM_TO_POINT(10.0) ) ;
00334         setIndentValue(indent);
00335         m_maxRecentFiles = config->readNumEntry( "NbRecentFile", 10 );
00336         setShowRuler(config->readBoolEntry("Rulers",true));
00337         zoom = config->readNumEntry( "Zoom", 100 );
00338         setShowStatusBar( config->readBoolEntry( "ShowStatusBar" , true ));
00339         setAllowAutoFormat( config->readBoolEntry( "AllowAutoFormat" , true ));
00340         setViewFormattingChars( config->readBoolEntry( "ViewFormattingChars", false ) );
00341         setShowGrid( config->readBoolEntry( "ShowGrid" , true ));
00342         setSnapToGrid( config->readBoolEntry( "SnapToGrid", true ));
00343         setGridX( config->readDoubleNumEntry( "ResolutionX", MM_TO_POINT( 5.0 ) ));
00344         setGridY( config->readDoubleNumEntry( "ResolutionY", MM_TO_POINT( 5.0 ) ));
00345 
00346         m_bInsertDirectCursor= config->readBoolEntry( "InsertDirectCursor", false );
00347         m_globalLanguage=config->readEntry("language", KGlobal::locale()->language());
00348 
00349     }
00350     else
00351         zoom=100;
00352 
00353     QColor oldBgColor = Qt::white;
00354     QColor oldGridColor = Qt::black;
00355     if ( config->hasGroup( "KPresenter Color" ) ) {
00356         config->setGroup( "KPresenter Color" );
00357         setTxtBackCol(config->readColorEntry( "BackgroundColor", &oldBgColor ));
00358         setGridColor(config->readColorEntry( "GridColor", &oldGridColor ));
00359     }
00360 
00361 
00362     if( config->hasGroup("KSpell kpresenter" ) )
00363     {
00364         config->setGroup( "KSpell kpresenter" );
00365 
00366        // Default is false for spellcheck, but the spell-check config dialog
00367        // should write out "true" when the user configures spell checking.
00368         if ( isReadWrite() )
00369           m_bgSpellCheck->setEnabled(config->readBoolEntry( "SpellCheck", false ));
00370        else
00371           m_bgSpellCheck->setEnabled( false );
00372     }
00373     int undo=30;
00374     if(config->hasGroup("Misc" ) )
00375     {
00376         config->setGroup( "Misc" );
00377         undo=config->readNumEntry("UndoRedo",-1);
00378     }
00379     if(undo!=-1)
00380         setUndoRedoLimit(undo);
00381 
00382     if(config->hasGroup("Kpresenter Path" ) )
00383     {
00384         config->setGroup( "Kpresenter Path" );
00385         m_picturePath=config->readPathEntry( "picture path",KGlobalSettings::documentPath());
00386         setBackupPath(config->readPathEntry( "backup path" ));
00387     }
00388 
00389     // Load personal dict
00390     KConfigGroup group( KoGlobal::kofficeConfig(), "Spelling" );
00391     m_spellCheckPersonalDict = group.readListEntry( "PersonalDict" );
00392 
00393     // Apply configuration, without creating an undo/redo command
00394     replaceObjs( false );
00395     zoomHandler()->setZoom( zoom );
00396     newZoomAndResolution(false,false);
00397 }
00398 
00399 DCOPObject* KPrDocument::dcopObject()
00400 {
00401     if ( !dcop )
00402         dcop = new KPrDocumentIface( this );
00403 
00404     return dcop;
00405 }
00406 
00407 KPrDocument::~KPrDocument()
00408 {
00409     if(isReadWrite())
00410         saveConfig();
00411     clearTestCustomSlideShow();
00412     //Be carefull !!!!!! don't delete this pointer delete in stickypage
00413 #if 0
00414     delete _header;
00415     delete _footer;
00416 #endif
00417 
00418     delete m_commandHistory;
00419     delete m_zoomHandler;
00420     delete m_autoFormat;
00421     delete m_varColl;
00422     delete m_varFormatCollection;
00423     delete dcop;
00424     delete m_masterPage;
00425     delete m_bgSpellCheck;
00426     delete m_styleColl;
00427 
00428     m_pageList.setAutoDelete( true );
00429     m_pageList.clear();
00430     m_deletedPageList.setAutoDelete( true );
00431     m_deletedPageList.clear();
00432     tmpSoundFileList.setAutoDelete( true );
00433     tmpSoundFileList.clear();
00434 }
00435 
00436 void KPrDocument::addCommand( KCommand * cmd )
00437 {
00438     kdDebug(33001) << "KPrDocument::addCommand " << cmd->name() << endl;
00439     m_commandHistory->addCommand( cmd, false );
00440     setModified( true );
00441 }
00442 
00443 bool KPrDocument::saveChildren( KoStore* _store )
00444 {
00445     int i = 0;
00446 
00447     QPtrListIterator<KoDocumentChild> it( children() );
00448     for( ; it.current(); ++it ) {
00449         // Don't save children that are only in the undo/redo history
00450         // but not anymore in the presentation
00451         QPtrListIterator<KPrPage> pageIt( m_pageList );
00452         for ( int pagePos = 0; pageIt.current(); ++pageIt, ++pagePos )
00453         {
00454             if ( saveOnlyPage == -1 || pagePos == saveOnlyPage )
00455             {
00456                 QPtrListIterator<KPrObject> oIt(pageIt.current()->objectList());
00457                 for (; oIt.current(); ++oIt )
00458                 {
00459                     if ( oIt.current()->getType() == OT_PART &&
00460                          dynamic_cast<KPrPartObject*>( oIt.current() )->getChild() == it.current() )
00461                     {
00462                         if (((KoDocumentChild*)(it.current()))->document()!=0)
00463                             if ( !((KoDocumentChild*)(it.current()))->document()->saveToStore( _store, QString::number( i++ ) ) )
00464                                 return false;
00465                     }
00466                 }
00467             }
00468         }
00469         if ( saveOnlyPage == -1 )
00470         {
00471             QPtrListIterator<KPrObject> oIt(m_masterPage->objectList());
00472             for (; oIt.current(); ++oIt )
00473             {
00474                 if ( oIt.current()->getType() == OT_PART &&
00475                         dynamic_cast<KPrPartObject*>( oIt.current() )->getChild() == it.current() )
00476                 {
00477                     if (((KoDocumentChild*)(it.current()))->document()!=0)
00478                         if ( !((KoDocumentChild*)(it.current()))->document()->saveToStore( _store, QString::number( i++ ) ) )
00479                             return false;
00480                 }
00481             }
00482         }
00483     }
00484     return true;
00485 }
00486 
00487 QDomDocument KPrDocument::saveXML()
00488 {
00489     if ( saveOnlyPage == -1 ) {
00490         emit sigProgress( 0 );
00491     }
00492 
00493     m_varColl->variableSetting()->setModificationDate(QDateTime::currentDateTime());
00494     recalcVariables( VT_DATE );
00495     recalcVariables( VT_TIME );
00496     recalcVariables( VT_STATISTIC );
00497     QDomDocument doc = createDomDocument( "DOC", CURRENT_DTD_VERSION );
00498     QDomElement presenter=doc.documentElement();
00499     presenter.setAttribute("editor", "KPresenter");
00500     presenter.setAttribute("mime", "application/x-kpresenter");
00501     presenter.setAttribute("syntaxVersion", CURRENT_SYNTAX_VERSION);
00502     QDomElement paper=doc.createElement("PAPER");
00503     paper.setAttribute("format", static_cast<int>( m_pageLayout.format ));
00504     paper.setAttribute("ptWidth", QString::number( m_pageLayout.ptWidth, 'g', 10 ));
00505     paper.setAttribute("ptHeight", QString::number( m_pageLayout.ptHeight, 'g', 10 ));
00506 
00507     paper.setAttribute("orientation", static_cast<int>( m_pageLayout.orientation ));
00508     paper.setAttribute("unit", unit() );
00509     paper.setAttribute("tabStopValue", m_tabStop );
00510 
00511     QDomElement paperBorders=doc.createElement("PAPERBORDERS");
00512 
00513     paperBorders.setAttribute("ptLeft", m_pageLayout.ptLeft);
00514     paperBorders.setAttribute("ptTop", m_pageLayout.ptTop);
00515     paperBorders.setAttribute("ptRight", m_pageLayout.ptRight);
00516     paperBorders.setAttribute("ptBottom", m_pageLayout.ptBottom);
00517     paper.appendChild(paperBorders);
00518     presenter.appendChild(paper);
00519 
00520     m_varColl->variableSetting()->save(presenter );
00521 
00522     presenter.appendChild(saveAttribute( doc ));
00523 
00524     if ( saveOnlyPage == -1 )
00525         emit sigProgress( 5 );
00526 
00527     QDomElement element=doc.createElement("BACKGROUND");
00528     element.appendChild(saveBackground( doc ));
00529     presenter.appendChild(element);
00530 
00531     if ( saveOnlyPage == -1 )
00532         emit sigProgress( 10 );
00533 
00534     //TODO save correct page info for header/footer
00535     element=doc.createElement("HEADER");
00536     element.setAttribute("show", static_cast<int>( m_pageList.at(0)->hasHeader() ));
00537     element.appendChild(_header->save( doc,0 ));
00538     presenter.appendChild(element);
00539 
00540     element=doc.createElement("FOOTER");
00541     element.setAttribute("show", static_cast<int>( m_pageList.at(0)->hasFooter() ));
00542     element.appendChild(_footer->save( doc,0 ));
00543     presenter.appendChild(element);
00544 
00545     element = doc.createElement( "HEADERFOOTERBYPAGE" );
00546     element.setAttribute( "value", "true" );
00547     presenter.appendChild( element );
00548 
00549     element=doc.createElement("HELPLINES");
00550     element.setAttribute("show", static_cast<int>( showGuideLines() ));
00551     saveGuideLines( doc, element );
00552     presenter.appendChild(element);
00553 
00554     if ( saveOnlyPage == -1 )
00555     {
00556         if( !m_spellCheckIgnoreList.isEmpty() )
00557         {
00558             QDomElement spellCheckIgnore = doc.createElement( "SPELLCHECKIGNORELIST" );
00559             presenter.appendChild( spellCheckIgnore );
00560             for ( QStringList::Iterator it = m_spellCheckIgnoreList.begin(); it != m_spellCheckIgnoreList.end(); ++it )
00561             {
00562                 QDomElement spellElem = doc.createElement( "SPELLCHECKIGNOREWORD" );
00563                 spellCheckIgnore.appendChild( spellElem );
00564                 spellElem.setAttribute( "word", *it );
00565             }
00566         }
00567     }
00568 
00569     if ( saveOnlyPage == -1 )
00570         emit sigProgress( 20 );
00571 
00572     presenter.appendChild(saveTitle( doc ));
00573 
00574     presenter.appendChild(saveNote( doc ));
00575 
00576     if ( saveOnlyPage == -1 )
00577         emit sigProgress( 30 );
00578 
00579     presenter.appendChild(saveObjects(doc));
00580 
00581     // ### If we will create a new version of the file format, fix that spelling error
00582     element=doc.createElement("INFINITLOOP");
00583     element.setAttribute("value", _spInfiniteLoop);
00584    element=doc.createElement("SHOWENDOFPRESENTATIONSLIDE");
00585    element.setAttribute("value", _spShowEndOfPresentationSlide);
00586     presenter.appendChild(element);
00587     element=doc.createElement("MANUALSWITCH");
00588     element.setAttribute("value", _spManualSwitch);
00589     presenter.appendChild(element);
00590     element=doc.createElement("PRESSPEED");
00591 //TODO FIXME !!!!!!!!!!
00592 //element.setAttribute("value", static_cast<int>( presSpeed ));
00593     presenter.appendChild(element);
00594     element=doc.createElement("SHOWPRESENTATIONDURATION");
00595     element.setAttribute("value", _showPresentationDuration);
00596     presenter.appendChild(element);
00597 
00598     if ( saveOnlyPage == -1 )
00599     {
00600         if ( !m_customListSlideShow.isEmpty() )
00601         {
00602             QMap<KPrPage *, QString> page2name;
00603             int pos = 1;
00604             for ( QPtrListIterator<KPrPage> it( m_pageList ); it.current(); ++it )
00605             {
00606                 page2name.insert( it.current(), "page" + QString::number( pos++ ) ) ;
00607             }
00608 
00609             element = doc.createElement( "CUSTOMSLIDESHOWCONFIG" );
00610             CustomSlideShowMap::Iterator it;
00611             for ( it = m_customListSlideShow.begin(); it != m_customListSlideShow.end(); ++it )
00612             {
00613                 QDomElement slide=doc.createElement("CUSTOMSLIDESHOW");
00614                 slide.setAttribute("name", it.key() );
00615                 QString tmp;
00616                 QValueListIterator<KPrPage*> itPage ;
00617                 for( itPage = ( *it ).begin(); itPage != ( *it ).end(); ++itPage )
00618                 {
00619                     int posPage = m_pageList.find( *itPage );
00620                     if ( posPage != -1 )
00621                     {
00622                         if ( itPage != ( *it ).begin() )
00623                             tmp += ",";
00624                         tmp += page2name[*itPage];
00625                     }
00626                 }
00627                 slide.setAttribute( "pages", tmp );
00628                 element.appendChild(slide);
00629             }
00630             presenter.appendChild(element);
00631 
00632         }
00633 
00634         if ( !m_presentationName.isEmpty() )
00635         {
00636             element = doc.createElement( "DEFAULTCUSTOMSLIDESHOWNAME" );
00637             element.setAttribute( "name", m_presentationName );
00638             presenter.appendChild(element);
00639         }
00640     }
00641 
00642     if ( saveOnlyPage == -1 )
00643         emit sigProgress( 40 );
00644 
00645     if ( saveOnlyPage == -1 )
00646     {
00647         element=doc.createElement("SELSLIDES");
00648         for ( uint i = 0; i < m_pageList.count(); i++ ) {
00649             QDomElement slide=doc.createElement("SLIDE");
00650             slide.setAttribute("nr", i);
00651             slide.setAttribute("show", m_pageList.at(i)->isSlideSelected());
00652             element.appendChild(slide);
00653         }
00654         presenter.appendChild(element);
00655 
00656         emit sigProgress( 50 );
00657     }
00658 
00659     if ( saveOnlyPage == -1 )
00660     {
00661         QDomElement styles = doc.createElement( "STYLES" );
00662         presenter.appendChild( styles );
00663         QValueList<KoUserStyle *> styleList(m_styleColl->styleList());
00664         for ( QValueList<KoUserStyle *>::const_iterator it = styleList.begin(), end = styleList.end();
00665               it != end ; ++it )
00666             saveStyle( static_cast<KoParagStyle *>( *it ), styles );
00667 
00668         emit sigProgress( 60 );
00669     }
00670 
00671     // Write "OBJECT" tag for every child
00672     QPtrListIterator<KoDocumentChild> chl( children() );
00673     for( ; chl.current(); ++chl ) {
00674         // Don't save children that are only in the undo/redo history
00675         // but not anymore in the presentation
00676         for ( int i = 0; i < static_cast<int>( m_pageList.count() ); i++ ) {
00677             if ( saveOnlyPage != -1 && i != saveOnlyPage )
00678                 continue;
00679             double offset=0;
00680             if ( saveOnlyPage == -1 )
00681             {
00682                 offset = i * m_pageList.at(i)->getPageRect().height();
00683             }
00684             saveEmbeddedObject(m_pageList.at(i), chl.current(),doc,presenter,offset );
00685         }
00686         if ( saveOnlyPage == -1 )
00687         {
00688             saveEmbeddedObject(m_masterPage, chl.current(),doc,presenter,0.0 );
00689         }
00690     }
00691 
00692     if ( saveOnlyPage == -1 )
00693         emit sigProgress( 70 );
00694     makeUsedPixmapList();
00695 
00696     QDomElement pictures = m_pictureCollection.saveXML( KoPictureCollection::CollectionPicture, doc, usedPictures );
00697     presenter.appendChild( pictures );
00698 
00699     if ( saveOnlyPage == -1 )
00700         emit sigProgress( 90 );
00701 
00702     // Save sound file list.
00703     makeUsedSoundFileList();
00704     QDomElement soundFiles = saveUsedSoundFileToXML( doc, usedSoundFile );
00705     presenter.appendChild( soundFiles );
00706 
00707     if ( saveOnlyPage == -1 )
00708         setModified( false );
00709     return doc;
00710 }
00711 
00712 void KPrDocument::saveEmbeddedObject(KPrPage *page, const QPtrList<KoDocumentChild>& childList,
00713                                        QDomDocument &doc,QDomElement &presenter )
00714 {
00715     QPtrListIterator<KoDocumentChild> chl( childList );
00716     double offset = 0.0;
00717     // we need no offset for objects on the master page and when we copy a page
00718     if ( m_pageList.findRef( page ) )
00719     {
00720         offset=m_pageList.findRef(page)*page->getPageRect().height();
00721     }
00722     for( ; chl.current(); ++chl )
00723         saveEmbeddedObject(page, chl.current(),doc,presenter, offset );
00724 }
00725 
00726 void KPrDocument::saveEmbeddedObject(KPrPage *page, KoDocumentChild *chl, QDomDocument &doc,
00727                                        QDomElement &presenter, double offset )
00728 {
00729     QPtrListIterator<KPrObject> oIt(page->objectList());
00730     for ( int pos = 0; oIt.current(); ++oIt, ++pos )
00731     {
00732         if ( oIt.current()->getType() == OT_PART &&
00733              static_cast<KPrPartObject*>( oIt.current() )->getChild() == chl )
00734         {
00735             QDomElement embedded=doc.createElement("EMBEDDED");
00736             KPrChild* curr = (KPrChild*)chl;
00737 
00738             // geometry is no zoom value !
00739             QRect _rect = curr->geometry();
00740             int tmpX = (int)zoomHandler()->unzoomItX( _rect.x() );
00741             int tmpY = (int)zoomHandler()->unzoomItY( _rect.y() );
00742             int tmpWidth = (int)zoomHandler()->unzoomItX( _rect.width() );
00743             int tmpHeight = (int)zoomHandler()->unzoomItY( _rect.height() );
00744             curr->setGeometry( QRect( tmpX, tmpY, tmpWidth, tmpHeight ) );
00745 
00746             embedded.appendChild(curr->save(doc, true));
00747 
00748             curr->setGeometry( _rect ); // replace zoom value
00749 
00750             QDomElement settings=doc.createElement("SETTINGS");
00751             settings.setAttribute( "z-index", pos );
00752             if ( page == m_masterPage )
00753                 settings.setAttribute("sticky", 1 );
00754             QPtrListIterator<KPrObject> setOIt(page->objectList());
00755             for (; setOIt.current(); ++setOIt )
00756             {
00757                 if ( setOIt.current()->getType() == OT_PART &&
00758                      dynamic_cast<KPrPartObject*>( setOIt.current() )->getChild() == curr )
00759                     settings.appendChild(setOIt.current()->save( doc,offset ));
00760             }
00761             embedded.appendChild(settings);
00762             presenter.appendChild(embedded);
00763         }
00764     }
00765 
00766 }
00767 
00768 //TODO with changes with new file format header/footer can't be change
00769 void KPrDocument::compatibilityFromOldFileFormat()
00770 {
00771     //function to keep compatibility with old file format
00772     //for example for presSpeed
00773     if ( m_loadingInfo && m_loadingInfo->oldFormat() )
00774     {
00775         EffectSpeed newValue = ES_MEDIUM;
00776         bool presSpeedChanged = ( m_loadingInfo->presSpeed != -1 );
00777         if ( presSpeedChanged )
00778         {
00779             if ( m_loadingInfo->presSpeed < 3 )
00780                 newValue = ES_SLOW;
00781             else if ( m_loadingInfo->presSpeed > 7 )
00782                 newValue = ES_FAST;
00783         }
00784         if ( !m_loadingInfo->m_headerFooterByPage )
00785         {
00786             for ( int i = 0; i < static_cast<int>( m_pageList.count() ); i++ )
00787             {
00788                 if ( presSpeedChanged )
00789                     m_pageList.at(i)->setPageEffectSpeed( newValue );
00790                 m_pageList.at( i )->setHeader( m_loadingInfo->m_header );
00791                 m_pageList.at( i )->setFooter( m_loadingInfo->m_footer );
00792             }
00793         }
00794 
00795     }
00796     delete m_loadingInfo;
00797     m_loadingInfo = 0L;
00798 
00799 }
00800 
00801 void KPrDocument::enableEmbeddedParts( bool f )
00802 {
00803     QPtrListIterator<KPrPage> it( m_pageList );
00804     for ( ; it.current(); ++it )
00805         it.current()->enableEmbeddedParts(f);
00806 }
00807 
00808 QDomDocumentFragment KPrDocument::saveBackground( QDomDocument &doc )
00809 {
00810     QDomDocumentFragment fragment=doc.createDocumentFragment();
00811     for ( int i = 0; i < static_cast<int>( m_pageList.count() ); i++ ) {
00812         if ( saveOnlyPage != -1 && i != saveOnlyPage )
00813             continue;
00814         fragment.appendChild( m_pageList.at(i)->save( doc ) );
00815     }
00816     // save backgound of masterpage only when the complete doc is saved
00817     if ( saveOnlyPage == -1 )
00818     {
00819         fragment.appendChild( m_masterPage->save( doc ) );
00820     }
00821     return fragment;
00822 }
00823 
00824 QDomElement KPrDocument::saveObjects( QDomDocument &doc )
00825 {
00826     QDomElement objects=doc.createElement("OBJECTS");
00827     double yoffset=0.0;
00828     for ( int i = 0; i < static_cast<int>( m_pageList.count() ); i++ ) {
00829         if ( saveOnlyPage != -1 && saveOnlyPage!=i)
00830             continue;
00831         yoffset=i*m_pageList.at(i)->getPageRect().height(); // yoffset is not zoom value !!
00832         objects=m_pageList.at(i)->saveObjects( doc, objects, yoffset, saveOnlyPage );
00833 
00834     }
00835     if ( !_duplicatePage ) //don't copy objects on master slide when we duplicate page
00836     {
00837         objects = m_masterPage->saveObjects( doc, objects, 0.0, saveOnlyPage );
00838     }
00839 
00840     return objects;
00841 }
00842 
00843 QDomElement KPrDocument::saveTitle( QDomDocument &doc )
00844 {
00845     QDomElement titles=doc.createElement("PAGETITLES");
00846 
00847     if ( saveOnlyPage == -1 )
00848     { // All page titles.
00849         for ( int i = 0; i < static_cast<int>( m_pageList.count() ); i++ )
00850         {
00851             QDomElement title=doc.createElement("Title");
00852             title.setAttribute("title", m_pageList.at(i)->manualTitle());
00853             titles.appendChild(title);
00854         }
00855     }
00856     else
00857     { // Only current page title.
00858         QDomElement title=doc.createElement("Title");
00859         title.setAttribute("title", m_pageList.at(saveOnlyPage)->manualTitle());
00860         titles.appendChild(title);
00861     }
00862     return titles;
00863 }
00864 
00865 QDomElement KPrDocument::saveNote( QDomDocument &doc )
00866 {
00867     QDomElement notes=doc.createElement("PAGENOTES");
00868 
00869     if ( saveOnlyPage == -1 ) { // All page notes.
00870         for ( int i = 0; i < static_cast<int>( m_pageList.count() ); i++ )
00871         {
00872             QDomElement note=doc.createElement("Note");
00873             note.setAttribute("note", m_pageList.at(i)->noteText( ));
00874             notes.appendChild(note);
00875         }
00876     }
00877     else { // Only current page note.
00878         QDomElement note=doc.createElement("Note");
00879         note.setAttribute("note", m_pageList.at(saveOnlyPage)->noteText( ));
00880         notes.appendChild(note);
00881     }
00882 
00883     return notes;
00884 }
00885 
00886 QDomElement KPrDocument::saveAttribute( QDomDocument &doc )
00887 {
00888     QDomElement attributes=doc.createElement("ATTRIBUTES");
00889     //store first view parameter.
00890     int activePage=0;
00891 
00892     if ( m_initialActivePage )
00893         activePage=m_pageList.findRef(m_initialActivePage);
00894     activePage = QMAX( activePage, 0);
00895     attributes.setAttribute("activePage",activePage );
00896     attributes.setAttribute("gridx", m_gridX );
00897     attributes.setAttribute("gridy", m_gridY );
00898     attributes.setAttribute("snaptogrid", (int)m_bSnapToGrid );
00899     return attributes;
00900 }
00901 
00902 QDomElement KPrDocument::saveUsedSoundFileToXML( QDomDocument &_doc, QStringList _list )
00903 {
00904     QDomElement soundFiles = _doc.createElement( "SOUNDS" );
00905 
00906     unsigned int i = 0;
00907     QStringList::Iterator it = _list.begin();
00908     for ( ; it != _list.end(); ++it ) {
00909         QString soundFileName = *it;
00910         int position = soundFileName.findRev( '.' );
00911         QString format = soundFileName.right( soundFileName.length() - position - 1 );
00912         QString _name = QString( "sounds/sound%1.%2" ).arg( ++i ).arg( format.lower() );
00913 
00914         QDomElement fileElem = _doc.createElement( "FILE" );
00915         soundFiles.appendChild( fileElem );
00916         fileElem.setAttribute( "filename", soundFileName );
00917         fileElem.setAttribute( "name", _name );
00918     }
00919 
00920     return soundFiles;
00921 }
00922 
00923 bool KPrDocument::completeSaving( KoStore* _store )
00924 {
00925     if ( !_store ) {
00926         if ( saveOnlyPage == -1 ) {
00927             emit sigProgress( 100 );
00928             emit sigProgress( -1 );
00929         }
00930         return true;
00931     }
00932 
00933     m_pictureCollection.saveToStore( KoPictureCollection::CollectionPicture, _store, usedPictures );
00934 
00935     saveUsedSoundFileToStore( _store, usedSoundFile );
00936 
00937     if ( saveOnlyPage == -1 ) {
00938         emit sigProgress( 100 );
00939         emit sigProgress( -1 );
00940     }
00941 
00942     return true;
00943 }
00944 
00945 int KPrDocument::supportedSpecialFormats() const
00946 {
00947     return KoDocument::supportedSpecialFormats();
00948 }
00949 
00950 void KPrDocument::saveUsedSoundFileToStore( KoStore *_store, QStringList _list )
00951 {
00952     unsigned int i = 0;
00953     QStringList::Iterator it = _list.begin();
00954     for ( ; it != _list.end(); ++it ) {
00955         QString soundFileName = *it;
00956         int position = soundFileName.findRev( '.' );
00957         QString format = soundFileName.right( soundFileName.length() - position - 1 );
00958         QString _storeURL = QString( "sounds/sound%1.%2" ).arg( ++i ).arg( format.lower() );
00959 
00960         if ( _store->open( _storeURL ) ) {
00961             KoStoreDevice dev( _store );
00962             QFile _file( soundFileName );
00963             if ( _file.open( IO_ReadOnly ) ) {
00964                 dev.writeBlock( ( _file.readAll() ).data(), _file.size() );
00965                 _file.close();
00966             }
00967             _store->close();
00968         }
00969     }
00970 }
00971 
00972 bool KPrDocument::loadChildren( KoStore* _store )
00973 {
00974     if ( objStartY == 0 && _clean) // Don't do this when inserting a template or a page...
00975     {
00976         QPtrListIterator<KoDocumentChild> it( children() );
00977         for( ; it.current(); ++it ) {
00978             if ( !((KoDocumentChild*)it.current())->loadDocument( _store ) )
00979                 return false;
00980         }
00981     }
00982     else // instead load form the correct child on, m_childCountBeforeInsert has the be set
00983     {
00984         QPtrListIterator<KoDocumentChild> it( children() );
00985         for( int i = 0; it.current(); ++it, ++i ) {
00986             if ( i < m_childCountBeforeInsert )
00987                 continue;
00988             if ( !((KoDocumentChild*)it.current())->loadDocument( _store ) )
00989                 return false;
00990         }
00991     }
00992     return true;
00993 }
00994 
00995 bool KPrDocument::saveOasis( KoStore* store, KoXmlWriter* manifestWriter )
00996 {
00997 
00998     //todo necessary for new format ?
00999     if ( saveOnlyPage == -1 ) {
01000         emit sigProgress( 0 );
01001     }
01002     if ( !store->open( "content.xml" ) )
01003         return false;
01004     m_pictureCollection.assignUniqueIds();
01005     KoStoreDevice contentDev( store );
01006     KoXmlWriter* contentWriter = createOasisXmlWriter( &contentDev, "office:document-content" );
01007 
01008 
01009     m_varColl->variableSetting()->setModificationDate(QDateTime::currentDateTime());
01010     recalcVariables( VT_DATE );
01011     recalcVariables( VT_TIME );
01012     recalcVariables( VT_STATISTIC );
01013     KoGenStyles mainStyles;
01014     KoSavingContext savingContext( mainStyles, 0, false, KoSavingContext::Store );
01015 
01016     // Save user styles as KoGenStyle objects
01017     m_styleColl->saveOasis( mainStyles, KoGenStyle::STYLE_USER, savingContext );
01018 
01019     KTempFile contentTmpFile;
01020     contentTmpFile.setAutoDelete( true );
01021     QFile* tmpFile = contentTmpFile.file();
01022     KoXmlWriter contentTmpWriter( tmpFile, 1 );
01023 
01024 
01025     //For sticky objects
01026     KTempFile stickyTmpFile;
01027     stickyTmpFile.setAutoDelete( true );
01028     QFile* masterStyles = stickyTmpFile.file();
01029     KoXmlWriter stickyTmpWriter( masterStyles, 1 );
01030 
01031 
01032     contentTmpWriter.startElement( "office:body" );
01033     contentTmpWriter.startElement( "office:presentation" );
01034 
01035     saveOasisCustomFied( contentTmpWriter );
01036 
01037     int indexObj = 1;
01038     int partIndexObj = 0;
01039 //save page
01040 
01041     QMap<QString, int> pageNames;
01042 
01043     if ( !_duplicatePage )
01044     {
01045         m_masterPage->saveOasisPage( store, stickyTmpWriter, 0, savingContext, indexObj, partIndexObj, manifestWriter, pageNames );
01046 
01047         // Now mark all autostyles as "for styles.xml" since headers/footers need them
01048         QValueList<KoGenStyles::NamedStyle> autoStyles = mainStyles.styles(  KoGenStyle::STYLE_AUTO );
01049         for ( QValueList<KoGenStyles::NamedStyle>::const_iterator it = autoStyles.begin();
01050                 it != autoStyles.end(); ++it ) {
01051             kdDebug() << "marking for styles.xml:" << (  *it ).name << endl;
01052             mainStyles.markStyleForStylesXml(  ( *it ).name );
01053         }
01054 
01055     }
01056 
01057     if ( saveOnlyPage != -1 )
01058     {
01059         m_pageList.at( saveOnlyPage )->saveOasisPage( store, contentTmpWriter, ( saveOnlyPage+1 ), savingContext, indexObj, partIndexObj , manifestWriter, pageNames );
01060     }
01061     else
01062     {
01063         for ( int i = 0; i < static_cast<int>( m_pageList.count() ); i++ )
01064         {
01065             m_pageList.at( i )->saveOasisPage( store, contentTmpWriter, ( i+1 ), savingContext, indexObj, partIndexObj , manifestWriter, pageNames );
01066         }
01067     }
01068     if ( saveOnlyPage == -1 ) //don't save setting when we save on page
01069     {
01070         QMap<int, QString> page2name;
01071         QMap<QString, int>::ConstIterator it( pageNames.begin() );
01072         for ( ; it != pageNames.end(); ++it )
01073         {
01074             page2name.insert( it.data(), it.key() );
01075         }
01076         saveOasisPresentationSettings( contentTmpWriter, page2name );
01077     }
01078 
01079     contentTmpWriter.endElement(); //office:presentation
01080     contentTmpWriter.endElement(); //office:body
01081 
01082     writeAutomaticStyles( *contentWriter, mainStyles, savingContext, false );
01083 
01084     // And now we can copy over the contents from the tempfile to the real one
01085     tmpFile->close();
01086     contentWriter->addCompleteElement( tmpFile );
01087     contentTmpFile.close();
01088 
01089     contentWriter->endElement(); // root element
01090     contentWriter->endDocument();
01091     delete contentWriter;
01092 
01093     if ( !store->close() ) // done with content.xml
01094         return false;
01095 
01096     //add manifest line for content.xml
01097     manifestWriter->addManifestEntry( "content.xml", "text/xml" );
01098 
01099     if ( !store->open( "styles.xml" ) )
01100         return false;
01101 
01102     manifestWriter->addManifestEntry( "styles.xml", "text/xml" );
01103 
01104     //todo fixme????
01105     masterStyles->close();
01106     saveOasisDocumentStyles( store, mainStyles, masterStyles, savingContext );
01107     stickyTmpFile.close();
01108 
01109     if ( !store->close() ) // done with styles.xml
01110         return false;
01111 
01112 
01113     if ( saveOnlyPage == -1 )
01114         emit sigProgress( 90 );
01115 
01116     // Save sound file list.
01117 //todo ????
01118 
01119 
01120     makeUsedPixmapList();
01121 
01122     m_pictureCollection.saveOasisToStore( store, usedPictures, manifestWriter);
01123 
01124     if(!store->open("settings.xml"))
01125         return false;
01126 
01127     KoXmlWriter& settingsWriter = *createOasisXmlWriter(&contentDev, "office:document-settings");
01128     settingsWriter.startElement("office:settings");
01129 
01130     settingsWriter.startElement("config:config-item-set");
01131     settingsWriter.addAttribute("config:name", "view-settings");
01132 
01133     KoUnit::saveOasis(&settingsWriter, unit());
01134     saveOasisSettings( settingsWriter );
01135 
01136     settingsWriter.endElement(); // config:config-item-set
01137 
01138     settingsWriter.startElement("config:config-item-set");
01139     settingsWriter.addAttribute("config:name", "configuration-settings");
01140     settingsWriter.addConfigItem("SpellCheckerIgnoreList", m_spellCheckIgnoreList.join( "," ) );
01141     settingsWriter.addConfigItem("ShowPresentationDuration", _showPresentationDuration );
01142     settingsWriter.endElement(); // config:config-item-set
01143 
01144     m_varColl->variableSetting()->saveOasis( settingsWriter );
01145 
01146     settingsWriter.endElement(); // office:settings
01147     settingsWriter.endElement(); // Root:Element
01148     settingsWriter.endDocument();
01149     delete &settingsWriter;
01150 
01151     if(!store->close())
01152         return false;
01153 
01154     manifestWriter->addManifestEntry("settings.xml", "text/xml");
01155 
01156     //reset progressbar
01157     emit sigProgress( 100 );
01158     emit sigProgress( -1 );
01159 
01160     setModified( false );
01161 
01162     return true;
01163 }
01164 
01165 void KPrDocument::saveOasisCustomFied( KoXmlWriter &writer )const
01166 {
01167     bool customVariableFound = false;
01168     QPtrListIterator<KoVariable> it( m_varColl->getVariables() );
01169     for ( ; it.current() ; ++it )
01170     {
01171         if ( it.current()->type() == VT_CUSTOM )
01172         {
01173             if ( !customVariableFound )
01174             {
01175                 writer.startElement( "text:user-field-decls" );
01176                 customVariableFound = true;
01177             }
01178             //<text:user-field-decl office:value-type="string" office:string-value="dfddd" text:name="cvbcbcbx"/>
01179             writer.startElement( "text:user-field-decl" );
01180             writer.addAttribute( "office:value-type", "string" );
01181             writer.addAttribute( "office:string-value", static_cast<KoCustomVariable *>( it.current() )->value() );
01182             writer.addAttribute( "text:name", static_cast<KoCustomVariable*>( it.current() )->name() );
01183             writer.endElement();
01184         }
01185     }
01186     if ( customVariableFound )
01187         writer.endElement();
01188 }
01189 
01190 void KPrDocument::loadOasisIgnoreList( const KoOasisSettings& settings )
01191 {
01192     KoOasisSettings::Items configurationSettings = settings.itemSet( "configuration-settings" );
01193     if ( !configurationSettings.isNull() )
01194     {
01195         _showPresentationDuration = configurationSettings.parseConfigItemBool( "ShowPresentationDuration", false );
01196         const QString ignorelist = configurationSettings.parseConfigItemString( "SpellCheckerIgnoreList" );
01197         m_spellCheckIgnoreList = QStringList::split( ',', ignorelist );
01198     }
01199 }
01200 
01201 void KPrDocument::writeAutomaticStyles( KoXmlWriter& contentWriter, KoGenStyles& mainStyles, KoSavingContext& context, bool stylesDotXml )
01202 {
01203     if ( !stylesDotXml )
01204     {
01205         context.writeFontFaces( contentWriter );
01206         contentWriter.startElement( "office:automatic-styles" );
01207     }
01208     QValueList<KoGenStyles::NamedStyle> styles = mainStyles.styles( KoGenStyle::STYLE_AUTO, stylesDotXml );
01209     QValueList<KoGenStyles::NamedStyle>::const_iterator it = styles.begin();
01210     for ( ; it != styles.end() ; ++it ) {
01211         (*it).style->writeStyle( &contentWriter, mainStyles, "style:style", (*it).name, "style:paragraph-properties" );
01212     }
01213 
01214     styles = mainStyles.styles( KoGenStyle::STYLE_AUTO_LIST, stylesDotXml );
01215     it = styles.begin();
01216     for ( ; it != styles.end() ; ++it ) {
01217         ( *it ).style->writeStyle( &contentWriter, mainStyles, "text:list-style", (*it).name, 0 );
01218     }
01219 
01220     styles = mainStyles.styles( STYLE_BACKGROUNDPAGEAUTO, stylesDotXml );
01221     it = styles.begin();
01222     for ( ; it != styles.end() ; ++it ) {
01223         (*it).style->writeStyle( &contentWriter, mainStyles, "style:style", (*it).name, "style:drawing-page-properties" );
01224     }
01225 
01226     styles = mainStyles.styles( KoGenStyle::STYLE_GRAPHICAUTO, stylesDotXml );
01227     it = styles.begin();
01228     for ( ; it != styles.end() ; ++it ) {
01229         (*it).style->writeStyle( &contentWriter, mainStyles, "style:style", (*it).name , "style:graphic-properties"  );
01230     }
01231 
01232     styles = mainStyles.styles( KoGenStyle::STYLE_NUMERIC_DATE, stylesDotXml );
01233     it = styles.begin();
01234     for ( ; it != styles.end() ; ++it ) {
01235         (*it).style->writeStyle( &contentWriter, mainStyles, "number:date-style", (*it).name, 0 /*TODO ????*/  );
01236     }
01237     styles = mainStyles.styles( KoGenStyle::STYLE_NUMERIC_TIME, stylesDotXml );
01238     it = styles.begin();
01239     for ( ; it != styles.end() ; ++it ) {
01240         (*it).style->writeStyle( &contentWriter, mainStyles, "number:time-style", (*it).name, 0 /*TODO ????*/  );
01241     }
01242 
01243     if ( !stylesDotXml )
01244     {
01245         contentWriter.endElement(); // office:automatic-styles
01246     }
01247 }
01248 
01249 void KPrDocument::loadOasisHeaderFooter(QDomNode & drawPage, KoOasisContext & context)
01250 {
01251     QDomNode tmp = KoDom::namedItemNS( drawPage, KoXmlNS::style, "header" );
01252     if ( !tmp.isNull() )
01253     {
01254         //kdDebug()<<" there is a header \n";
01255         _header->textObject()->loadOasisContent( tmp.toElement(), context, styleCollection() );
01256     }
01257     tmp = KoDom::namedItemNS( drawPage, KoXmlNS::style, "footer" );
01258     if ( !tmp.isNull() )
01259     {
01260         //kdDebug()<<" there is a footer \n";
01261         _footer->textObject()->loadOasisContent( tmp.toElement(), context, styleCollection() );
01262     }
01263 }
01264 
01265 void KPrDocument::saveOasisSettings( KoXmlWriter &settingsWriter )
01266 {
01267     settingsWriter.startElement("config:config-item-map-indexed");
01268     settingsWriter.addAttribute("config:name", "Views");
01269     settingsWriter.startElement( "config:config-item-map-entry" );
01270 
01271     //ooimpress save it as this line.
01272     //<config:config-item config:name="SnapLinesDrawing" config:type="string">H2260V14397H7693H12415H15345H1424</config:config-item>
01273     QString guideLinesOasis;
01274     //save in mm as in oo
01275     for( QValueList<double>::Iterator it = m_vGuideLines.begin(); it != m_vGuideLines.end(); ++it )
01276     {
01277         int tmpX = ( int ) ( KoUnit::toMM( *it  )*100 );
01278         guideLinesOasis += "V" + QString::number( tmpX );
01279     }
01280 
01281     for( QValueList<double>::Iterator it = m_hGuideLines.begin(); it != m_hGuideLines.end(); ++it )
01282     {
01283         int tmpY = ( int ) ( KoUnit::toMM( *it  )*100 );
01284         guideLinesOasis += "H" + QString::number( tmpY );
01285     }
01286     if ( !guideLinesOasis.isEmpty() )
01287     {
01288         settingsWriter.addConfigItem( "SnapLinesDrawing", guideLinesOasis );
01289     }
01290     //<config:config-item config:name="IsSnapToGrid" config:type="boolean">false</config:config-item>
01291     settingsWriter.addConfigItem( "IsSnapToGrid", m_bSnapToGrid );
01292 
01293     //<config:config-item config:name="GridFineWidth" config:type="int">500</config:config-item>
01294     settingsWriter.addConfigItem( "GridFineWidth", ( ( int ) ( KoUnit::toMM( ( m_gridX )  )*100 ) ) );
01295 
01296 
01297     //<config:config-item config:name="GridFineHeight" config:type="int">500</config:config-item>
01298     settingsWriter.addConfigItem( "GridFineHeight", ( ( int ) ( KoUnit::toMM( ( m_gridY )  )*100 ) ) );
01299 
01300     //<config:config-item config:name="SelectedPage" config:type="short">3</config:config-item>
01301     //store first view parameter.
01302     int activePage=0;
01303     if ( m_initialActivePage )
01304         activePage=m_pageList.findRef(m_initialActivePage);
01305     activePage = QMAX( activePage, 0);
01306     settingsWriter.addConfigItem( "SelectedPage", activePage );
01307 
01308     //not define into oo spec
01309     settingsWriter.addConfigItem( "SnapLineIsVisible", showGuideLines() );
01310     settingsWriter.endElement();
01311     settingsWriter.endElement();
01312 }
01313 
01314 void KPrDocument::loadOasisSettings(const QDomDocument&settingsDoc)
01315 {
01316     kdDebug(33001)<<"void KPrDocument::loadOasisSettings(const QDomDocument&settingsDoc)**********\n";
01317     KoOasisSettings settings( settingsDoc );
01318     KoOasisSettings::Items viewSettings = settings.itemSet( "view-settings" );
01319     setUnit(KoUnit::unit(viewSettings.parseConfigItemString("unit")));
01320     KoOasisSettings::IndexedMap viewMap = viewSettings.indexedMap( "Views" );
01321     KoOasisSettings::Items firstView = viewMap.entry( 0 );
01322     if ( !firstView.isNull() )
01323     {
01324         parseOasisGuideLines( firstView.parseConfigItemString( "SnapLinesDrawing" ) );
01325         setShowGuideLines( firstView.parseConfigItemBool( "SnapLineIsVisible" ) );
01326         int valx = firstView.parseConfigItemInt( "GridFineWidth" );
01327         m_gridX = MM_TO_POINT( valx / 100.0 );
01328         int valy = firstView.parseConfigItemInt( "GridFineHeight" );
01329         m_gridY = MM_TO_POINT( valy / 100.0 );
01330 
01331         m_bSnapToGrid = firstView.parseConfigItemBool( "IsSnapToGrid" );
01332 
01333         int activePage = firstView.parseConfigItemInt( "SelectedPage" );
01334         kdDebug(33001)<<" activePage :"<<activePage<<endl;
01335         if(activePage!=-1)
01336             m_initialActivePage=m_pageList.at(activePage);
01337     }
01338     loadOasisIgnoreList( settings );
01339     m_varColl->variableSetting()->loadOasis( settings );
01340 }
01341 
01342 void KPrDocument::parseOasisGuideLines( const QString &text )
01343 {
01344     QString str;
01345     int newPos = text.length()-1; //start to element = 1
01346     for ( int pos = text.length()-1; pos >=0;--pos )
01347     {
01348         if ( text[pos]=='V' )
01349         {
01350             //vertical element
01351             str = text.mid( pos+1, ( newPos-pos ) );
01352             //kdDebug()<<" vertical  :"<< str <<endl;
01353             double posX = ( str.toInt() / 100.0 );
01354             m_vGuideLines.append( MM_TO_POINT( posX ) );
01355             newPos = pos-1;
01356         }
01357         else if ( text[pos]=='H' )
01358         {
01359             //horizontal element
01360             str = text.mid( pos+1, ( newPos-pos ) );
01361             //kdDebug()<<" horizontal  :"<< str <<endl;
01362             double posY = ( str.toInt() / 100.0 );
01363             m_hGuideLines.append( MM_TO_POINT( posY ) );
01364             newPos = pos-1;
01365         }
01366     }
01367 }
01368 
01369 void KPrDocument::loadOasisPresentationSettings( QDomNode &settingsDoc )
01370 {
01371     //kdDebug()<<"presentation:settings ********************************************* \n";
01372     QDomElement settings( settingsDoc.toElement() );
01373     //kdDebug()<<"settings.attribute(presentation:endless) :"<<settings.attributeNS( KoXmlNS::presentation, "endless", QString::null)<<endl;
01374     if (settings.attributeNS( KoXmlNS::presentation, "endless", QString::null)=="true")
01375         _spInfiniteLoop = true;
01376    if (settings.attributeNS( KoXmlNS::presentation, "show-end-of-presentation-slide", QString::null)=="true")
01377        _spShowEndOfPresentationSlide = true;
01378     if (settings.attributeNS( KoXmlNS::presentation, "force-manual", QString::null)=="true")
01379         _spManualSwitch = true;
01380     if ( settings.hasAttributeNS( KoXmlNS::presentation, "start-page" ) )
01381     {
01382         //TODO allow to start presentation to specific page
01383         //???? = settings.attributeNS( KoXmlNS::presentation, "start-page", QString::null );
01384     }
01385     if ( settings.hasAttributeNS( KoXmlNS::presentation, "show" ) )
01386     {
01387         m_presentationName = settings.attributeNS( KoXmlNS::presentation, "show", QString::null );
01388         kdDebug()<<" default presentation name :"<<m_presentationName<<endl;
01389     }
01390     loadOasisPresentationCustomSlideShow( settingsDoc );
01391 }
01392 
01393 void KPrDocument::loadOasisPresentationCustomSlideShow( QDomNode &settingsDoc )
01394 {
01395     //kdDebug()<<"void KPrDocument::loadOasisPresentationCustomSlideShow( QDomNode &settingsDoc )**********\n";
01396     for ( QDomNode element = settingsDoc.firstChild(); !element.isNull(); element = element.nextSibling() )
01397     {
01398         QDomElement e = element.toElement();
01399         QCString tagName = e.tagName().latin1();
01400         //kdDebug()<<" tagName :"<<tagName<<endl;
01401         if ( tagName == "show" && e.namespaceURI() == KoXmlNS::presentation )
01402         {
01403             //kdDebug()<<" e.attribute(presentation:name) :"<<e.attributeNS( KoXmlNS::presentation, "name", QString::null)<< " e.attribute(presentation:pages) :"<<e.attributeNS( KoXmlNS::presentation, "pages", QString::null)<<endl;
01404             QString name = e.attributeNS( KoXmlNS::presentation, "name", QString::null );
01405             QStringList tmp = QStringList::split( ",", e.attributeNS( KoXmlNS::presentation, "pages", QString::null) );
01406             QValueList<KPrPage *> pageList;
01407             for ( QStringList::Iterator it = tmp.begin(); it != tmp.end(); ++it )
01408             {
01409                 if ( m_loadingInfo->m_name2page.contains( *it ) )
01410                 {
01411                     kdDebug(33001) << "slide show " << name << " page = " << *it << endl;
01412                     pageList.push_back( m_loadingInfo->m_name2page[*it] );
01413                 }
01414             }
01415             if ( ! pageList.empty() )
01416             {
01417                 m_customListSlideShow.insert( name, pageList );
01418             }
01419         }
01420     }
01421 }
01422 
01423 void KPrDocument::saveOasisPresentationSettings( KoXmlWriter &contentTmpWriter, QMap<int, QString> &page2name )
01424 {
01425     //todo don't save when is not value by default (check with oo)
01426     //FIXME
01427     contentTmpWriter.startElement( "presentation:settings" );
01428     contentTmpWriter.addAttribute( "presentation:endless",  ( _spInfiniteLoop ? "true" : "false" ) );
01429     contentTmpWriter.addAttribute( "presentation:show-end-of-presentation-slide",  ( _spShowEndOfPresentationSlide ? "true" : "false" ) );
01430     contentTmpWriter.addAttribute( "presentation:force-manual",  ( _spManualSwitch ? "true" : "false" ) );
01431     //add for default presentation
01432     if ( !m_presentationName.isEmpty() )
01433         contentTmpWriter.addAttribute( "presentation:show",  m_presentationName );
01434 
01435     saveOasisPresentationCustomSlideShow( contentTmpWriter, page2name );
01436     contentTmpWriter.endElement();
01437 }
01438 
01439 void KPrDocument::saveOasisPresentationCustomSlideShow( KoXmlWriter &contentTmpWriter, QMap<int, QString> &page2name )
01440 {
01441     if ( m_customListSlideShow.isEmpty() )
01442         return;
01443 
01444     CustomSlideShowMap::Iterator it;
01445     for ( it = m_customListSlideShow.begin(); it != m_customListSlideShow.end(); ++it )
01446     {
01447         contentTmpWriter.startElement( "presentation:show" );
01448         contentTmpWriter.addAttribute( "presentation:name", it.key() );
01449         QString tmp;
01450         QValueListIterator<KPrPage*> itPage ;
01451         for( itPage = ( *it ).begin(); itPage != ( *it ).end(); ++itPage )
01452         {
01453             int posPage = m_pageList.find(*itPage );
01454             if ( posPage != -1 )
01455             {
01456                 if ( itPage != ( *it ).begin() )
01457                     tmp += ",";
01458                 //tmp+=( *itPage )->oasisNamePage(posPage+1)+",";
01459                 tmp += page2name[posPage + 1];
01460             }
01461         }
01462         contentTmpWriter.addAttribute( "presentation:pages", tmp );
01463         contentTmpWriter.endElement();
01464     }
01465     //<presentation:show presentation:name="New Custom Slide Show" presentation:pages="page1,page1,page1,page1,page1"/>
01466 }
01467 
01468 void KPrDocument::saveOasisDocumentStyles( KoStore* store, KoGenStyles& mainStyles, QFile* masterStyles,
01469                                            KoSavingContext & savingContext, SaveFlag saveFlag ) const
01470 {
01471     KoStoreDevice stylesDev( store );
01472     KoXmlWriter* stylesWriter = createOasisXmlWriter( &stylesDev, "office:document-styles" );
01473 
01474     // Yeah we need to save the same font faces in both content.xml and styles.xml... 
01475     savingContext.writeFontFaces(  *stylesWriter ); 
01476           
01477     stylesWriter->startElement( "office:styles" );
01478     QValueList<KoGenStyles::NamedStyle> styles = mainStyles.styles( KoGenStyle::STYLE_USER );
01479     QValueList<KoGenStyles::NamedStyle>::const_iterator it = styles.begin();
01480     for ( ; it != styles.end() ; ++it ) {
01481         (*it).style->writeStyle( stylesWriter, mainStyles, "style:style", (*it).name, "style:paragraph-properties" );
01482     }
01483     styles = mainStyles.styles( KoGenStyle::STYLE_LIST );
01484     it = styles.begin();
01485     for ( ; it != styles.end() ; ++it ) {
01486         (*it).style->writeStyle( stylesWriter, mainStyles, "text:list-style", (*it).name, 0 );
01487     }
01488     styles = mainStyles.styles( KoGenStyle::STYLE_HATCH );
01489     it = styles.begin();
01490     for ( ; it != styles.end() ; ++it ) {
01491         (*it).style->writeStyle( stylesWriter, mainStyles, "draw:hatch", (*it).name, "style:graphic-properties" ,  true,  true /*add draw:name*/);
01492     }
01493     styles = mainStyles.styles( STYLE_GRADIENT );
01494     it = styles.begin();
01495     for ( ; it != styles.end() ; ++it ) {
01496         (*it).style->writeStyle( stylesWriter, mainStyles, "draw:gradient", (*it).name, "style:graphic-properties" ,  true,  true /*add draw:name*/);
01497     }
01498 
01499     styles = mainStyles.styles( STYLE_STROKE );
01500     it = styles.begin();
01501     for ( ; it != styles.end() ; ++it ) {
01502         (*it).style->writeStyle( stylesWriter, mainStyles, "draw:stroke-dash", (*it).name, "style:graphic-properties" ,  true,  true /*add draw:name*/);
01503     }
01504 
01505     styles = mainStyles.styles( STYLE_MARKER );
01506     it = styles.begin();
01507     for ( ; it != styles.end() ; ++it ) {
01508         (*it).style->writeStyle( stylesWriter, mainStyles, "draw:marker", (*it).name, "style:graphic-properties" ,  true,  true /*add draw:name*/);
01509     }
01510     styles = mainStyles.styles( STYLE_PICTURE );
01511     it = styles.begin();
01512     for ( ; it != styles.end() ; ++it ) {
01513         (*it).style->writeStyle( stylesWriter, mainStyles, "draw:fill-image", (*it).name, "style:image-properties" ,  true,  true /*add draw:name*/);
01514     }
01515 
01516     stylesWriter->endElement(); // office:styles
01517 
01518     if ( saveFlag == SaveAll )
01519     {
01520         stylesWriter->startElement( "office:automatic-styles" );
01521         // this has to be the first
01522         if ( masterStyles )
01523         {
01524             writeAutomaticStyles( *stylesWriter, mainStyles, savingContext, true );
01525         }
01526 
01527         styles = mainStyles.styles( STYLE_BACKGROUNDPAGE );
01528         it = styles.begin();
01529         for ( ; it != styles.end() ; ++it ) {
01530             (*it).style->writeStyle( stylesWriter, mainStyles, "style:style", (*it).name , "style:drawing-page-properties"  );
01531         }
01532 
01533         // if there's more than one pagemaster we need to rethink all this
01534         styles = mainStyles.styles( KoGenStyle::STYLE_PAGELAYOUT );
01535         Q_ASSERT( styles.count() == 1 );
01536         it = styles.begin();
01537         for ( ; it != styles.end() ; ++it ) {
01538             (*it).style->writeStyle( stylesWriter, mainStyles, "style:page-layout", (*it).name, "style:page-layout-properties", false /*don't close*/ );
01539             stylesWriter->endElement();
01540         }
01541 
01542         styles = mainStyles.styles( STYLE_PRESENTATIONSTICKYOBJECT );
01543         it = styles.begin();
01544         for ( ; it != styles.end() ; ++it ) {
01545             //TODO fix me graphic-properties ???
01546             (*it).style->writeStyle( stylesWriter, mainStyles, "style:style", (*it).name , "style:graphic-properties"  );
01547         }
01548 
01549         stylesWriter->endElement(); // office:automatic-styles
01550 
01551 
01552         if ( masterStyles )
01553         {
01554             stylesWriter->startElement( "office:master-styles" );
01555             stylesWriter->addCompleteElement( masterStyles );
01556             stylesWriter->endElement();
01557         }
01558     }
01559 
01560     stylesWriter->endElement(); // root element (office:document-styles)
01561     stylesWriter->endDocument();
01562     delete stylesWriter;
01563 }
01564 
01565 bool KPrDocument::loadOasis( const QDomDocument& doc, KoOasisStyles&oasisStyles, const QDomDocument&settingsDoc, KoStore*store )
01566 {
01567     QTime dt;
01568     dt.start();
01569     m_loadingInfo = new KPrLoadingInfo;
01570     ignoreSticky = FALSE;
01571     emit sigProgress( 0 );
01572 
01573     lastObj = -1;
01574     // clean
01575     if ( _clean ) {
01576         m_styleColl->clear();
01577         // Some simple import filters don't define any style,
01578         // so let's have a Standard style at least
01579         KoParagStyle * standardStyle = new KoParagStyle( "Standard" ); // This gets translated later on
01580         //kdDebug() << "KWDocument::KWDocument creating standardStyle " << standardStyle << endl;
01581         standardStyle->format().setFont( m_defaultFont );
01582         m_styleColl->addStyle( standardStyle );
01583 
01584         __pgLayout = KoPageLayout::standardLayout();
01585         _spInfiniteLoop = false;
01586         _spShowEndOfPresentationSlide = true;
01587         _spManualSwitch = true;
01588         _showPresentationDuration = false;
01589         _xRnd = 20;
01590         _yRnd = 20;
01591         urlIntern = url().path();
01592     }
01593     else
01594         m_spellCheckIgnoreList.clear();
01595     emit sigProgress( 5 );
01596 
01597     QDomElement content = doc.documentElement();
01598     QDomElement realBody (KoDom::namedItemNS( content, KoXmlNS::office, "body" ) );
01599     if ( realBody.isNull() )
01600     {
01601         kdError(33001) << "No office:body found!" << endl;
01602         setErrorMessage( i18n( "Invalid OASIS OpenDocument file. No office:body tag found." ) );
01603         return false;
01604     }
01605     QDomElement body = KoDom::namedItemNS( realBody, KoXmlNS::office, "presentation" );
01606     if ( body.isNull() )
01607     {
01608         kdError(33001) << "No office:presentation found!" << endl;
01609         QDomElement childElem;
01610         QString localName;
01611         forEachElement( childElem, realBody ) {
01612             localName = childElem.localName();
01613         }
01614         if ( localName.isEmpty() )
01615             setErrorMessage( i18n( "Invalid OASIS OpenDocument file. No tag found inside office:body." ) );
01616         else
01617             setErrorMessage( i18n( "This document is not a presentation, but a %1. Please try opening it with the appropriate application." ).arg( KoDocument::tagNameToDocumentType( localName ) ) );
01618         return false;
01619     }
01620 
01621     // it seems that ooimpress has different paper-settings for every slide.
01622     // we take the settings of the first slide for the whole document.
01623     QDomNode drawPage = KoDom::namedItemNS( body, KoXmlNS::draw, "page" );
01624     if ( drawPage.isNull() ) // no slides? give up.
01625         return false;
01626     QDomElement dp = drawPage.toElement();
01627 
01628     //code from kword
01629     // TODO variable settings
01630     // By default display real variable value
01631     if ( !isReadWrite())
01632         getVariableCollection()->variableSetting()->setDisplayFieldCode(false);
01633 
01634     KoOasisContext context( this, *m_varColl, oasisStyles, store );
01635     Q_ASSERT( !oasisStyles.officeStyle().isNull() );
01636 
01637     // Load all styles before the corresponding paragraphs try to use them!
01638     m_styleColl->loadOasisStyles( context );
01639 
01640     // if we only copy a page we have no master
01641     // also don't copy master when you insert file as long as we don't have multiple masters
01642     if ( !m_pageWhereLoadObject && _clean )
01643     {
01644         QString masterPageName = drawPage.toElement().attributeNS( KoXmlNS::draw, "master-page-name", QString::null );
01645         QDomElement *master = oasisStyles.masterPages()[ masterPageName];
01646 
01647         kdDebug()<<" master :"<<master<<endl;
01648         kdDebug()<<" masterPageName:"<<masterPageName<<endl;
01649         if ( ! master )
01650         {
01651             masterPageName = "Standard"; // use default layout as fallback (default in kpresenter)
01652             master = oasisStyles.masterPages()[ masterPageName];
01653             if ( !master ) //last test...
01654                 master = oasisStyles.masterPages()["Default"];
01655         }
01656 
01657         if ( master == 0 )
01658         {
01659             setErrorMessage( i18n( "Invalid OASIS OpenDocument file. No master-style found inside office:master-styles." ) );
01660             return false;
01661         }
01662 
01663         kdDebug()<<" load oasis master styles\n";
01664         QDomNode node = *master;
01665         QDomElement masterElement = node.toElement();
01666         kdDebug()<<" node.isNull() :"<<node.isNull()<< ", " << masterElement.attributeNS( KoXmlNS::draw, "style-name", QString::null ) << endl;
01667         // add the correct styles
01668         const QDomElement* masterPageStyle = context.oasisStyles().findStyleAutoStyle( masterElement.attributeNS( KoXmlNS::draw, "style-name", QString::null ), "drawing-page" );
01669         if (masterPageStyle)
01670             context.styleStack().push( *masterPageStyle );
01671 
01672         context.setUseStylesAutoStyles( true );
01673         m_masterPage->loadOasis( context );
01674 
01675         createPresentationAnimation( KoDom::namedItemNS( node, KoXmlNS::presentation, "animations"));
01676 
01677         loadOasisObject( m_masterPage, node , context);
01678 
01679         m_loadingInfo->clearAnimationShowDict(); // clear all show animations style
01680         m_loadingInfo->clearAnimationHideDict(); // clear all hide animations style
01681 
01682         loadOasisHeaderFooter( node,context );
01683         context.setUseStylesAutoStyles( false );
01684 
01685         kdDebug()<<" end load oasis master style \n";
01686 
01687         Q_ASSERT( master );
01688         const QDomElement *style = master ? oasisStyles.findStyle(master->attributeNS( KoXmlNS::style, "page-layout-name", QString::null )) : 0;
01689         const QDomElement *backgroundStyle = oasisStyles.findStyle( "Standard-background", "presentation" );
01690         kdDebug()<<"Standard background "<<backgroundStyle<<endl;
01691         // parse all pages
01692         Q_ASSERT( style );
01693         if ( style )
01694         {
01695             __pgLayout.loadOasis( *style );
01696             kdDebug()<<"Page size __pgLayout.ptWidth :"<<__pgLayout.ptWidth<<" __pgLayout.ptHeight :"<<__pgLayout.ptHeight<<endl;
01697             kdDebug()<<"Page orientation :"<<(( __pgLayout.orientation== PG_LANDSCAPE )? " landscape " : " portrait ")<<endl;
01698 
01699             kdDebug()<<" margin right:"<< __pgLayout.ptRight <<" __pgLayout.ptBottom :"<<__pgLayout.ptBottom<<" __pgLayout.ptLeft :"<<__pgLayout.ptLeft<<" __pgLayout.ptTop :"<<__pgLayout.ptTop<<endl;
01700         }
01701         if ( _clean )
01702         {
01704             setPageLayout( __pgLayout );
01705         }
01706     }
01707 
01708     int pos = m_insertFilePage;
01709     for ( drawPage = body.firstChild(); !drawPage.isNull(); drawPage = drawPage.nextSibling() )
01710     {
01711         dp = drawPage.toElement();
01712         kdDebug()<<"dp.tagName() :"<<dp.tagName()<<endl;
01713         if ( dp.tagName()== "page" && dp.namespaceURI() == KoXmlNS::draw ) // don't try to parse "</draw:page>" as page
01714         {
01715             context.styleStack().clear(); // remove all styles
01716             fillStyleStack( dp, context, "drawing-page" );
01717             context.styleStack().save();
01718             kdDebug ()<<"insert new page "<<pos<<endl;
01719             KPrPage *newpage = 0L;
01720             if ( m_pageWhereLoadObject )
01721             {
01722                 newpage = m_pageWhereLoadObject;
01723             }
01724             else
01725             {
01726                 if ( pos != 0 )
01727                 {
01728                     newpage = new KPrPage( this, m_masterPage );
01729                     m_pageList.insert( pos,newpage);
01730                 }
01731                 else //we create a first page into KPrDocument()
01732                 {
01733                     newpage = m_pageList.at(pos);
01734                 }
01735             }
01736             //only set the manual title if it is different to the draw:id. Only in this case it had one.
01737             QString str = dp.attributeNS( KoXmlNS::draw, "name", QString::null );
01738             m_loadingInfo->m_name2page.insert( str, newpage );
01739             QString idPage = dp.attributeNS( KoXmlNS::draw, "id", QString::null );
01740 
01741             if ( dp.hasAttributeNS( KoXmlNS::koffice, "name" ) )
01742             {
01743                 str = dp.attributeNS( KoXmlNS::koffice, "name", QString::null );
01744                 newpage->insertManualTitle(str);
01745             }
01746             else
01747             {
01748                 // OO uses /page[0-9]+$/ as default for no name set
01749                 QRegExp rx( "^page[0-9]+$" );
01750                 if ( rx.search( str ) == -1 )
01751                     newpage->insertManualTitle(str);
01752             }
01753             context.styleStack().setTypeProperties( "drawing-page" );
01754 
01755             newpage->loadOasis( context );
01756 
01757             //All animation object for current page is store into this element
01758             createPresentationAnimation(KoDom::namedItemNS( drawPage, KoXmlNS::presentation, "animations"));
01759             // parse all objects
01760             loadOasisObject( newpage, drawPage, context );
01761 
01762             context.styleStack().restore();
01763             m_loadingInfo->clearAnimationShowDict(); // clear all show animations style
01764             m_loadingInfo->clearAnimationHideDict(); // clear all hide animations style
01765             ++pos;
01766         }
01767     }
01768 
01769     //load settings at the end as we need to know what the draw:name of a page is
01770     QDomNode settings  = KoDom::namedItemNS( body, KoXmlNS::presentation, "settings" );
01771     kdDebug()<<"settings :"<<settings.isNull()<<endl;
01772     if (!settings.isNull() && _clean /*don't load settings when we copy/paste a page*/)
01773         loadOasisPresentationSettings( settings );
01774 
01775     ignoreSticky = TRUE;
01776     kdDebug()<<" _clean :"<<_clean<<endl;
01777     if(_clean)
01778     {
01779         setModified(false);
01780 #if 0   //FIXME
01781         //it crashed, I don't know why for the moment.
01782         startBackgroundSpellCheck();
01783 #endif
01784     }
01785     kdDebug(33001) << "Loading took " << (float)(dt.elapsed()) / 1000.0 << " seconds" << endl;
01786 
01787     if ( !settingsDoc.isNull() )
01788     {
01789         loadOasisSettings( settingsDoc );
01790     }
01791 
01792     // set the initial active page
01793     if ( m_initialActivePage == 0 )
01794     {
01795         m_initialActivePage = m_pageList.at( 0 );
01796     }
01797 
01798     emit sigProgress( 100 );
01799     recalcVariables( VT_ALL );
01800     emit sigProgress( -1 );
01801 
01802     setModified( false );
01803     return true;
01804 }
01805 
01806 
01807 void KPrDocument::loadOasisObject( KPrPage * newpage, QDomNode & drawPage, KoOasisContext & context, KPrGroupObject *groupObject )
01808 {
01809     for ( QDomNode object = drawPage.firstChild(); !object.isNull(); object = object.nextSibling() )
01810     {
01811         QDomElement o = object.toElement();
01812         QString name = o.tagName();
01813         if ( !name.isEmpty() )
01814         {
01815             kdDebug()<<" name :"<<name<<endl;
01816             if ( o.hasAttributeNS( KoXmlNS::presentation, "placeholder" ) &&
01817                  o.attributeNS( KoXmlNS::presentation, "placeholder", QString::null ) == "true" )
01818             {
01819                 kdDebug(33001) << "Placeholder" << endl;
01820                 continue;
01821             }
01822             context.styleStack().save();
01823             const bool isDrawNS = o.namespaceURI() == KoXmlNS::draw;
01824             // draw:frame
01825             if ( name == "frame" && isDrawNS )
01826             {
01827                 fillStyleStack( o, context, "graphic" );
01828                 QDomElement elem;
01829                 forEachElement( elem, o )
01830                 {
01831                     if ( elem.namespaceURI() != KoXmlNS::draw )
01832                         continue;
01833                     const QString localName = elem.localName();
01834                     if ( localName == "text-box" )
01835                     {
01836                         KPrTextObject *kptextobject = new KPrTextObject( this );
01837                         kptextobject->loadOasis(o, context, m_loadingInfo);
01838                         if ( groupObject )
01839                             groupObject->addObjects( kptextobject );
01840                         else
01841                             newpage->appendObject(kptextobject);
01842                         break;
01843                     }
01844                     else if ( localName == "image" )
01845                     {
01846                         KPrPixmapObject *kppixmapobject = new KPrPixmapObject( pictureCollection() );
01847                         kppixmapobject->loadOasis( o, context, m_loadingInfo);
01848                         if ( groupObject )
01849                             groupObject->addObjects( kppixmapobject );
01850                         else
01851                             newpage->appendObject(kppixmapobject);
01852                         break;
01853                     }
01854                     else if ( localName == "object" )
01855                     {
01856                         KPrChild *ch = new KPrChild( this );
01857                         QRect r;
01858                         KPrPartObject *kppartobject = new KPrPartObject( ch );
01859                         kppartobject->loadOasis( o, context, m_loadingInfo );
01860                         r = ch->geometry();
01861                         if ( groupObject )
01862                             groupObject->addObjects( kppartobject );
01863                         else
01864                             newpage->appendObject(kppartobject);
01865                         insertChild( ch );
01866                         kppartobject->setOrig( r.x(), r.y() );
01867                         kppartobject->setSize( r.width(), r.height() );
01868                         break;
01869                     }
01870                 }
01871             }
01872             else if ( name == "rect" && isDrawNS) // rectangle
01873             {
01874                 fillStyleStack( o, context, "graphic" );
01875                 KPrRectObject *kprectobject = new KPrRectObject();
01876                 kprectobject->loadOasis(o, context , m_loadingInfo);
01877                 if ( groupObject )
01878                     groupObject->addObjects( kprectobject );
01879                 else
01880                     newpage->appendObject(kprectobject);
01881             }
01882             else if ( ( name == "circle" || name == "ellipse" )&& isDrawNS)
01883             {
01884                 fillStyleStack( o, context, "graphic" );
01885                 if ( o.hasAttributeNS( KoXmlNS::draw, "kind" ) ) // pie, chord or arc
01886                 {
01887                     KPrPieObject *kppieobject = new KPrPieObject();
01888                     kppieobject->loadOasis(o, context, m_loadingInfo);
01889                     if ( groupObject )
01890                         groupObject->addObjects( kppieobject );
01891                     else
01892                         newpage->appendObject(kppieobject);
01893                 }
01894                 else  // circle or ellipse
01895                 {
01896                     KPrEllipseObject *kpellipseobject = new KPrEllipseObject();
01897                     kpellipseobject->loadOasis(o,context, m_loadingInfo);
01898                     if ( groupObject )
01899                         groupObject->addObjects( kpellipseobject );
01900                     else
01901                         newpage->appendObject(kpellipseobject);
01902                 }
01903             }
01904             else if ( name == "line" && isDrawNS) // line
01905             {
01906                 fillStyleStack( o, context, "graphic" );
01907                 KPrLineObject *kplineobject = new KPrLineObject();
01908                 kplineobject->loadOasis(o, context, m_loadingInfo);
01909                 if ( groupObject )
01910                     groupObject->addObjects( kplineobject );
01911                 else
01912                     newpage->appendObject( kplineobject );
01913             }
01914             else if (name=="polyline" && isDrawNS) { // polyline
01915                 fillStyleStack( o, context, "graphic" );
01916                 KPrPolylineObject *kppolylineobject = new KPrPolylineObject();
01917                 kppolylineobject->loadOasis(o, context, m_loadingInfo);
01918                 if ( groupObject )
01919                     groupObject->addObjects( kppolylineobject );
01920                 else
01921                     newpage->appendObject(kppolylineobject);
01922             }
01923             else if (name=="polygon" && isDrawNS) { // plcloseobject
01924                 fillStyleStack( o, context, "graphic" );
01925                 KPrClosedLineObject *kpClosedObject = new KPrClosedLineObject();
01926                 kpClosedObject->loadOasis( o, context, m_loadingInfo);
01927                 if ( groupObject )
01928                     groupObject->addObjects( kpClosedObject );
01929                 else
01930                     newpage->appendObject(kpClosedObject);
01931             }
01932             else if (name=="regular-polygon"&& isDrawNS) { // kppolygone object
01933                 fillStyleStack( o, context, "graphic" );
01934                 KPrPolygonObject *kpPolygoneObject = new KPrPolygonObject();
01935                 kpPolygoneObject->loadOasis( o, context, m_loadingInfo);
01936                 if ( groupObject )
01937                     groupObject->addObjects( kpPolygoneObject );
01938                 else
01939                     newpage->appendObject(kpPolygoneObject);
01940             }
01941             else if ( name == "path" && isDrawNS)
01942             {
01943                 fillStyleStack( o, context, "graphic" );
01944                 QString d = o.attributeNS( KoXmlNS::svg, "d", QString::null);
01945 
01946                 KPrSVGPathParser parser;
01947                 ObjType objType = parser.getType( d );
01948 
01949                 switch ( objType )
01950                 {
01951                     case OT_CUBICBEZIERCURVE:
01952                         {
01953                             kdDebug(33001) << "Cubicbeziercurve" << endl;
01954                             KPrCubicBezierCurveObject *kpCurveObject = new KPrCubicBezierCurveObject();
01955                             kpCurveObject->loadOasis( o, context, m_loadingInfo );
01956                             if ( groupObject )
01957                                 groupObject->addObjects( kpCurveObject );
01958                             else
01959                                 newpage->appendObject( kpCurveObject );
01960                         } break;
01961                     case OT_QUADRICBEZIERCURVE:
01962                         {
01963                             kdDebug(33001) << "Quadricbeziercurve" << endl;
01964                             KPrQuadricBezierCurveObject *kpQuadricObject = new KPrQuadricBezierCurveObject();
01965                             kpQuadricObject->loadOasis( o, context, m_loadingInfo );
01966                             if ( groupObject )
01967                                 groupObject->addObjects( kpQuadricObject );
01968                             else
01969                                 newpage->appendObject( kpQuadricObject );
01970                         } break;
01971                     case OT_FREEHAND:
01972                         {
01973                             kdDebug(33001) << "Freehand" << endl;
01974                             KPrFreehandObject *kpFreeHandObject = new KPrFreehandObject();
01975                             kpFreeHandObject->loadOasis( o, context, m_loadingInfo );
01976                             if ( groupObject )
01977                                 groupObject->addObjects( kpFreeHandObject );
01978                             else
01979                                 newpage->appendObject( kpFreeHandObject );
01980                         } break;
01981                     case OT_CLOSED_LINE:
01982                         {
01983                             kdDebug(33001) << "Closed Line" << endl;
01984                             KPrClosedLineObject *kpClosedObject = new KPrClosedLineObject();
01985                             kpClosedObject->loadOasis( o, context, m_loadingInfo );
01986                             if ( groupObject )
01987                                 groupObject->addObjects( kpClosedObject );
01988                             else
01989                                 newpage->appendObject( kpClosedObject );
01990                         } break;
01991                     default:
01992                         kdDebug(33001) << "draw:path found unsupported object type " << objType << " in svg:d " << d << endl;
01993                         break;
01994                 }
01995             }
01996             else if ( name == "custom-shape" && isDrawNS )
01997             {
01998                 fillStyleStack( o, context, "graphic" );
01999 
02000                 QDomElement enhancedGeometry = KoDom::namedItemNS( o, KoXmlNS::draw, "enhanced-geometry" );
02001 
02002                 if ( !enhancedGeometry.isNull() )
02003                 {
02004                     QString d = enhancedGeometry.attributeNS( KoXmlNS::draw, "enhanced-path", QString::null );
02005                     QRegExp rx( "^([0-9 ML]+Z) N$" );
02006                     if ( rx.search( d ) != -1 )
02007                     {
02008                         d = rx.cap( 1 );
02009                         KPrSVGPathParser parser;
02010                         ObjType objType = parser.getType( d );
02011 
02012                         switch ( objType )
02013                         {
02014 #if 0 // not yet supported
02015                             case OT_CUBICBEZIERCURVE:
02016                                 {
02017                                     kdDebug(33001) << "Cubicbeziercurve" << endl;
02018                                     KPrCubicBezierCurveObject *kpCurveObject = new KPrCubicBezierCurveObject();
02019                                     kpCurveObject->loadOasis( o, context, m_loadingInfo );
02020                                     if ( groupObject )
02021                                         groupObject->addObjects( kpCurveObject );
02022                                     else
02023                                         newpage->appendObject( kpCurveObject );
02024                                 } break;
02025                             case OT_QUADRICBEZIERCURVE:
02026                                 {
02027                                     kdDebug(33001) << "Quadricbeziercurve" << endl;
02028                                     KPrQuadricBezierCurveObject *kpQuadricObject = new KPrQuadricBezierCurveObject();
02029                                     kpQuadricObject->loadOasis( o, context, m_loadingInfo );
02030                                     if ( groupObject )
02031                                         groupObject->addObjects( kpQuadricObject );
02032                                     else
02033                                         newpage->appendObject( kpQuadricObject );
02034                                 } break;
02035                             case OT_FREEHAND:
02036                                 {
02037                                     kdDebug(33001) << "Freehand" << endl;
02038                                     KPrFreehandObject *kpFreeHandObject = new KPrFreehandObject();
02039                                     kpFreeHandObject->loadOasis( o, context, m_loadingInfo );
02040                                     if ( groupObject )
02041                                         groupObject->addObjects( kpFreeHandObject );
02042                                     else
02043                                         newpage->appendObject( kpFreeHandObject );
02044                                 } break;
02045 #endif
02046                             case OT_CLOSED_LINE:
02047                                 {
02048                                     kdDebug(33001) << "Closed Line" << endl;
02049                                     KPrClosedLineObject *kpClosedObject = new KPrClosedLineObject();
02050                                     kpClosedObject->loadOasis( o, context, m_loadingInfo );
02051                                     if ( groupObject )
02052                                         groupObject->addObjects( kpClosedObject );
02053                                     else
02054                                         newpage->appendObject( kpClosedObject );
02055                                 } break;
02056                             default:
02057                                 kdDebug(33001) << "draw:custom-shape found unsupported object type " << objType << " in draw:enhanced-path " << d << endl;
02058                                 break;
02059                         }
02060                     }
02061                     else
02062                     {
02063                         kdDebug(33001) << "draw:custom-shape not supported" << endl;
02064                     }
02065                 }
02066             }
02067             else if ( name == "g" && isDrawNS)
02068             {
02069                 fillStyleStack( o, context, "graphic" );
02070                 KPrGroupObject *kpgroupobject = new KPrGroupObject();
02071                 QDomNode nodegroup = object.firstChild();
02072 
02073                 kpgroupobject->loadOasisGroupObject( this, newpage, object, context, m_loadingInfo);
02074                 if ( groupObject )
02075                     groupObject->addObjects( kpgroupobject );
02076                 else
02077                     newpage->appendObject(kpgroupobject);
02078             }
02079             else if ( name == "notes" && o.namespaceURI() == KoXmlNS::presentation ) // notes
02080             {
02081                 //we must extend note attribute
02082                 //kdDebug()<<"presentation:notes----------------------------------\n";
02083                 QDomNode frameBox = KoDom::namedItemNS( o, KoXmlNS::draw, "frame" );
02084                 QString note;
02085 
02086                 while ( !frameBox.isNull() )
02087                 {
02088                     //add an empty line between the different frames
02089                     if ( !note.isEmpty() )
02090                         note += "\n";
02091 
02092                     //todo load layout for note.
02093                     QDomNode textBox = KoDom::namedItemNS( frameBox, KoXmlNS::draw, "text-box" );
02094 
02095                     if ( !textBox.isNull() )
02096                     {
02097                         for ( QDomNode text = textBox.firstChild(); !text.isNull(); text = text.nextSibling() )
02098                         {
02099                             // We don't care about styles as they are not supported in kpresenter.
02100                             // Only add a linebreak for every child.
02101                             QDomElement t = text.toElement();
02102                             if ( t.tagName() == "p" )
02103                             {
02104                                 note += t.text() + "\n";
02105                             }
02106                         }
02107                     }
02108                     frameBox = frameBox.nextSibling();
02109                 }
02110                 newpage->setNoteText( note );
02111             }
02112             else if ( ( name == "header" || name == "footer" ) && o.namespaceURI() == KoXmlNS::style ||
02113                       ( name == "animations" && o.namespaceURI() == KoXmlNS::presentation) )
02114             {
02115                 //nothing
02116             }
02117             else
02118             {
02119                 kdDebug() << "Unsupported object '" << name << "'" << endl;
02120             }
02121             context.styleStack().restore();
02122         }
02123     }
02124 
02125 }
02126 
02127 int KPrDocument::createPresentationAnimation(const QDomElement& element, int order, bool increaseOrder)
02128 {
02129     kdDebug()<<"void KPrDocument::createPresentationAnimation(const QDomElement& element)\n";
02130     int orderAnimation = increaseOrder ? 0 : order;
02131     for ( QDomNode n = element.firstChild(); !n.isNull(); n = n.nextSibling() )
02132     {
02133         QDomElement e = n.toElement();
02134         QCString tagName = e.tagName().latin1();
02135         if ( ! tagName.isEmpty() ) // only tags that open
02136         {
02137             const bool isPresentationNS = e.namespaceURI() == KoXmlNS::presentation;
02138             if ( isPresentationNS &&
02139                  ( tagName == "show-shape" || tagName == "hide-shape" ) )
02140             {
02141                 Q_ASSERT( e.hasAttributeNS( KoXmlNS::draw, "shape-id" ) );
02142                 QString name = e.attributeNS( KoXmlNS::draw, "shape-id", QString::null );
02143                 kdDebug()<<" insert animation " << tagName << " name :" << name << endl;
02144 
02145                 if ( e.hasAttributeNS( KoXmlNS::koffice, "order-id" ) )
02146                 {
02147                     orderAnimation = e.attributeNS( KoXmlNS::koffice, "order-id", QString::null ).toInt();
02148                 }
02149 
02150                 lstAnimation *tmp = new lstAnimation;
02151                 tmp->element = new QDomElement( e );
02152                 tmp->order = orderAnimation;
02153                 if ( tagName == "show-shape" )
02154                 {
02155                     m_loadingInfo->storePresentationShowAnimation( tmp, name );
02156                 }
02157                 else
02158                 {
02159                     m_loadingInfo->storePresentationHideAnimation( tmp, name );
02160                 }
02161                 if ( increaseOrder )
02162                     ++orderAnimation;
02163             }
02164             else if ( tagName == "animation-group" && isPresentationNS )
02165             {
02166                 orderAnimation = createPresentationAnimation( e, orderAnimation, false );
02167             }
02168         }
02169     }
02170     //increase when we finish it necessary for group object
02171     ++orderAnimation;
02172     return orderAnimation;
02173 }
02174 
02175 void KPrDocument::fillStyleStack( const QDomElement& object, KoOasisContext & context, const char* family )
02176 {
02177     // See OpenDoc 9.2.15 Common Drawing Shape Attributes
02178     // presentation:style-name is allways family presentation
02179     if ( object.hasAttributeNS( KoXmlNS::presentation, "style-name" ))
02180     {
02181         context.fillStyleStack( object, KoXmlNS::presentation, "style-name", "presentation" );
02182     }
02183     if ( object.hasAttributeNS( KoXmlNS::draw, "style-name" ) )
02184     {
02185         context.fillStyleStack( object, KoXmlNS::draw, "style-name", family );
02186     }
02187     // draw:tex-style-name is allways family paragraph
02188     if ( object.hasAttributeNS( KoXmlNS::draw, "text-style-name" ) )
02189     {
02190         context.fillStyleStack( object, KoXmlNS::draw, "text-style-name", "paragraph" );
02191     }
02192     if ( object.hasAttributeNS( KoXmlNS::text, "style-name" ) )
02193     {
02194         context.fillStyleStack( object, KoXmlNS::text, "style-name", family );
02195     }
02196 }
02197 
02198 bool KPrDocument::loadXML( QIODevice * dev, const QDomDocument& doc )
02199 {
02200     QTime dt;
02201     dt.start();
02202     m_loadingInfo = new KPrLoadingInfo( true );
02203 
02204     ignoreSticky = FALSE;
02205     bool b=false;
02206     QDomElement docelem = doc.documentElement();
02207     const int syntaxVersion = docelem.attribute( "syntaxVersion" ).toInt();
02208     if ( syntaxVersion < 2 )
02209     {
02210         // This is an old style document, before the current TextObject
02211         // We have kprconverter.pl for it
02212         kdWarning(33001) << "KPresenter document version 1. Launching perl script to convert it." << endl;
02213 
02214         // Read the full XML and write it to a temp file
02215         KTempFile tmpFileIn;
02216         tmpFileIn.setAutoDelete( true );
02217         dev->reset();
02218         tmpFileIn.file()->writeBlock( dev->readAll() ); // copy stresm to temp file
02219         tmpFileIn.close();
02220 
02221         // Launch the perl script on it
02222         KTempFile tmpFileOut;
02223         tmpFileOut.setAutoDelete( true );
02224         QString cmd = KGlobal::dirs()->findExe("perl");
02225         if (cmd.isEmpty())
02226         {
02227             setErrorMessage( i18n("You don't appear to have PERL installed.\nIt is needed to convert this document.\nPlease install PERL and try again."));
02228             return false;
02229         }
02230         cmd += " ";
02231         cmd += locate( "exe", "kprconverter.pl" );
02232         cmd += " ";
02233         cmd += KProcess::quote( tmpFileIn.name() );
02234         cmd += " ";
02235         cmd += KProcess::quote( tmpFileOut.name() );
02236         system( QFile::encodeName(cmd) );
02237 
02238         // Build a new QDomDocument from the result
02239         QString errorMsg;
02240         int errorLine;
02241         int errorColumn;
02242         QDomDocument newdoc;
02243         if ( ! newdoc.setContent( tmpFileOut.file(), &errorMsg, &errorLine, &errorColumn ) )
02244         {
02245             kdError (33001) << "Parsing Error! Aborting! (in KPrDocument::loadXML)" << endl
02246                             << "  Line: " << errorLine << " Column: " << errorColumn << endl
02247                             << "  Message: " << errorMsg << endl;
02248             setErrorMessage( i18n( "parsing error in the main document (converted from an old KPresenter format) at line %1, column %2\nError message: %3" )
02249                              .arg( errorLine ).arg( errorColumn ).arg( i18n ( errorMsg.utf8() ) ) );
02250             return false;
02251         }
02252         b = loadXML( newdoc );
02253     }
02254     else
02255         b = loadXML( doc );
02256 
02257     ignoreSticky = TRUE;
02258 
02259     if(_clean)
02260     {
02261         startBackgroundSpellCheck();
02262     }
02263     if ( m_pageWhereLoadObject == 0 && m_insertFilePage == 0 )
02264         setModified( false );
02265     kdDebug(33001) << "Loading took " << (float)(dt.elapsed()) / 1000.0 << " seconds" << endl;
02266     return b;
02267 }
02268 
02269 void KPrDocument::createHeaderFooter()
02270 {
02271     //add header/footer to sticky page
02272     KoRect pageRect=m_masterPage->getPageRect();
02273     _header->setOrig(pageRect.topLeft());
02274     _header->setSize(pageRect.width(),20);
02275 
02276     _footer->setOrig(pageRect.left(),pageRect.bottom()-20);
02277     _footer->setSize(pageRect.width(),20);
02278 
02279     m_masterPage->appendObject(_header);
02280     m_masterPage->appendObject(_footer);
02281 }
02282 
02283 void KPrDocument::insertEmbedded( KoStore *store, QDomElement topElem, KMacroCommand * macroCmd, KPrPage *page, int pos )
02284 {
02285     QDomElement elem = topElem.firstChild().toElement();
02286     for ( ; !elem.isNull() ; elem = elem.nextSibling().toElement() )
02287     {
02288         kdDebug(33001) << "Element name: " << elem.tagName() << endl;
02289         if(elem.tagName()=="EMBEDDED") {
02290             KPrChild *ch = new KPrChild( this );
02291             KPrPartObject *kppartobject = 0L;
02292             QRect r;
02293 
02294             QDomElement object=elem.namedItem("OBJECT").toElement();
02295             if(!object.isNull()) {
02296                 ch->load(object, true);  // true == uppercase
02297                 r = ch->geometry();
02298                 ch->loadDocument( store );
02299                 insertChild( ch );
02300                 kppartobject = new KPrPartObject( ch );
02301             }
02302             QDomElement settings=elem.namedItem("SETTINGS").toElement();
02303             int zIndex = 0;
02304             if ( settings.hasAttribute( "z-index" ) )
02305             {
02306                 zIndex = settings.attribute( "z-index" ).toInt();
02307             }
02308             double offset = 0.0;
02309             if(!settings.isNull() && kppartobject!=0)
02310                 offset=kppartobject->load(settings);
02311             else if ( settings.isNull() ) // all embedded obj must have SETTING tags
02312             {
02313                 delete kppartobject;
02314                 kppartobject = 0L;
02315                 return;
02316             }
02317             int index = m_pageList.findRef(page);
02318             int pageIndex = (int)(offset/__pgLayout.ptHeight)+index;
02319             int newPos=(int)((offset+index*__pgLayout.ptHeight)-pageIndex*__pgLayout.ptHeight);
02320             kppartobject->setOrig(kppartobject->getOrig().x(),newPos);
02321 
02322             KPrInsertCmd *insertCmd = new KPrInsertCmd( i18n( "Insert Part Object" ), kppartobject, this,page );
02323             insertCmd->execute();
02324             if ( !macroCmd )
02325                 macroCmd = new KMacroCommand( i18n("Insert Part Object"));
02326             macroCmd->addCommand( insertCmd );
02327             if ( pos != 0 )
02328             {
02329                 const QPtrList<KPrObject>& oldList( page->objectList() );
02330                 // tz TODO this is not 100% correct
02331                 if ( static_cast<int>( oldList.count() ) > pos + zIndex )
02332                 {
02333                     page->takeObject( kppartobject );
02334                     page->insertObject( kppartobject, pos + zIndex );
02335                     KPrLowerRaiseCmd *lrCmd = new KPrLowerRaiseCmd( i18n("Insert Part Object"),
02336                                                               oldList, page->objectList(),
02337                                                               this, page );
02338                     macroCmd->addCommand( lrCmd );
02339                 }
02340             }
02341         }
02342     }
02343 }
02344 
02345 bool KPrDocument::loadXML( const QDomDocument &doc )
02346 {
02347     emit sigProgress( 0 );
02348     int activePage=0;
02349     lastObj = -1;
02350     bool allSlides = false;
02351     // clean
02352     if ( _clean ) {
02353         __pgLayout = KoPageLayout::standardLayout();
02354         _spInfiniteLoop = false;
02355         _spShowEndOfPresentationSlide = true;
02356         _spManualSwitch = true;
02357         _showPresentationDuration = false;
02358         _xRnd = 20;
02359         _yRnd = 20;
02360         //_txtBackCol = white;
02361         urlIntern = url().path();
02362     }
02363     else
02364         m_spellCheckIgnoreList.clear();
02365     emit sigProgress( 5 );
02366 
02367     QDomElement document=doc.documentElement();
02368     // DOC
02369     if(document.tagName()!="DOC") {
02370         kdWarning(33001) << "Missing DOC" << endl;
02371         setErrorMessage( i18n("Invalid document, DOC tag missing.") );
02372         return false;
02373     }
02374 
02375     if(!document.hasAttribute("mime") ||  (
02376            document.attribute("mime")!="application/x-kpresenter" &&
02377            document.attribute("mime")!="application/vnd.kde.kpresenter" ) ) {
02378         kdError(33001) << "Unknown mime type " << document.attribute("mime") << endl;
02379         setErrorMessage( i18n("Invalid document, expected mimetype application/x-kpresenter or application/vnd.kde.kpresenter, got %1").arg(document.attribute("mime")) );
02380         return false;
02381     }
02382     if(document.hasAttribute("url"))
02383         urlIntern=KURL(document.attribute("url")).path();
02384 
02385     emit sigProgress( 10 );
02386 
02387     QDomElement elem=document.firstChild().toElement();
02388 
02389     uint childTotalCount=document.childNodes().count();
02390     uint childCount = 0;
02391 
02392     loadTextStyle( document );
02393 
02394     while(!elem.isNull()) {
02395         kdDebug(33001) << "Element name: " << elem.tagName() << endl;
02396         if(elem.tagName()=="EMBEDDED") {
02397             KPrChild *ch = new KPrChild( this );
02398             KPrPartObject *kppartobject = 0L;
02399             QRect r;
02400 
02401             QDomElement object=elem.namedItem("OBJECT").toElement();
02402             if(!object.isNull()) {
02403                 ch->load(object, true);  // true == uppercase
02404                 r = ch->geometry();
02405                 insertChild( ch );
02406                 kppartobject = new KPrPartObject( ch );
02407                 //emit sig_insertObject( ch, kppartobject );
02408             }
02409             QDomElement settings=elem.namedItem("SETTINGS").toElement();
02410             int tmp=0;
02411             int pos = -1;
02412             if ( settings.hasAttribute( "z-index" ) )
02413             {
02414                 pos = settings.attribute( "z-index" ).toInt();
02415             }
02416             if(settings.hasAttribute("sticky"))
02417                 tmp=settings.attribute("sticky").toInt();
02418             bool sticky=static_cast<bool>(tmp);
02419             double offset = 0.0;
02420             if(!settings.isNull() && kppartobject!=0)
02421             {
02422                 offset=kppartobject->load(settings);
02423             }
02424             else if ( settings.isNull() ) // all embedded obj must have SETTING tags
02425             {
02426                 delete kppartobject;
02427                 kppartobject = 0L;
02428             }
02429             //hack for some old file, they don't have ORIG tag !
02430             if ( offset == -1.0 )
02431                 offset = r.y();
02432             if ( sticky && !ignoreSticky && kppartobject )
02433             {
02434                 if ( pos == -1 )
02435                 {
02436                     m_masterPage->appendObject( kppartobject );
02437                 }
02438                 else
02439                 {
02440                     m_masterPage->insertObject( kppartobject, pos );
02441                 }
02442                 kppartobject->setOrig(kppartobject->getOrig().x(), offset);
02443             }
02444             else if ( kppartobject ) {
02445                 if ( m_pageWhereLoadObject )
02446                 {
02447                     kppartobject->setOrig(kppartobject->getOrig().x(), offset);
02448                     m_pageWhereLoadObject->insertObject( kppartobject, pos );
02449                 }
02450                 else
02451                 {
02452                     insertObjectInPage( offset, kppartobject, pos );
02453                 }
02454             }
02455         } else if(elem.tagName()=="PAPER" && _clean)  {
02456             if(elem.hasAttribute("format"))
02457                 __pgLayout.format=static_cast<KoFormat>(elem.attribute("format").toInt());
02458             if(elem.hasAttribute("orientation"))
02459                 __pgLayout.orientation=static_cast<KoOrientation>(elem.attribute("orientation").toInt());
02460             if(elem.hasAttribute("ptWidth"))
02461                 __pgLayout.ptWidth = elem.attribute("ptWidth").toDouble();
02462             else if(elem.hasAttribute("inchWidth"))  //compatibility
02463                 __pgLayout.ptWidth = INCH_TO_POINT( elem.attribute("inchWidth").toDouble() );
02464             else if(elem.hasAttribute("mmWidth"))    //compatibility
02465                 __pgLayout.ptWidth = MM_TO_POINT( elem.attribute("mmWidth").toDouble() );
02466             if(elem.hasAttribute("ptHeight"))
02467                 __pgLayout.ptHeight = elem.attribute("ptHeight").toDouble();
02468             else if(elem.hasAttribute("inchHeight")) //compatibility
02469                 __pgLayout.ptHeight = INCH_TO_POINT( elem.attribute("inchHeight").toDouble() );
02470             else if(elem.hasAttribute("mmHeight"))   //compatibility
02471                 __pgLayout.ptHeight = MM_TO_POINT( elem.attribute("mmHeight").toDouble() );
02472             if(elem.hasAttribute("unit"))
02473                 setUnit( static_cast<KoUnit::Unit>(elem.attribute("unit").toInt()) );
02474             if ( elem.hasAttribute("tabStopValue"))
02475                 m_tabStop = elem.attribute("tabStopValue").toDouble();
02476 
02477             if(elem.hasAttribute("width"))
02478                 __pgLayout.ptWidth = MM_TO_POINT( elem.attribute("width").toDouble() );
02479             if(elem.hasAttribute("height"))
02480                 __pgLayout.ptHeight = MM_TO_POINT( elem.attribute("height").toDouble() );
02481 
02482             QDomElement borders=elem.namedItem("PAPERBORDERS").toElement();
02483             if(!borders.isNull()) {
02484                 if(borders.hasAttribute("left"))
02485                     __pgLayout.ptLeft = MM_TO_POINT( borders.attribute("left").toDouble() );
02486                 if(borders.hasAttribute("top"))
02487                     __pgLayout.ptTop = MM_TO_POINT( borders.attribute("top").toDouble() );
02488                 if(borders.hasAttribute("right"))
02489                     __pgLayout.ptRight = MM_TO_POINT( borders.attribute("right").toDouble() );
02490                 if(borders.hasAttribute("bottom"))
02491                     __pgLayout.ptBottom = MM_TO_POINT( borders.attribute("bottom").toDouble() );
02492                 if(borders.hasAttribute("ptLeft"))
02493                     __pgLayout.ptLeft = borders.attribute("ptLeft").toDouble();
02494                 else if(borders.hasAttribute("inchLeft"))    //compatibility
02495                     __pgLayout.ptLeft = INCH_TO_POINT( borders.attribute("inchLeft").toDouble() );
02496                 else if(borders.hasAttribute("mmLeft"))      //compatibility
02497                     __pgLayout.ptLeft = MM_TO_POINT( borders.attribute("mmLeft").toDouble() );
02498                 if(borders.hasAttribute("ptRight"))
02499                     __pgLayout.ptRight = borders.attribute("ptRight").toDouble();
02500                 else if(borders.hasAttribute("inchRight"))   //compatibility
02501                     __pgLayout.ptRight = INCH_TO_POINT( borders.attribute("inchRight").toDouble() );
02502                 else if(borders.hasAttribute("mmRight"))     //compatibility
02503                     __pgLayout.ptRight = MM_TO_POINT( borders.attribute("mmRight").toDouble() );
02504                 if(borders.hasAttribute("ptTop"))
02505                     __pgLayout.ptTop = borders.attribute("ptTop").toDouble();
02506                 else if(borders.hasAttribute("inchTop"))     //compatibility
02507                     __pgLayout.ptTop = INCH_TO_POINT( borders.attribute("inchTop").toDouble() );
02508                 else if(borders.hasAttribute("mmTop"))       //compatibility
02509                     __pgLayout.ptTop = MM_TO_POINT( borders.attribute("mmTop").toDouble() );
02510                 if(borders.hasAttribute("ptBottom"))
02511                     __pgLayout.ptBottom = borders.attribute("ptBottom").toDouble();
02512                 else if(borders.hasAttribute("inchBottom"))  //compatibility
02513                     __pgLayout.ptBottom = INCH_TO_POINT( borders.attribute("inchBottom").toDouble() );
02514                 else if(borders.hasAttribute("mmBottom"))    //compatibility
02515                     __pgLayout.ptBottom = MM_TO_POINT( borders.attribute("inchBottom").toDouble() );
02516             }
02517             // PAPER found and parsed -> apply page layout
02518             // e.g. the text objects need it
02519             if ( _clean )
02520                 setPageLayout( __pgLayout );
02521 
02522         } else if(elem.tagName()=="VARIABLESETTINGS" && _clean){
02523             getVariableCollection()->variableSetting()->load(document);
02524             //by default display real variable value
02525             if ( !isReadWrite())
02526                 getVariableCollection()->variableSetting()->setDisplayFieldCode(false);
02527 
02528         }
02529         else if(elem.tagName()=="BACKGROUND") {
02530             int red=0, green=0, blue=0;
02531             if(elem.hasAttribute("xRnd"))
02532                 _xRnd = elem.attribute("xRnd").toInt();
02533             if(elem.hasAttribute("yRnd"))
02534                 _yRnd = elem.attribute("yRnd").toInt();
02535             if(elem.hasAttribute("bred"))
02536                 red = elem.attribute("bred").toInt();
02537             if(elem.hasAttribute("bgreen"))
02538                 green = elem.attribute("bgreen").toInt();
02539             if(elem.hasAttribute("bblue"))
02540                 blue = elem.attribute("bblue").toInt();
02541             loadBackground(elem);
02542         } else if(elem.tagName()=="HEADER") {
02543             if ( _clean /*don't reload header footer, header/footer was created at the beginning || !hasHeader()*/ ) {
02544                 if(elem.hasAttribute("show")) {
02545                     setHeader(static_cast<bool>(elem.attribute("show").toInt()));
02546                 }
02547                 _header->load(elem);
02548             }
02549         } else if ( elem.tagName()=="HEADERFOOTERBYPAGE" ) {
02550             if ( elem.hasAttribute( "value" ) ) {
02551                 m_loadingInfo->m_headerFooterByPage = true;
02552             }
02553         } else if(elem.tagName()=="FOOTER") {
02554             if ( _clean /*|| !hasFooter()*/ ) {
02555                 if(elem.hasAttribute("show")) {
02556                     setFooter( static_cast<bool>(elem.attribute("show").toInt() ) );
02557                 }
02558                 _footer->load(elem);
02559             }
02560         }else if( elem.tagName()=="HELPLINES"){
02561             if ( _clean  ) {
02562                 if(elem.hasAttribute("show")) {
02563                     setShowGuideLines( static_cast<bool>(elem.attribute("show").toInt() ) );
02564                 }
02565                 loadGuideLines( elem );
02566             }
02567         }else if( elem.tagName()=="SPELLCHECKIGNORELIST"){
02568             QDomElement spellWord=elem.toElement();
02569             spellWord=spellWord.firstChild().toElement();
02570             while ( !spellWord.isNull() )
02571             {
02572                 if ( spellWord.tagName()=="SPELLCHECKIGNOREWORD" )
02573                 {
02574                     m_spellCheckIgnoreList.append(spellWord.attribute("word"));
02575                 }
02576                 spellWord=spellWord.nextSibling().toElement();
02577             }
02578         }else if(elem.tagName()=="ATTRIBUTES" && _clean) {
02579             if(elem.hasAttribute("activePage"))
02580                 activePage=elem.attribute("activePage").toInt();
02581             if(elem.hasAttribute("gridx"))
02582                 m_gridX = elem.attribute("gridx").toDouble();
02583             if(elem.hasAttribute("gridy"))
02584                 m_gridY = elem.attribute("gridy").toDouble();
02585             if(elem.hasAttribute("snaptogrid"))
02586                 m_bSnapToGrid = (bool)elem.attribute("snaptogrid").toInt();
02587         } else if(elem.tagName()=="PAGETITLES") {
02588             loadTitle(elem);
02589         } else if(elem.tagName()=="PAGENOTES") {
02590             loadNote(elem);
02591         } else if(elem.tagName()=="OBJECTS") {
02592             //FIXME**********************
02593 #if 0
02594             lastObj = _objectList->count() - 1;
02595 #endif
02596             //don't add command we don't paste object
02597             KCommand * cmd =loadObjects(elem);
02598             if ( cmd )
02599                 delete cmd;
02600         } else if(elem.tagName()=="INFINITLOOP") {
02601             if(_clean) {
02602                 if(elem.hasAttribute("value"))
02603                     _spInfiniteLoop = static_cast<bool>(elem.attribute("value").toInt());
02604             }
02605         } else if(elem.tagName()=="SHOWENDOFPRESENTATIONSLIDE") {
02606             if(_clean) {
02607                 if(elem.hasAttribute("value"))
02608                     _spShowEndOfPresentationSlide = static_cast<bool>(elem.attribute("value").toInt());
02609             }
02610         } else if(elem.tagName()=="PRESSPEED") {
02611             if(_clean) {
02612                 if(elem.hasAttribute("value"))
02613                     m_loadingInfo->presSpeed = elem.attribute("value").toInt();
02614             }
02615         } else if(elem.tagName()=="MANUALSWITCH") {
02616             if(_clean) {
02617                 if(elem.hasAttribute("value"))
02618                     _spManualSwitch = static_cast<bool>(elem.attribute("value").toInt());
02619             }
02620         } else if(elem.tagName()=="SHOWPRESENTATIONDURATION") {
02621             if(_clean) {
02622                 if(elem.hasAttribute("value"))
02623                     _showPresentationDuration = static_cast<bool>(elem.attribute("value").toInt());
02624             }
02625         } else if(elem.tagName()=="PRESSLIDES") {
02626             if(elem.hasAttribute("value") && elem.attribute("value").toInt()==0)
02627                 allSlides = TRUE;
02628         } else if ( elem.tagName()=="DEFAULTCUSTOMSLIDESHOWNAME" ) {
02629             if(elem.hasAttribute("name") )
02630                 m_presentationName=elem.attribute( "name" );
02631         } else if ( elem.tagName()=="CUSTOMSLIDESHOWCONFIG" ) {
02632             if ( _clean ) {
02633                 QMap<QString, KPrPage *> name2page;
02634                 int pos = 1;
02635                 for ( QPtrListIterator<KPrPage> it( m_pageList ); it.current(); ++it )
02636                 {
02637                     name2page.insert( "page" + QString::number( pos++ ), it.current() ) ;
02638                 }
02639 
02640                 QDomElement slide=elem.firstChild().toElement();
02641                 while(!slide.isNull()) {
02642                     if(slide.tagName()=="CUSTOMSLIDESHOW") {
02643                         QStringList tmp = QStringList::split( ",", slide.attribute( "pages" ) );
02644                         QValueList<KPrPage *> pageList;
02645                         for ( QStringList::Iterator it = tmp.begin(); it != tmp.end(); ++it )
02646                         {
02647                             if ( name2page.contains( *it ) )
02648                             {
02649                                 kdDebug(33001) << "slide show " << slide.attribute( "name" ) << " page = " << *it << endl;
02650                                 pageList.push_back( name2page[*it] );
02651                             }
02652                         }
02653                         if ( ! pageList.empty() )
02654                         {
02655                             m_customListSlideShow.insert( slide.attribute( "name" ), pageList );
02656                         }
02657                     }
02658                     slide=slide.nextSibling().toElement();
02659                 }
02660             }
02661         } else if(elem.tagName()=="SELSLIDES") {
02662             if( _clean ) { // Skip this when loading a single page
02663                 QDomElement slide=elem.firstChild().toElement();
02664                 while(!slide.isNull()) {
02665                     if(slide.tagName()=="SLIDE") {
02666                         int nr = -1;
02667                         bool show = false;
02668                         if(slide.hasAttribute("nr"))
02669                             nr=slide.attribute("nr").toInt();
02670                         if(slide.hasAttribute("show"))
02671                             show=static_cast<bool>(slide.attribute("show").toInt());
02672                         if ( nr >= 0 )
02673                         {
02674                             //kdDebug(33001) << "KPrDocument::loadXML m_selectedSlides nr=" << nr << " show=" << show << endl;
02675                             if ( nr > ( (int)m_pageList.count() - 1 ) )
02676                             {
02677                                 for (int i=(m_pageList.count()-1); i<nr;i++)
02678                                     m_pageList.append( new KPrPage( this, m_masterPage ) );
02679                             }
02680                             m_pageList.at(nr)->slideSelected(show);
02681                         } else kdWarning(33001) << "Parse error. No nr in <SLIDE> !" << endl;
02682                     }
02683                     slide=slide.nextSibling().toElement();
02684                 }
02685             }
02686         } else if ( elem.tagName() == "SOUNDS" ) {
02687             loadUsedSoundFileFromXML( elem );
02688         }
02689         elem=elem.nextSibling().toElement();
02690 
02691         emit sigProgress( childCount * ( 70/childTotalCount ) + 15 );
02692         childCount += 1;
02693     }
02694 
02695     loadPictureMap( document );
02696 
02697     if(activePage!=-1)
02698         m_initialActivePage=m_pageList.at(activePage);
02699     if ( m_pageWhereLoadObject == 0 && m_insertFilePage == 0 )
02700         setModified(false);
02701 
02702     return true;
02703 }
02704 
02705 void KPrDocument::loadTextStyle( const QDomElement& domElement )
02706 {
02707     QDomElement style = domElement.namedItem( "STYLES" ).toElement();
02708     if ( _clean && ! style.isNull() )
02709         loadStyleTemplates( style );
02710 }
02711 
02712 void KPrDocument::loadPictureMap ( const QDomElement& domElement )
02713 {
02714     m_pictureMap.clear();
02715 
02716     // <PICTURES>
02717     QDomElement picturesElem = domElement.namedItem( "PICTURES" ).toElement();
02718     if ( !picturesElem.isNull() )
02719         m_pictureCollection.readXML( picturesElem, m_pictureMap );
02720 
02721     // <PIXMAPS>
02722     QDomElement pixmapsElem = domElement.namedItem( "PIXMAPS" ).toElement();
02723     if ( !pixmapsElem.isNull() )
02724         m_pictureCollection.readXML( pixmapsElem, m_pictureMap );
02725 
02726     // <CLIPARTS>
02727     QDomElement clipartsElem = domElement.namedItem( "CLIPARTS" ).toElement();
02728     if ( !clipartsElem.isNull() )
02729         m_pictureCollection.readXML( pixmapsElem, m_pictureMap );
02730 }
02731 
02732 void KPrDocument::loadBackground( const QDomElement &element )
02733 {
02734     kdDebug(33001) << "KPrDocument::loadBackground" << endl;
02735     QDomElement page=element.firstChild().toElement();
02736     int i=m_insertFilePage;
02737     while(!page.isNull()) {
02738         if(m_pageWhereLoadObject)
02739         {
02740             kdDebug(33001) << "m_pageWhereLoadObject->load(...)" << m_pageWhereLoadObject <<  endl;
02741             m_pageWhereLoadObject->load(page);
02742             break;
02743         }
02744         else
02745         {
02746             if ( page.tagName() == "MASTERPAGE" )
02747             {
02748                 m_masterPage->load( page );
02749             }
02750             else
02751             {
02752                 //test if there is a page at this index
02753                 //=> don't add new page if there is again a page
02754                 if ( i > ( (int)m_pageList.count() - 1 ) )
02755                     m_pageList.append( new KPrPage( this, m_masterPage ) );
02756                 m_pageList.at(i)->load(page);
02757                 i++;
02758             }
02759         }
02760         page=page.nextSibling().toElement();
02761     }
02762 }
02763 
02764 KCommand *KPrDocument::loadObjects( const QDomElement &element, bool paste )
02765 {
02766     ObjType t = OT_LINE;
02767     QDomElement obj=element.firstChild().toElement();
02768     QValueList<KPrObject *> pasteObjects;
02769     while(!obj.isNull()) {
02770         if(obj.tagName()=="OBJECT" ) {
02771             bool sticky=false;
02772             int tmp=0;
02773             if(obj.hasAttribute("type"))
02774                 tmp=obj.attribute("type").toInt();
02775             t=static_cast<ObjType>(tmp);
02776             tmp=0;
02777             if(obj.hasAttribute("sticky"))
02778                 tmp=obj.attribute("sticky").toInt();
02779             sticky=static_cast<bool>(tmp);
02780             double offset=0;
02781             switch ( t ) {
02782             case OT_LINE: {
02783                 KPrLineObject *kplineobject = new KPrLineObject();
02784                 offset=kplineobject->load(obj);
02785                 if ( sticky && !ignoreSticky)
02786                 {
02787                     m_masterPage->appendObject(kplineobject);
02788                     kplineobject->setOrig(kplineobject->getOrig().x(),offset);
02789                 }
02790                 else if (m_pageWhereLoadObject && paste) {
02791                     kplineobject->setOrig(kplineobject->getOrig().x(),offset);
02792                     pasteObjects.append( kplineobject );
02793                 }
02794                 else if( m_pageWhereLoadObject &&!paste)
02795                 {
02796                     m_pageWhereLoadObject->appendObject(kplineobject);
02797                     kplineobject->setOrig(kplineobject->getOrig().x(),offset);
02798                 }
02799                 else
02800                     insertObjectInPage(offset, kplineobject);
02801             } break;
02802             case OT_RECT: {
02803                 KPrRectObject *kprectobject = new KPrRectObject();
02804                 offset=kprectobject->load(obj);
02805                 if ( sticky && !ignoreSticky)
02806                 {
02807                     m_masterPage->appendObject(kprectobject);
02808                     kprectobject->setOrig(kprectobject->getOrig().x(),offset);
02809                 }
02810                 else if (m_pageWhereLoadObject && paste) {
02811                     kprectobject->setOrig(kprectobject->getOrig().x(),offset);
02812                     pasteObjects.append( kprectobject );
02813                 }
02814                 else if( m_pageWhereLoadObject &&!paste)
02815                 {
02816                     m_pageWhereLoadObject->appendObject(kprectobject);
02817                     kprectobject->setOrig(kprectobject->getOrig().x(),offset);
02818                 }
02819                 else
02820                     insertObjectInPage(offset, kprectobject);
02821             } break;
02822             case OT_ELLIPSE: {
02823                 KPrEllipseObject *kpellipseobject = new KPrEllipseObject();
02824                 offset=kpellipseobject->load(obj);
02825                 if ( sticky && !ignoreSticky)
02826                 {
02827                     m_masterPage->appendObject(kpellipseobject);
02828                     kpellipseobject->setOrig(kpellipseobject->getOrig().x(),offset);
02829                 }
02830                 else if ( m_pageWhereLoadObject && paste)
02831                 {
02832                     kpellipseobject->setOrig(kpellipseobject->getOrig().x(),offset);
02833                     pasteObjects.append( kpellipseobject );
02834                 }
02835                 else if( m_pageWhereLoadObject &&!paste)
02836                 {
02837                     m_pageWhereLoadObject->appendObject(kpellipseobject);
02838                     kpellipseobject->setOrig(kpellipseobject->getOrig().x(),offset);
02839                 }
02840                 else
02841                     insertObjectInPage(offset, kpellipseobject);
02842             } break;
02843             case OT_PIE: {
02844                 KPrPieObject *kppieobject = new KPrPieObject();
02845                 offset=kppieobject->load(obj);
02846                 if ( sticky && !ignoreSticky)
02847                 {
02848                     m_masterPage->appendObject(kppieobject);
02849                     kppieobject->setOrig(kppieobject->getOrig().x(),offset);
02850                 }
02851                 else if ( m_pageWhereLoadObject && paste) {
02852                     kppieobject->setOrig(kppieobject->getOrig().x(),offset);
02853                     pasteObjects.append( kppieobject );
02854                 }
02855                 else if( m_pageWhereLoadObject &&!paste)
02856                 {
02857                     m_pageWhereLoadObject->appendObject(kppieobject);
02858                     kppieobject->setOrig(kppieobject->getOrig().x(),offset);
02859                 }
02860                 else
02861                     insertObjectInPage(offset, kppieobject);
02862             } break;
02863             case OT_AUTOFORM: {
02864                 KPrAutoformObject *kpautoformobject = new KPrAutoformObject();
02865                 offset=kpautoformobject->load(obj);
02866                 if ( sticky && !ignoreSticky)
02867                 {
02868                     m_masterPage->appendObject(kpautoformobject);
02869                     kpautoformobject->setOrig(kpautoformobject->getOrig().x(),offset);
02870                 }
02871                 else if ( m_pageWhereLoadObject&& paste) {
02872                     kpautoformobject->setOrig(kpautoformobject->getOrig().x(),offset);
02873                     pasteObjects.append( kpautoformobject );
02874                 }
02875                 else if( m_pageWhereLoadObject &&!paste)
02876                 {
02877                     m_pageWhereLoadObject->appendObject(kpautoformobject);
02878                     kpautoformobject->setOrig(kpautoformobject->getOrig().x(),offset);
02879                 }
02880                 else
02881                     insertObjectInPage(offset, kpautoformobject);
02882             } break;
02883             case OT_TEXT: {
02884                 KPrTextObject *kptextobject = new KPrTextObject( this );
02885                 offset=kptextobject->load(obj);
02886                 if ( sticky && !ignoreSticky)
02887                 {
02888                     m_masterPage->appendObject(kptextobject);
02889                     kptextobject->setOrig(kptextobject->getOrig().x(),offset);
02890                 }
02891                 else if ( m_pageWhereLoadObject && paste) {
02892                     kptextobject->setOrig(kptextobject->getOrig().x(),offset);
02893                     pasteObjects.append( kptextobject );
02894                 }
02895                 else if( m_pageWhereLoadObject &&!paste)
02896                 {
02897                     m_pageWhereLoadObject->appendObject(kptextobject);
02898                     kptextobject->setOrig(kptextobject->getOrig().x(),offset);
02899                 }
02900                 else
02901                     insertObjectInPage(offset, kptextobject);
02902             } break;
02903             case OT_CLIPART:
02904             case OT_PICTURE: {
02905                 KPrPixmapObject *kppixmapobject = new KPrPixmapObject( pictureCollection() );
02906                 offset=kppixmapobject->load(obj);
02907                 if ( sticky && !ignoreSticky)
02908                 {
02909                     m_masterPage->appendObject(kppixmapobject);
02910                     kppixmapobject->setOrig(kppixmapobject->getOrig().x(),offset);
02911                 }
02912                 else if ( m_pageWhereLoadObject && paste) {
02913                     kppixmapobject->setOrig(kppixmapobject->getOrig().x(),offset);
02914                     pasteObjects.append( kppixmapobject );
02915                     kppixmapobject->reload();
02916                 }
02917                 else if( m_pageWhereLoadObject &&!paste)
02918                 {
02919                     m_pageWhereLoadObject->appendObject(kppixmapobject);
02920                     kppixmapobject->setOrig(kppixmapobject->getOrig().x(),offset);
02921                 }
02922                 else
02923                     insertObjectInPage(offset, kppixmapobject);
02924             } break;
02925             case OT_FREEHAND: {
02926                 KPrFreehandObject *kpfreehandobject = new KPrFreehandObject();
02927                 offset=kpfreehandobject->load(obj);
02928 
02929                 if ( sticky && !ignoreSticky)
02930                 {
02931                     m_masterPage->appendObject(kpfreehandobject);
02932                     kpfreehandobject->setOrig(kpfreehandobject->getOrig().x(),offset);
02933                 }
02934                 else if ( m_pageWhereLoadObject && paste) {
02935                     kpfreehandobject->setOrig(kpfreehandobject->getOrig().x(),offset);
02936                     pasteObjects.append( kpfreehandobject );
02937                 }
02938                 else if( m_pageWhereLoadObject &&!paste)
02939                 {
02940                     m_pageWhereLoadObject->appendObject(kpfreehandobject);
02941                     kpfreehandobject->setOrig(kpfreehandobject->getOrig().x(),offset);
02942                 }
02943                 else
02944                     insertObjectInPage(offset,kpfreehandobject);
02945             } break;
02946             case OT_POLYLINE: {
02947                 KPrPolylineObject *kppolylineobject = new KPrPolylineObject();
02948                 offset=kppolylineobject->load(obj);
02949                 if ( sticky && !ignoreSticky)
02950                 {
02951                     m_masterPage->appendObject(kppolylineobject);
02952                     kppolylineobject->setOrig(kppolylineobject->getOrig().x(),offset);
02953                 }
02954                 else if (m_pageWhereLoadObject && paste) {
02955                     kppolylineobject->setOrig(kppolylineobject->getOrig().x(),offset);
02956                     pasteObjects.append( kppolylineobject );
02957                 }
02958                 else if( m_pageWhereLoadObject &&!paste)
02959                 {
02960                     m_pageWhereLoadObject->appendObject(kppolylineobject);
02961                     kppolylineobject->setOrig(kppolylineobject->getOrig().x(),offset);
02962                 }
02963                 else
02964                     insertObjectInPage(offset, kppolylineobject);
02965             } break;
02966             case OT_QUADRICBEZIERCURVE: {
02967                 KPrQuadricBezierCurveObject *kpQuadricBezierCurveObject = new KPrQuadricBezierCurveObject();
02968                 offset=kpQuadricBezierCurveObject->load(obj);
02969                 if ( sticky && !ignoreSticky)
02970                 {
02971                     m_masterPage->appendObject(kpQuadricBezierCurveObject);
02972                     kpQuadricBezierCurveObject->setOrig(kpQuadricBezierCurveObject->getOrig().x(),offset);
02973                 }
02974                 else if ( m_pageWhereLoadObject && paste) {
02975                     kpQuadricBezierCurveObject->setOrig(kpQuadricBezierCurveObject->getOrig().x(),offset);
02976                     pasteObjects.append( kpQuadricBezierCurveObject );
02977                 }
02978                 else if( m_pageWhereLoadObject &&!paste)
02979                 {
02980                     m_pageWhereLoadObject->appendObject(kpQuadricBezierCurveObject);
02981                     kpQuadricBezierCurveObject->setOrig(kpQuadricBezierCurveObject->getOrig().x(),offset);
02982                 }
02983                 else
02984                     insertObjectInPage(offset, kpQuadricBezierCurveObject);
02985             } break;
02986             case OT_CUBICBEZIERCURVE: {
02987                 KPrCubicBezierCurveObject *kpCubicBezierCurveObject = new KPrCubicBezierCurveObject();
02988                 offset=kpCubicBezierCurveObject->load(obj);
02989                 if ( sticky && !ignoreSticky)
02990                 {
02991                     m_masterPage->appendObject(kpCubicBezierCurveObject);
02992                     kpCubicBezierCurveObject->setOrig(kpCubicBezierCurveObject->getOrig().x(),offset);
02993                 }
02994                 else if ( m_pageWhereLoadObject && paste) {
02995                     kpCubicBezierCurveObject->setOrig(kpCubicBezierCurveObject->getOrig().x(),offset);
02996                     pasteObjects.append( kpCubicBezierCurveObject );
02997                 }
02998                 else if( m_pageWhereLoadObject &&!paste)
02999                 {
03000                     m_pageWhereLoadObject->appendObject(kpCubicBezierCurveObject);
03001                     kpCubicBezierCurveObject->setOrig(kpCubicBezierCurveObject->getOrig().x(),offset);
03002                 }
03003                 else
03004                     insertObjectInPage(offset, kpCubicBezierCurveObject);
03005             } break;
03006             case OT_POLYGON: {
03007                 KPrPolygonObject *kpPolygonObject = new KPrPolygonObject();
03008                 offset=kpPolygonObject->load( obj );
03009                 if ( sticky && !ignoreSticky)
03010                 {
03011                     m_masterPage->appendObject(kpPolygonObject);
03012                     kpPolygonObject->setOrig(kpPolygonObject->getOrig().x(),offset);
03013                 }
03014                 else if ( m_pageWhereLoadObject && paste) {
03015                     kpPolygonObject->setOrig(kpPolygonObject->getOrig().x(),offset);
03016                     pasteObjects.append( kpPolygonObject );
03017                 }
03018                 else if( m_pageWhereLoadObject &&!paste)
03019                 {
03020                     m_pageWhereLoadObject->appendObject(kpPolygonObject);
03021                     kpPolygonObject->setOrig(kpPolygonObject->getOrig().x(),offset);
03022                 }
03023                 else
03024                     insertObjectInPage(offset, kpPolygonObject);
03025             } break;
03026             case OT_CLOSED_LINE: {
03027                 KPrClosedLineObject *kpClosedLinneObject = new KPrClosedLineObject();
03028                 offset = kpClosedLinneObject->load( obj );
03029                 if ( sticky && !ignoreSticky) {
03030                     m_masterPage->appendObject( kpClosedLinneObject );
03031                     kpClosedLinneObject->setOrig( kpClosedLinneObject->getOrig().x(), offset );
03032                 }
03033                 else if ( m_pageWhereLoadObject && paste ) {
03034                     kpClosedLinneObject->setOrig( kpClosedLinneObject->getOrig().x(), offset );
03035                     pasteObjects.append( kpClosedLinneObject );
03036                 }
03037                 else if( m_pageWhereLoadObject &&!paste)
03038                 {
03039                     m_pageWhereLoadObject->appendObject( kpClosedLinneObject );
03040                     kpClosedLinneObject->setOrig( kpClosedLinneObject->getOrig().x(), offset );
03041                 }
03042                 else
03043                     insertObjectInPage( offset, kpClosedLinneObject );
03044             } break;
03045             case OT_GROUP: {
03046                 KPrGroupObject *kpgroupobject = new KPrGroupObject();
03047                 offset=kpgroupobject->load(obj, this);
03048                 if ( sticky && !ignoreSticky)
03049                 {
03050                     m_masterPage->appendObject(kpgroupobject);
03051                     kpgroupobject->setOrig(kpgroupobject->getOrig().x(),offset);
03052                 }
03053                 else if ( m_pageWhereLoadObject && paste) {
03054                     kpgroupobject->setOrig(kpgroupobject->getOrig().x(),offset);
03055                     pasteObjects.append( kpgroupobject );
03056                 }
03057                 else if( m_pageWhereLoadObject &&!paste)
03058                 {
03059                     m_pageWhereLoadObject->appendObject(kpgroupobject);
03060                     kpgroupobject->setOrig(kpgroupobject->getOrig().x(),offset);
03061                 }
03062                 else
03063                     insertObjectInPage(offset, kpgroupobject);
03064             } break;
03065             default: break;
03066             }
03067         }
03068         obj=obj.nextSibling().toElement();
03069     }
03070 
03071     KPrInsertCmd *insertCmd = 0;
03072     if ( ! pasteObjects.empty() )
03073     {
03074         insertCmd = new KPrInsertCmd( i18n( "Paste Objects" ), pasteObjects,
03075                                       this , m_pageWhereLoadObject );
03076         insertCmd->execute();
03077     }
03078     return insertCmd;
03079 }
03080 
03081 void KPrDocument::loadTitle( const QDomElement &element )
03082 {
03083     QDomElement title=element.firstChild().toElement();
03084     int i=m_insertFilePage;
03085     while ( !title.isNull() ) {
03086         if ( title.tagName()=="Title" )
03087         {
03088             //test if there is a page at this index
03089             //=> don't add new page if there is again a page
03090             if(!m_pageWhereLoadObject)
03091             {
03092                 if ( i > ( (int)m_pageList.count() - 1 ) )
03093                     m_pageList.append( new KPrPage( this, m_masterPage ) );
03094                 m_pageList.at(i)->insertManualTitle(title.attribute("title"));
03095                 i++;
03096             }
03097             else
03098                 m_pageWhereLoadObject->insertManualTitle(title.attribute("title"));
03099         }
03100         title=title.nextSibling().toElement();
03101     }
03102 }
03103 
03104 void KPrDocument::loadNote( const QDomElement &element )
03105 {
03106     QDomElement note=element.firstChild().toElement();
03107     int i=m_insertFilePage;
03108     while ( !note.isNull() ) {
03109         if ( note.tagName()=="Note" )
03110         {
03111             //test if there is a page at this index
03112             //=> don't add new page if there is again a page
03113             if(!m_pageWhereLoadObject)
03114             {
03115                 if ( i > ( (int)m_pageList.count() - 1 ) )
03116                     m_pageList.append( new KPrPage( this, m_masterPage ) );
03117                 m_pageList.at(i)->setNoteText(note.attribute("note"));
03118                 i++;
03119             }
03120             else
03121                 m_pageWhereLoadObject->setNoteText(note.attribute("note"));
03122         }
03123         note=note.nextSibling().toElement();
03124     }
03125 }
03126 
03127 void KPrDocument::loadUsedSoundFileFromXML( const QDomElement &element )
03128 {
03129     usedSoundFile = QStringList();
03130     haveNotOwnDiskSoundFile = QStringList();
03131     QDomElement fileElement = element.firstChild().toElement();
03132     while ( !fileElement.isNull() ) {
03133         if ( fileElement.tagName() == "FILE" ) {
03134             QString fileName;
03135             if ( fileElement.hasAttribute( "name" ) )
03136                 fileName = fileElement.attribute( "name" );
03137 
03138             if ( fileElement.hasAttribute( "filename" ) ) {
03139                 QString name = fileElement.attribute( "filename" );
03140                 QFile _file( name );
03141                 if ( _file.open( IO_ReadOnly ) ) {
03142                     fileName = name;
03143                     _file.close();
03144                 }
03145                 else
03146                     haveNotOwnDiskSoundFile.append( name );
03147             }
03148 
03149             usedSoundFile.append( fileName );
03150 
03151             fileElement = fileElement.nextSibling().toElement();
03152         }
03153     }
03154 }
03155 
03156 void KPrDocument::loadImagesFromStore( KoStore *_store )
03157 {
03158     if ( _store ) {
03159         m_pictureCollection.readFromStore( _store, m_pictureMap );
03160         m_pictureMap.clear(); // Release memory
03161     }
03162 }
03163 
03164 bool KPrDocument::completeLoading( KoStore* _store )
03165 {
03166     kdDebug()<<"bool KPrDocument::completeLoading( KoStore* _store )*************************\n";
03167     emit sigProgress( 80 );
03168 
03169     if ( _store ) {
03170         loadImagesFromStore( _store );
03171         emit sigProgress( 90 );
03172 
03173         if ( !usedSoundFile.isEmpty() )
03174             loadUsedSoundFileFromStore( _store, usedSoundFile );
03175 
03176         if ( _clean )
03177             createHeaderFooter();
03178         //else {
03179         //m_pageList.last()->updateBackgroundSize();
03180         //}
03181 
03182 
03183         if ( saveOnlyPage == -1 ) {
03184             // ### following call independant of saveOnlyPage's value?
03185             m_masterPage->completeLoading( _clean, lastObj );
03186             QPtrListIterator<KPrPage> it( m_pageList );
03187             for ( ; it.current(); ++it )
03188                 it.current()->completeLoading( _clean, lastObj );
03189         }
03190     } else {
03191         if ( _clean )
03192         {
03194             setPageLayout( __pgLayout );
03195         }
03196         else
03197             setPageLayout( m_pageLayout );
03198     }
03199 
03200     compatibilityFromOldFileFormat();
03201 
03202     emit sigProgress( 100 );
03203     recalcVariables( VT_FIELD );
03204     emit sigProgress( -1 );
03205 
03206     connect( documentInfo(), SIGNAL( sigDocumentInfoModifed()),this,SLOT(slotDocumentInfoModifed() ) );
03207     //desactivate bgspellchecking
03208     //attributes isReadWrite is not placed at the beginning !
03209     if ( !isReadWrite())
03210         enableBackgroundSpellCheck( false );
03211     return true;
03212 }
03213 
03214 void KPrDocument::loadUsedSoundFileFromStore( KoStore *_store, QStringList _list )
03215 {
03216     int i = m_insertFilePage;
03217     QStringList::Iterator it = _list.begin();
03218     for ( ; it != _list.end(); ++it ) {
03219         QString soundFile = *it;
03220 
03221         if ( _store->open( soundFile ) ) {
03222             kdDebug( 33001 ) << "Not found file on disk. Use this( " << soundFile << " ) file." << endl;
03223             KoStoreDevice dev( _store );
03224             int size = _store->size();
03225             char *data = new char[size];
03226             dev.readBlock( data, size );
03227 
03228             int position = soundFile.findRev( '.' );
03229             QString format = soundFile.right( soundFile.length() - position );
03230             KTempFile *tmpFile = new KTempFile( QString::null, format );
03231             tmpFile->setAutoDelete( true );
03232             tmpFile->file()->writeBlock( data, size );
03233             tmpFile->close();
03234 
03235             QString tmpFileName = tmpFile->name();
03236             tmpSoundFileList.append( tmpFile );
03237 
03238             QString _fileName = *haveNotOwnDiskSoundFile.at( i );
03239             ++i;
03240 
03241             QPtrListIterator<KPrPage> it( m_pageList );
03242             for ( ; it.current(); ++it ) {
03243                 QString _file = it.current()->getPageSoundFileName();
03244                 if ( !_file.isEmpty() && _file == _fileName )
03245                     it.current()->setPageSoundFileName( tmpFileName );
03246 
03247                 QPtrListIterator<KPrObject> oIt( it.current()->objectList() );
03248                 for ( ; oIt.current(); ++oIt ) {
03249                     _file = oIt.current()->getAppearSoundEffectFileName();
03250                     if ( !_file.isEmpty() && _file == _fileName )
03251                         oIt.current()->setAppearSoundEffectFileName( tmpFileName );
03252 
03253                     _file = oIt.current()->getDisappearSoundEffectFileName();
03254                     if ( !_file.isEmpty() && _file == _fileName )
03255                         oIt.current()->setDisappearSoundEffectFileName( tmpFileName );
03256                 }
03257             }
03258 
03259             _store->close();
03260             delete[] data;
03261         }
03262         else {
03263             kdDebug( 33001 ) << "Found this( " << soundFile << " ) file on disk" << endl;
03264         }
03265     }
03266 }
03267 
03268 void KPrDocument::setPageLayout( const KoPageLayout &pgLayout )
03269 {
03270     //     if ( _pageLayout == pgLayout )
03271     //  return;
03272 
03273     m_pageLayout = pgLayout;
03274 
03275     //for ( int i = 0; i < static_cast<int>( m_pageList.count() ); i++ )
03276     //    m_pageList.at( i )->updateBackgroundSize();
03277 
03278     repaint( false );
03279     layout();
03280     // don't setModified(true) here, since this is called on startup
03281 }
03282 
03283 //when we change pagelayout we must re-position header/footer
03284 void KPrDocument::updateHeaderFooterPosition( )
03285 {
03286     KoRect pageRect=m_masterPage->getPageRect();
03287     QRect oldBoundingRect = zoomHandler()->zoomRect( _header->getRepaintRect() );
03288     _header->setOrig(pageRect.topLeft ());
03289     _header->setSize(pageRect.width(),_header->getSize().height());
03290     repaint( oldBoundingRect );
03291     repaint(_header);
03292 
03293     oldBoundingRect = zoomHandler()->zoomRect( _footer->getRepaintRect() );
03294     _footer->setOrig(pageRect.left(),pageRect.bottom()-_footer->getSize().height());
03295     _footer->setSize(pageRect.width(),_footer->getSize().height());
03296     repaint(oldBoundingRect);
03297     repaint(_footer);
03298 }
03299 
03300 bool KPrDocument::initDoc(InitDocFlags flags, QWidget* parentWidget)
03301 {
03302 
03303     if (flags==KoDocument::InitDocEmpty)
03304     {
03305         QString fileName( locate("kpresenter_template", "Screenpresentations/.source/Plain.kpt",
03306                                  KPrFactory::global() ) );
03307         objStartY = 0;
03308         _clean = true;
03309         bool ok = loadNativeFormat( fileName );
03310         if ( !ok )
03311             showLoadingErrorDialog();
03312         resetURL();
03313         setEmpty();
03314         return ok;
03315     }
03316 
03317     QString file;
03318     KoTemplateChooseDia::ReturnType ret;
03319     KoTemplateChooseDia::DialogType dlgtype;
03320     if (flags != InitDocFileNew)
03321             dlgtype = KoTemplateChooseDia::Everything;
03322     else
03323             dlgtype = KoTemplateChooseDia::OnlyTemplates;
03324 
03325     ret = KoTemplateChooseDia::choose( KPrFactory::global(), file,
03326                                        dlgtype, "kpresenter_template", parentWidget );
03327     if ( ret == KoTemplateChooseDia::Template ) {
03328         _clean = true; //was a parameter called "clean", but unused
03329         bool ok = loadNativeFormat( file );
03330         if ( !ok )
03331             showLoadingErrorDialog();
03332         objStartY = 0;
03333         _clean = true;
03334         resetURL();
03335         setEmpty();
03336         return ok;
03337     } else if ( ret == KoTemplateChooseDia::File ) {
03338         objStartY = 0;
03339         _clean = true;
03340         KURL url( file );
03341         bool ok = openURL( url );
03342         return ok;
03343     } else if ( ret == KoTemplateChooseDia::Empty ) {
03344         QString fileName( locate("kpresenter_template", "Screenpresentations/.source/Plain.kpt",
03345                                  KPrFactory::global() ) );
03346         objStartY = 0;
03347         _clean = true;
03348         bool ok = loadNativeFormat( fileName );
03349         if ( !ok )
03350             showLoadingErrorDialog();
03351         resetURL();
03352         setEmpty();
03353         return ok;
03354     } else
03355         return false;
03356 }
03357 
03358 void KPrDocument::openExistingFile( const QString& file )
03359 {
03360     objStartY = 0;
03361     _clean = true;
03362     KoDocument::openExistingFile( file );
03363 }
03364 
03365 void KPrDocument::openTemplate( const QString& file )
03366 {
03367   KoDocument::openTemplate( file );
03368   objStartY = 0;
03369   _clean = true;
03370 }
03371 
03372 void KPrDocument::initEmpty()
03373 {
03374     QString fileName( locate("kpresenter_template", "Screenpresentations/.source/Plain.kpt",
03375                              KPrFactory::global() ) );
03376     objStartY = 0;
03377     _clean = true;
03378     setModified(true);
03379     bool ok = loadNativeFormat( fileName );
03380     if ( !ok )
03381         showLoadingErrorDialog();
03382     resetURL();
03383 }
03384 
03385 void KPrDocument::setEmpty()
03386 {
03387     KoDocument::setEmpty();
03388     // Whether loaded from template or from empty doc: this is a new one -> set creation date
03389     m_varColl->variableSetting()->setCreationDate(QDateTime::currentDateTime());
03390     recalcVariables( VT_DATE ); // , VST_CREATION_DATE ...
03391     // If we then load a document, it will override that date.
03392 }
03393 
03394 void KPrDocument::setGridValue( double _x, double _y, bool _replace )
03395 {
03396     oldGridX = m_gridX;
03397     oldGridY = m_gridY;
03398     m_gridX=_x;
03399     m_gridY=_y;
03400     if ( _replace )
03401         replaceObjs();
03402 }
03403 
03404 void KPrDocument::repaint( bool erase )
03405 {
03406     QPtrListIterator<KoView> it( views() );
03407     for( ; it.current(); ++it ) {
03408         KPrCanvas* canvas = ((KPrView*)it.current())->getCanvas();
03409         canvas->repaint( erase );
03410     }
03411 }
03412 
03413 void KPrDocument::repaint( const QRect& rect )
03414 {
03415     QRect r;
03416     QPtrListIterator<KoView> it( views() );
03417     for( ; it.current(); ++it ) {
03418         r = rect;
03419         KPrCanvas* canvas = ((KPrView*)it.current())->getCanvas();
03420         r.moveTopLeft( QPoint( r.x() - canvas->diffx(),
03421                                r.y() - canvas->diffy() ) );
03422         canvas->update( r );
03423     }
03424 }
03425 
03426 void KPrDocument::layout(KPrObject *kpobject)
03427 {
03428     KPrTextObject * obj = dynamic_cast<KPrTextObject *>( kpobject );
03429     if (obj)
03430         obj->layout();
03431 }
03432 
03433 void KPrDocument::layout()
03434 {
03435     QPtrListIterator<KoView> it( views() );
03436     for( ; it.current(); ++it ) {
03437         KPrCanvas* canvas = ((KPrView*)it.current())->getCanvas();
03438         canvas->layout();
03439     }
03440 }
03441 
03442 void KPrDocument::repaint( KPrObject *kpobject )
03443 {
03444     repaint( m_zoomHandler->zoomRect( kpobject->getRepaintRect() ) );
03445 }
03446 
03447 QValueList<int> KPrDocument::getPageEffectSteps( unsigned int num )
03448 {
03449     return m_pageList.at(num)->getEffectSteps();
03450 }
03451 
03452 QRect KPrDocument::getPageRect( bool decBorders ) const
03453 {
03454     int pw, ph, bl = static_cast<int>(m_pageLayout.ptLeft);
03455     int br = static_cast<int>(m_pageLayout.ptRight);
03456     int bt = static_cast<int>(m_pageLayout.ptTop);
03457     int bb = static_cast<int>(m_pageLayout.ptBottom);
03458     int wid = static_cast<int>(m_pageLayout.ptWidth);
03459     int hei = static_cast<int>(m_pageLayout.ptHeight);
03460 
03461     if ( !decBorders ) {
03462         br = 0;
03463         bt = 0;
03464         bl = 0;
03465         bb = 0;
03466     }
03467 
03468     pw = wid  - ( bl + br );
03469     ph = hei - ( bt + bb );
03470 
03471     return QRect( bl, bt, pw, ph );
03472 }
03473 
03474 int KPrDocument::getLeftBorder() const
03475 {
03476     return static_cast<int>(m_pageLayout.ptLeft);
03477 }
03478 
03479 int KPrDocument::getTopBorder() const
03480 {
03481     return static_cast<int>(m_pageLayout.ptTop);
03482 }
03483 
03484 int KPrDocument::getBottomBorder() const
03485 {
03486     return static_cast<int>(m_pageLayout.ptBottom);
03487 }
03488 
03489 int KPrDocument::getRightBorder() const
03490 {
03491     return static_cast<int>(m_pageLayout.ptRight);
03492 }
03493 
03494 void KPrDocument::deletePage( int _page )
03495 {
03496     kdDebug(33001) << "KPrDocument::deletePage " << _page << endl;
03497     //m_pageList.at(_page)->deletePage();
03498     if ( m_pageList.count()==1 )
03499         return;
03500     KPrDeletePageCmd *cmd = new KPrDeletePageCmd( i18n("Delete Slide"), _page, this );
03501     cmd->execute();
03502     addCommand(cmd);
03503 }
03504 
03505 void KPrDocument::insertPage( KPrPage *page, int currentPageNum, int insertPageNum )
03506 {
03507     // check if page was allready deleted
03508     int pos = m_deletedPageList.findRef( page );
03509     if ( pos != -1 )
03510         m_deletedPageList.take( pos );
03511 
03512     m_pageList.insert( insertPageNum, page );
03513 
03514     pageOrderChanged();
03515     //activate this page in all views which on slide currentPageNum
03516     QPtrListIterator<KoView> it( views() );
03517     for (; it.current(); ++it )
03518     {
03519         KPrView *view = static_cast<KPrView*>( it.current() );
03520         view->addSideBarItem( insertPageNum );
03521 
03522         // change to the new page if the view was on the current page.
03523         if ( (int)view->getCurrPgNum() - 1 == currentPageNum )
03524         {
03525             view->skipToPage( insertPageNum );
03526         }
03527         else // recalc the page number as it might have been changed
03528         {
03529             view->recalcCurrentPageNum();
03530         }
03531     }
03532 }
03533 
03534 void KPrDocument::takePage( KPrPage *page, int pageNum )
03535 {
03536     int pos = m_pageList.findRef( page );
03537     m_pageList.take( pos );
03538     m_deletedPageList.append( page );
03539 
03540     pageOrderChanged();
03541 
03542     QPtrListIterator<KoView> it( views() );
03543     for (; it.current(); ++it )
03544     {
03545         KPrView *view = static_cast<KPrView*>( it.current() );
03546         view->removeSideBarItem( pos );
03547 
03548         // change to the new page if the view was on the current page.
03549         if ( (int)view->getCurrPgNum() - 1 == pos )
03550         {
03551             view->skipToPage( pageNum );
03552         }
03553         else // recalc the page number as it might have been changed
03554         {
03555             view->recalcCurrentPageNum();
03556         }
03557     }
03558 
03559     repaint( false );
03560 }
03561 
03562 void KPrDocument::pageOrderChanged()
03563 {
03564     recalcVariables( VT_PGNUM );
03565 
03566     //update statusbar
03567     emit pageNumChanged();
03568     emit sig_updateMenuBar();
03569 }
03570 
03571 void KPrDocument::movePageTo( int oldPos, int newPos )
03572 {
03573     kdDebug(33001) << "movePage oldPos = " << oldPos << ", neuPos = " << newPos << endl;
03574 
03575     KPrPage * page = m_pageList.take( oldPos );
03576     m_pageList.insert( newPos, page );
03577 
03578     pageOrderChanged();
03579 
03580     // Update the sidebars
03581     QPtrListIterator<KoView> it( views() );
03582     for (; it.current(); ++it )
03583     {
03584         KPrView *view = static_cast<KPrView*>( it.current() );
03585         view->moveSideBarItem( oldPos, newPos );
03586 
03587         // change to the new page if the view was on the old pos.
03588         if ( (int)view->getCurrPgNum() - 1 == oldPos )
03589         {
03590             view->skipToPage( newPos );
03591         }
03592         else // recalc the page number as it might have been changed
03593         {
03594             view->recalcCurrentPageNum();
03595         }
03596     }
03597 }
03598 
03599 QString KPrDocument::templateFileName( bool chooseTemplate, const QString &theFile )
03600 {
03601     QString fileName;
03602     if ( !chooseTemplate ) {
03603         if ( theFile.isEmpty() )
03604             fileName = locateLocal( "appdata", "default.kpr" );
03605         else
03606             fileName = theFile;
03607     } else {
03608         // TODO: pass parentWidget as parameter to this method
03609         QWidget* parentWidget = 0;
03610         QString _template;
03611         if ( KoTemplateChooseDia::choose( KPrFactory::global(), _template,
03612                                           KoTemplateChooseDia::OnlyTemplates,
03613                                           "kpresenter_template", parentWidget ) == KoTemplateChooseDia::Cancel )
03614             return QString::null;
03615         QFileInfo fileInfo( _template );
03616         fileName = fileInfo.dirPath( true ) + "/" + fileInfo.baseName() + ".kpt";
03617 
03618         KURL src, dest;
03619         src.setPath( fileName );
03620         dest.setPath( locateLocal( "appdata", "default.kpr" ) );
03621         kdDebug(33001) << "Copying template  (in KPrDocument::templateFileName)" << endl
03622                        << "  from: " << src.prettyURL() << endl
03623                        << "  to: " << dest.prettyURL() << endl;
03624         KIO::NetAccess::file_copy( src,
03625                    dest,
03626                    -1, /* default permissions */
03627                    true /* overwrite */ );
03628     }
03629     return fileName;
03630 }
03631 
03632 int KPrDocument::insertNewPage( const QString &cmdName, int _page, InsertPos _insPos,
03633                                   bool chooseTemplate, const QString &theFile )
03634 {
03635     kdDebug(33001) << "KPrDocument::insertNewPage " << _page << endl;
03636 
03637     QString fileName=templateFileName(chooseTemplate, theFile);
03638     if(fileName.isEmpty())
03639         return -1;
03640 
03641     _clean = false;
03642 
03643     objStartY=-1;
03644 
03645     //insert page.
03646     KPrPage *newpage = new KPrPage( this, m_masterPage );
03647 
03648     m_pageWhereLoadObject=newpage;
03649     m_childCountBeforeInsert = children().count();
03650 
03651     bool ok = loadNativeFormat( fileName );
03652     if ( !ok )
03653         showLoadingErrorDialog();
03654 
03655     objStartY = 0;
03656 
03657     KPrInsertPageCmd *cmd = new KPrInsertPageCmd( cmdName, _page, _insPos, newpage, this );
03658     cmd->execute();
03659     addCommand(cmd);
03660 
03661     _clean = true;
03662     m_pageWhereLoadObject=0L;
03663     m_childCountBeforeInsert = 0;
03664     return _page;
03665 }
03666 
03667 void KPrDocument::savePage( const QString &file, int pgnum, bool ignore )
03668 {
03669     saveOnlyPage = pgnum;
03670     _duplicatePage=ignore;
03671     saveNativeFormat( file );
03672     _duplicatePage=false;
03673     saveOnlyPage = -1;
03674 }
03675 
03676 void KPrDocument::replaceObjs( bool createUndoRedo )
03677 {
03678     KMacroCommand * macroCmd = 0L;
03679     QPtrListIterator<KPrPage> oIt(m_pageList);
03680     for (; oIt.current(); ++oIt )
03681     {
03682         KCommand *cmd=oIt.current()->replaceObjs( createUndoRedo, oldGridX,oldGridY,_txtBackCol, _otxtBackCol);
03683         if(cmd && createUndoRedo)
03684         {
03685             if ( !macroCmd)
03686                 macroCmd = new KMacroCommand( i18n("Set New Options") );
03687             macroCmd->addCommand(cmd);
03688         }
03689         else
03690             delete cmd;
03691     }
03692 
03693     if(macroCmd)
03694     {
03695         macroCmd->execute();
03696         addCommand(macroCmd);
03697     }
03698 }
03699 
03700 void KPrDocument::restoreBackground( KPrPage *page )
03701 {
03702     page->background()->reload();
03703 }
03704 
03705 KCommand * KPrDocument::loadPastedObjs( const QString &in, KPrPage* _page )
03706 {
03707     QDomDocument doc;
03708     doc.setContent( in );
03709 
03710     QDomElement document=doc.documentElement();
03711 
03712     // DOC
03713     if (document.tagName()!="DOC") {
03714         kdError(33001) << "Missing DOC" << endl;
03715         return 0L;
03716     }
03717 
03718     bool ok = false;
03719 
03720     if(document.hasAttribute("mime") && document.attribute("mime")=="application/x-kpresenter")
03721         ok=true;
03722 
03723     if ( !ok )
03724         return 0L;
03725     m_pageWhereLoadObject=_page;
03726     KCommand *cmd = loadObjects(document,true);
03727     m_pageWhereLoadObject=0L;
03728 
03729     repaint( false );
03730     setModified( true );
03731     return cmd;
03732 }
03733 
03734 void KPrDocument::deSelectAllObj()
03735 {
03736     QPtrListIterator<KoView> it( views() );
03737     for (; it.current(); ++it )
03738         ((KPrView*)it.current())->getCanvas()->deSelectAllObj();
03739 }
03740 
03741 void KPrDocument::deSelectObj(KPrObject *obj)
03742 {
03743     QPtrListIterator<KoView> it( views() );
03744     for (; it.current(); ++it )
03745         ((KPrView*)it.current())->getCanvas()->deSelectObj( obj );
03746 }
03747 
03748 void KPrDocument::setDisplayObjectMasterPage( bool b )
03749 {
03750     QPtrListIterator<KoView> it( views() );
03751     for (; it.current(); ++it )
03752         ((KPrView*)it.current())->updateDisplayObjectMasterPageButton();
03753     repaint(b);
03754 }
03755 
03756 void KPrDocument::setDisplayBackground( bool b )
03757 {
03758     QPtrListIterator<KoView> it( views() );
03759     for (; it.current(); ++it )
03760         ((KPrView*)it.current())->updateDisplayBackgroundButton();
03761     repaint(b);
03762 }
03763 
03764 void KPrDocument::setHeader( bool b )
03765 {
03766     _header->setDrawEditRect( b );
03767     _header->setDrawEmpty( b );
03768     if(!b)
03769     {
03770         terminateEditing(_header);
03771         deSelectObj(_header);
03772     }
03773     m_masterPage->setHeader( b, false );
03774     updateHeaderFooterButton();
03775     repaint(b);
03776 }
03777 
03778 void KPrDocument::setFooter( bool b )
03779 {
03780     _footer->setDrawEditRect( b );
03781     _footer->setDrawEmpty( b );
03782     if(!b)
03783     {
03784         terminateEditing(_footer);
03785         deSelectObj(_footer);
03786     }
03787     m_masterPage->setFooter( b, false );
03788     updateHeaderFooterButton();
03789     repaint(b);
03790 }
03791 
03792 void KPrDocument::updateHeaderFooterButton()
03793 {
03794     QPtrListIterator<KoView> it( views() );
03795     for (; it.current(); ++it )
03796         ((KPrView*)it.current())->updateHeaderFooterButton();
03797 }
03798 
03799 void KPrDocument::makeUsedPixmapList()
03800 {
03801     usedPictures.clear();
03802 
03803     for ( uint i = 0; i < m_pageList.count(); i++ ) {
03804         if ( saveOnlyPage != -1 &&
03805              static_cast<int>(i) != saveOnlyPage )
03806             continue;
03807         m_pageList.at(i)->makeUsedPixmapList();
03808     }
03809     // ### following call independant of saveOnlyPage's value?
03810     if ( saveOnlyPage == -1 )
03811         m_masterPage->makeUsedPixmapList();
03812 }
03813 
03814 void KPrDocument::makeUsedSoundFileList()
03815 {
03816     if ( saveOnlyPage != -1 )
03817         return;
03818 
03819     usedSoundFile.clear();
03820 
03821     QPtrListIterator<KPrPage> it( m_pageList );
03822     for ( ; it.current(); ++it ) {
03823         QString _file = it.current()->getPageSoundFileName();
03824         if ( !_file.isEmpty() && usedSoundFile.findIndex( _file ) == -1 )
03825             usedSoundFile.append( _file );
03826 
03827         QPtrListIterator<KPrObject> oIt( it.current()->objectList() );
03828         for ( ; oIt.current(); ++oIt ) {
03829             _file = oIt.current()->getAppearSoundEffectFileName();
03830             if ( !_file.isEmpty() && usedSoundFile.findIndex( _file ) == -1 )
03831                 usedSoundFile.append( _file );
03832 
03833             _file = oIt.current()->getDisappearSoundEffectFileName();
03834             if ( !_file.isEmpty() && usedSoundFile.findIndex( _file ) == -1 )
03835                 usedSoundFile.append( _file );
03836         }
03837     }
03838 }
03839 
03840 KoView* KPrDocument::createViewInstance( QWidget* parent, const char* name )
03841 {
03842     //the page numbers have to be recalced for the sticky objects
03843     //as it could not be done during the constructor of KPrView
03844     recalcPageNum();
03845     return new KPrView( this, parent, name );
03846 }
03847 
03848 void KPrDocument::paintContent( QPainter& painter, const QRect& rect,
03849                                   bool /*transparent*/, double zoomX, double zoomY )
03850 {
03851     m_zoomHandler->setZoom( 100 );
03852     if ( zoomHandler()->zoomedResolutionX() != zoomX || zoomHandler()->zoomedResolutionY() != zoomY )
03853     {
03854         int zoomLevel = qRound( 100 * zoomY / zoomHandler()->zoomedResolutionY() ); // ## ignores the case where the x and y scaling differs
03855         zoomHandler()->setZoom( zoomLevel );
03856         bool forPrint = painter.device() && painter.device()->devType() == QInternal::Printer;
03857         newZoomAndResolution( false, forPrint );
03858     }
03859     //for the moment draw first page.
03860     KPrPage *page=m_pageList.first();
03861     if( m_initialActivePage )
03862         page = m_initialActivePage;
03863 
03864     int pageNum = m_pageList.findRef( page );
03865 
03866     if ( page->displayBackground() )
03867         page->background()->drawBackground( &painter, zoomHandler(), rect, false );
03868     if ( page->displayObjectFromMasterPage() )
03869     {
03870         KPrPage *masterPage = page->masterPage();
03871         if ( masterPage )
03872         {
03873             QPtrListIterator<KPrObject> it( masterPage->objectList() );
03874             //draw objects on master slide
03875             for ( ; it.current() ; ++it )
03876             {
03877                 if( (it.current()==_header && !page->hasHeader())||(it.current()==_footer && !page->hasFooter()))
03878                     continue;
03879                 it.current()->draw( &painter, zoomHandler(), pageNum, SM_NONE );
03880             }
03881         }
03882     }
03883     QPtrListIterator<KPrObject> it( page->objectList() );
03884     for ( ; it.current() ; ++it )
03885         it.current()->draw( &painter, zoomHandler(), pageNum, SM_NONE );
03886 }
03887 
03888 QPixmap KPrDocument::generatePreview( const QSize& size )
03889 {
03890     int oldZoom = zoomHandler()->zoom();
03891     double oldResolutionX = zoomHandler()->resolutionX();
03892     double oldResolutionY = zoomHandler()->resolutionY();
03893 
03894     QPixmap pix = KoDocument::generatePreview(size);
03895 
03896     zoomHandler()->setResolution( oldResolutionX, oldResolutionY );
03897     zoomHandler()->setZoom(oldZoom);
03898     newZoomAndResolution( false, false );
03899 
03900     return pix;
03901 }
03902 
03903 void KPrDocument::addShell( KoMainWindow *shell )
03904 {
03905     connect( shell, SIGNAL( documentSaved() ), m_commandHistory, SLOT( documentSaved() ) );
03906     KoDocument::addShell( shell );
03907 }
03908 
03909 void KPrDocument::movePage( int from, int to )
03910 {
03911     kdDebug(33001) << "KPrDocument::movePage from=" << from << " to=" << to << endl;
03912     KPrMovePageCmd *cmd = new KPrMovePageCmd( i18n("Move Slide"), from, to, this );
03913     cmd->execute();
03914     addCommand(cmd);
03915 }
03916 
03917 void KPrDocument::copyPage( int from )
03918 {
03919     _clean = false;
03920     m_childCountBeforeInsert = children().count();
03921 
03922     _duplicatePage=true; // ### now also set via savePage() parameter below
03923 
03924     kdDebug(33001) << "KPrDocument::copyPage from=" << from << " to=" << from + 1 << endl;
03925     kdDebug(33001) << "mimeType = " << mimeType() << ", outputMimeType = " << outputMimeType() << endl;
03926     bool wasSelected = isSlideSelected( from );
03927     KTempFile tempFile( QString::null, mimeType() == nativeOasisMimeType() ? ".oop": ".kpr" );
03928     tempFile.setAutoDelete( true );
03929     savePage( tempFile.name(), from, true );
03930 
03931     //insert page.
03932     KPrPage *newpage = new KPrPage( this, m_masterPage );
03933 
03934     m_pageWhereLoadObject = newpage;
03935 
03936     bool ok = loadNativeFormat( tempFile.name() );
03937     if ( !ok )
03938         showLoadingErrorDialog();
03939 
03940     KPrInsertPageCmd *cmd = new KPrInsertPageCmd( i18n("Duplicate Slide"), from, IP_AFTER, newpage, this );
03941     cmd->execute();
03942     addCommand(cmd);
03943 
03944     _duplicatePage=false;
03945 
03946     _clean = true;
03947     m_pageWhereLoadObject=0L;
03948     m_childCountBeforeInsert = 0;
03949 
03950     selectPage( from + 1, wasSelected );
03951 }
03952 
03953 void KPrDocument::copyPageToClipboard( int pgnum )
03954 {
03955     // We save the page to a temp file and set the URL of the file in the clipboard
03956     // Yes it's a hack but at least we don't hit the clipboard size limit :)
03957     // (and we don't have to implement copy-tar-structure-to-clipboard)
03958     // In fact it even allows copying a [1-page] kpr in konq and pasting it in kpresenter :))
03959     kdDebug(33001) << "KPrDocument::copyPageToClipboard pgnum=" << pgnum << endl;
03960     kdDebug(33001) << "mimeType = " << mimeType() << ", outputMimeType = " << outputMimeType() << endl;
03961     KTempFile tempFile( QString::null, mimeType() == nativeOasisMimeType() ? ".oop": ".kpr" );
03962     savePage( tempFile.name(), pgnum, true );
03963     KURL url; url.setPath( tempFile.name() );
03964     KURL::List lst;
03965     lst.append( url );
03966     QApplication::clipboard()->setData( new KURLDrag( lst ) );
03967     m_tempFileInClipboard = tempFile.name(); // do this last, the above calls clipboardDataChanged
03968 }
03969 
03970 void KPrDocument::pastePage( const QMimeSource * data, int pgnum )
03971 {
03972     KURL::List lst;
03973     if ( KURLDrag::decode( data, lst ) && !lst.isEmpty() )
03974     {
03975         insertNewPage(i18n("Paste Slide"),  pgnum, IP_BEFORE, FALSE, lst.first().path() );
03976         //selectPage( pgnum, true /* should be part of the file ? */ );
03977     }
03978 }
03979 
03980 void KPrDocument::clipboardDataChanged()
03981 {
03982     if ( !m_tempFileInClipboard.isEmpty() )
03983     {
03984         kdDebug(33001) << "KPrDocument::clipboardDataChanged, deleting temp file " << m_tempFileInClipboard << endl;
03985         unlink( QFile::encodeName( m_tempFileInClipboard ) );
03986         m_tempFileInClipboard = QString::null;
03987     }
03988     // TODO enable paste as well, when a txtobject is activated
03989     // and there is plain text in the clipboard. Then enable this code.
03990     //QMimeSource *data = QApplication::clipboard()->data();
03991     //bool canPaste = data->provides( "text/uri-list" ) || data->provides( "application/x-kpresenter-selection" );
03992     // emit enablePaste( canPaste );
03993 }
03994 
03995 void KPrDocument::selectPage( int pgNum /* 0-based */, bool select )
03996 {
03997     Q_ASSERT( pgNum >= 0 );
03998     KPrPage *page = m_pageList.at( pgNum );
03999     page->slideSelected(select);
04000     kdDebug(33001) << "KPrDocument::selectPage pgNum=" << pgNum << " select=" << select << endl;
04001     setModified(true);
04002 
04003     updateSideBarItem( page );
04004     updatePresentationButton();
04005     //update statusbar
04006     emit pageNumChanged();
04007 }
04008 
04009 KPrPage * KPrDocument::findPage(KPrObject *object)
04010 {
04011     QPtrList<KPrObject> masterObjects( m_masterPage->objectList() );
04012     if ( masterObjects.findRef( object ) != -1 )
04013     {
04014         //kdDebug(33001) << "Object is on the master page" << endl;
04015         return m_masterPage;
04016     }
04017     QPtrListIterator<KPrPage> it( m_pageList );
04018     for ( ; it.current(); ++it ) {
04019         QPtrList<KPrObject> list( it.current()->objectList() );
04020         if ( list.findRef( object ) != -1 ) {
04021             //kdDebug(33001) << "Object is on page " << m_pageList.findRef(it.current()) + 1 << endl;
04022             return it.current();
04023         }
04024     }
04025     kdDebug(33001) << "Object not found on a page" << endl;
04026     return 0L;
04027 }
04028 
04029 KPrPage * KPrDocument::findPage(QPtrList<KPrObject> &objects)
04030 {
04031     KPrObject *object;
04032     for ( object = objects.first(); object; object=objects.next() ) {
04033         QPtrList<KPrObject> list( m_masterPage->objectList() );
04034         if ( list.findRef( object ) != -1 )
04035         {
04036             //kdDebug(33001) << "Object is on the master page" << endl;
04037             return m_masterPage;
04038         }
04039     }
04040     object = objects.first();
04041     for ( KPrPage *page=m_pageList.first(); page; page=m_pageList.next() ) {
04042         QPtrList<KPrObject> list( page->objectList() );
04043         if ( list.findRef( object ) != -1 ) {
04044             //kdDebug(33001) << "The Objects are on page " << m_pageList.findRef(page) + 1 << endl;
04045             return page;
04046         }
04047     }
04048     kdDebug(33001) << "Objects not found on a page" << endl;
04049     return 0L;
04050 }
04051 
04052 void KPrDocument::updateSideBarItem( KPrPage * page )
04053 {
04054     // Update the views
04055     QPtrListIterator<KoView> it( views() );
04056     for (; it.current(); ++it )
04057         static_cast<KPrView*>( it.current() )->updateSideBarItem( page );
04058 }
04059 
04060 bool KPrDocument::isSlideSelected( int pgNum /* 0-based */ )
04061 {
04062     Q_ASSERT( pgNum >= 0 );
04063     return m_pageList.at(pgNum)->isSlideSelected();
04064 }
04065 
04066 QValueList<int> KPrDocument::listOfDisplaySelectedSlides( const QValueList<KPrPage*> & lst) /* returned list is 0-based */
04067 {
04068     QValueList<int> result;
04069     QValueListConstIterator<KPrPage*> itPage;
04070     QValueListConstIterator<KPrPage*> itPageEnd = lst.end();
04071     for( itPage =  lst.begin() ; itPage != itPageEnd; ++itPage )
04072     {
04073         int pageNum = m_pageList.find(*itPage );
04074         if ( pageNum != -1 )
04075         {
04076             kdDebug()<<" KPrDocument::displaySelectedSlide : add slide number :"<<pageNum<<endl;
04077             result << pageNum;
04078         }
04079     }
04080     return result;
04081 }
04082 
04083 
04084 QValueList<int> KPrDocument::displaySelectedSlides()  /* returned list is 0-based */
04085 {
04086     QValueList<int> result;
04087     if ( m_customListTest )
04088         return *m_customListTest;
04089     if ( m_presentationName.isEmpty() )
04090         return selectedSlides();
04091     else
04092     {
04093         kdDebug()<<" KPrDocument::displaySelectedSlide m_presentationName : "<<m_presentationName<<endl;
04094         result = listOfDisplaySelectedSlides( m_customListSlideShow[m_presentationName]);
04095     }
04096     return result;
04097 }
04098 
04099 QValueList<int> KPrDocument::selectedSlides() /* returned list is 0-based */
04100 {
04101     QValueList<int> result;
04102     for ( int i = 0; i < static_cast<int>( m_pageList.count() ); i++ ) {
04103         if(m_pageList.at(i)->isSlideSelected())
04104             result <<i;
04105     }
04106     return result;
04107 }
04108 
04109 QString KPrDocument::selectedForPrinting() {
04110     QString ret;
04111     int start=-1, end=-1;
04112     bool continuous=false;
04113     for ( int i = 0; i < static_cast<int>( m_pageList.count() ); i++ ) {
04114         if(m_pageList.at(i)->isSlideSelected()) {
04115             if(continuous)
04116                 ++end;
04117             else {
04118                 start=i;
04119                 end=i;
04120                 continuous=true;
04121             }
04122         }
04123         else {
04124             if(continuous) {
04125                 if(start==end)
04126                     ret+=QString::number(start+1)+",";
04127                 else
04128                     ret+=QString::number(start+1)+"-"+QString::number(end+1)+",";
04129                 continuous=false;
04130             }
04131         }
04132     }
04133     if(continuous) {
04134         if(start==end)
04135             ret+=QString::number(start+1);
04136         else
04137             ret+=QString::number(start+1)+"-"+QString::number(end+1);
04138     }
04139     if(','==ret[ret.length()-1])
04140         ret.truncate(ret.length()-1);
04141     return ret;
04142 }
04143 
04144 void KPrDocument::slotRepaintChanged( KPrTextObject *kptextobj )
04145 {
04146     //todo
04147     //use this function for the moment
04148     repaint( kptextobj );
04149 }
04150 
04151 
04152 void KPrDocument::recalcVariables( int type )
04153 {
04154     recalcPageNum();
04155     QValueList<KoVariable* > modifiedVariables = m_varColl->recalcVariables(type);
04156     if ( modifiedVariables.isEmpty() )
04157         return;
04158 
04159     // TODO use the return value from recalcVariables to only repaint what has changed.
04160     QPtrListIterator<KPrPage> it( m_pageList );
04161     for ( ; it.current(); ++it )
04162         it.current()->slotRepaintVariable();
04163     m_masterPage->slotRepaintVariable();
04164 }
04165 
04166 void KPrDocument::slotGuideLinesChanged( KoView *view )
04167 {
04168     ( (KPrView*)view )->getCanvas()->guideLines().getGuideLines( m_hGuideLines, m_vGuideLines );
04169     QPtrListIterator<KoView> it( views() );
04170     for (; it.current(); ++it )
04171     {
04172         if ( it.current() != view )
04173         {
04174             ( (KPrView*)it.current() )->getCanvas()->guideLines().setGuideLines( m_hGuideLines, m_vGuideLines );
04175         }
04176     }
04177 }
04178 
04179 void KPrDocument::slotDocumentInfoModifed()
04180 {
04181     if (!getVariableCollection()->variableSetting()->displayFieldCode())
04182         recalcVariables( VT_FIELD );
04183 }
04184 
04185 void KPrDocument::reorganizeGUI()
04186 {
04187     QPtrListIterator<KoView> it( views() );
04188     for (; it.current(); ++it )
04189         ((KPrView*)it.current())->reorganize();
04190 }
04191 
04192 int KPrDocument::undoRedoLimit() const
04193 {
04194     return m_commandHistory->undoLimit();
04195 }
04196 
04197 void KPrDocument::setUndoRedoLimit(int val)
04198 {
04199     m_commandHistory->setUndoLimit(val);
04200     m_commandHistory->setRedoLimit(val);
04201 }
04202 
04203 void KPrDocument::updateRuler()
04204 {
04205     emit sig_updateRuler();
04206 }
04207 
04208 void KPrDocument::recalcPageNum()
04209 {
04210     QPtrListIterator<KPrPage> it( m_pageList );
04211     for ( ; it.current(); ++it )
04212         it.current()->recalcPageNum();
04213     m_masterPage->recalcPageNum();
04214 }
04215 
04216 KPrPage * KPrDocument::activePage()const
04217 {
04218     return m_initialActivePage;
04219 }
04220 
04221 void KPrDocument::insertObjectInPage(double offset, KPrObject *_obj, int pos)
04222 {
04224     int page = (int)(offset/__pgLayout.ptHeight)+m_insertFilePage;
04225     if ( page < 0 )
04226     {
04227         kdDebug(33001) << "insertObjectInPage object cound not be inserted page = " << page << endl;
04228         return;
04229     }
04230     double newPos = offset - ( page - m_insertFilePage ) * __pgLayout.ptHeight;
04231     // due to a very small caluculating error which gives us the wrong page
04232     // for objects placed on top of the page we have to move them to the right page.
04233     if ( __pgLayout.ptHeight - newPos < 1e-6 )
04234     {
04235         page++;
04236         newPos = 0.0;
04237     }
04238     if ( page > ( (int)m_pageList.count()-1 ) )
04239     {
04240         for (int i=(m_pageList.count()-1); i<page;i++)
04241             m_pageList.append( new KPrPage( this, m_masterPage ) );
04242     }
04243     _obj->setOrig(_obj->getOrig().x(),newPos);
04244 
04245     if ( pos == -1 )
04246     {
04247         m_pageList.at(page)->appendObject(_obj);
04248     }
04249     else
04250     {
04251         m_pageList.at( page )->insertObject( _obj, pos );
04252     }
04253 }
04254 
04255 void KPrDocument::insertPixmapKey( KoPictureKey key )
04256 {
04257     if ( !usedPictures.contains( key ) )
04258         usedPictures.append( key );
04259 }
04260 
04261 KPrPage * KPrDocument::initialActivePage() const
04262 {
04263     return m_initialActivePage;
04264 }
04265 
04266 void KPrDocument::displayActivePage(KPrPage * _page)
04267 {
04268     m_initialActivePage = _page;
04269 }
04270 
04271 void KPrDocument::updateZoomRuler()
04272 {
04273     QPtrListIterator<KoView> it( views() );
04274     for (; it.current(); ++it )
04275     {
04276         ((KPrView*)it.current())->getHRuler()->setZoom( m_zoomHandler->zoomedResolutionX() );
04277         ((KPrView*)it.current())->getVRuler()->setZoom( m_zoomHandler->zoomedResolutionY() );
04278         ((KPrView*)it.current())->slotUpdateRuler();
04279     }
04280 }
04281 
04282 void KPrDocument::newZoomAndResolution( bool updateViews, bool /*forPrint*/ )
04283 {
04284     QPtrListIterator<KPrPage> it( m_pageList );
04285     for ( ; it.current(); ++it ) {
04286         QPtrListIterator<KPrObject> oit(it.current()->objectList());
04287         for ( ; oit.current(); ++oit ) {
04288             if ( oit.current()->getType() == OT_TEXT )
04289                 static_cast<KPrTextObject *>( oit.current() )->textDocument()->formatCollection()->zoomChanged();
04290         }
04291     }
04292     if ( updateViews )
04293     {
04294         QPtrListIterator<KoView> it( views() );
04295         for (; it.current(); ++it )
04296         {
04297             static_cast<KPrView *>( it.current() )->getCanvas()->update();
04298             static_cast<KPrView *>( it.current() )->getCanvas()->layout();
04299         }
04300     }
04301 }
04302 
04303 bool KPrDocument::isHeader(const KPrObject *obj) const
04304 {
04305     return (obj==_header);
04306 }
04307 
04308 bool KPrDocument::isFooter(const KPrObject *obj) const
04309 {
04310     return (obj==_footer);
04311 }
04312 
04313 bool KPrDocument::isHeaderFooter(const KPrObject *obj) const
04314 {
04315     return (obj==_header)||(obj==_footer);
04316 }
04317 
04318 void KPrDocument::updateRulerPageLayout()
04319 {
04320     QPtrListIterator<KoView> it( views() );
04321     for (; it.current(); ++it )
04322     {
04323         ((KPrView*)it.current())->getHRuler()->setPageLayout(m_pageLayout );
04324         ((KPrView*)it.current())->getVRuler()->setPageLayout(m_pageLayout );
04325 
04326     }
04327 }
04328 
04329 void KPrDocument::refreshAllNoteBarMasterPage(const QString &text, KPrView *exceptView)
04330 {
04331     m_masterPage->setNoteText(text );
04332     QPtrListIterator<KoView> it( views() );
04333     for (; it.current(); ++it )
04334     {
04335         KPrView* view=(KPrView*)it.current();
04336         if ( view->getNoteBar() && view != exceptView && view->editMaster() )
04337             view->getNoteBar()->setCurrentNoteText(text );
04338     }
04339 }
04340 
04341 void KPrDocument::refreshAllNoteBar(int page, const QString &text, KPrView *exceptView)
04342 {
04343     m_pageList.at(page)->setNoteText(text );
04344     QPtrListIterator<KoView> it( views() );
04345     for (; it.current(); ++it )
04346     {
04347         KPrView* view=(KPrView*)it.current();
04348         if ( view->getNoteBar() && view != exceptView && ((int)(view->getCurrPgNum())-1 == page))
04349             view->getNoteBar()->setCurrentNoteText(text );
04350     }
04351 }
04352 
04353 void KPrDocument::loadStyleTemplates( const QDomElement &stylesElem )
04354 {
04355     QValueList<QString> followingStyles;
04356 
04357     QDomNodeList listStyles = stylesElem.elementsByTagName( "STYLE" );
04358     if( listStyles.count() > 0) { // we are going to import at least one style.
04359         KoParagStyle *s = m_styleColl->findStyle("Standard");
04360         kdDebug(32001) << "KPrDocument::loadStyleTemplates looking for Standard, to delete it. Found " << s << endl;
04361         if(s) // delete the standard style.
04362             m_styleColl->removeStyle(s);
04363     }
04364     for (unsigned int item = 0; item < listStyles.count(); item++) {
04365         QDomElement styleElem = listStyles.item( item ).toElement();
04366 
04367         KoParagStyle *sty = new KoParagStyle( QString::null );
04368         // Load the style from the <STYLE> element
04369         sty->loadStyle( styleElem );
04370 
04371         QDomElement formatElem = styleElem.namedItem( "FORMAT" ).toElement();
04372         if ( !formatElem.isNull() )
04373             sty->format() = KPrTextObject::loadFormat( formatElem, 0L, defaultFont(), globalLanguage(), globalHyphenation() );
04374         else
04375             kdWarning(33001) << "No FORMAT tag in <STYLE>" << endl; // This leads to problems in applyStyle().
04376 
04377         // Style created, now let's try to add it
04378         sty = m_styleColl->addStyle( sty );
04379         kdDebug() << k_funcinfo << m_styleColl->styleList().count() << " styles, " << followingStyles.count() << " following styles" << endl;
04380         if(m_styleColl->styleList().count() > followingStyles.count() )
04381         {
04382             QString following = styleElem.namedItem("FOLLOWING").toElement().attribute("name");
04383             followingStyles.append( following );
04384         }
04385         else
04386             kdWarning (33001) << "Found duplicate style declaration, overwriting former " << sty->name() << endl;
04387     }
04388 
04389     Q_ASSERT( followingStyles.count() == m_styleColl->styleList().count() );
04390     unsigned int i=0;
04391     for( QValueList<QString>::Iterator it = followingStyles.begin(); it != followingStyles.end(); ++it ) {
04392         KoParagStyle * style = m_styleColl->findStyle(*it);
04393         m_styleColl->styleAt( i++)->setFollowingStyle( style );
04394     }
04395 }
04396 
04397 
04398 void KPrDocument::updateAllStyleLists()
04399 {
04400     QPtrListIterator<KoView> it( views() );
04401     for (; it.current(); ++it )
04402         ((KPrView*)it.current())->updateStyleList();
04403 }
04404 
04405 void KPrDocument::applyStyleChange( KoStyleChangeDefMap changed )
04406 {
04407     QPtrListIterator<KPrPage> it( m_pageList );
04408     for ( ; it.current(); ++it )
04409         it.current()->applyStyleChange( changed );
04410     m_masterPage->applyStyleChange( changed );
04411 }
04412 
04413 void KPrDocument::saveStyle( KoParagStyle *sty, QDomElement parentElem )
04414 {
04415     QDomDocument doc = parentElem.ownerDocument();
04416     QDomElement styleElem = doc.createElement( "STYLE" );
04417     parentElem.appendChild( styleElem );
04418 
04419     sty->saveStyle( styleElem );
04420     QDomElement formatElem = doc.createElement("FORMAT");
04421     KPrTextObject::saveFormat( formatElem, &sty->format() );
04422     styleElem.appendChild( formatElem );
04423 }
04424 
04425 void KPrDocument::startBackgroundSpellCheck()
04426 {
04427     //don't start spell checking when document is embedded in konqueror
04428     if(backgroundSpellCheckEnabled() && isReadWrite())
04429     {
04430         if(m_initialActivePage->allTextObjects().count()>0)
04431         {
04432             m_bgSpellCheck->start();
04433         }
04434     }
04435 }
04436 
04437 void KPrDocument::enableBackgroundSpellCheck( bool b )
04438 {
04439     //m_bgSpellCheck->enableBackgroundSpellCheck(b);
04440     m_bgSpellCheck->setEnabled(b);
04441     QPtrListIterator<KoView> it( views() );
04442     for( ; it.current(); ++it )
04443         ((KPrView*)it.current())->updateBgSpellCheckingState();
04444 }
04445 
04446 bool KPrDocument::backgroundSpellCheckEnabled() const
04447 {
04448     return m_bgSpellCheck->enabled();
04449 }
04450 
04451 void KPrDocument::reactivateBgSpellChecking(bool refreshTextObj)
04452 {
04453     QPtrListIterator<KPrPage> it( m_pageList );
04454 #if 0
04455     if(m_kpresenterView && m_kpresenterView->getCanvas())
04456         activePage=m_kpresenterView->getCanvas()->activePage();
04457 #endif
04458     KPrPage *activePage=m_initialActivePage;
04459     for ( ; it.current(); ++it )
04460     {
04461         if( it.current()!=activePage)
04462             it.current()->reactivateBgSpellChecking(false );
04463         else
04464             it.current()->reactivateBgSpellChecking( true);
04465     }
04466     m_masterPage->reactivateBgSpellChecking(refreshTextObj);
04467     startBackgroundSpellCheck();
04468 }
04469 
04470 QPtrList<KoTextObject> KPrDocument::allTextObjects() const
04471 {
04472     QPtrList<KoTextObject> lst;
04473     QPtrListIterator<KPrPage> it( m_pageList );
04474     for ( ; it.current(); ++it )
04475         it.current()->addTextObjects( lst );
04476     m_masterPage->addTextObjects( lst );
04477     return lst;
04478 }
04479 
04480 QValueList<KoTextDocument *> KPrDocument::allTextDocuments() const
04481 {
04482     QValueList<KoTextDocument *> lst;
04483     const QPtrList<KoTextObject> textObjects = allTextObjects();
04484     QPtrListIterator<KoTextObject> it( textObjects );
04485     for ( ; it.current() ; ++it ) {
04486         lst.append( it.current()->textDocument() );
04487     }
04488     return lst;
04489 }
04490 
04491 QValueList<KoTextObject *> KPrDocument::visibleTextObjects( ) const
04492 {
04493     QValueList<KoTextObject *> lst;
04494     QPtrList<KoTextObject> textFramesets = allTextObjects(  );
04495 
04496     KoTextObject *frm;
04497     for ( frm=textFramesets.first(); frm != 0; frm=textFramesets.next() ) {
04498         if ( frm && !frm->protectContent() )
04499         {
04500             lst.append( frm );
04501         }
04502     }
04503     return lst;
04504 }
04505 
04506 void KPrDocument::setShowGuideLines( bool b )
04507 {
04508     m_bShowGuideLines = b;
04509     setModified( true );
04510 }
04511 
04512 void KPrDocument::horizontalGuideLines( const QValueList<double> &lines )
04513 {
04514     m_hGuideLines = lines;
04515 }
04516 
04517 void KPrDocument::verticalGuideLines( const QValueList<double> &lines )
04518 {
04519     m_vGuideLines = lines;
04520 }
04521 
04522 
04523 void KPrDocument::addGuideLine( Qt::Orientation o, double pos )
04524 {
04525     if ( o == Qt::Horizontal )
04526     {
04527         m_hGuideLines.append( pos );
04528     }
04529     else
04530     {
04531         m_vGuideLines.append( pos );
04532     }
04533 
04534     QPtrListIterator<KoView> it( views() );
04535     for (; it.current(); ++it )
04536     {
04537         ( (KPrView*)it.current() )->getCanvas()->guideLines().setGuideLines( m_hGuideLines, m_vGuideLines );
04538     }
04539 }
04540 
04541 
04542 void KPrDocument::updateGuideLineButton()
04543 {
04544     QPtrListIterator<KoView> it( views() );
04545     for (; it.current(); ++it )
04546         ((KPrView*)it.current())->updateGuideLineButton();
04547 }
04548 
04549 void KPrDocument::loadGuideLines( const QDomElement &element )
04550 {
04551     // In early versions of KPresenter 1.2 (up to Beta 2), there is child also naed <HELPLINES>
04552     // Before KPresenter 1.5 the guide lines where named helplines that is why they are still
04553     // named like this in the fileformat
04554     QDomElement guidelines = element.namedItem( "HELPLINES" ).toElement();
04555     if ( guidelines.isNull() )
04556         guidelines = element;
04557 
04558     guidelines = guidelines.firstChild().toElement();
04559     while ( !guidelines.isNull() )
04560     {
04561         if ( guidelines.tagName() == "Vertical" )
04562             m_vGuideLines.append( guidelines.attribute( "value" ).toDouble() );
04563         else if ( guidelines.tagName() == "Horizontal" )
04564             m_hGuideLines.append( guidelines.attribute( "value" ).toDouble() );
04565         guidelines = guidelines.nextSibling().toElement();
04566     }
04567 }
04568 
04569 void KPrDocument::saveGuideLines( QDomDocument &doc, QDomElement& element )
04570 {
04571     for(QValueList<double>::Iterator it = m_vGuideLines.begin(); it != m_vGuideLines.end(); ++it)
04572     {
04573         QDomElement lines=doc.createElement("Vertical");
04574         lines.setAttribute("value", (double)*it);
04575         element.appendChild( lines );
04576     }
04577 
04578     for(QValueList<double>::Iterator it = m_hGuideLines.begin(); it != m_hGuideLines.end(); ++it)
04579     {
04580         QDomElement lines=doc.createElement("Horizontal");
04581         lines.setAttribute("value", *it);
04582         element.appendChild( lines );
04583     }
04584 }
04585 
04586 void KPrDocument::updateGridButton()
04587 {
04588     QPtrListIterator<KoView> it( views() );
04589     for (; it.current(); ++it )
04590         ((KPrView*)it.current())->updateGridButton();
04591 
04592 }
04593 
04594 void KPrDocument::setSpellCheckIgnoreList( const QStringList& lst )
04595 {
04596     m_spellCheckIgnoreList = lst;
04597     m_bgSpellCheck->settings()->setCurrentIgnoreList( m_spellCheckIgnoreList + m_spellCheckPersonalDict );
04598    setModified( true );
04599 }
04600 
04601 void KPrDocument::addSpellCheckIgnoreWord( const QString & word )
04602 {
04603     // ### missing: undo/redo support
04604     if( m_spellCheckIgnoreList.findIndex( word ) == -1 )
04605         m_spellCheckIgnoreList.append( word );
04606     setSpellCheckIgnoreList( m_spellCheckIgnoreList );
04607 }
04608 
04609 void KPrDocument::updateObjectStatusBarItem()
04610 {
04611     QPtrListIterator<KoView> it( views() );
04612     for (; it.current(); ++it )
04613         ((KPrView*)it.current())->updateObjectStatusBarItem();
04614 }
04615 
04616 void KPrDocument::updateObjectSelected()
04617 {
04618     QPtrListIterator<KoView> it( views() );
04619     for (; it.current(); ++it )
04620         ((KPrView*)it.current())->objectSelectedChanged();
04621 }
04622 
04623 void KPrDocument::setTabStopValue ( double _tabStop )
04624 {
04625     m_tabStop = _tabStop;
04626     QPtrListIterator<KPrPage> it( m_pageList );
04627     for ( ; it.current(); ++it )
04628         it.current()->changeTabStopValue( m_tabStop );
04629     //styckypage
04630     m_masterPage->changeTabStopValue( m_tabStop );
04631 }
04632 
04633 void KPrDocument::changeBgSpellCheckingState( bool b )
04634 {
04635     enableBackgroundSpellCheck( b );
04636     reactivateBgSpellChecking();
04637     KConfig *config = KPrFactory::global()->config();
04638     config->setGroup("KSpell kpresenter" );
04639     config->writeEntry( "SpellCheck", (int)b );
04640 }
04641 
04642 
04643 bool KPrDocument::cursorInProtectedArea()const
04644 {
04645     return m_cursorInProtectectedArea;
04646 }
04647 
04648 void KPrDocument::setCursorInProtectedArea( bool b )
04649 {
04650     m_cursorInProtectectedArea=b;
04651     testAndCloseAllTextObjectProtectedContent();
04652 }
04653 
04654 void KPrDocument::testAndCloseAllTextObjectProtectedContent()
04655 {
04656     if ( !m_cursorInProtectectedArea )
04657     {
04658         QPtrListIterator<KoView> it( views() );
04659         for (; it.current(); ++it )
04660             static_cast<KPrView*>(it.current())->testAndCloseAllTextObjectProtectedContent();
04661     }
04662 }
04663 
04664 void KPrDocument::insertFile(const QString & file )
04665 {
04666     m_insertFilePage = m_pageList.count();
04667 
04668     m_childCountBeforeInsert = children().count();
04669     objStartY = 0;
04670     bool clean = _clean;
04671     _clean = false;
04672     bool ok = loadNativeFormat(file );
04673     if ( !ok )
04674     {
04675         showLoadingErrorDialog();
04676         return;
04677     }
04678     KMacroCommand *macro = 0L;
04679     for ( int i = m_insertFilePage; i<(int)m_pageList.count();i++)
04680     {
04681         if ( !macro )
04682             macro = new KMacroCommand( i18n("Insert File"));
04683         KPrInsertPageCmd * cmd = new KPrInsertPageCmd( i18n("Insert File"), i - 1, IP_AFTER, m_pageList.at(i), this ) ;
04684         macro->addCommand(cmd );
04685     }
04686     if ( macro )
04687         addCommand( macro );
04688 
04689     m_insertFilePage = 0;
04690     m_childCountBeforeInsert = 0;
04691     // Update the views
04692     int newPos = m_pageList.count()-1;
04693     QPtrListIterator<KoView> it( views() );
04694     for (; it.current(); ++it )
04695         static_cast<KPrView*>(it.current())->updateSideBar();
04696     _clean = clean;
04697     updatePresentationButton();
04698 
04699     //activate this page in all views (...)
04700     QPtrListIterator<KoView>it2( views() );
04701     for (; it2.current(); ++it2 )
04702         static_cast<KPrView*>(it2.current())->skipToPage(newPos);
04703 }
04704 
04705 void KPrDocument::spellCheckParagraphDeleted( KoTextParag * /* _parag */,  KPrTextObject * /* frm */ )
04706 {
04707     //m_bgSpellCheck->spellCheckParagraphDeleted( _parag, frm->textObject());
04708 }
04709 
04710 void KPrDocument::updateRulerInProtectContentMode()
04711 {
04712     QPtrListIterator<KoView> it( views() );
04713     for (; it.current(); ++it )
04714         static_cast<KPrView*>(it.current())->updateRulerInProtectContentMode();
04715 }
04716 
04717 void KPrDocument::updatePresentationButton()
04718 {
04719     QPtrListIterator<KoView> it( views() );
04720     for (; it.current(); ++it )
04721         static_cast<KPrView*>(it.current())->updatePresentationButton((selectedSlides().count()>0));
04722 }
04723 
04724 void KPrDocument::refreshGroupButton()
04725 {
04726     QPtrListIterator<KoView> it( views() );
04727     for (; it.current(); ++it )
04728         static_cast<KPrView*>(it.current())->refreshGroupButton();
04729 }
04730 
04731 void KPrDocument::addView( KoView *_view )
04732 {
04733     KoDocument::addView( _view );
04734     QPtrListIterator<KoView> it( views() );
04735     for (; it.current(); ++it )
04736         static_cast<KPrView*>(it.current())->closeTextObject();
04737 }
04738 
04739 void KPrDocument::removeView( KoView *_view )
04740 {
04741     KoDocument::removeView( _view );
04742     QPtrListIterator<KoView> it( views() );
04743     for (; it.current(); ++it )
04744         static_cast<KPrView*>(it.current())->deSelectAllObjects();
04745 }
04746 
04747 void KPrDocument::updateStyleListOrder( const QStringList &list )
04748 {
04749     styleCollection()->updateStyleListOrder( list );
04750 }
04751 
04752 void KPrDocument::updateDirectCursorButton()
04753 {
04754     QPtrListIterator<KoView> it( views() );
04755     for (; it.current(); ++it )
04756         static_cast<KPrView*>(it.current())->updateDirectCursorButton();
04757 }
04758 
04759 void KPrDocument::setInsertDirectCursor(bool _b)
04760 {
04761     m_bInsertDirectCursor=_b;
04762     KConfig *config = KPrFactory::global()->config();
04763     config->setGroup( "Interface" );
04764     config->writeEntry( "InsertDirectCursor", _b );
04765     updateDirectCursorButton();
04766 }
04767 
04768 KPrView *KPrDocument::firstView() const
04769 {
04770     if ( views().count()>0)
04771         return static_cast<KPrView*>(views().getFirst());
04772     else
04773         return 0L;
04774 }
04775 
04776 void KPrDocument::addWordToDictionary( const QString & word)
04777 {
04778     if ( m_bgSpellCheck )
04779     {
04780         if( m_spellCheckPersonalDict.findIndex( word ) == -1 )
04781             m_spellCheckPersonalDict.append( word );
04782         m_bgSpellCheck->settings()->setCurrentIgnoreList( m_spellCheckIgnoreList + m_spellCheckPersonalDict );
04783         if ( backgroundSpellCheckEnabled() )
04784             // Re-check everything to make this word normal again
04785             reactivateBgSpellChecking();
04786     }
04787 }
04788 
04789 QValueList <KPrPage *> KPrDocument::customListPage( const QStringList & lst, bool loadOasis )
04790 {
04791     QStringList tmp( lst );
04792     QValueList <KPrPage *> tmpValueList;
04793     for ( QStringList::Iterator itList = tmp.begin(); itList != tmp.end(); ++itList )
04794     {
04795         for ( int i = 0; i < static_cast<int>( m_pageList.count() ); i++ )
04796         {
04797             //kdDebug()<<" insert page name :"<<*itList<<endl;
04798             if ( loadOasis )
04799             {
04800                 if ( m_pageList.at( i )->oasisNamePage(i+1)== ( *itList ) )
04801                 {
04802                     tmpValueList.append(  m_pageList.at( i ) );
04803                     //kdDebug()<<" really insert\n";
04804                     break;
04805                 }
04806             }
04807             else
04808             {
04809                 if ( m_pageList.at( i )->pageTitle()== ( *itList ) )
04810                 {
04811                     tmpValueList.append( m_pageList.at( i ) );
04812                     //kdDebug()<<" really insert\n";
04813                     break;
04814                 }
04815             }
04816 
04817         }
04818     }
04819     return tmpValueList;
04820 
04821 }
04822 
04823 void KPrDocument::setCustomSlideShows( const CustomSlideShowMap & customSlideShows )
04824 {
04825     m_customListSlideShow = customSlideShows;
04826     setModified( true );
04827 }
04828 
04829 QStringList KPrDocument::presentationList()
04830 {
04831     QStringList lst;
04832     if ( !m_customListSlideShow.isEmpty() )
04833     {
04834         CustomSlideShowMap::Iterator it;
04835         for ( it = m_customListSlideShow.begin(); it != m_customListSlideShow.end(); ++it )
04836             lst << it.key();
04837     }
04838     return lst;
04839 }
04840 
04841 void KPrDocument::testCustomSlideShow( const QValueList<KPrPage *> &pages, KPrView *view )
04842 {
04843     delete m_customListTest;
04844     m_customListTest = new QValueList<int>( listOfDisplaySelectedSlides( pages ) );
04845     if ( view )
04846         view->screenStartFromFirst();
04847 
04848 }
04849 
04850 void KPrDocument::clearTestCustomSlideShow()
04851 {
04852     delete m_customListTest;
04853     m_customListTest = 0L;
04854 }
04855 
04856 
04857 #include "KPrDocument.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys