00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "KWDocument.h"
00023
00024 #include "KWordDocIface.h"
00025 #include "KWBgSpellCheck.h"
00026 #include "KoTextBookmark.h"
00027 #include "KWCanvas.h"
00028 #include "KWCommand.h"
00029 #include "KWFormulaFrameSet.h"
00030 #include "KWFrameLayout.h"
00031 #include "KWPictureFrameSet.h"
00032 #include "KWPartFrameSet.h"
00033 #include "KWTableFrameSet.h"
00034 #include "KWTableStyle.h"
00035 #include "KWTableTemplate.h"
00036 #include "KWTextImage.h"
00037 #include "KWVariable.h"
00038 #include "KWView.h"
00039 #include "KWViewMode.h"
00040 #include "KWMailMergeDataBase.h"
00041 #include "KWLoadingInfo.h"
00042 #include "KWCollectFramesetsVisitor.h"
00043 #include "KWOasisLoader.h"
00044 #include "KWOasisSaver.h"
00045 #include "KWFrameList.h"
00046 #include "KWPageManager.h"
00047 #include "KWPage.h"
00048 #include "KWFrameView.h"
00049 #include "KWFrameViewManager.h"
00050 #include "KWStartupWidget.h"
00051
00052 #include <KoPictureCollection.h>
00053 #include <KoTemplateChooseDia.h>
00054 #include <KoMainWindow.h>
00055 #include <KoDocumentInfo.h>
00056 #include <KoGlobal.h>
00057 #include <KoParagCounter.h>
00058 #include <KoTextObject.h>
00059 #include <KoAutoFormat.h>
00060 #include <KoVariable.h>
00061 #include <kformuladocument.h>
00062 #include <KoApplication.h>
00063 #include <KoOasisContext.h>
00064 #include <KoCommandHistory.h>
00065 #include <KoGenStyles.h>
00066 #include <KoStore.h>
00067 #include <KoStoreDrag.h>
00068 #include <KoStoreDevice.h>
00069 #include <KoXmlWriter.h>
00070 #include <KoOasisStore.h>
00071 #include <KoOasisStyles.h>
00072 #include <KoXmlNS.h>
00073 #include <KoDom.h>
00074
00075 #include <kcursor.h>
00076 #include <kdebug.h>
00077 #include <kglobalsettings.h>
00078 #include <klibloader.h>
00079 #include <kmultipledrag.h>
00080 #include <klocale.h>
00081 #include <kmessagebox.h>
00082 #include <kspell.h>
00083 #include <kstandarddirs.h>
00084
00085 #include <kspell2/settings.h>
00086
00087 #include <qfileinfo.h>
00088 #include <qregexp.h>
00089 #include <qtimer.h>
00090 #include <qbuffer.h>
00091
00092 #include <unistd.h>
00093 #include <math.h>
00094
00095
00096
00097
00098
00099 static const char * CURRENT_DTD_VERSION = "1.2";
00100
00101
00102
00103
00104 class KWCommandHistory : public KoCommandHistory
00105 {
00106 public:
00107 KWCommandHistory( KWDocument * doc ) : KoCommandHistory( doc->actionCollection(), true ), m_pDoc( doc ) {}
00108 public :
00109 virtual void undo();
00110 virtual void redo();
00111 private:
00112 KWDocument * m_pDoc;
00113 };
00114
00115 void KWCommandHistory::undo()
00116 {
00117 m_pDoc->clearUndoRedoInfos();
00118 KoCommandHistory::undo();
00119 }
00120
00121 void KWCommandHistory::redo()
00122 {
00123 m_pDoc->clearUndoRedoInfos();
00124 KoCommandHistory::redo();
00125 }
00126
00127
00128
00129
00130 void KWDocument::clearUndoRedoInfos()
00131 {
00132 QPtrListIterator<KWFrameSet> fit = framesetsIterator();
00133 for ( ; fit.current() ; ++fit )
00134 {
00135 KWTextFrameSet *fs = dynamic_cast<KWTextFrameSet *>( fit.current() );
00136 if ( fs )
00137 fs->clearUndoRedoInfo();
00138 }
00139 }
00140
00145 class KWDocument::InitialEditing {
00146 public:
00147 QString m_initialFrameSet;
00148 int m_initialCursorParag;
00149 int m_initialCursorIndex;
00150 };
00151
00152 const int KWDocument::CURRENT_SYNTAX_VERSION = 3;
00153
00154 KWDocument::KWDocument(QWidget *parentWidget, const char *widname, QObject* parent, const char* name, bool singleViewMode )
00155 : KoDocument( parentWidget, widname, parent, name, singleViewMode ),
00156 m_urlIntern()
00157 {
00158 KWStatisticVariable::setExtendedType( true );
00159 dcop = 0;
00160 m_framesChangedHandler = 0;
00161 m_pageManager = new KWPageManager();
00162 m_pageManager->appendPage();
00163 m_loadingInfo = 0L;
00164 m_tabStop = MM_TO_POINT( 15.0 );
00165 m_processingType = WP;
00166
00167
00168 m_lstFrameSet.setAutoDelete( true );
00169
00170 m_textImageRequests.setAutoDelete(false);
00171
00172 m_styleColl = new KoStyleCollection();
00173 m_frameStyleColl = new KWFrameStyleCollection();
00174 m_tableStyleColl = new KWTableStyleCollection();
00175 m_tableTemplateColl = new KWTableTemplateCollection();
00176 m_pictureCollection = new KoPictureCollection();
00177
00178 m_personalExpressionPath = KWFactory::instance()->dirs()->resourceDirs("expression");
00179
00180 m_bShowGrid = false;
00181 m_bSnapToGrid = false;
00182
00183
00184 setInstance( KWFactory::instance(), false );
00185 setTemplateType( "kword_template" );
00186
00187 m_gridX = m_gridY = MM_TO_POINT(5.0 );
00188 m_indent = MM_TO_POINT( 10.0 );
00189
00190 m_iNbPagePerRow = 4;
00191 m_maxRecentFiles = 10;
00192 m_bShowRuler = true;
00193
00194 m_footNoteSeparatorLinePos=SLP_LEFT;
00195
00196 m_iFootNoteSeparatorLineLength = 20;
00197 m_footNoteSeparatorLineWidth = 2.0;
00198 m_footNoteSeparatorLineType = SLT_SOLID;
00199
00200 m_viewFormattingChars = false;
00201
00202 m_viewFormattingEndParag = true;
00203 m_viewFormattingSpace = true;
00204 m_viewFormattingTabs = true;
00205 m_viewFormattingBreak = true;
00206
00207 m_viewFrameBorders = true;
00208 m_repaintAllViewsPending = false;
00209 m_recalcFramesPending = -1;
00210 m_bShowDocStruct = true;
00211 m_bShowRuler = true;
00212 m_bShowStatusBar = true;
00213 m_bAllowAutoFormat = true;
00214 m_pgUpDownMovesCaret = true;
00215 m_bShowScrollBar = true;
00216 m_cursorInProtectectedArea = true;
00217 m_bHasEndNotes = false;
00218
00219 m_bInsertDirectCursor=false;
00220 m_globalLanguage = KGlobal::locale()->language();
00221 m_bGlobalHyphenation = false;
00222 m_bGeneratingPreview = false;
00223 m_viewModeType="ModeNormal";
00224 m_layoutViewMode = 0;
00225
00226 m_commandHistory = new KWCommandHistory( this );
00227 connect( m_commandHistory, SIGNAL( documentRestored() ), this, SLOT( slotDocumentRestored() ) );
00228 connect( m_commandHistory, SIGNAL( commandExecuted() ), this, SLOT( slotCommandExecuted() ) );
00229
00230
00231
00232 m_headerVisible = false;
00233 m_footerVisible = false;
00234
00235 m_pasteFramesetsMap = 0L;
00236 m_initialEditing = 0L;
00237 m_bufPixmap = 0L;
00238 m_varFormatCollection = new KoVariableFormatCollection;
00239 m_varColl = new KWVariableCollection( new KWVariableSettings(), m_varFormatCollection );
00240
00241 m_autoFormat = new KoAutoFormat(this,m_varColl,m_varFormatCollection );
00242 m_bgSpellCheck = new KWBgSpellCheck(this);
00243 m_slDataBase = new KWMailMergeDataBase( this );
00244 m_bookmarkList = new KoTextBookmarkList;
00245 slRecordNum = -1;
00246
00247 m_syntaxVersion = CURRENT_SYNTAX_VERSION;
00248
00249 m_hasTOC=false;
00250
00251
00252
00253 m_formulaDocumentWrapper =
00254 new KFormula::DocumentWrapper( instance()->config(),
00255 actionCollection(),
00256 m_commandHistory );
00257
00258 setEmpty();
00259 setModified(false);
00260
00261 initConfig();
00262
00263
00264 KConfig *config = KWFactory::instance()->config();
00265 config->setGroup("Document defaults" );
00266 QString defaultFontname=config->readEntry("DefaultFont");
00267 if ( !defaultFontname.isEmpty() )
00268 m_defaultFont.fromString( defaultFontname );
00269
00270
00271
00272 m_defaultFont.setStyleStrategy( QFont::ForceOutline );
00273
00274 int ptSize = m_defaultFont.pointSize();
00275 if ( ptSize == -1 )
00276 ptSize = QFontInfo(m_defaultFont).pointSize();
00277
00278
00279
00280
00281 if ( name )
00282 dcopObject();
00283 }
00284
00285 DCOPObject* KWDocument::dcopObject()
00286 {
00287 if ( !dcop )
00288 dcop = new KWordDocIface( this );
00289 return dcop;
00290 }
00291
00292 KWDocument::~KWDocument()
00293 {
00294
00295 if(isReadWrite())
00296 saveConfig();
00297
00298 m_lstFrameSet.clear();
00299 delete m_loadingInfo;
00300 delete m_autoFormat;
00301 delete m_formulaDocumentWrapper;
00302 delete m_commandHistory;
00303 delete m_varColl;
00304 delete m_varFormatCollection;
00305 delete m_slDataBase;
00306 delete dcop;
00307 delete m_bgSpellCheck;
00308 delete m_styleColl;
00309 delete m_frameStyleColl;
00310 delete m_tableStyleColl;
00311 delete m_tableTemplateColl;
00312 delete m_layoutViewMode;
00313 delete m_bufPixmap;
00314 delete m_pictureCollection;
00315 delete m_pageManager;
00316 delete m_bookmarkList;
00317 }
00318
00319 void KWDocument::initConfig()
00320 {
00321 KConfig *config = KWFactory::instance()->config();
00322 if( config->hasGroup("KSpell kword" ) )
00323 {
00324 config->setGroup( "KSpell kword" );
00325
00326
00327
00328 if ( isReadWrite() )
00329 m_bgSpellCheck->setEnabled(config->readBoolEntry( "SpellCheck", false ));
00330 else
00331 m_bgSpellCheck->setEnabled( false );
00332 }
00333
00334 if(config->hasGroup("Interface" ) )
00335 {
00336 config->setGroup( "Interface" );
00337 setGridY(QMAX( config->readDoubleNumEntry("GridY",MM_TO_POINT(5.0) ), 0.1));
00338 setGridX(QMAX( config->readDoubleNumEntry("GridX",MM_TO_POINT(5.0) ), 0.1));
00339 setCursorInProtectedArea( config->readBoolEntry( "cursorInProtectArea", true ));
00340
00341 double indent = config->readDoubleNumEntry("Indent", MM_TO_POINT(10.0) ) ;
00342 setIndentValue(indent);
00343 setShowRuler(config->readBoolEntry("Rulers",true));
00344 int defaultAutoSave = KoDocument::defaultAutoSave()/60;
00345 setAutoSave(config->readNumEntry("AutoSave",defaultAutoSave)*60);
00346 setBackupFile( config->readBoolEntry("BackupFile", true) );
00347
00348 setNbPagePerRow(config->readNumEntry("nbPagePerRow",4));
00349 m_maxRecentFiles = config->readNumEntry( "NbRecentFile", 10 );
00350
00351 m_viewFormattingChars = config->readBoolEntry( "ViewFormattingChars", false );
00352 m_viewFormattingBreak = config->readBoolEntry( "ViewFormattingBreaks", true );
00353 m_viewFormattingSpace = config->readBoolEntry( "ViewFormattingSpace", true );
00354 m_viewFormattingEndParag = config->readBoolEntry( "ViewFormattingEndParag", true );
00355 m_viewFormattingTabs = config->readBoolEntry( "ViewFormattingTabs", true );
00356
00357 m_viewFrameBorders = config->readBoolEntry( "ViewFrameBorders", true );
00358
00359 m_zoom = config->readNumEntry( "Zoom", 100 );
00360 m_zoomMode = static_cast<KoZoomMode::Mode> (
00361 config->readNumEntry( "ZoomMode", KoZoomMode::ZOOM_CONSTANT )
00362 );
00363
00364 m_bShowDocStruct = config->readBoolEntry( "showDocStruct", true );
00365 m_viewModeType = config->readEntry( "viewmode", "ModeNormal" );
00366 setShowStatusBar( config->readBoolEntry( "ShowStatusBar" , true ) );
00367 setAllowAutoFormat( config->readBoolEntry( "AllowAutoFormat" , true ) );
00368 setShowScrollBar( config->readBoolEntry( "ShowScrollBar", true ) );
00369 if ( isEmbedded() )
00370 m_bShowDocStruct = false;
00371 m_pgUpDownMovesCaret = config->readBoolEntry( "PgUpDownMovesCaret", true );
00372 m_bInsertDirectCursor= config->readBoolEntry( "InsertDirectCursor", false );
00373 m_globalLanguage=config->readEntry("language", KGlobal::locale()->language());
00374 m_bGlobalHyphenation=config->readBoolEntry("hyphenation", false);
00375
00376 setShowGrid( config->readBoolEntry( "ShowGrid" , false ));
00377 setSnapToGrid( config->readBoolEntry( "SnapToGrid", false ));
00378 setGridX( config->readDoubleNumEntry( "ResolutionX", MM_TO_POINT( 5.0 ) ));
00379 setGridY( config->readDoubleNumEntry( "ResolutionY", MM_TO_POINT( 5.0 ) ));
00380 }
00381 else
00382 {
00383 m_zoom = 100;
00384 m_zoomMode = KoZoomMode::ZOOM_WIDTH;
00385 }
00386 int undo=30;
00387 if(config->hasGroup("Misc" ) )
00388 {
00389 config->setGroup( "Misc" );
00390 undo=config->readNumEntry("UndoRedo",-1);
00391
00392
00393 if ( config->hasKey( "Units" ) )
00394 setUnit( KoUnit::unit( config->readEntry("Units") ) );
00395 m_defaultColumnSpacing = config->readDoubleNumEntry( "ColumnSpacing", 3.0 );
00396 }
00397
00398 if(undo!=-1)
00399 setUndoRedoLimit(undo);
00400
00401 setZoomAndResolution( m_zoom, KoGlobal::dpiX(), KoGlobal::dpiY() );
00402
00403
00404 if ( !isReadWrite() && m_viewModeType =="ModeText" )
00405 m_viewModeType= "ModeNormal";
00406
00407 m_layoutViewMode = KWViewMode::create( m_viewModeType, this, 0 );
00408
00409 if(config->hasGroup("Kword Path" ) )
00410 {
00411 config->setGroup( "Kword Path" );
00412 if ( config->hasKey( "expression path" ) )
00413 m_personalExpressionPath = config->readPathListEntry( "expression path" );
00414 setBackupPath(config->readPathEntry( "backup path" ));
00415 }
00416
00417
00418 KConfigGroup group( KoGlobal::kofficeConfig(), "Spelling" );
00419 m_spellCheckPersonalDict = group.readListEntry( "PersonalDict" );
00420 }
00421
00422 void KWDocument::saveConfig()
00423 {
00424 if ( !isReadWrite() )
00425 return;
00426 KConfigGroup group( KoGlobal::kofficeConfig(), "Spelling" );
00427 group.writeEntry( "PersonalDict", m_spellCheckPersonalDict );
00428
00429 if ( !isEmbedded() )
00430 {
00431
00432
00433 KConfig *config = KWFactory::instance()->config();
00434 config->setGroup( "Interface" );
00435 config->writeEntry( "ViewFormattingChars", m_viewFormattingChars );
00436 config->writeEntry( "ViewFormattingBreaks", m_viewFormattingBreak );
00437 config->writeEntry( "ViewFormattingEndParag", m_viewFormattingEndParag );
00438 config->writeEntry( "ViewFormattingTabs", m_viewFormattingTabs );
00439 config->writeEntry( "ViewFormattingSpace", m_viewFormattingSpace );
00440 config->writeEntry( "ViewFrameBorders", m_viewFrameBorders );
00441 config->writeEntry( "Zoom", m_zoom );
00442 config->writeEntry( "ZoomMode", m_zoomMode );
00443 config->writeEntry( "showDocStruct", m_bShowDocStruct );
00444 config->writeEntry( "Rulers", m_bShowRuler );
00445 config->writeEntry( "viewmode", m_viewModeType) ;
00446 config->writeEntry( "AllowAutoFormat", m_bAllowAutoFormat );
00447 config->writeEntry( "ShowGrid" , m_bShowGrid );
00448 config->writeEntry( "SnapToGrid" , m_bSnapToGrid );
00449 config->writeEntry( "ResolutionX", m_gridX );
00450 config->writeEntry( "ResolutionY", m_gridY );
00451 }
00452 }
00453
00454 void KWDocument::setZoomAndResolution( int zoom, int dpiX, int dpiY )
00455 {
00456 KoTextZoomHandler::setZoomAndResolution( zoom, dpiX, dpiY );
00457 if ( KFormula::Document* formulaDocument = m_formulaDocumentWrapper->document() )
00458 formulaDocument->setZoomAndResolution( zoom, dpiX, dpiY );
00459 }
00460
00461 KWTextFrameSet * KWDocument::textFrameSet ( unsigned int num ) const
00462 {
00463 unsigned int i=0;
00464 QPtrListIterator<KWFrameSet> fit = framesetsIterator();
00465 for ( ; fit.current() ; ++fit )
00466 {
00467 if(fit.current()->isDeleted()) continue;
00468 if(fit.current()->type()==FT_TEXT)
00469 {
00470 if(i==num)
00471 return static_cast<KWTextFrameSet*>(fit.current());
00472 i++;
00473 }
00474 }
00475 return static_cast<KWTextFrameSet*>(m_lstFrameSet.getFirst());
00476 }
00477
00478 void KWDocument::newZoomAndResolution( bool updateViews, bool forPrint )
00479 {
00480 if ( KFormula::Document* formulaDocument = m_formulaDocumentWrapper->document() )
00481 formulaDocument->newZoomAndResolution( updateViews,forPrint );
00482 #if 0
00483 QPtrListIterator<KWFrameSet> fit = framesetsIterator();
00484 for ( ; fit.current() ; ++fit )
00485 fit.current()->zoom( forPrint );
00486 #endif
00487
00488
00489 updateAllFrames();
00490
00491 layout();
00492 if ( updateViews )
00493 {
00494 emit newContentsSize();
00495 repaintAllViews( true );
00496 }
00497 }
00498
00499 bool KWDocument::initDoc(InitDocFlags flags, QWidget* parentWidget)
00500 {
00501 m_pageColumns.columns = 1;
00502 m_pageColumns.ptColumnSpacing = m_defaultColumnSpacing;
00503
00504 m_pageHeaderFooter.header = HF_SAME;
00505 m_pageHeaderFooter.footer = HF_SAME;
00506 m_pageHeaderFooter.ptHeaderBodySpacing = 10;
00507 m_pageHeaderFooter.ptFooterBodySpacing = 10;
00508 m_pageHeaderFooter.ptFootNoteBodySpacing = 10;
00509
00510 bool ok = FALSE;
00511
00512 if ( isEmbedded() )
00513 {
00514 QString fileName( locate( "kword_template", "Normal/.source/Embedded.kwt" , KWFactory::instance() ) );
00515 resetURL();
00516 ok = loadNativeFormat( fileName );
00517 if ( !ok )
00518 showLoadingErrorDialog();
00519 setEmpty();
00520 setModified( FALSE );
00521 return ok;
00522 }
00523 else if (flags==KoDocument::InitDocEmpty)
00524 {
00525 QString fileName( locate( "kword_template", "Normal/.source/PlainText.kwt" , KWFactory::instance() ) );
00526 resetURL();
00527 ok = loadNativeFormat( fileName );
00528 if ( !ok )
00529 showLoadingErrorDialog();
00530 setEmpty();
00531 setModified( FALSE );
00532 return ok;
00533 }
00534
00535 KoTemplateChooseDia::DialogType dlgtype;
00536
00537 if (flags != KoDocument::InitDocFileNew)
00538 dlgtype = KoTemplateChooseDia::Everything;
00539 else
00540 dlgtype = KoTemplateChooseDia::OnlyTemplates;
00541
00542
00543 QString file;
00544 KoTemplateChooseDia::ReturnType ret = KoTemplateChooseDia::choose(
00545 KWFactory::instance(), file,
00546 dlgtype, "kword_template", parentWidget );
00547 if ( ret == KoTemplateChooseDia::Template ) {
00548 resetURL();
00549 ok = loadNativeFormat( file );
00550 if ( !ok )
00551 showLoadingErrorDialog();
00552 setEmpty();
00553 } else if ( ret == KoTemplateChooseDia::File ) {
00554 KURL url( file );
00555
00556 ok = openURL( url );
00557 } else if ( ret == KoTemplateChooseDia::Empty ) {
00558 QString fileName( locate( "kword_template", "Normal/.source/PlainText.kwt" , KWFactory::instance() ) );
00559 resetURL();
00560 ok = loadNativeFormat( fileName );
00561 if ( !ok )
00562 showLoadingErrorDialog();
00563 setEmpty();
00564 }
00565 setModified( FALSE );
00566 return ok;
00567 }
00568
00569 void KWDocument::openExistingFile( const QString& file )
00570 {
00571 m_pageColumns.columns = 1;
00572 m_pageColumns.ptColumnSpacing = m_defaultColumnSpacing;
00573
00574 m_pageHeaderFooter.header = HF_SAME;
00575 m_pageHeaderFooter.footer = HF_SAME;
00576 m_pageHeaderFooter.ptHeaderBodySpacing = 10;
00577 m_pageHeaderFooter.ptFooterBodySpacing = 10;
00578 m_pageHeaderFooter.ptFootNoteBodySpacing = 10;
00579
00580 KoDocument::openExistingFile( file );
00581 }
00582
00583 void KWDocument::openTemplate( const QString& file )
00584 {
00585 m_pageColumns.columns = 1;
00586 m_pageColumns.ptColumnSpacing = m_defaultColumnSpacing;
00587
00588 m_pageHeaderFooter.header = HF_SAME;
00589 m_pageHeaderFooter.footer = HF_SAME;
00590 m_pageHeaderFooter.ptHeaderBodySpacing = 10;
00591 m_pageHeaderFooter.ptFooterBodySpacing = 10;
00592 m_pageHeaderFooter.ptFootNoteBodySpacing = 10;
00593
00594 KoDocument::openTemplate( file );
00595 }
00596
00597 void KWDocument::initEmpty()
00598 {
00599 m_pageColumns.columns = 1;
00600 m_pageColumns.ptColumnSpacing = m_defaultColumnSpacing;
00601
00602 m_pageHeaderFooter.header = HF_SAME;
00603 m_pageHeaderFooter.footer = HF_SAME;
00604 m_pageHeaderFooter.ptHeaderBodySpacing = 10;
00605 m_pageHeaderFooter.ptFooterBodySpacing = 10;
00606 m_pageHeaderFooter.ptFootNoteBodySpacing = 10;
00607
00608 QString fileName( locate( "kword_template", "Normal/.source/PlainText.kwt" , KWFactory::instance() ) );
00609 bool ok = loadNativeFormat( fileName );
00610 if ( !ok )
00611 showLoadingErrorDialog();
00612 resetURL();
00613 setModified( FALSE );
00614 setEmpty();
00615 }
00616
00617 KoPageLayout KWDocument::pageLayout(int pageNumber ) const
00618 {
00619 if( pageNumber < startPage())
00620 pageNumber = startPage();
00621 return pageManager()->pageLayout(pageNumber);
00622 }
00623
00624 void KWDocument::setPageLayout( const KoPageLayout& layout, const KoColumns& cl, const KoKWHeaderFooter& hf, bool updateViews )
00625 {
00626 m_pageLayout = layout;
00627 if ( m_processingType == WP ) {
00628 m_pageColumns = cl;
00629 }
00630 if ( m_processingType == DTP || isEmbedded() ) {
00631 m_pageLayout.ptLeft = 0;
00632 m_pageLayout.ptRight = 0;
00633 m_pageLayout.ptTop = 0;
00634 m_pageLayout.ptBottom = 0;
00635 }
00636 pageManager()->setDefaultPage(m_pageLayout);
00637 m_pageHeaderFooter = hf;
00638
00639
00640
00641
00642 updateAllFrames( KWFrameSet::UpdateFramesInPage );
00643
00644 recalcFrames();
00645
00646 updateAllFrames();
00647
00648 if ( updateViews )
00649 {
00650
00651 this->layout();
00652 emit pageLayoutChanged( m_pageLayout );
00653 updateContentsSize();
00654 }
00655 }
00656
00657
00658 double KWDocument::ptColumnWidth() const
00659 {
00660 KWPage *page = pageManager()->page(pageManager()->startPage());
00661 return ( page->width() - page->leftMargin() - page->rightMargin() -
00662 ptColumnSpacing() * ( m_pageColumns.columns - 1 ) )
00663 / m_pageColumns.columns;
00664 }
00665
00666 class KWFootNoteFrameSetList : public QPtrList<KWFootNoteFrameSet>
00667 {
00668 public:
00669 KWFootNoteFrameSetList( bool reversed ) : m_reversed( reversed ) {}
00670 protected:
00671
00672 virtual int compareItems(QPtrCollection::Item a, QPtrCollection::Item b)
00673 {
00674 KWFootNoteFrameSet* fsa = ((KWFootNoteFrameSet *)a);
00675 KWFootNoteFrameSet* fsb = ((KWFootNoteFrameSet *)b);
00676 Q_ASSERT( fsa->footNoteVariable() );
00677 Q_ASSERT( fsb->footNoteVariable() );
00678 if ( fsa->footNoteVariable() && fsb->footNoteVariable() )
00679 {
00680 int numa = fsa->footNoteVariable()->num();
00681 int numb = fsb->footNoteVariable()->num();
00682 if (numa == numb) return 0;
00683 if (numa > numb) return m_reversed ? -1 : 1;
00684 return m_reversed ? 1 : -1;
00685 }
00686 return -1;
00687 }
00688 private:
00689 bool m_reversed;
00690 };
00691
00692
00693 void KWDocument::recalcFrames( int fromPage, int toPage , uint flags )
00694 {
00695 fromPage = QMAX(pageManager()->startPage(), fromPage);
00696 if ( m_lstFrameSet.isEmpty() )
00697 return;
00698
00699 kdDebug(32002) << "KWDocument::recalcFrames from=" << fromPage << " to=" << toPage << endl;
00700
00701 KWFrameSet *frameset = m_lstFrameSet.getFirst();
00702
00703 if ( m_processingType == WP ) {
00704
00705 KWTextFrameSet *firstHeader = 0L, *evenHeader = 0L, *oddHeader = 0L;
00706 KWTextFrameSet *firstFooter = 0L, *evenFooter = 0L, *oddFooter = 0L;
00707 m_bHasEndNotes = false;
00708
00709
00710
00711
00712 KWFootNoteFrameSetList footnotesList( true );
00713 KWFootNoteFrameSetList endnotesList( false );
00714 QPtrListIterator<KWFrameSet> fit = framesetsIterator();
00715 for ( ; fit.current() ; ++fit )
00716 {
00717 KWFrameSet * fs = fit.current();
00718 switch ( fs->frameSetInfo() ) {
00719 case KWFrameSet::FI_FIRST_HEADER:
00720 if ( isHeaderVisible() ) {
00721 firstHeader = dynamic_cast<KWTextFrameSet*>( fs );
00722 } else { fs->setVisible( false ); fs->deleteAllCopies(); }
00723 break;
00724 case KWFrameSet::FI_ODD_HEADER:
00725 if ( isHeaderVisible() ) {
00726 oddHeader = dynamic_cast<KWTextFrameSet*>( fs );
00727 } else { fs->setVisible( false ); fs->deleteAllCopies(); }
00728 break;
00729 case KWFrameSet::FI_EVEN_HEADER:
00730 if ( isHeaderVisible() ) {
00731 evenHeader = dynamic_cast<KWTextFrameSet*>( fs );
00732 } else { fs->setVisible( false ); fs->deleteAllCopies(); }
00733 break;
00734 case KWFrameSet::FI_FIRST_FOOTER:
00735 if ( isFooterVisible() ) {
00736 firstFooter = dynamic_cast<KWTextFrameSet*>( fs );
00737 } else { fs->setVisible( false ); fs->deleteAllCopies(); }
00738 break;
00739 case KWFrameSet::FI_ODD_FOOTER:
00740 if ( isFooterVisible() ) {
00741 oddFooter = dynamic_cast<KWTextFrameSet*>( fs );
00742 } else { fs->setVisible( false ); fs->deleteAllCopies(); }
00743 break;
00744 case KWFrameSet::FI_EVEN_FOOTER:
00745 if ( isFooterVisible() ) {
00746 evenFooter = dynamic_cast<KWTextFrameSet*>( fs );
00747 } else { fs->setVisible( false ); fs->deleteAllCopies(); }
00748 case KWFrameSet::FI_FOOTNOTE: {
00749 KWFootNoteFrameSet* fnfs = dynamic_cast<KWFootNoteFrameSet *>(fs);
00750 if ( fnfs && fnfs->isVisible() )
00751 {
00752 if ( fnfs->isFootNote() )
00753 footnotesList.append( fnfs );
00754 else if ( fnfs->isEndNote() ) {
00755 endnotesList.append( fnfs );
00756 m_bHasEndNotes = true;
00757 }
00758 }
00759 }
00760 break;
00761 default: break;
00762 }
00763 }
00764
00765
00766
00767
00768 QPtrList<KWFrameLayout::HeaderFooterFrameset> headerFooterList;
00769 headerFooterList.setAutoDelete( true );
00770 const int firstPageNum = startPage();
00771
00772
00773 if ( isHeaderVisible() ) {
00774 Q_ASSERT( firstHeader );
00775 Q_ASSERT( oddHeader );
00776 Q_ASSERT( evenHeader );
00777 switch ( headerType() ) {
00778 case HF_SAME:
00779 oddHeader->setVisible( true );
00780 evenHeader->setVisible( false );
00781 evenHeader->deleteAllCopies();
00782 firstHeader->setVisible( false );
00783 firstHeader->deleteAllCopies();
00784
00785 headerFooterList.append( new KWFrameLayout::HeaderFooterFrameset(
00786 oddHeader, firstPageNum, -1, m_pageHeaderFooter.ptHeaderBodySpacing ) );
00787 break;
00788 case HF_FIRST_EO_DIFF:
00789 firstHeader->setVisible( true );
00790 oddHeader->setVisible( true );
00791 evenHeader->setVisible( true );
00792
00793 headerFooterList.append( new KWFrameLayout::HeaderFooterFrameset(
00794 firstHeader, firstPageNum, firstPageNum, m_pageHeaderFooter.ptHeaderBodySpacing ) );
00795 headerFooterList.append( new KWFrameLayout::HeaderFooterFrameset(
00796 oddHeader, firstPageNum + 2, -1, m_pageHeaderFooter.ptHeaderBodySpacing,
00797 KWFrameLayout::HeaderFooterFrameset::Odd ) );
00798 headerFooterList.append( new KWFrameLayout::HeaderFooterFrameset(
00799 evenHeader, firstPageNum + 1, -1, m_pageHeaderFooter.ptHeaderBodySpacing,
00800 KWFrameLayout::HeaderFooterFrameset::Even ) );
00801 break;
00802 case HF_FIRST_DIFF:
00803 oddHeader->setVisible( true );
00804 evenHeader->setVisible( false );
00805 evenHeader->deleteAllCopies();
00806 firstHeader->setVisible( true );
00807
00808 headerFooterList.append( new KWFrameLayout::HeaderFooterFrameset(
00809 firstHeader, firstPageNum, firstPageNum, m_pageHeaderFooter.ptHeaderBodySpacing ) );
00810 headerFooterList.append( new KWFrameLayout::HeaderFooterFrameset(
00811 oddHeader, firstPageNum + 1, -1, m_pageHeaderFooter.ptHeaderBodySpacing ) );
00812 break;
00813 case HF_EO_DIFF:
00814 oddHeader->setVisible( true );
00815 evenHeader->setVisible( true );
00816 firstHeader->setVisible( false );
00817 firstHeader->deleteAllCopies();
00818
00819 headerFooterList.append( new KWFrameLayout::HeaderFooterFrameset(
00820 oddHeader, firstPageNum, -1, m_pageHeaderFooter.ptHeaderBodySpacing,
00821 KWFrameLayout::HeaderFooterFrameset::Odd ) );
00822 headerFooterList.append( new KWFrameLayout::HeaderFooterFrameset(
00823 evenHeader, firstPageNum + 1, -1, m_pageHeaderFooter.ptHeaderBodySpacing,
00824 KWFrameLayout::HeaderFooterFrameset::Even ) );
00825 break;
00826 }
00827 }
00828 if ( isFooterVisible() ) {
00829 Q_ASSERT( firstFooter );
00830 Q_ASSERT( oddFooter );
00831 Q_ASSERT( evenFooter );
00832 switch ( footerType() ) {
00833 case HF_SAME:
00834 oddFooter->setVisible( true );
00835 evenFooter->setVisible( false );
00836 evenFooter->deleteAllCopies();
00837 firstFooter->setVisible( false );
00838 firstFooter->deleteAllCopies();
00839
00840 headerFooterList.append( new KWFrameLayout::HeaderFooterFrameset(
00841 oddFooter, firstPageNum, -1, m_pageHeaderFooter.ptFooterBodySpacing ) );
00842 break;
00843 case HF_FIRST_EO_DIFF:
00844 firstFooter->setVisible( true );
00845 oddFooter->setVisible( true );
00846 evenFooter->setVisible( true );
00847
00848 headerFooterList.append( new KWFrameLayout::HeaderFooterFrameset(
00849 firstFooter, firstPageNum, firstPageNum, m_pageHeaderFooter.ptFooterBodySpacing ) );
00850 headerFooterList.append( new KWFrameLayout::HeaderFooterFrameset(
00851 oddFooter, firstPageNum + 2, -1, m_pageHeaderFooter.ptFooterBodySpacing,
00852 KWFrameLayout::HeaderFooterFrameset::Odd ) );
00853 headerFooterList.append( new KWFrameLayout::HeaderFooterFrameset(
00854 evenFooter, firstPageNum + 1, -1, m_pageHeaderFooter.ptFooterBodySpacing,
00855 KWFrameLayout::HeaderFooterFrameset::Even ) );
00856 break;
00857 case HF_FIRST_DIFF:
00858 oddFooter->setVisible( true );
00859 evenFooter->setVisible( false );
00860 evenFooter->deleteAllCopies();
00861 firstFooter->setVisible( true );
00862
00863 headerFooterList.append( new KWFrameLayout::HeaderFooterFrameset(
00864 firstFooter, firstPageNum, firstPageNum, m_pageHeaderFooter.ptFooterBodySpacing ) );
00865 headerFooterList.append( new KWFrameLayout::HeaderFooterFrameset(
00866 oddFooter, firstPageNum + 1, -1, m_pageHeaderFooter.ptFooterBodySpacing ) );
00867 break;
00868 case HF_EO_DIFF:
00869 oddFooter->setVisible( true );
00870 evenFooter->setVisible( true );
00871 firstFooter->setVisible( false );
00872 firstFooter->deleteAllCopies();
00873
00874 headerFooterList.append( new KWFrameLayout::HeaderFooterFrameset(
00875 oddFooter, firstPageNum, -1, m_pageHeaderFooter.ptFooterBodySpacing,
00876 KWFrameLayout::HeaderFooterFrameset::Odd ) );
00877 headerFooterList.append( new KWFrameLayout::HeaderFooterFrameset(
00878 evenFooter, firstPageNum + 1, -1, m_pageHeaderFooter.ptFooterBodySpacing,
00879 KWFrameLayout::HeaderFooterFrameset::Even ) );
00880 break;
00881 }
00882 }
00883
00884
00885
00886
00887
00888
00889
00890
00891 QPtrList<KWFrameLayout::HeaderFooterFrameset> footnotesHFList;
00892 footnotesHFList.setAutoDelete( true );
00893
00894 footnotesList.sort();
00895 QPtrListIterator<KWFootNoteFrameSet> fnfsIt( footnotesList );
00896 for ( ; fnfsIt.current() ; ++fnfsIt )
00897 {
00898 KWFootNoteFrameSet* fnfs = fnfsIt.current();
00899 int pageNum = -42;
00900 KWFrameLayout::HeaderFooterFrameset* hff = new KWFrameLayout::HeaderFooterFrameset(
00901 fnfs, pageNum, pageNum,
00902 m_pageHeaderFooter.ptFootNoteBodySpacing,
00903 KWFrameLayout::HeaderFooterFrameset::All );
00904
00905
00906
00907 hff->m_height = 0;
00908 for (QPtrListIterator<KWFrame> f = fnfs->frameIterator(); f.current() ; ++f )
00909 hff->m_height += f.current()->height();
00910
00911 footnotesHFList.append( hff );
00912 }
00913
00914
00915 QPtrList<KWFrameLayout::HeaderFooterFrameset> endnotesHFList;
00916 endnotesHFList.setAutoDelete( true );
00917
00918 endnotesList.sort();
00919 QPtrListIterator<KWFootNoteFrameSet> enfsIt( endnotesList );
00920 for ( ; enfsIt.current() ; ++enfsIt )
00921 {
00922 KWFootNoteFrameSet* enfs = enfsIt.current();
00923 KWFrameLayout::HeaderFooterFrameset* hff = new KWFrameLayout::HeaderFooterFrameset(
00924 enfs, -42, -42,
00925 m_pageHeaderFooter.ptFootNoteBodySpacing,
00926 KWFrameLayout::HeaderFooterFrameset::All );
00927
00928
00929 hff->m_height = 0;
00930 for (QPtrListIterator<KWFrame> f = enfs->frameIterator(); f.current() ; ++f )
00931 hff->m_height += f.current()->height();
00932
00933 endnotesHFList.append( hff );
00934 }
00935
00936
00937 double maxBottom = 0;
00938 for (QPtrListIterator<KWFrameSet> fsit = framesetsIterator(); fsit.current() ; ++fsit ) {
00939 KWFrameSet *fs = fsit.current();
00940 if ( !fs->isVisible() || fs->isAHeader() || !fs->isAFooter() ||
00941 !fs->isFloating() || !fs->isFootEndNote() )
00942 continue;
00943 for (QPtrListIterator<KWFrame> fit = fs->frameIterator(); fit.current() ; ++fit )
00944 maxBottom = QMAX(maxBottom, fit.current()->bottom());
00945 }
00946 KWPage *last = pageManager()->page(lastPage());
00947 double docHeight = last->offsetInDocument() + last->height();
00948 while(docHeight <= maxBottom) {
00949 last = pageManager()->appendPage();
00950 docHeight += last->height();
00951 }
00952 int oldPages = pageCount();
00953
00954 if ( toPage == -1 )
00955 toPage = lastPage();
00956 if ( fromPage > toPage )
00957 fromPage = toPage;
00958 KWFrameLayout frameLayout( this, headerFooterList, footnotesHFList, endnotesHFList );
00959 frameLayout.layout( frameset, m_pageColumns.columns, fromPage, toPage, flags );
00960
00961
00962
00963 if ( pageCount() != oldPages && !m_bGeneratingPreview )
00964 {
00965
00966 emit newContentsSize();
00967 emit numPagesChanged();
00968 recalcVariables( VT_PGNUM );
00969 }
00970
00971 }
00972 else {
00973
00974 double maxBottom=0;
00975 for (QPtrListIterator<KWFrameSet> fit = framesetsIterator(); fit.current() ; ++fit ) {
00976 if(fit.current()->isDeleted()) continue;
00977 if(fit.current()->frameSetInfo()==KWFrameSet::FI_BODY && !fit.current()->isFloating()) {
00978 KWFrameSet * fs = fit.current();
00979 for (QPtrListIterator<KWFrame> f = fs->frameIterator(); f.current() ; ++f )
00980 maxBottom=QMAX(maxBottom, f.current()->bottom());
00981 }
00982 }
00983 KWPage *last = pageManager()->page(lastPage());
00984 double docHeight = last->offsetInDocument() + last->height();
00985 while(docHeight <= maxBottom) {
00986 last = pageManager()->appendPage();
00987 docHeight += last->height();
00988 }
00989 if ( toPage == -1 )
00990 toPage = pageCount() - 1;
00991 KWFrameList::recalcFrames(this, fromPage, toPage);
00992 }
00993 kdDebug(32002) << " ~recalcFrames" << endl;
00994 }
00995
00996 bool KWDocument::loadChildren( KoStore *store )
00997 {
00998
00999 QPtrListIterator<KoDocumentChild> it( children() );
01000 for( ; it.current(); ++it ) {
01001 if ( !it.current()->loadDocument( store ) )
01002 return FALSE;
01003 }
01004
01005 return TRUE;
01006 }
01007
01008 void KWDocument::loadPictureMap ( QDomElement& domElement )
01009 {
01010 m_pictureMap.clear();
01011
01012
01013 QDomElement picturesElem = domElement.namedItem( "PICTURES" ).toElement();
01014 if ( !picturesElem.isNull() )
01015 {
01016 m_pictureCollection->readXML( picturesElem, m_pictureMap );
01017 }
01018
01019
01020 QDomElement pixmapsElem = domElement.namedItem( "PIXMAPS" ).toElement();
01021 if ( !pixmapsElem.isNull() )
01022 {
01023 m_pictureCollection->readXML( pixmapsElem, m_pictureMap );
01024 }
01025
01026
01027 QDomElement clipartsElem = domElement.namedItem( "CLIPARTS" ).toElement();
01028 if ( !clipartsElem.isNull() )
01029 {
01030 m_pictureCollection->readXML( pixmapsElem, m_pictureMap );
01031 }
01032 }
01033
01034
01035 bool KWDocument::loadOasis( const QDomDocument& doc, KoOasisStyles& oasisStyles, const QDomDocument& settings, KoStore* store )
01036 {
01037 QTime dt;
01038 dt.start();
01039 emit sigProgress( 0 );
01040 clear();
01041 kdDebug(32001) << "KWDocument::loadOasis" << endl;
01042
01043 QDomElement content = doc.documentElement();
01044 QDomElement realBody ( KoDom::namedItemNS( content, KoXmlNS::office, "body" ) );
01045 if ( realBody.isNull() )
01046 {
01047 kdError(32001) << "No office:body found!" << endl;
01048 setErrorMessage( i18n( "Invalid OASIS OpenDocument file. No office:body tag found." ) );
01049 return false;
01050 }
01051 QDomElement body = KoDom::namedItemNS( realBody, KoXmlNS::office, "text" );
01052 if ( body.isNull() )
01053 {
01054 kdError(32001) << "No office:text found!" << endl;
01055 QDomElement childElem;
01056 QString localName;
01057 forEachElement( childElem, realBody ) {
01058 localName = childElem.localName();
01059 }
01060 if ( localName.isEmpty() )
01061 setErrorMessage( i18n( "Invalid OASIS OpenDocument file. No tag found inside office:body." ) );
01062 else
01063 setErrorMessage( i18n( "This is not a word processing document, but %1. Please try opening it with the appropriate application." ).arg( KoDocument::tagNameToDocumentType( localName ) ) );
01064 return false;
01065 }
01066
01067
01068
01069 KoOasisContext context( this, *m_varColl, oasisStyles, store );
01070
01071 createLoadingInfo();
01072
01073
01074
01075
01076
01077 m_loadingInfo->m_currentMasterPage = "Standard";
01078 if ( !loadOasisPageLayout( m_loadingInfo->m_currentMasterPage, context ) )
01079 return false;
01080
01081 KWOasisLoader oasisLoader( this );
01082
01083
01084 m_processingType = ( !KoDom::namedItemNS( body, KoXmlNS::text, "page-sequence" ).isNull() )
01085 ? DTP : WP;
01086
01087 m_hasTOC = false;
01088 m_tabStop = MM_TO_POINT(15);
01089 const QDomElement* defaultParagStyle = oasisStyles.defaultStyle( "paragraph" );
01090 if ( defaultParagStyle ) {
01091 KoStyleStack stack;
01092 stack.push( *defaultParagStyle );
01093 stack.setTypeProperties( "paragraph" );
01094 QString tabStopVal = stack.attributeNS( KoXmlNS::style, "tab-stop-distance" );
01095 if ( !tabStopVal.isEmpty() )
01096 m_tabStop = KoUnit::parseValue( tabStopVal );
01097 }
01098 m_initialEditing = 0;
01099
01100
01101
01102
01103
01104 if ( !isReadWrite())
01105 m_varColl->variableSetting()->setDisplayFieldCode(false);
01106
01107
01108 m_styleColl->loadOasisStyles( context );
01109 if ( m_frameStyleColl->loadOasisStyles( context ) == 0 ) {
01110
01111 loadDefaultFrameStyleTemplates();
01112 }
01113
01114 if ( m_tableStyleColl->loadOasisStyles( context, *m_styleColl, *m_frameStyleColl ) == 0 ) {
01115
01116 loadDefaultTableStyleTemplates();
01117 }
01118
01119 static_cast<KWVariableSettings *>( m_varColl->variableSetting() )
01120 ->loadNoteConfiguration( oasisStyles.officeStyle() );
01121
01122 loadDefaultTableTemplates();
01123
01124 if ( m_processingType == WP ) {
01125
01126 KWTextFrameSet *fs = new KWTextFrameSet( this, i18n( "Main Text Frameset" ) );
01127 m_lstFrameSet.append( fs );
01128 fs->loadOasisContent( body, context );
01129 KWFrame* frame = new KWFrame( fs, 29, 42, 566-29, 798-42 );
01130 frame->setFrameBehavior( KWFrame::AutoCreateNewFrame );
01131 frame->setNewFrameBehavior( KWFrame::Reconnect );
01132 fs->addFrame( frame );
01133
01134
01135 const QDomElement* masterPage = context.oasisStyles().masterPages()[ m_loadingInfo->m_currentMasterPage ];
01136 const QDomElement *masterPageStyle = masterPage ? context.oasisStyles().findStyle(masterPage->attributeNS( KoXmlNS::style, "page-layout-name", QString::null ) ) : 0;
01137 if ( masterPageStyle )
01138 {
01139 KoStyleStack styleStack;
01140 styleStack.push( *masterPageStyle );
01141 styleStack.setTypeProperties( "page-layout" );
01142 frame->loadBorderProperties( styleStack );
01143 }
01144 fs->renumberFootNotes( false );
01145
01146 } else {
01147
01148 QDomElement tag;
01149 forEachElement( tag, body )
01150 {
01151 context.styleStack().save();
01152 const QString localName = tag.localName();
01153 if ( localName == "page-sequence" && tag.namespaceURI() == KoXmlNS::text )
01154 {
01155
01156
01157 int pages=1;
01158 QDomElement page;
01159 forEachElement( page, tag )
01160 ++pages;
01161 kdDebug() << "DTP mode: found " << pages << "pages" << endl;
01162
01163 }
01164 else if ( localName == "frame" && tag.namespaceURI() == KoXmlNS::draw )
01165 oasisLoader.loadFrame( tag, context, KoPoint() );
01166 else
01167 kdWarning(32001) << "Unsupported tag in DTP loading:" << tag.tagName() << endl;
01168 }
01169 }
01170
01171 loadMasterPageStyle( m_loadingInfo->m_currentMasterPage, context );
01172
01173 if ( context.cursorTextParagraph() ) {
01174
01175
01176
01177 m_initialEditing = new InitialEditing();
01178 KWTextFrameSet* fs = static_cast<KWTextDocument *>( context.cursorTextParagraph()->textDocument() )->textFrameSet();
01179 m_initialEditing->m_initialFrameSet = fs->name();
01180 m_initialEditing->m_initialCursorParag = context.cursorTextParagraph()->paragId();
01181 m_initialEditing->m_initialCursorIndex = context.cursorTextIndex();
01182 }
01183
01184 if ( !settings.isNull() )
01185 {
01186 oasisLoader.loadOasisSettings( settings );
01187 }
01188
01189 kdDebug(32001) << "Loading took " << (float)(dt.elapsed()) / 1000 << " seconds" << endl;
01190 endOfLoading();
01191
01192
01193
01194 setPageLayout( m_pageLayout, m_loadingInfo->columns, m_loadingInfo->hf, false );
01195
01196
01197 return true;
01198 }
01199
01200 bool KWDocument::loadOasisPageLayout( const QString& masterPageName, KoOasisContext& context )
01201 {
01202 KoColumns& columns = m_loadingInfo->columns;
01203
01204 const KoOasisStyles& oasisStyles = context.oasisStyles();
01205 const QDomElement* masterPage = oasisStyles.masterPages()[ masterPageName ];
01206 Q_ASSERT( masterPage );
01207 const QDomElement *masterPageStyle = masterPage ? oasisStyles.findStyle( masterPage->attributeNS( KoXmlNS::style, "page-layout-name", QString::null ) ) : 0;
01208 Q_ASSERT( masterPageStyle );
01209 if ( masterPageStyle )
01210 {
01211 m_pageLayout.loadOasis( *masterPageStyle );
01212 if ( m_pageLayout.ptWidth <= 1e-13 || m_pageLayout.ptHeight <= 1e-13 )
01213 {
01214
01215 QDomElement properties( KoDom::namedItemNS( *masterPageStyle, KoXmlNS::style, "page-layout-properties" ) );
01216
01217
01218
01219
01220
01221 if ( properties.hasAttributeNS( "http://www.w3.org/1999/XSL/Format", "page-width" ) )
01222 setErrorMessage( i18n( "Invalid document. 'fo' has the wrong namespace. The application which produced this document is not OASIS-compliant." ) );
01223 else
01224 setErrorMessage( i18n( "Invalid document. Paper size: %1x%2" ).arg( m_pageLayout.ptWidth ).arg( m_pageLayout.ptHeight ) );
01225 return false;
01226 }
01227 pageManager()->setDefaultPage(m_pageLayout);
01228
01229 const QDomElement properties( KoDom::namedItemNS( *masterPageStyle, KoXmlNS::style, "page-layout-properties" ) );
01230 const QDomElement footnoteSep = KoDom::namedItemNS( properties, KoXmlNS::style, "footnote-sep" );
01231 if ( !footnoteSep.isNull() ) {
01232
01233
01234
01235 const QString width = footnoteSep.attributeNS( KoXmlNS::style, "width", QString::null );
01236 if ( !width.isEmpty() ) {
01237 m_footNoteSeparatorLineWidth = KoUnit::parseValue( width );
01238 }
01239
01240 QString pageWidth = footnoteSep.attributeNS( KoXmlNS::style, "rel-width", QString::null );
01241 if ( pageWidth.endsWith( "%" ) ) {
01242 pageWidth.truncate( pageWidth.length() - 1 );
01243 m_iFootNoteSeparatorLineLength = qRound( pageWidth.toDouble() );
01244 }
01245
01246
01247 const QString style = footnoteSep.attributeNS( KoXmlNS::style, "line-style", QString::null );
01248 if ( style == "solid" || style.isEmpty() )
01249 m_footNoteSeparatorLineType = SLT_SOLID;
01250 else if ( style == "dash" )
01251 m_footNoteSeparatorLineType = SLT_DASH;
01252 else if ( style == "dotted" )
01253 m_footNoteSeparatorLineType = SLT_DOT;
01254 else if ( style == "dot-dash" )
01255 m_footNoteSeparatorLineType = SLT_DASH_DOT;
01256 else if ( style == "dot-dot-dash" )
01257 m_footNoteSeparatorLineType = SLT_DASH_DOT_DOT;
01258 else
01259 kdDebug() << "Unknown value for m_footNoteSeparatorLineType: " << style << endl;
01260
01261 const QString pos = footnoteSep.attributeNS( KoXmlNS::style, "adjustment", QString::null );
01262 if ( pos == "centered" )
01263 m_footNoteSeparatorLinePos = SLP_CENTERED;
01264 else if ( pos == "right")
01265 m_footNoteSeparatorLinePos = SLP_RIGHT;
01266 else
01267 m_footNoteSeparatorLinePos = SLP_LEFT;
01268 }
01269
01270 const QDomElement columnsElem = KoDom::namedItemNS( properties, KoXmlNS::style, "columns" );
01271 if ( !columnsElem.isNull() )
01272 {
01273 columns.columns = columnsElem.attributeNS( KoXmlNS::fo, "column-count", QString::null ).toInt();
01274 if ( columns.columns == 0 )
01275 columns.columns = 1;
01276
01277
01278
01279 if ( columnsElem.hasAttributeNS( KoXmlNS::fo, "column-gap" ) )
01280 columns.ptColumnSpacing = KoUnit::parseValue( columnsElem.attributeNS( KoXmlNS::fo, "column-gap", QString::null ) );
01281
01282 }
01283
01284 m_headerVisible = false;
01285 m_footerVisible = false;
01286
01287
01288
01289
01290 }
01291 else
01292
01293 {
01294 columns.columns = 1;
01295 columns.ptColumnSpacing = 2;
01296 m_headerVisible = false;
01297 m_footerVisible = false;
01298 m_pageLayout = KoPageLayout::standardLayout();
01299 pageManager()->setDefaultPage(m_pageLayout);
01300 }
01301 return true;
01302 }
01303
01304 void KWDocument::loadMasterPageStyle( const QString& masterPageName, KoOasisContext& context )
01305 {
01306 const KoOasisStyles& oasisStyles = context.oasisStyles();
01307 const QDomElement* masterPage = oasisStyles.masterPages()[ masterPageName ];
01308 Q_ASSERT( masterPage );
01309 const QDomElement *masterPageStyle = masterPage ? oasisStyles.findStyle( masterPage->attributeNS( KoXmlNS::style, "page-layout-name", QString::null ) ) : 0;
01310 Q_ASSERT( masterPageStyle );
01311
01312 KoKWHeaderFooter& hf = m_loadingInfo->hf;
01313
01314 bool hasEvenOddHeader = false;
01315 bool hasEvenOddFooter = false;
01316 if ( masterPageStyle )
01317 {
01318 KWOasisLoader oasisLoader( this );
01319
01320 QDomElement headerStyle = KoDom::namedItemNS( *masterPageStyle, KoXmlNS::style, "header-style" );
01321 QDomElement footerStyle = KoDom::namedItemNS( *masterPageStyle, KoXmlNS::style, "footer-style" );
01322 QDomElement headerLeftElem = KoDom::namedItemNS( *masterPage, KoXmlNS::style, "header-left" );
01323 QDomElement headerFirstElem = KoDom::namedItemNS( *masterPage, KoXmlNS::style, "header-first" );
01324 const bool hasFirstHeader = !headerFirstElem.isNull();
01325 if ( !headerLeftElem.isNull() )
01326 {
01327 hasEvenOddHeader = true;
01328 hf.header = hasFirstHeader ? HF_FIRST_EO_DIFF : HF_EO_DIFF;
01329 oasisLoader.loadOasisHeaderFooter( headerLeftElem, hasEvenOddHeader, headerStyle, context );
01330 }
01331 else
01332 {
01333 hf.header = hasFirstHeader ? HF_FIRST_DIFF : HF_SAME;
01334 }
01335 if ( hasFirstHeader )
01336 {
01337 oasisLoader.loadOasisHeaderFooter( headerFirstElem, hasEvenOddHeader, headerStyle, context );
01338 }
01339
01340 QDomElement headerElem = KoDom::namedItemNS( *masterPage, KoXmlNS::style, "header" );
01341 if ( !headerElem.isNull() )
01342 {
01343 oasisLoader.loadOasisHeaderFooter( headerElem, hasEvenOddHeader, headerStyle, context );
01344 }
01345
01346
01347
01348 QDomElement footerLeftElem = KoDom::namedItemNS( *masterPage, KoXmlNS::style, "footer-left" );
01349 QDomElement footerFirstElem = KoDom::namedItemNS( *masterPage, KoXmlNS::style, "footer-first" );
01350 const bool hasFirstFooter = !footerFirstElem.isNull();
01351 if ( !footerLeftElem.isNull() )
01352 {
01353 hasEvenOddFooter = true;
01354 hf.footer = hasFirstFooter ? HF_FIRST_EO_DIFF : HF_EO_DIFF;
01355 oasisLoader.loadOasisHeaderFooter( footerLeftElem, hasEvenOddFooter, footerStyle, context );
01356 }
01357 else
01358 {
01359 hf.footer = hasFirstFooter ? HF_FIRST_DIFF : HF_SAME;
01360 }
01361 if ( hasFirstFooter )
01362 {
01363 oasisLoader.loadOasisHeaderFooter( footerFirstElem, hasEvenOddFooter, footerStyle, context );
01364 }
01365 QDomElement footerElem = KoDom::namedItemNS( *masterPage, KoXmlNS::style, "footer" );
01366 if ( !footerElem.isNull() )
01367 {
01368 oasisLoader.loadOasisHeaderFooter( footerElem, hasEvenOddFooter, footerStyle, context );
01369 }
01370
01371
01372
01373 if ( !headerStyle.isNull() ) {
01374 context.styleStack().push( headerStyle );
01375 context.styleStack().setTypeProperties( "header-footer" );
01376 hf.ptHeaderBodySpacing = KoUnit::parseValue( context.styleStack().attributeNS( KoXmlNS::fo, "margin-bottom" ) );
01377 context.styleStack().pop();
01378 }
01379
01380
01381 if ( !footerStyle.isNull() ) {
01382 context.styleStack().push( footerStyle );
01383 context.styleStack().setTypeProperties( "header-footer" );
01384 hf.ptFooterBodySpacing = KoUnit::parseValue( context.styleStack().attributeNS( KoXmlNS::fo, "margin-top" ) );
01385 context.styleStack().pop();
01386 }
01387
01388 }
01389 }
01390
01391
01392
01393
01394
01395 void KWDocument::clear()
01396 {
01397 m_pictureMap.clear();
01398 m_textImageRequests.clear();
01399 m_pictureRequests.clear();
01400 m_anchorRequests.clear();
01401 m_footnoteVarRequests.clear();
01402 m_spellCheckIgnoreList.clear();
01403
01404 m_pageHeaderFooter.header = HF_SAME;
01405 m_pageHeaderFooter.footer = HF_SAME;
01406 m_pageHeaderFooter.ptHeaderBodySpacing = 10;
01407 m_pageHeaderFooter.ptFooterBodySpacing = 10;
01408 m_pageHeaderFooter.ptFootNoteBodySpacing = 10;
01409 m_pageColumns.columns = 1;
01410 m_pageColumns.ptColumnSpacing = m_defaultColumnSpacing;
01411 m_bHasEndNotes = false;
01412
01413 m_lstFrameSet.clear();
01414
01415 m_varColl->clear();
01416 m_pictureCollection->clear();
01417 m_varFormatCollection->clear();
01418
01419 m_styleColl->clear();
01420 m_frameStyleColl->clear();
01421 m_tableStyleColl->clear();
01422 m_tableTemplateColl->clear();
01423
01424
01425
01426 KoParagStyle * standardStyle = new KoParagStyle( "Standard" );
01427
01428 standardStyle->format().setFont( m_defaultFont );
01429 m_styleColl->addStyle( standardStyle );
01430
01431
01432 KWFrameStyle * standardFrameStyle = new KWFrameStyle( "Plain" );
01433 standardFrameStyle->setBackgroundColor(Qt::white);
01434 standardFrameStyle->setTopBorder(KoBorder(Qt::black,KoBorder::SOLID,0));
01435 standardFrameStyle->setRightBorder(KoBorder(Qt::black,KoBorder::SOLID,0));
01436 standardFrameStyle->setLeftBorder(KoBorder(Qt::black,KoBorder::SOLID,0));
01437 standardFrameStyle->setBottomBorder(KoBorder(Qt::black,KoBorder::SOLID,0));
01438 m_frameStyleColl->addStyle( standardFrameStyle );
01439
01440
01441 KWTableStyle *standardTableStyle = new KWTableStyle( "Plain", standardStyle, standardFrameStyle );
01442 m_tableStyleColl->addStyle( standardTableStyle );
01443 }
01444
01445 bool KWDocument::loadXML( QIODevice *, const QDomDocument & doc )
01446 {
01447 QTime dt;
01448 dt.start();
01449 emit sigProgress( 0 );
01450 kdDebug(32001) << "KWDocument::loadXML" << endl;
01451 clear();
01452
01453 KoPageLayout pgLayout;
01454 KoColumns columns;
01455 columns.columns = 1;
01456 columns.ptColumnSpacing = m_defaultColumnSpacing;
01457 KoKWHeaderFooter hf;
01458 hf.header = HF_SAME;
01459 hf.footer = HF_SAME;
01460 hf.ptHeaderBodySpacing = 10.0;
01461 hf.ptFooterBodySpacing = 10.0;
01462 hf.ptFootNoteBodySpacing = 10.0;
01463
01464 QString value;
01465 QDomElement word = doc.documentElement();
01466
01467 value = KWDocument::getAttribute( word, "mime", QString::null );
01468 if ( value.isEmpty() )
01469 {
01470 kdError(32001) << "No mime type specified!" << endl;
01471 setErrorMessage( i18n( "Invalid document. No mimetype specified." ) );
01472 return false;
01473 }
01474 else if ( value != "application/x-kword" && value != "application/vnd.kde.kword" )
01475 {
01476 kdError(32001) << "Unknown mime type " << value << endl;
01477 setErrorMessage( i18n( "Invalid document. Expected mimetype application/x-kword or application/vnd.kde.kword, got %1" ).arg( value ) );
01478 return false;
01479 }
01480 m_syntaxVersion = KWDocument::getAttribute( word, "syntaxVersion", 0 );
01481 if ( m_syntaxVersion > CURRENT_SYNTAX_VERSION )
01482 {
01483 int ret = KMessageBox::warningContinueCancel(
01484 0, i18n("This document was created with a newer version of KWord (syntax version: %1)\n"
01485 "Opening it in this version of KWord will lose some information.").arg(m_syntaxVersion),
01486 i18n("File Format Mismatch"), KStdGuiItem::cont() );
01487 if ( ret == KMessageBox::Cancel )
01488 {
01489 setErrorMessage( "USER_CANCELED" );
01490 return false;
01491 }
01492 }
01493
01494 createLoadingInfo();
01495
01496
01497
01498 value = KWDocument::getAttribute( word, "url", QString::null );
01499 if ( !value.isNull() )
01500 {
01501 m_urlIntern = KURL( value ).path();
01502 }
01503
01504 emit sigProgress(5);
01505
01506
01507 QDomElement paper = word.namedItem( "PAPER" ).toElement();
01508 if ( !paper.isNull() )
01509 {
01510 pgLayout.format = static_cast<KoFormat>( KWDocument::getAttribute( paper, "format", 0 ) );
01511 pgLayout.orientation = static_cast<KoOrientation>( KWDocument::getAttribute( paper, "orientation", 0 ) );
01512 pgLayout.ptWidth = getAttribute( paper, "width", 0.0 );
01513 pgLayout.ptHeight = getAttribute( paper, "height", 0.0 );
01514 kdDebug() << " ptWidth=" << pgLayout.ptWidth << endl;
01515 kdDebug() << " ptHeight=" << pgLayout.ptHeight << endl;
01516 if ( pgLayout.ptWidth <= 0 || pgLayout.ptHeight <= 0 )
01517 {
01518
01519 pgLayout.ptWidth = getAttribute( paper, "ptWidth", 0.0 );
01520 pgLayout.ptHeight = getAttribute( paper, "ptHeight", 0.0 );
01521 kdDebug() << " ptWidth=" << pgLayout.ptWidth << endl;
01522 kdDebug() << " ptHeight=" << pgLayout.ptHeight << endl;
01523
01524
01525 if ( pgLayout.ptWidth <= 0 || pgLayout.ptHeight <= 0 )
01526 {
01527 setErrorMessage( i18n( "Invalid document. Paper size: %1x%2" )
01528 .arg( pgLayout.ptWidth ).arg( pgLayout.ptHeight ) );
01529 return false;
01530 }
01531 }
01532
01533 hf.header = static_cast<KoHFType>( KWDocument::getAttribute( paper, "hType", 0 ) );
01534 hf.footer = static_cast<KoHFType>( KWDocument::getAttribute( paper, "fType", 0 ) );
01535 hf.ptHeaderBodySpacing = getAttribute( paper, "spHeadBody", 0.0 );
01536 hf.ptFooterBodySpacing = getAttribute( paper, "spFootBody", 0.0 );
01537 hf.ptFootNoteBodySpacing = getAttribute( paper, "spFootNoteBody", 10.0 );
01538 m_iFootNoteSeparatorLineLength = getAttribute( paper, "slFootNoteLength", 20);
01539 m_footNoteSeparatorLineWidth = getAttribute( paper, "slFootNoteWidth",2.0);
01540 m_footNoteSeparatorLineType = static_cast<SeparatorLineLineType>(getAttribute( paper, "slFootNoteType",0));
01541
01542 if ( paper.hasAttribute("slFootNotePosition"))
01543 {
01544 QString tmp =paper.attribute("slFootNotePosition");
01545 if ( tmp =="centered" )
01546 m_footNoteSeparatorLinePos = SLP_CENTERED;
01547 else if ( tmp =="right")
01548 m_footNoteSeparatorLinePos = SLP_RIGHT;
01549 else if ( tmp =="left" )
01550 m_footNoteSeparatorLinePos = SLP_LEFT;
01551 }
01552 columns.columns = KWDocument::getAttribute( paper, "columns", 1 );
01553 columns.ptColumnSpacing = KWDocument::getAttribute( paper, "columnspacing", 0.0 );
01554
01555
01556
01557
01558
01559
01560
01561
01562 if ( pgLayout.ptWidth == 0.0 )
01563 pgLayout.ptWidth = getAttribute( paper, "ptWidth", 0.0 );
01564 if ( pgLayout.ptHeight == 0.0 )
01565 pgLayout.ptHeight = getAttribute( paper, "ptHeight", 0.0 );
01566 if ( hf.ptHeaderBodySpacing == 0.0 )
01567 hf.ptHeaderBodySpacing = getAttribute( paper, "ptHeadBody", 0.0 );
01568 if ( hf.ptFooterBodySpacing == 0.0 )
01569 hf.ptFooterBodySpacing = getAttribute( paper, "ptFootBody", 0.0 );
01570 if ( columns.ptColumnSpacing == 0.0 )
01571 columns.ptColumnSpacing = getAttribute( paper, "ptColumnspc", 0.0 );
01572
01573
01574 QDomElement paperborders = paper.namedItem( "PAPERBORDERS" ).toElement();
01575 if ( !paperborders.isNull() )
01576 {
01577 pgLayout.ptLeft = getAttribute( paperborders, "left", 0.0 );
01578 pgLayout.ptTop = getAttribute( paperborders, "top", 0.0 );
01579 pgLayout.ptRight = getAttribute( paperborders, "right", 0.0 );
01580 pgLayout.ptBottom = getAttribute( paperborders, "bottom", 0.0 );
01581
01582
01583 if ( pgLayout.ptLeft == 0.0 )
01584 pgLayout.ptLeft = getAttribute( paperborders, "ptLeft", 0.0 );
01585 if ( pgLayout.ptTop == 0.0 )
01586 pgLayout.ptTop = getAttribute( paperborders, "ptTop", 0.0 );
01587 if ( pgLayout.ptRight == 0.0 )
01588 pgLayout.ptRight = getAttribute( paperborders, "ptRight", 0.0 );
01589 if ( pgLayout.ptBottom == 0.0 )
01590 pgLayout.ptBottom = getAttribute( paperborders, "ptBottom", 0.0 );
01591 }
01592 else
01593 kdWarning() << "No <PAPERBORDERS> tag!" << endl;
01594 }
01595 else
01596 kdWarning() << "No <PAPER> tag! This is a mandatory tag! Expect weird page sizes..." << endl;
01597
01598
01599 QDomElement attributes = word.namedItem( "ATTRIBUTES" ).toElement();
01600 if ( !attributes.isNull() )
01601 {
01602 m_processingType = static_cast<ProcessingType>( KWDocument::getAttribute( attributes, "processing", 0 ) );
01603
01604 m_headerVisible = static_cast<bool>( KWDocument::getAttribute( attributes, "hasHeader", 0 ) );
01605 m_footerVisible = static_cast<bool>( KWDocument::getAttribute( attributes, "hasFooter", 0 ) );
01606 if ( attributes.hasAttribute( "unit" ) )
01607 setUnit( KoUnit::unit( attributes.attribute( "unit" ) ) );
01608 m_hasTOC = static_cast<bool>(KWDocument::getAttribute( attributes,"hasTOC", 0 ) );
01609 m_tabStop = KWDocument::getAttribute( attributes, "tabStopValue", MM_TO_POINT(15) );
01610 m_initialEditing = new InitialEditing();
01611 m_initialEditing->m_initialFrameSet = attributes.attribute( "activeFrameset" );
01612 m_initialEditing->m_initialCursorParag = attributes.attribute( "cursorParagraph" ).toInt();
01613 m_initialEditing->m_initialCursorIndex = attributes.attribute( "cursorIndex" ).toInt();
01614 } else {
01615 m_processingType = WP;
01616 m_headerVisible = false;
01617 m_footerVisible = false;
01618 m_hasTOC = false;
01619 m_tabStop = MM_TO_POINT(15);
01620 delete m_initialEditing;
01621 m_initialEditing = 0L;
01622 }
01623
01624 setPageLayout( pgLayout, columns, hf, false );
01625
01626 variableCollection()->variableSetting()->load(word );
01627
01628 if ( !isReadWrite())
01629 variableCollection()->variableSetting()->setDisplayFieldCode(false);
01630
01631 emit sigProgress(10);
01632
01633 QDomElement mailmerge = word.namedItem( "MAILMERGE" ).toElement();
01634 if (mailmerge!=QDomElement())
01635 {
01636 m_slDataBase->load(mailmerge);
01637 }
01638
01639 emit sigProgress(15);
01640
01641
01642 QDomElement stylesElem = word.namedItem( "STYLES" ).toElement();
01643 if ( !stylesElem.isNull() )
01644 loadStyleTemplates( stylesElem );
01645
01646 emit sigProgress(17);
01647
01648 QDomElement frameStylesElem = word.namedItem( "FRAMESTYLES" ).toElement();
01649 if ( !frameStylesElem.isNull() )
01650 loadFrameStyleTemplates( frameStylesElem );
01651 else
01652 loadDefaultFrameStyleTemplates();
01653
01654 emit sigProgress(18);
01655
01656 QDomElement tableStylesElem = word.namedItem( "TABLESTYLES" ).toElement();
01657 if ( !tableStylesElem.isNull() )
01658 loadTableStyleTemplates( tableStylesElem );
01659 else
01660 loadDefaultTableStyleTemplates();
01661
01662 emit sigProgress(19);
01663
01664 loadDefaultTableTemplates();
01665
01666 emit sigProgress(20);
01667
01668 QDomElement bookmark = word.namedItem( "BOOKMARKS" ).toElement();
01669 if( !bookmark.isNull() )
01670 {
01671 QDomElement bookmarkitem = word.namedItem("BOOKMARKS").toElement();
01672 bookmarkitem = bookmarkitem.firstChild().toElement();
01673
01674 while ( !bookmarkitem.isNull() )
01675 {
01676 if ( bookmarkitem.tagName() == "BOOKMARKITEM" )
01677 {
01678 KWLoadingInfo::BookMark bk;
01679 bk.bookname=bookmarkitem.attribute("name");
01680 bk.cursorStartIndex=bookmarkitem.attribute("cursorIndexStart").toInt();
01681 bk.frameSetName=bookmarkitem.attribute("frameset");
01682 bk.paragStartIndex = bookmarkitem.attribute("startparag").toInt();
01683 bk.paragEndIndex = bookmarkitem.attribute("endparag").toInt();
01684 bk.cursorEndIndex = bookmarkitem.attribute("cursorIndexEnd").toInt();
01685 Q_ASSERT( m_loadingInfo );
01686 m_loadingInfo->bookMarkList.append( bk );
01687 }
01688 bookmarkitem = bookmarkitem.nextSibling().toElement();
01689 }
01690 }
01691
01692 QStringList lst;
01693 QDomElement spellCheckIgnore = word.namedItem( "SPELLCHECKIGNORELIST" ).toElement();
01694 if( !spellCheckIgnore.isNull() )
01695 {
01696 QDomElement spellWord=word.namedItem("SPELLCHECKIGNORELIST").toElement();
01697 spellWord=spellWord.firstChild().toElement();
01698 while ( !spellWord.isNull() )
01699 {
01700 if ( spellWord.tagName()=="SPELLCHECKIGNOREWORD" )
01701 lst.append(spellWord.attribute("word"));
01702 spellWord=spellWord.nextSibling().toElement();
01703 }
01704 }
01705 setSpellCheckIgnoreList( lst );
01706
01707 emit sigProgress(25);
01708
01709
01710 QDomElement framesets = word.namedItem( "FRAMESETS" ).toElement();
01711 if ( !framesets.isNull() )
01712 loadFrameSets( framesets );
01713
01714 emit sigProgress(85);
01715
01716 loadPictureMap( word );
01717
01718 emit sigProgress(90);
01719
01720
01721 loadEmbeddedObjects( word );
01722
01723 emit sigProgress(100);
01724
01725 kdDebug(32001) << "Loading took " << (float)(dt.elapsed()) / 1000 << " seconds" << endl;
01726
01727 endOfLoading();
01728 return true;
01729 }
01730
01731 void KWDocument::endOfLoading()
01732 {
01733
01734 double maxBottom = 0;
01735 for (QPtrListIterator<KWFrameSet> fsit = framesetsIterator(); fsit.current() ; ++fsit ) {
01736 KWFrameSet *fs = fsit.current();
01737 for (QPtrListIterator<KWFrame> fit = fs->frameIterator(); fit.current() ; ++fit ) {
01738 KWFrame *frame = fit.current();
01739 maxBottom = QMAX(maxBottom, frame->bottom());
01740 }
01741 }
01742 KWPage *last = pageManager()->page(lastPage());
01743 double docHeight = last->offsetInDocument() + last->height();
01744 while(docHeight <= maxBottom) {
01745 kdDebug(32001) << "KWDocument::loadXML appends a page\n";
01746 last = pageManager()->appendPage();
01747 docHeight += last->height();
01748 }
01749
01750 bool first_footer = false, even_footer = false, odd_footer = false;
01751 bool first_header = false, even_header = false, odd_header = false;
01752
01753 QPtrListIterator<KWFrameSet> fit = framesetsIterator();
01754 for ( ; fit.current() ; ++fit )
01755 {
01756 switch( fit.current()->frameSetInfo() ) {
01757 case KWFrameSet::FI_FIRST_HEADER: first_header = true; break;
01758 case KWFrameSet::FI_ODD_HEADER: odd_header = true; break;
01759 case KWFrameSet::FI_EVEN_HEADER: even_header = true; break;
01760 case KWFrameSet::FI_FIRST_FOOTER: first_footer = true; break;
01761 case KWFrameSet::FI_ODD_FOOTER: odd_footer = true; break;
01762 case KWFrameSet::FI_EVEN_FOOTER: even_footer = true; break;
01763 case KWFrameSet::FI_FOOTNOTE: break;
01764 default: break;
01765 }
01766 }
01767
01768
01769
01770
01771 uint newFramesetsIndex = m_lstFrameSet.isEmpty() ? 0 : 1;
01772
01773 if ( !first_header ) {
01774 KWTextFrameSet *fs = new KWTextFrameSet( this, i18n( "First Page Header" ) );
01775
01776 fs->setFrameSetInfo( KWFrameSet::FI_FIRST_HEADER );
01777 KWPage *page = pageManager()->page(startPage());
01778 KWFrame *frame = new KWFrame(fs, page->leftMargin(), page->topMargin(),
01779 page->width() - page->leftMargin() - page->rightMargin(), 20 );
01780
01781 frame->setFrameBehavior( KWFrame::AutoExtendFrame );
01782 frame->setNewFrameBehavior( KWFrame::Copy );
01783 fs->addFrame( frame );
01784 m_lstFrameSet.insert( newFramesetsIndex++, fs );
01785 }
01786
01787 if ( !odd_header ) {
01788 KWTextFrameSet *fs = new KWTextFrameSet( this, i18n( "Odd Pages Header" ) );
01789
01790 fs->setFrameSetInfo( KWFrameSet::FI_ODD_HEADER );
01791 KWPage *page = pageManager()->page(QMIN(startPage()+2, lastPage()));
01792 KWFrame *frame = new KWFrame(fs, page->leftMargin(), page->topMargin(),
01793 page->width() - page->leftMargin() - page->rightMargin(), 20 );
01794
01795 frame->setFrameBehavior( KWFrame::AutoExtendFrame );
01796 frame->setNewFrameBehavior( KWFrame::Copy );
01797 fs->addFrame( frame );
01798 m_lstFrameSet.insert( newFramesetsIndex++, fs );
01799 }
01800
01801 if ( !even_header ) {
01802 KWTextFrameSet *fs = new KWTextFrameSet( this, i18n( "Even Pages Header" ) );
01803
01804 fs->setFrameSetInfo( KWFrameSet::FI_EVEN_HEADER );
01805 KWPage *page = pageManager()->page(QMIN(startPage()+1, lastPage()));
01806 KWFrame *frame = new KWFrame(fs, page->leftMargin(), page->topMargin(), page->width() -
01807 page->leftMargin() - page->rightMargin(), 20 );
01808
01809 frame->setFrameBehavior( KWFrame::AutoExtendFrame );
01810 frame->setNewFrameBehavior( KWFrame::Copy );
01811 fs->addFrame( frame );
01812 m_lstFrameSet.insert( newFramesetsIndex++, fs );
01813 }
01814
01815 if ( !first_footer ) {
01816 KWTextFrameSet *fs = new KWTextFrameSet( this, i18n( "First Page Footer" ) );
01817
01818 fs->setFrameSetInfo( KWFrameSet::FI_FIRST_FOOTER );
01819 KWPage *page = pageManager()->page(pageManager()->startPage());
01820 KWFrame *frame = new KWFrame(fs, page->leftMargin(), page->height() - page->topMargin()- 20,
01821 page->width() - page->leftMargin() - page->rightMargin(), 20 );
01822
01823 frame->setFrameBehavior( KWFrame::AutoExtendFrame );
01824 frame->setNewFrameBehavior( KWFrame::Copy );
01825 fs->addFrame( frame );
01826 m_lstFrameSet.insert( newFramesetsIndex++, fs );
01827 }
01828
01829 if ( !odd_footer ) {
01830 KWTextFrameSet *fs = new KWTextFrameSet( this, i18n( "Odd Pages Footer" ) );
01831
01832 fs->setFrameSetInfo( KWFrameSet::FI_ODD_FOOTER );
01833 KWPage *page = pageManager()->page(QMIN(startPage()+2, lastPage()));
01834 KWFrame *frame = new KWFrame(fs, page->leftMargin(), page->height()- page->topMargin() - 20,
01835 page->width() - page->leftMargin() - page->rightMargin(), 20 );
01836
01837 frame->setFrameBehavior( KWFrame::AutoExtendFrame );
01838 frame->setNewFrameBehavior( KWFrame::Copy );
01839 fs->addFrame( frame );
01840 m_lstFrameSet.insert( newFramesetsIndex++, fs );
01841 }
01842
01843 if ( !even_footer ) {
01844 KWTextFrameSet *fs = new KWTextFrameSet( this, i18n( "Even Pages Footer" ) );
01845
01846 fs->setFrameSetInfo( KWFrameSet::FI_EVEN_FOOTER );
01847 KWPage *page = pageManager()->page(QMIN(startPage()+1, lastPage()));
01848 KWFrame *frame = new KWFrame(fs, page->leftMargin(), page->height() - page->topMargin()- 20,
01849 page->width() - page->leftMargin() - page->rightMargin(), 20 );
01850
01851 frame->setFrameBehavior( KWFrame::AutoExtendFrame );
01852 frame->setNewFrameBehavior( KWFrame::Copy );
01853 fs->addFrame( frame );
01854 m_lstFrameSet.insert( newFramesetsIndex++, fs );
01855 }
01856
01857
01858 for (int i = frameSetCount()-1; i>-1; i--) {
01859 KWFrameSet *fs = frameSet(i);
01860 if(!fs) {
01861 kdWarning() << "frameset " << i << " is NULL!!" << endl;
01862 m_lstFrameSet.remove(i);
01863 continue;
01864 }
01865 if( fs->type()==FT_TABLE) {
01866 static_cast<KWTableFrameSet *>( fs )->validate();
01867 } else if (fs->type() == FT_TEXT) {
01868 for (int f=fs->frameCount()-1; f>=0; f--) {
01869 KWFrame *frame = fs->frame(f);
01870 if(frame->left() < 0) {
01871 kdWarning() << fs->name() << " frame " << f << " pos.x is < 0, moving frame" << endl;
01872 frame->moveBy( 0- frame->left(), 0);
01873 }
01874 if(frame->right() > m_pageLayout.ptWidth) {
01875 kdWarning() << fs->name() << " frame " << f << " rightborder outside page ("
01876 << frame->right() << ">" << m_pageLayout.ptWidth << "), shrinking" << endl;
01877 frame->setRight(m_pageLayout.ptWidth);
01878 }
01879 if(fs->isProtectSize())
01880 continue;
01881 if(frame->height() < s_minFrameHeight) {
01882 kdWarning() << fs->name() << " frame " << f << " height is so small no text will fit, adjusting (was: "
01883 << frame->height() << " is: " << s_minFrameHeight << ")" << endl;
01884 frame->setHeight(s_minFrameHeight);
01885 }
01886 if(frame->width() < s_minFrameWidth) {
01887 kdWarning() << fs->name() << " frame " << f << " width is so small no text will fit, adjusting (was: "
01888 << frame->width() << " is: " << s_minFrameWidth << ")" << endl;
01889 frame->setWidth(s_minFrameWidth);
01890 }
01891 }
01892 if(fs->frameCount() == 0) {
01893 KWPage *page = pageManager()->page(startPage());
01894 KWFrame *frame = new KWFrame(fs, page->leftMargin(), page->topMargin(),
01895 page->width() - page->leftMargin() - page->rightMargin(),
01896 page->height() - page->topMargin() - page->bottomMargin());
01897
01898 fs->addFrame( frame );
01899 }
01900 } else if(fs->frameCount() == 0) {
01901 kdWarning () << "frameset " << i << " " << fs->name() << " has no frames" << endl;
01902 removeFrameSet(fs);
01903 if ( fs->type() == FT_PART )
01904 delete static_cast<KWPartFrameSet *>(fs)->getChild();
01905 delete fs;
01906 continue;
01907 }
01908 if(fs->frameCount() > 0) {
01909 KWFrame *frame = fs->frame(0);
01910 if(frame->isCopy()) {
01911 kdWarning() << "First frame in a frameset[" << fs->name() << "] was set to be a copy; resetting\n";
01912 frame->setCopy(false);
01913 }
01914 }
01915 }
01916
01917
01918 KWTextFrameSet *frameset = dynamic_cast<KWTextFrameSet *>( m_lstFrameSet.getFirst() );
01919 if ( frameset )
01920 frameset->renumberFootNotes( false );
01921
01922 emit sigProgress(-1);
01923
01924
01925
01926
01927 if ( frameset ) {
01928 connect( frameset->textObject(), SIGNAL( chapterParagraphFormatted( KoTextParag * ) ),
01929 SLOT( slotChapterParagraphFormatted( KoTextParag * ) ) );
01930 connect( frameset, SIGNAL( mainTextHeightChanged() ),
01931 SIGNAL( mainTextHeightChanged() ) );
01932 }
01933
01934
01935 }
01936
01937 void KWDocument::startBackgroundSpellCheck()
01938 {
01939 if ( backgroundSpellCheckEnabled() && isReadWrite() )
01940 {
01941 m_bgSpellCheck->start();
01942 }
01943 }
01944
01945 void KWDocument::loadEmbeddedObjects( QDomElement& word )
01946 {
01947 QDomNodeList listEmbedded = word.elementsByTagName ( "EMBEDDED" );
01948 for (unsigned int item = 0; item < listEmbedded.count(); item++)
01949 {
01950 QDomElement embedded = listEmbedded.item( item ).toElement();
01951 loadEmbedded( embedded );
01952 }
01953 }
01954
01955 void KWDocument::loadEmbedded( const QDomElement &embedded )
01956 {
01957 QDomElement object = embedded.namedItem( "OBJECT" ).toElement();
01958 if ( !object.isNull() )
01959 {
01960 KWDocumentChild *ch = new KWDocumentChild( this );
01961 ch->load( object, true );
01962 insertChild( ch );
01963 QDomElement settings = embedded.namedItem( "SETTINGS" ).toElement();
01964 QString name;
01965 if ( !settings.isNull() )
01966 name = settings.attribute( "name" );
01967 KWPartFrameSet *fs = new KWPartFrameSet( this, ch, name );
01968 m_lstFrameSet.append( fs );
01969 if ( !settings.isNull() )
01970 {
01971 kdDebug(32001) << "KWDocument::loadXML loading embedded object" << endl;
01972 fs->load( settings );
01973 }
01974 else
01975 kdError(32001) << "No <SETTINGS> tag in EMBEDDED" << endl;
01976
01977 } else
01978 kdError(32001) << "No <OBJECT> tag in EMBEDDED" << endl;
01979 }
01980
01981
01982 void KWDocument::loadStyleTemplates( const QDomElement &stylesElem )
01983 {
01984 QValueList<QString> followingStyles;
01985 QDomNodeList listStyles = stylesElem.elementsByTagName( "STYLE" );
01986 if( listStyles.count() > 0) {
01987 KoParagStyle *s = m_styleColl->findStyle("Standard");
01988
01989 if(s)
01990 m_styleColl->removeStyle(s);
01991 }
01992 for (unsigned int item = 0; item < listStyles.count(); item++) {
01993 QDomElement styleElem = listStyles.item( item ).toElement();
01994
01995 KoParagStyle *sty = new KoParagStyle( QString::null );
01996
01997 sty->loadStyle( styleElem, m_syntaxVersion );
01998
01999
02000
02001 if ( m_syntaxVersion < 3 )
02002 {
02003
02004
02005 if ( sty->paragLayout().counter && sty->paragLayout().counter->numbering() == KoParagCounter::NUM_CHAPTER )
02006 sty->setOutline( true );
02007 }
02008
02009
02010 sty->setFollowingStyle( sty );
02011
02012 QDomElement formatElem = styleElem.namedItem( "FORMAT" ).toElement();
02013 if ( !formatElem.isNull() )
02014 sty->format() = KWTextParag::loadFormat( formatElem, 0L, defaultFont(), globalLanguage(), globalHyphenation() );
02015 else
02016 kdWarning(32001) << "No FORMAT tag in <STYLE>" << endl;
02017
02018
02019 sty = m_styleColl->addStyle( sty );
02020
02021 if(m_styleColl->styleList().count() > followingStyles.count() )
02022 {
02023 QString following = styleElem.namedItem("FOLLOWING").toElement().attribute("name");
02024 followingStyles.append( following );
02025 }
02026 else
02027 kdWarning () << "Found duplicate style declaration, overwriting former " << sty->name() << endl;
02028 }
02029
02030 Q_ASSERT( followingStyles.count() == m_styleColl->styleList().count() );
02031
02032 unsigned int i=0;
02033 for( QValueList<QString>::Iterator it = followingStyles.begin(); it != followingStyles.end(); ++it ) {
02034 KoParagStyle * style = m_styleColl->findStyle(*it);
02035 m_styleColl->styleAt(i++)->setFollowingStyle( style );
02036 }
02037
02038 }
02039
02040 void KWDocument::loadFrameStyleTemplates( const QDomElement &stylesElem )
02041 {
02042 QDomNodeList listStyles = stylesElem.elementsByTagName( "FRAMESTYLE" );
02043 if( listStyles.count() > 0) {
02044 KWFrameStyle *s = m_frameStyleColl->findStyle("Plain");
02045 if(s)
02046 m_frameStyleColl->removeStyle(s);
02047 }
02048 for (unsigned int item = 0; item < listStyles.count(); item++) {
02049 QDomElement styleElem = listStyles.item( item ).toElement();
02050
02051 KWFrameStyle *sty = new KWFrameStyle( styleElem );
02052 m_frameStyleColl->addStyle( sty );
02053 }
02054 }
02055
02056 void KWDocument::loadDefaultFrameStyleTemplates()
02057 {
02058 const QString fsfileName( locate("data", "kword/framestyles.xml") );
02059
02060 kdDebug(30003) << "Data directory: " << KGlobal::dirs()->resourceDirs( "data" ) << endl;
02061 kdDebug(30003) << "Directory searched: " << KGlobal::dirs()->resourceDirs( "data" ) << endl;
02062 kdDebug(30003) << "File framestyles.xml searched at: " << fsfileName << endl;
02063
02064 m_frameStyleColl->setDefault( true );
02065
02066 if ( ! QFile::exists( fsfileName ) )
02067 {
02068 kdWarning(30003) << "Cannot find any framestyles.xml" << endl;
02069 if (!m_frameStyleColl->findStyle("Plain")) {
02070 KWFrameStyle * standardFrameStyle = new KWFrameStyle( "Plain" );
02071 standardFrameStyle->setBackgroundColor(QColor("white"));
02072 standardFrameStyle->setTopBorder(KoBorder(QColor("black"),KoBorder::SOLID,0));
02073 standardFrameStyle->setRightBorder(KoBorder(QColor("black"),KoBorder::SOLID,0));
02074 standardFrameStyle->setLeftBorder(KoBorder(QColor("black"),KoBorder::SOLID,0));
02075 standardFrameStyle->setBottomBorder(KoBorder(QColor("black"),KoBorder::SOLID,0));
02076 m_frameStyleColl->addStyle( standardFrameStyle );
02077 }
02078 return;
02079 }
02080
02081 kdDebug(30003) << "File framestyles.xml found!" << endl;
02082
02083
02084 QFile in( fsfileName );
02085 if ( !in.open( IO_ReadOnly ) )
02086 {
02087
02088 kdWarning(30003) << "Couldn't open the file for reading (check read permissions)" << endl;
02089 return;
02090 }
02091 QString errorMsg;
02092 int errorLine;
02093 int errorColumn;
02094 QDomDocument doc;
02095 if ( ! doc.setContent( &in , &errorMsg, &errorLine, &errorColumn ) )
02096 {
02097 kdError (30003) << "Parsing Error! Aborting! (in KWDocument::loadDefaultFrameStyleTemplates())" << endl
02098 << " Line: " << errorLine << " Column: " << errorColumn << endl
02099 << " Message: " << errorMsg << endl;
02100 }
02101 in.close();
02102
02103
02104 QDomElement stylesElem = doc.documentElement();
02105
02106 QDomNodeList listStyles = stylesElem.elementsByTagName( "FRAMESTYLE" );
02107 if( listStyles.count() > 0) {
02108 KWFrameStyle *s = m_frameStyleColl->findStyle("Plain");
02109 if(s)
02110 m_frameStyleColl->removeStyle(s);
02111 }
02112 for (unsigned int item = 0; item < listStyles.count(); item++) {
02113 QDomElement styleElem = listStyles.item( item ).toElement();
02114
02115 KWFrameStyle *sty = new KWFrameStyle( styleElem );
02116 m_frameStyleColl->addStyle( sty );
02117 }
02118 }
02119
02120 void KWDocument::loadTableStyleTemplates( const QDomElement& stylesElem )
02121 {
02122 QDomNodeList listStyles = stylesElem.elementsByTagName( "TABLESTYLE" );
02123 if( listStyles.count() > 0) {
02124 KWTableStyle *s = m_tableStyleColl->findStyle("Plain");
02125 if(s)
02126 m_tableStyleColl->removeStyle(s);
02127 }
02128 for (unsigned int item = 0; item < listStyles.count(); item++) {
02129 QDomElement styleElem = listStyles.item( item ).toElement();
02130
02131 KWTableStyle *sty = new KWTableStyle( styleElem, this );
02132 m_tableStyleColl->addStyle( sty );
02133 }
02134 }
02135
02136 void KWDocument::loadDefaultTableStyleTemplates()
02137 {
02138 KURL fsfile;
02139
02140 m_tableStyleColl->setDefault( true );
02141
02142 if ( ! QFile::exists(locate("data", "kword/tablestyles.xml")) )
02143 {
02144 if (!m_tableStyleColl->findStyle("Plain")) {
02145 m_tableStyleColl->addStyle( new KWTableStyle( "Plain", m_styleColl->styleAt(0), m_frameStyleColl->frameStyleAt(0) ) );
02146 }
02147 return;
02148 }
02149
02150 fsfile.setPath( locate("data", "kword/tablestyles.xml") );
02151
02152
02153 QFile in( fsfile.path() );
02154 if ( !in.open( IO_ReadOnly ) )
02155 {
02156
02157 return;
02158 }
02159 in.at(0);
02160 QString errorMsg;
02161 int errorLine;
02162 int errorColumn;
02163 QDomDocument doc;
02164 if ( doc.setContent( &in , &errorMsg, &errorLine, &errorColumn ) ) {
02165 }
02166 else
02167 {
02168 kdError (30003) << "Parsing Error! Aborting! (in KWDocument::loadDefaultTableStyleTemplates())" << endl
02169 << " Line: " << errorLine << " Column: " << errorColumn << endl
02170 << " Message: " << errorMsg << endl;
02171 }
02172 in.close();
02173
02174
02175 QDomElement stylesElem = doc.documentElement();
02176
02177 QDomNodeList listStyles = stylesElem.elementsByTagName( "TABLESTYLE" );
02178 if( listStyles.count() > 0) {
02179 KWTableStyle *s = m_tableStyleColl->findStyle("Plain");
02180 if(s)
02181 m_tableStyleColl->removeStyle(s);
02182 }
02183 for (unsigned int item = 0; item < listStyles.count(); item++) {
02184 QDomElement styleElem = listStyles.item( item ).toElement();
02185
02186 KWTableStyle *sty = new KWTableStyle( styleElem, this );
02187 m_tableStyleColl->addStyle( sty );
02188 }
02189 }
02190
02191 void KWDocument::loadDefaultTableTemplates()
02192 {
02193 KURL fsfile;
02194
02195 if ( ! QFile::exists(locate("data", "kword/tabletemplates.xml")) )
02196 {
02197 if (!m_tableTemplateColl->findTableTemplate("Plain")) {
02198 KWTableTemplate * standardTableTemplate = new KWTableTemplate( "Plain" );
02199 KWTableStyle* defaultTableStyle = tableStyleCollection()->findStyle("Plain");
02200 standardTableTemplate->setFirstRow( defaultTableStyle );
02201 standardTableTemplate->setLastRow( defaultTableStyle );
02202 standardTableTemplate->setFirstCol( defaultTableStyle );
02203 standardTableTemplate->setLastCol( defaultTableStyle );
02204 standardTableTemplate->setBodyCell( defaultTableStyle );
02205 standardTableTemplate->setTopLeftCorner( defaultTableStyle );
02206 standardTableTemplate->setTopRightCorner( defaultTableStyle );
02207 standardTableTemplate->setBottomLeftCorner( defaultTableStyle );
02208 standardTableTemplate->setBottomRightCorner( defaultTableStyle );
02209 m_tableTemplateColl->addTableTemplate( standardTableTemplate );
02210 }
02211 return;
02212 }
02213
02214 fsfile.setPath( locate("data", "kword/tabletemplates.xml") );
02215
02216
02217 QFile in( fsfile.path() );
02218 if ( !in.open( IO_ReadOnly ) )
02219 {
02220
02221 return;
02222 }
02223 in.at(0);
02224 QString errorMsg;
02225 int errorLine;
02226 int errorColumn;
02227 QDomDocument doc;
02228 if ( doc.setContent( &in , &errorMsg, &errorLine, &errorColumn ) ) {
02229 }
02230 else
02231 {
02232 kdError (30003) << "Parsing Error! Aborting! (in KWDocument::readTableTemplates())" << endl
02233 << " Line: " << errorLine << " Column: " << errorColumn << endl
02234 << " Message: " << errorMsg << endl;
02235 }
02236 in.close();
02237
02238
02239 QDomElement templatesElem = doc.documentElement();
02240
02241 QDomNodeList listTemplates = templatesElem.elementsByTagName( "TABLETEMPLATE" );
02242 if( listTemplates.count() > 0) {
02243 KWTableTemplate *s = m_tableTemplateColl->findTableTemplate("Plain");
02244 if(s)
02245 m_tableTemplateColl->removeTableTemplate(s);
02246 }
02247 for (unsigned int item = 0; item < listTemplates.count(); item++) {
02248 QDomElement templateElem = listTemplates.item( item ).toElement();
02249
02250 KWTableTemplate *temp = new KWTableTemplate( templateElem, this );
02251 m_tableTemplateColl->addTableTemplate( temp );
02252 }
02253 }
02254
02255 void KWDocument::progressItemLoaded()
02256 {
02257 if ( !m_nrItemsToLoad )
02258 return;
02259 m_itemsLoaded++;
02260
02261 unsigned int perc = 65 * m_itemsLoaded / m_nrItemsToLoad;
02262 if ( perc != 65 * (m_itemsLoaded-1) / m_nrItemsToLoad )
02263 {
02264
02265 emit sigProgress( perc + 20 );
02266 }
02267 }
02268
02269 void KWDocument::loadFrameSets( const QDomElement &framesetsElem )
02270 {
02271
02272
02273 m_nrItemsToLoad = 0;
02274 QDomElement framesetElem = framesetsElem.firstChild().toElement();
02275
02276 QValueList<QDomElement> framesets;
02277 for ( ; !framesetElem.isNull() ; framesetElem = framesetElem.nextSibling().toElement() )
02278 {
02279 if ( framesetElem.tagName() == "FRAMESET" )
02280 {
02281 framesets.append( framesetElem );
02282 m_nrItemsToLoad += framesetElem.childNodes().count();
02283 }
02284 }
02285
02286 m_itemsLoaded = 0;
02287
02288 QValueList<QDomElement>::Iterator it = framesets.begin();
02289 QValueList<QDomElement>::Iterator end = framesets.end();
02290 for ( ; it != end ; ++it )
02291 {
02292 (void) loadFrameSet( *it );
02293 }
02294 }
02295
02296 KWFrameSet * KWDocument::loadFrameSet( QDomElement framesetElem, bool loadFrames, bool loadFootnote )
02297 {
02298 FrameSetType frameSetType = static_cast<FrameSetType>( KWDocument::getAttribute( framesetElem, "frameType", FT_BASE ) );
02299 QString fsname = KWDocument::getAttribute( framesetElem, "name", "" );
02300
02301 switch ( frameSetType ) {
02302 case FT_TEXT: {
02303 QString tableName = KWDocument::getAttribute( framesetElem, "grpMgr", "" );
02304 if ( !tableName.isEmpty() ) {
02305
02306 KWTableFrameSet *table = 0L;
02307 QPtrListIterator<KWFrameSet> fit = framesetsIterator();
02308 for ( ; fit.current() ; ++fit ) {
02309 KWFrameSet *f = fit.current();
02310 if( f->type() == FT_TABLE &&
02311 f->isVisible() &&
02312 f->name() == tableName ) {
02313 table = static_cast<KWTableFrameSet *> (f);
02314 break;
02315 }
02316 }
02317
02318 if ( !table ) {
02319 table = new KWTableFrameSet( this, tableName );
02320 addFrameSet(table, false);
02321 }
02322
02323 return table->loadCell( framesetElem );
02324 }
02325 else
02326 {
02327 KWFrameSet::Info info = static_cast<KWFrameSet::Info>( framesetElem.attribute("frameInfo").toInt() );
02328 if ( info == KWFrameSet::FI_FOOTNOTE )
02329 {
02330 if ( !loadFootnote )
02331 return 0L;
02332
02333 KWFootNoteFrameSet *fs = new KWFootNoteFrameSet( this, fsname );
02334 fs->load( framesetElem, loadFrames );
02335 addFrameSet(fs, false);
02336 return fs;
02337 }
02338 else
02339 {
02340 KWTextFrameSet *fs = new KWTextFrameSet( this, fsname );
02341 fs->load( framesetElem, loadFrames );
02342 addFrameSet(fs, false);
02343
02344
02345 if ( framesetElem.hasAttribute( "autoCreateNewFrame" ) )
02346 {
02347 KWFrame::FrameBehavior behav = static_cast<KWFrame::FrameBehavior>( framesetElem.attribute( "autoCreateNewFrame" ).toInt() );
02348 QPtrListIterator<KWFrame> frameIt( fs->frameIterator() );
02349 for ( ; frameIt.current() ; ++frameIt )
02350 frameIt.current()->setFrameBehavior( behav );
02351 }
02352 return fs;
02353 }
02354 }
02355 } break;
02356 case FT_CLIPART:
02357 {
02358 kdError(32001) << "FT_CLIPART used! (in KWDocument::loadFrameSet)" << endl;
02359
02360 }
02361 case FT_PICTURE:
02362 {
02363 KWPictureFrameSet *fs = new KWPictureFrameSet( this, fsname );
02364 fs->load( framesetElem, loadFrames );
02365 addFrameSet(fs, false);
02366 return fs;
02367 } break;
02368 case FT_FORMULA: {
02369 KWFormulaFrameSet *fs = new KWFormulaFrameSet( this, fsname );
02370 fs->load( framesetElem, loadFrames );
02371 addFrameSet(fs, false);
02372 return fs;
02373 } break;
02374
02375
02376 case FT_PART:
02377 kdWarning(32001) << "loadFrameSet: FT_PART: impossible case" << endl;
02378 break;
02379 case FT_TABLE:
02380 kdWarning(32001) << "loadFrameSet: FT_TABLE: impossible case" << endl;
02381 break;
02382 case FT_BASE:
02383 kdWarning(32001) << "loadFrameSet: FT_BASE !?!?" << endl;
02384 break;
02385 }
02386 return 0L;
02387 }
02388
02389 void KWDocument::loadImagesFromStore( KoStore *store )
02390 {
02391 if ( store && !m_pictureMap.isEmpty() ) {
02392 m_pictureCollection->readFromStore( store, m_pictureMap );
02393 m_pictureMap.clear();
02394 }
02395 }
02396
02397 bool KWDocument::completeLoading( KoStore *store )
02398 {
02399 kdDebug() << k_funcinfo << endl;
02400
02401 loadImagesFromStore( store );
02402 processPictureRequests();
02403 processAnchorRequests();
02404 processFootNoteRequests();
02405
02406
02407 m_urlIntern = QString::null;
02408
02409
02410 recalcVariables( VT_FIELD );
02411 recalcVariables( VT_DATE );
02412 recalcVariables( VT_STATISTIC );
02413
02414
02415 QPtrListIterator<KWFrameSet> fit = framesetsIterator();
02416 for ( ; fit.current() ; ++fit )
02417 fit.current()->finalize();
02418
02419
02420
02421
02422
02423 recalcFrames();
02424
02425
02426 fixZOrders();
02427
02428 emit newContentsSize();
02429 repaintAllViews( true );
02430 reactivateBgSpellChecking();
02431 connect( documentInfo(), SIGNAL( sigDocumentInfoModifed()),this,SLOT(slotDocumentInfoModifed() ) );
02432
02433
02434
02435 if ( !isReadWrite())
02436 enableBackgroundSpellCheck( false );
02437
02438
02439 initBookmarkList();
02440
02441 deleteLoadingInfo();
02442
02443 setModified( false );
02444
02445 return true;
02446 }
02447
02448 KWLoadingInfo* KWDocument::createLoadingInfo()
02449 {
02450 Q_ASSERT( !m_loadingInfo );
02451 m_loadingInfo = new KWLoadingInfo();
02452 m_loadingInfo->columns.ptColumnSpacing = m_defaultColumnSpacing;
02453 return m_loadingInfo;
02454 }
02455
02456 void KWDocument::deleteLoadingInfo()
02457 {
02458 Q_ASSERT( m_loadingInfo );
02459 delete m_loadingInfo;
02460 m_loadingInfo = 0;
02461 }
02462
02463 void KWDocument::processPictureRequests()
02464 {
02465 QPtrListIterator<KWTextImage> it2 ( m_textImageRequests );
02466 for ( ; it2.current() ; ++it2 )
02467 {
02468 it2.current()->setImage( *m_pictureCollection );
02469 }
02470 m_textImageRequests.clear();
02471
02472
02473 QPtrListIterator<KWPictureFrameSet> it3( m_pictureRequests );
02474 for ( ; it3.current() ; ++it3 )
02475 it3.current()->setPicture( m_pictureCollection->findPicture( it3.current()->key() ) );
02476 m_pictureRequests.clear();
02477 }
02478
02479 void KWDocument::processAnchorRequests()
02480 {
02481 QMapIterator<QString, KWAnchorPosition> itanch = m_anchorRequests.begin();
02482 for ( ; itanch != m_anchorRequests.end(); ++itanch )
02483 {
02484 QString fsname = itanch.key();
02485 if ( m_pasteFramesetsMap && m_pasteFramesetsMap->contains( fsname ) )
02486 fsname = (*m_pasteFramesetsMap)[ fsname ];
02487 kdDebug(32001) << "KWDocument::processAnchorRequests anchoring frameset " << fsname << endl;
02488 KWFrameSet * fs = frameSetByName( fsname );
02489 Q_ASSERT( fs );
02490 if ( fs )
02491 fs->setAnchored( itanch.data().textfs, itanch.data().paragId, itanch.data().index, true, false );
02492 }
02493 m_anchorRequests.clear();
02494 }
02495
02496 bool KWDocument::processFootNoteRequests()
02497 {
02498 bool ret = false;
02499 QMapIterator<QString, KWFootNoteVariable *> itvar = m_footnoteVarRequests.begin();
02500 for ( ; itvar != m_footnoteVarRequests.end(); ++itvar )
02501 {
02502 QString fsname = itvar.key();
02503 if ( m_pasteFramesetsMap && m_pasteFramesetsMap->contains( fsname ) )
02504 fsname = (*m_pasteFramesetsMap)[ fsname ];
02505
02506 KWFrameSet * fs = frameSetByName( fsname );
02507 Q_ASSERT( fs );
02508 if ( !fs )
02509 continue;
02510 Q_ASSERT( fs->type() == FT_TEXT );
02511 Q_ASSERT( fs->frameSetInfo() == KWFrameSet::FI_FOOTNOTE );
02512 KWFootNoteFrameSet* fnfs = dynamic_cast<KWFootNoteFrameSet *>(fs);
02513 if ( fnfs )
02514 {
02515 fnfs->setFootNoteVariable( itvar.data() );
02516 itvar.data()->setFrameSet( fnfs );
02517 ret = true;
02518 }
02519 }
02520 m_footnoteVarRequests.clear();
02521
02522 if ( ret ) {
02523 KWFrameSet *frameset = m_lstFrameSet.getFirst();
02524 if ( frameset && frameset->type() == FT_TEXT )
02525 static_cast<KWTextFrameSet *>(frameset)->renumberFootNotes( false );
02526 }
02527 return ret;
02528 }
02529
02530 QString KWDocument::uniqueFramesetName( const QString& oldName )
02531 {
02532 QString newName = oldName;
02533 if (frameSetByName( oldName ))
02534 {
02535
02536
02537 QString searchString( "^(" + i18n("Copy%1-%2").arg("\\d*").arg("){0,1}") );
02538 searchString = searchString.replace(QRegExp("\\-"), "\\-");
02539 QRegExp searcher(searchString);
02540 int count=0;
02541 do {
02542 newName=oldName;
02543 newName.replace(searcher,i18n("Copy%1-%2").arg(count > 0? QString("%1").arg(count):"").arg(""));
02544 count++;
02545 } while ( frameSetByName( newName ) );
02546 }
02547 return newName;
02548 }
02549
02550 void KWDocument::pasteFrames( QDomElement topElem, KMacroCommand * macroCmd, bool copyFootNote, bool loadFootNote, bool selectFrames )
02551 {
02552 m_pasteFramesetsMap = new QMap<QString, QString>();
02553
02554 int ref=0;
02555 int nb = 0;
02556 QDomElement elem = topElem.firstChild().toElement();
02557 for ( ; !elem.isNull() ; elem = elem.nextSibling().toElement() )
02558 {
02559
02560 QDomElement frameElem;
02561 KWFrameSet * fs = 0L;
02562 if ( elem.tagName() == "FRAME" )
02563 {
02564 QString frameSetName = frameElem.attribute( "parentFrameset" );
02565 fs = frameSetByName( frameSetName );
02566 if ( !fs )
02567 {
02568 kdWarning(32001) << "pasteFrames: Frameset '" << frameSetName << "' not found" << endl;
02569 continue;
02570 }
02571 frameElem = elem;
02572 }
02573 else if ( elem.tagName() == "FRAMESET" )
02574 {
02575
02576 QString oldName = elem.attribute( "name" );
02577 QString newName = uniqueFramesetName( oldName );
02578
02579 m_pasteFramesetsMap->insert( oldName, newName );
02580 if(oldName != newName)
02581 kdDebug(32001) << "KWDocument::pasteFrames new frameset: " << oldName << "->" << newName << endl;
02582 FrameSetType frameSetType = static_cast<FrameSetType>( KWDocument::getAttribute( elem, "frameType", FT_BASE ) );
02583 switch ( frameSetType ) {
02584 case FT_TABLE: {
02585 KWTableFrameSet *table = new KWTableFrameSet( this, newName );
02586 table->fromXML( elem, true, false );
02587 table->moveBy( 20.0, 20.0 );
02588 m_lstFrameSet.append( table );
02589 table->setZOrder();
02590 if ( macroCmd )
02591 macroCmd->addCommand( new KWCreateTableCommand( QString::null, table ) );
02592 fs = table;
02593 break;
02594 }
02595 case FT_PART:
02596 {
02597 ref |= Embedded;
02598 #if 0
02599 KWPartFrameSet *part = new KWPartFrameSet( this, newName );
02600 part->fromXML( elem, true, false );
02601 part->moveBy( 20.0, 20.0 );
02602 m_lstFrameSet.append( part );
02603 part->setZOrder();
02604 fs = part;
02605 #endif
02606 break;
02607 }
02608 default:
02609 fs = loadFrameSet( elem, false, loadFootNote );
02610 if ( fs )
02611 {
02612 kdDebug() << "KWDocument::pasteFrames created frameset: '" << newName << "'\n";
02613 fs->setName( newName );
02614 frameElem = elem.namedItem( "FRAME" ).toElement();
02615 }
02616 }
02617
02618 if(fs && (fs->isHeaderOrFooter() || ( !copyFootNote && fs->isFootEndNote())))
02619 fs->setFrameSetInfo(KWFrameSet::FI_BODY);
02620 }
02621
02622
02623
02624
02625 if ( fs )
02626 {
02627
02628
02629
02630
02631 if ( !frameElem.isNull() )
02632 {
02633 double offs = 20.0;
02634 KoRect rect;
02635 rect.setLeft( KWDocument::getAttribute( frameElem, "left", 0.0 ) + offs );
02636 rect.setTop( KWDocument::getAttribute( frameElem, "top", 0.0 ) + offs );
02637 rect.setRight( KWDocument::getAttribute( frameElem, "right", 0.0 ) + offs );
02638 rect.setBottom( KWDocument::getAttribute( frameElem, "bottom", 0.0 ) + offs );
02639 KWFrame * frame = new KWFrame( fs, rect.x(), rect.y(), rect.width(), rect.height() );
02640 frame->load( frameElem, fs, KWDocument::CURRENT_SYNTAX_VERSION );
02641 frame->setZOrder( maxZOrder( frame->pageNumber(this) ) + 1 +nb );
02642 nb++;
02643 fs->addFrame( frame, false );
02644 if ( selectFrames ) {
02645 for( QValueList<KWView *>::Iterator it = m_lstViews.begin();
02646 it != m_lstViews.end(); ++it ) {
02647 KWFrameView *fv = (*it)->frameViewManager()->view(frame);
02648 if(fv)
02649 fv->setSelected(true);
02650 }
02651 }
02652 if ( macroCmd )
02653 {
02654 KWCreateFrameCommand *cmd = new KWCreateFrameCommand( QString::null, frame );
02655 macroCmd->addCommand(cmd);
02656 }
02657 }
02658 int type=0;
02659
02660 switch(fs->type())
02661 {
02662 case FT_TEXT:
02663 type=(int)TextFrames;
02664 break;
02665 case FT_CLIPART:
02666 {
02667 kdError(32001) << "FT_CLIPART used! (in KWDocument::loadFrameSet)" << endl;
02668
02669 }
02670 case FT_PICTURE:
02671 type=(int)Pictures;
02672 break;
02673 case FT_PART:
02674 type=(int)Embedded;
02675 break;
02676 case FT_FORMULA:
02677 type=(int)FormulaFrames;
02678 break;
02679 case FT_TABLE:
02680 type=(int)Tables;
02681 break;
02682 default:
02683 type=(int)TextFrames;
02684 }
02685 ref|=type;
02686 }
02687 }
02688 refreshDocStructure(ref);
02689 }
02690
02691 void KWDocument::completePasting()
02692 {
02693 processPictureRequests();
02694 processAnchorRequests();
02695 if ( processFootNoteRequests() )
02696 {
02697
02698 recalcFrames();
02699 }
02700
02701
02702
02703
02704
02705 QPtrListIterator<KWFrameSet> fit = framesetsIterator();
02706 for ( ; fit.current() ; ++fit )
02707 fit.current()->finalize();
02708 repaintAllViews();
02709 delete m_pasteFramesetsMap;
02710 m_pasteFramesetsMap = 0L;
02711 }
02712
02713 void KWDocument::completeOasisPasting()
02714 {
02715 QPtrListIterator<KWFrameSet> fit = framesetsIterator();
02716 for ( ; fit.current() ; ++fit )
02717 fit.current()->finalize();
02718 repaintAllViews();
02719 }
02720
02721 void KWDocument::insertEmbedded( KoStore *store, QDomElement topElem, KMacroCommand * macroCmd, double offset )
02722 {
02723 if ( !m_pasteFramesetsMap )
02724 m_pasteFramesetsMap = new QMap<QString, QString>();
02725
02726 QDomElement elem = topElem.firstChild().toElement();
02727 for ( ; !elem.isNull() ; elem = elem.nextSibling().toElement() )
02728 {
02729 if ( elem.tagName() == "EMBEDDED" )
02730 {
02731 kdDebug()<<"KWDocument::insertEmbedded() Embedded object"<<endl;
02732 QDomElement object = elem.namedItem( "OBJECT" ).toElement();
02733 QDomElement settings = elem.namedItem( "SETTINGS" ).toElement();
02734 if ( object.isNull() || settings.isNull() )
02735 {
02736 kdError() << "No <OBJECT> or <SETTINGS> tag" << endl;
02737 }
02738 else
02739 {
02740 KWDocumentChild *ch = new KWDocumentChild( this );
02741 kdDebug()<<"KWDocument::insertEmbedded() loading document"<<endl;
02742 if ( ch->load( object, true ) )
02743 {
02744 ch->loadDocument( store );
02745 insertChild( ch );
02746 QString oldName = settings.attribute( "name" );
02747 QString newName = uniqueFramesetName( oldName );
02748 m_pasteFramesetsMap->insert( oldName, newName );
02749 KWPartFrameSet *part = new KWPartFrameSet( this, ch, newName );
02750 m_lstFrameSet.append( part );
02751 kdDebug() << "KWDocument::insertEmbedded loading embedded object" << endl;
02752 part->load( settings );
02753 if ( offset != 0 ) {
02754 QRect r = ch->geometry();
02755 r.moveBy( (int)offset, (int)offset );
02756 ch->setGeometry( r );
02757 }
02758 part->setZOrder();
02759 if ( macroCmd )
02760 {
02761 QPtrListIterator<KWFrame> frameIt( part->frameIterator() );
02762 for ( ; frameIt.current(); ++frameIt )
02763 {
02764 macroCmd->addCommand( new KWCreateFrameCommand( QString::null, frameIt.current() ) );
02765 }
02766 }
02767 }
02768 }
02769 }
02770 }
02771 refreshDocStructure( (int)Embedded );
02772 }
02773
02774 bool KWDocument::saveOasis( KoStore* store, KoXmlWriter* manifestWriter )
02775 {
02776 QValueList<KWFrameView*> noFrames;
02777 return saveOasisHelper( store, manifestWriter, SaveAll, noFrames);
02778 }
02779
02780
02781 bool KWDocument::saveOasisHelper( KoStore* store, KoXmlWriter* manifestWriter, SaveFlag saveFlag, const QValueList<KWFrameView*> &selectedFrames, QString* plainText, KoPicture* picture, KWTextFrameSet* fs) {
02782 m_pictureCollection->assignUniqueIds();
02783 fixZOrders();
02784
02785 manifestWriter->addManifestEntry( "content.xml", "text/xml" );
02786 KoOasisStore oasisStore( store );
02787
02788 KoXmlWriter* contentWriter = oasisStore.contentWriter();
02789 if ( !contentWriter )
02790 return false;
02791
02792 QValueList<KoPictureKey> pictureList;
02793 if ( saveFlag == SaveAll )
02794 pictureList = savePictureList();
02795
02796 m_varColl->variableSetting()->setModificationDate(QDateTime::currentDateTime());
02797 recalcVariables( VT_DATE );
02798 recalcVariables( VT_TIME );
02799 recalcVariables( VT_STATISTIC );
02800 m_syntaxVersion = CURRENT_SYNTAX_VERSION;
02801
02802 KoGenStyles mainStyles;
02803 KoSavingContext savingContext( mainStyles, m_varColl->variableSetting(), m_pageColumns.columns > 1, KoSavingContext::Store );
02804
02805
02806 m_styleColl->saveOasis( mainStyles, KoGenStyle::STYLE_USER, savingContext );
02807
02808 QByteArray headerFooterContent;
02809 if ( saveFlag == SaveAll )
02810 {
02811
02812
02813 KWView * view = static_cast<KWView*>(views().getFirst());
02814 if ( view )
02815 {
02816 KWFrameSetEdit* edit = view->getGUI()->canvasWidget()->currentFrameSetEdit();
02817 if ( edit )
02818 {
02819 KWTextFrameSetEdit* textedit = dynamic_cast<KWTextFrameSetEdit *>(edit);
02820 if ( textedit && textedit->cursor() ) {
02821 KoTextCursor* cursor = textedit->cursor();
02822 savingContext.setCursorPosition( cursor->parag(),
02823 cursor->index() );
02824 }
02825 }
02826 }
02827
02828
02829
02830
02831
02832
02833 QBuffer buffer( headerFooterContent );
02834 buffer.open( IO_WriteOnly );
02835 KoXmlWriter headerFooterTmpWriter( &buffer );
02836 QPtrListIterator<KWFrameSet> fit = framesetsIterator();
02837
02838 for ( ; fit.current() ; ++fit ) {
02839 const KWFrameSet* fs = fit.current();
02840 if ( fs->isVisible() &&
02841 !fs->isFloating() &&
02842 !fs->isDeleted() &&
02843 fs->type() == FT_TEXT &&
02844 fs->isHeaderOrFooter() )
02845 {
02846
02847 headerFooterTmpWriter.startElement( fs->headerFooterTag() );
02848 static_cast<const KWTextFrameSet *>(fs)->saveOasisContent( headerFooterTmpWriter, savingContext );
02849 headerFooterTmpWriter.endElement();
02850 }
02851 }
02852
02853 headerFooterContent.resize( headerFooterContent.size() + 1 );
02854 headerFooterContent[headerFooterContent.size()-1] = '\0';
02855
02856
02857 QValueList<KoGenStyles::NamedStyle> autoStyles = mainStyles.styles( KoGenStyle::STYLE_AUTO );
02858 for ( QValueList<KoGenStyles::NamedStyle>::const_iterator it = autoStyles.begin();
02859 it != autoStyles.end(); ++it ) {
02860 mainStyles.markStyleForStylesXml( (*it).name );
02861 }
02862 }
02863
02864 KoXmlWriter* bodyWriter = oasisStore.bodyWriter();
02865 bodyWriter->startElement( "office:body" );
02866 bodyWriter->startElement( "office:text" );
02867
02868 if ( saveFlag == SaveAll )
02869 {
02870
02871 saveOasisBody( *bodyWriter, savingContext );
02872 }
02873 else
02874 {
02875
02876
02877
02878 if ( fs ) {
02879 *plainText = fs->textDocument()->copySelection( *bodyWriter, savingContext, KoTextDocument::Standard );
02880
02881 KWCollectFramesetsVisitor visitor;
02882 fs->textDocument()->visitSelection( KoTextDocument::Standard, &visitor );
02883 const QValueList<KWFrameSet *>& frameset = visitor.frameSets();
02884 kdDebug(32001) << frameset.count() << " inline framesets" << endl;
02885 for ( QValueList<KWFrameSet *>::ConstIterator it = frameset.begin(); it != frameset.end(); ++it )
02886 {
02887 switch ( (*it)->type() ) {
02888 case FT_PICTURE:
02889 {
02890 const KoPictureKey key = static_cast<KWPictureFrameSet *>( *it )->key();
02891 if ( !pictureList.contains( key ) )
02892 pictureList.append( key );
02893 }
02894 break;
02895 case FT_PART:
02896
02897 default:
02898 break;
02899 }
02900 }
02901 }
02902
02903
02904 QString newText;
02905 saveSelectedFrames( *bodyWriter, savingContext, pictureList,
02906 selectedFrames, &newText );
02907 *plainText += newText;
02908
02909 if ( picture && pictureList.count() == 1 )
02910 {
02911 *picture = m_pictureCollection->findPicture( pictureList.first() );
02912 }
02913 }
02914
02915 bodyWriter->endElement();
02916 bodyWriter->endElement();
02917
02918 savingContext.writeFontFaces( *contentWriter );
02919 contentWriter->startElement( "office:automatic-styles" );
02920 KWOasisSaver::writeAutomaticStyles( *contentWriter, mainStyles, false );
02921 contentWriter->endElement();
02922
02923 oasisStore.closeContentWriter();
02924
02925
02926
02927 if ( !store->open( "styles.xml" ) )
02928 return false;
02929 manifestWriter->addManifestEntry( "styles.xml", "text/xml" );
02930 saveOasisDocumentStyles( store, mainStyles, savingContext, saveFlag, headerFooterContent );
02931 if ( !store->close() )
02932 return false;
02933
02934
02935 m_pictureCollection->saveOasisToStore( store, pictureList, manifestWriter );
02936
02937 if ( saveFlag == SaveSelected ) {
02938
02939
02940
02941
02942
02943
02944
02945 QValueList<KoDocumentChild*> embeddedObjects;
02946 QValueListConstIterator<KWFrameView*> framesIterator = selectedFrames.begin();
02947 for(; framesIterator != selectedFrames.end(); ++framesIterator) {
02948 KWFrame *frame = (*framesIterator)->frame();
02949 KWFrameSet *fs = frame->frameSet();
02950 if ( fs->isVisible() && fs->type() == FT_PART) {
02951 embeddedObjects.append( static_cast<KWPartFrameSet *>(fs)->getChild() );
02952 }
02953 }
02954
02955 QValueList<KoDocumentChild *>::const_iterator chl = embeddedObjects.begin();
02956 for( ; chl != embeddedObjects.end(); ++chl ) {
02957 if ( !(*chl)->saveOasis( store, manifestWriter ) )
02958 return false;
02959 }
02960 }
02961
02962 if ( saveFlag == SaveAll )
02963 {
02964
02965 if(!store->open("settings.xml"))
02966 return false;
02967
02968 KoStoreDevice contentDev( store );
02969 KoXmlWriter* settingsWriter = createOasisXmlWriter(&contentDev, "office:document-settings");
02970 saveOasisSettings( *settingsWriter );
02971 delete settingsWriter;
02972
02973 if(!store->close())
02974 return false;
02975
02976 manifestWriter->addManifestEntry("settings.xml", "text/xml");
02977 }
02978 return true;
02979 }
02980
02981
02982 QDragObject* KWDocument::dragSelected( const QValueList<KWFrameView*> &selectedFrames) {
02983 return dragSelectedPrivate(0, selectedFrames, 0);
02984 }
02985
02986 QDragObject* KWDocument::dragSelected( QWidget *parent, KWTextFrameSet* fs) {
02987 QValueList<KWFrameView*> noFrames;
02988 return dragSelectedPrivate(parent, noFrames, fs);
02989 }
02990
02991 QDragObject* KWDocument::dragSelectedPrivate( QWidget *parent, const QValueList<KWFrameView*> &selectedFrames, KWTextFrameSet* fs)
02992 {
02993
02994 QBuffer buffer;
02995 QCString mimeType = KWOasisSaver::selectionMimeType();
02996 KoStore* store = KoStore::createStore( &buffer, KoStore::Write, mimeType );
02997 Q_ASSERT( store );
02998 Q_ASSERT( !store->bad() );
02999 KoOasisStore oasisStore( store );
03000
03001 KoXmlWriter* manifestWriter = oasisStore.manifestWriter( mimeType );
03002
03003 QString plainText;
03004 KoPicture picture;
03005 if ( !saveOasisHelper( store, manifestWriter, KWDocument::SaveSelected, selectedFrames, &plainText, &picture, fs )
03006 || !oasisStore.closeManifestWriter() )
03007 {
03008 delete store;
03009 return 0;
03010 }
03011
03012 delete store;
03013
03014 KMultipleDrag* multiDrag = new KMultipleDrag( parent );
03015 if ( !plainText.isEmpty() )
03016 multiDrag->addDragObject( new QTextDrag( plainText, 0 ) );
03017 if ( !picture.isNull() )
03018 multiDrag->addDragObject( picture.dragObject( 0 ) );
03019 KoStoreDrag* storeDrag = new KoStoreDrag( KWOasisSaver::selectionMimeType(), 0 );
03020 kdDebug() << k_funcinfo << "setting zip data: " << buffer.buffer().size() << " bytes." << endl;
03021 storeDrag->setEncodedData( buffer.buffer() );
03022 multiDrag->addDragObject( storeDrag );
03023 return multiDrag;
03024 }
03025
03026 void KWDocument::saveSelectedFrames( KoXmlWriter& bodyWriter, KoSavingContext& savingContext, QValueList<KoPictureKey>& pictureList, const QValueList<KWFrameView*> &selectedFrames, QString* plainText ) const {
03027 QPtrList<KoDocumentChild> embeddedObjects;
03028 QValueListConstIterator<KWFrameView*> framesIterator = selectedFrames.begin();
03029 for(; framesIterator != selectedFrames.end(); ++framesIterator) {
03030 KWFrame *frame = (*framesIterator)->frame();
03031 KWFrameSet *fs = frame->frameSet();
03032 if ( fs->isVisible() && fs->type() == FT_PART) {
03033 embeddedObjects.append( static_cast<KWPartFrameSet *>(fs)->getChild() );
03034 }
03035 bool isTable = fs->type() == FT_TABLE;
03036
03037
03038
03039
03040 if ( frame == fs->frame(0) || isTable ) {
03041 fs->saveOasis( bodyWriter, savingContext, false );
03042 if ( plainText )
03043 *plainText += fs->toPlainText();
03044 }
03045 else if ( !isTable ) {
03046 #if 0
03047
03048 QDomElement frameElem = parentElem.ownerDocument().createElement( "FRAME" );
03049 parentElem.appendChild( frameElem );
03050 frame->save( frameElem );
03051 if ( frame != firstFrame )
03052 {
03053
03054 frameElem.setAttribute( "parentFrameset", fs->name() );
03055 }
03056 #endif
03057 }
03058 if ( fs->type() == FT_PICTURE ) {
03059 kdDebug(32001) << "found non-inline picture framesets" << endl;
03060
03061 const KoPictureKey key = static_cast<KWPictureFrameSet *>( fs )->key();
03062 if ( !pictureList.contains( key ) )
03063 pictureList.append( key );
03064 }
03065 if ( isTable )
03066 break;
03067 }
03068 }
03069
03070 void KWDocument::saveOasisSettings( KoXmlWriter& settingsWriter ) const
03071 {
03072 settingsWriter.startElement("office:settings");
03073 settingsWriter.startElement("config:config-item-set");
03074
03075 settingsWriter.addAttribute("config:name", "view-settings");
03076
03077 KoUnit::saveOasis(&settingsWriter, unit());
03078
03079 settingsWriter.endElement();
03080
03081 settingsWriter.startElement("config:config-item-set");
03082 settingsWriter.addAttribute("config:name", "configuration-settings");
03083 settingsWriter.addConfigItem("SpellCheckerIgnoreList", m_spellCheckIgnoreList.join( "," ) );
03084 settingsWriter.endElement();
03085
03086 m_varColl->variableSetting()->saveOasis( settingsWriter );
03087
03088 settingsWriter.endElement();
03089 settingsWriter.endElement();
03090 settingsWriter.endDocument();
03091 }
03092
03093 void KWDocument::saveOasisDocumentStyles( KoStore* store, KoGenStyles& mainStyles, KoSavingContext& savingContext, SaveFlag saveFlag, const QByteArray& headerFooterContent ) const
03094 {
03095 if ( saveFlag == SaveAll )
03096 {
03097 m_frameStyleColl->saveOasis( mainStyles, savingContext );
03098 m_tableStyleColl->saveOasis( mainStyles, savingContext );
03099 }
03100
03101 KoStoreDevice stylesDev( store );
03102 KoXmlWriter* stylesWriter = createOasisXmlWriter( &stylesDev, "office:document-styles" );
03103
03104 stylesWriter->startElement( "office:styles" );
03105
03106 if ( saveFlag == SaveAll )
03107 {
03108 stylesWriter->startElement( "style:default-style" );
03109 stylesWriter->addAttribute( "style:family", "paragraph" );
03110 stylesWriter->startElement( "style:paragraph-properties" );
03111 stylesWriter->addAttributePt( "style:tab-stop-distance", m_tabStop );
03112 stylesWriter->endElement();
03113 stylesWriter->endElement();
03114 }
03115
03116 QValueList<KoGenStyles::NamedStyle> styles = mainStyles.styles( KoGenStyle::STYLE_USER );
03117 QValueList<KoGenStyles::NamedStyle>::const_iterator it = styles.begin();
03118 for ( ; it != styles.end() ; ++it ) {
03119 (*it).style->writeStyle( stylesWriter, mainStyles, "style:style", (*it).name, "style:paragraph-properties" );
03120 }
03121 styles = mainStyles.styles( KWDocument::STYLE_FRAME_USER );
03122 it = styles.begin();
03123 for ( ; it != styles.end() ; ++it ) {
03124 (*it).style->writeStyle( stylesWriter, mainStyles, "style:style", (*it).name , "style:graphic-properties" );
03125 }
03126 styles = mainStyles.styles( KWDocument::STYLE_TABLE_CELL_USER );
03127 it = styles.begin();
03128 for ( ; it != styles.end() ; ++it ) {
03129 (*it).style->writeStyle( stylesWriter, mainStyles, "style:style", (*it).name , "style:table-cell-properties" );
03130 }
03131 styles = mainStyles.styles( KoGenStyle::STYLE_LIST );
03132 it = styles.begin();
03133 for ( ; it != styles.end() ; ++it ) {
03134 (*it).style->writeStyle( stylesWriter, mainStyles, "text:list-style", (*it).name, 0 );
03135 }
03136 m_styleColl->saveOasisOutlineStyles( *stylesWriter );
03137 if ( saveFlag == SaveAll )
03138 static_cast<KWVariableSettings *>( m_varColl->variableSetting() )->saveNoteConfiguration( *stylesWriter );
03139 stylesWriter->endElement();
03140
03141 QString pageLayoutName;
03142 if ( saveFlag == SaveAll )
03143 {
03144 stylesWriter->startElement( "office:automatic-styles" );
03145
03146 KoGenStyle pageLayout = m_pageLayout.saveOasis();
03147 pageLayout.addAttribute( "style:page-usage", "all" );
03148
03149
03150
03151 if ( m_processingType == WP )
03152 {
03153 KWTextFrameSet *frameset = dynamic_cast<KWTextFrameSet *>( m_lstFrameSet.getFirst() );
03154 if ( frameset ) {
03155 frameset->frame(0)->saveBorderProperties( pageLayout );
03156 }
03157 }
03158
03159 QBuffer buffer;
03160 buffer.open( IO_WriteOnly );
03161 KoXmlWriter footnoteSepTmpWriter( &buffer );
03162 footnoteSepTmpWriter.startElement( "style:footnote-sep" );
03163 QString tmp;
03164 switch( m_footNoteSeparatorLinePos )
03165 {
03166 case SLP_CENTERED:
03167 tmp = "centered";
03168 break;
03169 case SLP_RIGHT:
03170 tmp = "right";
03171 break;
03172 case SLP_LEFT:
03173 tmp = "left";
03174 break;
03175 }
03176
03177 footnoteSepTmpWriter.addAttribute( "style:adjustment", tmp );
03178 footnoteSepTmpWriter.addAttributePt( "style:width", m_footNoteSeparatorLineWidth );
03179 footnoteSepTmpWriter.addAttribute( "style:rel-width", QString::number( footNoteSeparatorLineLength() ) + "%" );
03180 switch( m_footNoteSeparatorLineType )
03181 {
03182 case SLT_SOLID:
03183 tmp = "solid";
03184 break;
03185 case SLT_DASH:
03186 tmp = "dash";
03187 break;
03188 case SLT_DOT:
03189 tmp = "dotted";
03190 break;
03191 case SLT_DASH_DOT:
03192 tmp = "dot-dash";
03193 break;
03194 case SLT_DASH_DOT_DOT:
03195 tmp = "dot-dot-dash";
03196 break;
03197 }
03198
03199 footnoteSepTmpWriter.addAttribute( "style:line-style", tmp );
03200
03201 footnoteSepTmpWriter.endElement();
03202 const QString elementContents = QString::fromUtf8( buffer.buffer(), buffer.buffer().size() );
03203 pageLayout.addChildElement( "separator", elementContents );
03204 buffer.close();
03205
03206 if ( m_pageColumns.columns > 1 ) {
03207 buffer.setBuffer( QByteArray() );
03208 buffer.open( IO_WriteOnly );
03209 KoXmlWriter columnsTmpWriter( &buffer );
03210 columnsTmpWriter.startElement( "style:columns" );
03211 columnsTmpWriter.addAttribute( "fo:column-count", m_pageColumns.columns );
03212 columnsTmpWriter.addAttributePt( "fo:column-gap", m_pageColumns.ptColumnSpacing );
03213 columnsTmpWriter.endElement();
03214 buffer.close();
03215 const QString elementContents = QString::fromUtf8( buffer.buffer(), buffer.buffer().size() );
03216 pageLayout.addChildElement( "columns", elementContents );
03217 }
03218
03219
03220
03221
03222 pageLayoutName = mainStyles.lookup( pageLayout, "pm" );
03223 pageLayout.writeStyle( stylesWriter, mainStyles, "style:page-layout", pageLayoutName,
03224 "style:page-layout-properties", false );
03225
03226
03227
03228 bool headerStyleSaved = false;
03229 bool footerStyleSaved = false;
03230
03231 QPtrListIterator<KWFrameSet> fit = framesetsIterator();
03232 for ( ; fit.current() ; ++fit ) {
03233 const KWFrameSet* fs = fit.current();
03234 if ( fs->isVisible() &&
03235 !fs->isFloating() &&
03236 !fs->isDeleted() &&
03237 fs->type() == FT_TEXT &&
03238 fs->isHeaderOrFooter() )
03239 {
03240
03241 KWFrame* frame = fs->frame(0);
03242 if ( fs->isAHeader() ) {
03243 if ( headerStyleSaved )
03244 continue;
03245 headerStyleSaved = true;
03246 stylesWriter->startElement( "style:header-style" );
03247 } else {
03248 if ( footerStyleSaved )
03249 continue;
03250 footerStyleSaved = true;
03251 stylesWriter->startElement( "style:footer-style" );
03252 }
03253 #if 0 // more code reuse, but harder to integrate
03254 KoGenStyle hfStyle;
03255 hfStyle.addPropertyPt( "fo:min-height", frame->minimumFrameHeight() );
03256 frame->saveBorderProperties( hfStyle );
03257 frame->saveMarginProperties( hfStyle );
03258 ...
03259 #endif
03260 stylesWriter->startElement( "style:header-footer-properties" );
03261 stylesWriter->addAttributePt( "fo:min-height", frame->minimumFrameHeight() );
03262 if ( fs->isAHeader() )
03263 stylesWriter->addAttributePt( "fo:margin-bottom", m_pageHeaderFooter.ptHeaderBodySpacing );
03264 else
03265 stylesWriter->addAttributePt( "fo:margin-top", m_pageHeaderFooter.ptFooterBodySpacing );
03266
03267
03268
03269 stylesWriter->endElement();
03270 stylesWriter->endElement();
03271 }
03272 }
03273 stylesWriter->endElement();
03274
03275
03276 KWOasisSaver::writeAutomaticStyles( *stylesWriter, mainStyles, true );
03277
03278 stylesWriter->endElement();
03279 }
03280
03281
03282 stylesWriter->startElement( "office:master-styles" );
03283 stylesWriter->startElement( "style:master-page" );
03284 stylesWriter->addAttribute( "style:name", "Standard" );
03285 stylesWriter->addAttribute( "style:page-layout-name", pageLayoutName );
03286
03287 if ( isHeaderVisible() || isFooterVisible() ) {
03288 stylesWriter->addCompleteElement( headerFooterContent.data() );
03289 }
03290
03291 stylesWriter->endElement();
03292 stylesWriter->endElement();
03293
03294 stylesWriter->endElement();
03295 stylesWriter->endDocument();
03296 delete stylesWriter;
03297 }
03298
03299 void KWDocument::saveOasisCustomFied( KoXmlWriter &writer )const
03300 {
03301 bool customVariableFound = false;
03302 QPtrListIterator<KoVariable> it( m_varColl->getVariables() );
03303 for ( ; it.current() ; ++it )
03304 {
03305 if ( it.current()->type() == VT_CUSTOM )
03306 {
03307 if ( !customVariableFound )
03308 {
03309 writer.startElement( "text:user-field-decls" );
03310 customVariableFound = true;
03311 }
03312
03313 writer.startElement( "text:user-field-decl" );
03314 writer.addAttribute( "office:value-type", "string" );
03315 writer.addAttribute( "office:string-value", static_cast<KoCustomVariable *>( it.current() )->value() );
03316 writer.addAttribute( "text:name", static_cast<KoCustomVariable*>( it.current() )->name() );
03317 writer.endElement();
03318 }
03319 }
03320 if ( customVariableFound )
03321 writer.endElement();
03322 }
03323
03324 void KWDocument::saveOasisBody( KoXmlWriter& writer, KoSavingContext& context ) const
03325 {
03326 saveOasisCustomFied( writer );
03327 if ( m_processingType == WP ) {
03328
03329
03330 QPtrListIterator<KWFrameSet> fit = framesetsIterator();
03331 ++fit;
03332 for ( ; fit.current() ; ++fit ) {
03333 KWFrameSet* fs = fit.current();
03334 if ( !fs->isFloating() &&
03335 !fs->isDeleted() &&
03336
03337 fs->frameSetInfo() == KWFrameSet::FI_BODY )
03338 {
03339 fs->saveOasis( writer, context, true );
03340 }
03341 }
03342
03343
03344 KWTextFrameSet *frameset = dynamic_cast<KWTextFrameSet *>( m_lstFrameSet.getFirst() );
03345 if ( frameset ) {
03346 frameset->saveOasisContent( writer, context );
03347 }
03348
03349 } else {
03350
03351 writer.startElement( "text:page-sequence" );
03352 for ( int page = 0; page < pageCount(); ++page )
03353 {
03354 writer.startElement( "text:page" );
03355
03356
03357 writer.addAttribute( "text:master-page-name", "pm" );
03358 writer.endElement();
03359 }
03360 writer.endElement() ;
03361
03362 QPtrListIterator<KWFrameSet> fit = framesetsIterator();
03363 for ( ; fit.current() ; ++fit ) {
03364 KWFrameSet* fs = fit.current();
03365 if ( !fs->isFloating() &&
03366 !fs->isDeleted() &&
03367 fs->frameSetInfo() == KWFrameSet::FI_BODY )
03368 {
03369 fs->saveOasis( writer, context, true );
03370 }
03371 }
03372 }
03373 }
03374
03375 QDomDocument KWDocument::saveXML()
03376 {
03377 m_varColl->variableSetting()->setModificationDate(QDateTime::currentDateTime());
03378 recalcVariables( VT_DATE );
03379 recalcVariables( VT_TIME );
03380 recalcVariables( VT_STATISTIC );
03381 QDomDocument doc = createDomDocument( "DOC", CURRENT_DTD_VERSION );
03382 QDomElement kwdoc = doc.documentElement();
03383 kwdoc.setAttribute( "editor", "KWord" );
03384 kwdoc.setAttribute( "mime", "application/x-kword" );
03385 m_syntaxVersion = CURRENT_SYNTAX_VERSION;
03386 kwdoc.setAttribute( "syntaxVersion", m_syntaxVersion );
03387
03388 QDomElement paper = doc.createElement( "PAPER" );
03389 kwdoc.appendChild( paper );
03390 paper.setAttribute( "format", static_cast<int>( m_pageLayout.format ) );
03391 paper.setAttribute( "pages", pageCount() );
03392 paper.setAttribute( "width", m_pageLayout.ptWidth );
03393 paper.setAttribute( "height", m_pageLayout.ptHeight );
03394 paper.setAttribute( "orientation", static_cast<int>( m_pageLayout.orientation ) );
03395 paper.setAttribute( "columns", m_pageColumns.columns );
03396 paper.setAttribute( "columnspacing", m_pageColumns.ptColumnSpacing );
03397 paper.setAttribute( "hType", static_cast<int>( m_pageHeaderFooter.header ) );
03398 paper.setAttribute( "fType", static_cast<int>( m_pageHeaderFooter.footer ) );
03399 paper.setAttribute( "spHeadBody", m_pageHeaderFooter.ptHeaderBodySpacing );
03400 paper.setAttribute( "spFootBody", m_pageHeaderFooter.ptFooterBodySpacing );
03401 paper.setAttribute( "spFootNoteBody", m_pageHeaderFooter.ptFootNoteBodySpacing );
03402 if ( m_footNoteSeparatorLinePos!=SLP_LEFT )
03403 {
03404 if (m_footNoteSeparatorLinePos==SLP_CENTERED )
03405 paper.setAttribute( "slFootNotePosition", "centered" );
03406 else if ( m_footNoteSeparatorLinePos==SLP_RIGHT )
03407 paper.setAttribute( "slFootNotePosition", "right" );
03408 else if ( m_footNoteSeparatorLinePos==SLP_LEFT )
03409 paper.setAttribute( "slFootNotePosition", "left" );
03410 }
03411 if ( m_footNoteSeparatorLineType != SLT_SOLID )
03412 paper.setAttribute( "slFootNoteType", static_cast<int>(m_footNoteSeparatorLineType) );
03413
03414
03415 paper.setAttribute("slFootNoteLength", m_iFootNoteSeparatorLineLength);
03416 paper.setAttribute("slFootNoteWidth", m_footNoteSeparatorLineWidth);
03417
03418
03419
03420
03421 QDomElement borders = doc.createElement( "PAPERBORDERS" );
03422 paper.appendChild( borders );
03423 borders.setAttribute( "left", m_pageLayout.ptLeft );
03424 borders.setAttribute( "top", m_pageLayout.ptTop );
03425 borders.setAttribute( "right", m_pageLayout.ptRight );
03426 borders.setAttribute( "bottom", m_pageLayout.ptBottom );
03427
03428 QDomElement docattrs = doc.createElement( "ATTRIBUTES" );
03429 kwdoc.appendChild( docattrs );
03430 docattrs.setAttribute( "processing", static_cast<int>( m_processingType ) );
03431 docattrs.setAttribute( "standardpage", 1 );
03432 docattrs.setAttribute( "hasHeader", static_cast<int>(isHeaderVisible()) );
03433 docattrs.setAttribute( "hasFooter", static_cast<int>(isFooterVisible()) );
03434 docattrs.setAttribute( "unit", KoUnit::unitName(unit()) );
03435 docattrs.setAttribute( "hasTOC", static_cast<int>(m_hasTOC));
03436 docattrs.setAttribute( "tabStopValue", m_tabStop );
03437
03438
03439
03440 KWView * view = static_cast<KWView*>(views().getFirst());
03441 if ( view )
03442 {
03443 KWFrameSetEdit* edit = view->getGUI()->canvasWidget()->currentFrameSetEdit();
03444 if ( edit )
03445 {
03446 docattrs.setAttribute( "activeFrameset", edit->frameSet()->name() );
03447 KWTextFrameSetEdit* textedit = dynamic_cast<KWTextFrameSetEdit *>(edit);
03448 if ( textedit && textedit->cursor() ) {
03449 KoTextCursor* cursor = textedit->cursor();
03450 docattrs.setAttribute( "cursorParagraph", cursor->parag()->paragId() );
03451 docattrs.setAttribute( "cursorIndex", cursor->index() );
03452 }
03453 }
03454 }
03455
03456 if( !m_bookmarkList->isEmpty() )
03457 {
03458 QDomElement bookmark = doc.createElement( "BOOKMARKS" );
03459 kwdoc.appendChild( bookmark );
03460
03461 for ( KoTextBookmarkList::const_iterator it = m_bookmarkList->begin();
03462 it != m_bookmarkList->end() ; ++it )
03463 {
03464 const KoTextBookmark& book = *it;
03465 KWTextFrameSet* fs = static_cast<KWTextDocument*>(book.textDocument())->textFrameSet();
03466 if ( book.startParag() &&
03467 book.endParag() &&
03468 fs && !fs->isDeleted() )
03469 {
03470 QDomElement bookElem = doc.createElement( "BOOKMARKITEM" );
03471 bookmark.appendChild( bookElem );
03472 bookElem.setAttribute( "name", book.bookmarkName() );
03473 bookElem.setAttribute( "frameset", fs->name() );
03474 bookElem.setAttribute( "startparag", book.startParag()->paragId() );
03475 bookElem.setAttribute( "endparag", book.endParag()->paragId() );
03476
03477 bookElem.setAttribute( "cursorIndexStart", book.bookmarkStartIndex() );
03478 bookElem.setAttribute( "cursorIndexEnd", book.bookmarkEndIndex() );
03479 }
03480 }
03481 }
03482 variableCollection()->variableSetting()->save(kwdoc );
03483
03484 QDomElement framesets = doc.createElement( "FRAMESETS" );
03485 kwdoc.appendChild( framesets );
03486
03487 m_textImageRequests.clear();
03488 QValueList<KoPictureKey> savePictures;
03489
03490 QPtrListIterator<KWFrameSet> fit = framesetsIterator();
03491 for ( ; fit.current() ; ++fit )
03492 {
03493 KWFrameSet *frameSet = fit.current();
03494
03495 if ( frameSet->type() != FT_PART )
03496 frameSet->save( framesets );
03497
03498
03499 if ( !frameSet->isDeleted() && ( frameSet->type() == FT_PICTURE ) )
03500 {
03501 KoPictureKey key = static_cast<KWPictureFrameSet *>( frameSet )->key();
03502 if ( !savePictures.contains( key ) )
03503 savePictures.append( key );
03504 }
03505 }
03506
03507
03508 QPtrListIterator<KWTextImage> textIt ( m_textImageRequests );
03509 for ( ; textIt.current() ; ++textIt )
03510 {
03511 KoPictureKey key = textIt.current()->getKey();
03512 kdDebug(32001) << "KWDocument::saveXML registering text image " << key.toString() << endl;
03513 if ( !savePictures.contains( key ) )
03514 savePictures.append( key );
03515 }
03516
03517 QDomElement styles = doc.createElement( "STYLES" );
03518 kwdoc.appendChild( styles );
03519 QValueList<KoUserStyle *> styleList(m_styleColl->styleList());
03520 for ( QValueList<KoUserStyle *>::const_iterator it = styleList.begin(), end = styleList.end();
03521 it != end ; ++it )
03522 saveStyle( static_cast<KoParagStyle *>( *it ), styles );
03523
03524 QDomElement frameStyles = doc.createElement( "FRAMESTYLES" );
03525 kwdoc.appendChild( frameStyles );
03526 QValueList<KoUserStyle *> frameStyleList(m_frameStyleColl->styleList());
03527 for ( QValueList<KoUserStyle *>::const_iterator it = frameStyleList.begin(), end = frameStyleList.end();
03528 it != end ; ++it )
03529 saveFrameStyle( static_cast<KWFrameStyle *>(*it), frameStyles );
03530
03531 QDomElement tableStyles = doc.createElement( "TABLESTYLES" );
03532 kwdoc.appendChild( tableStyles );
03533 QValueList<KoUserStyle *> tableStyleList(m_tableStyleColl->styleList());
03534 for ( QValueList<KoUserStyle *>::const_iterator it = tableStyleList.begin(), end = tableStyleList.end();
03535 it != end ; ++it )
03536 saveTableStyle( static_cast<KWTableStyle *>(*it), tableStyles );
03537
03538 QDomElement pictures = m_pictureCollection->saveXML( KoPictureCollection::CollectionPicture, doc, savePictures );
03539 kwdoc.appendChild( pictures );
03540
03541
03542 #if 0
03543
03544 if ( contents->hasContents() ) {
03545 QDomElement cParags = doc.createElement( "CPARAGS" );
03546 kwdoc.appendChild( cParags );
03547 QValueList<int>::Iterator it = contents->begin();
03548 for ( ; it != contents->end(); ++it )
03549 {
03550 QDomElement paragElem = doc.createElement( "PARAG" );
03551 cParags.appendChild( paragElem );
03552 paragElem.setAttribute( "name", QString::number( *it ) );
03553 }
03554 }
03555 #endif
03556
03557 QDomElement mailMerge=m_slDataBase->save(doc);
03558 kwdoc.appendChild(mailMerge);
03559
03560 if( !m_spellCheckIgnoreList.isEmpty() )
03561 {
03562 QDomElement spellCheckIgnore = doc.createElement( "SPELLCHECKIGNORELIST" );
03563 kwdoc.appendChild( spellCheckIgnore );
03564 for ( QStringList::ConstIterator it = m_spellCheckIgnoreList.begin(); it != m_spellCheckIgnoreList.end(); ++it )
03565 {
03566 QDomElement spellElem = doc.createElement( "SPELLCHECKIGNOREWORD" );
03567 spellCheckIgnore.appendChild( spellElem );
03568 spellElem.setAttribute( "word", *it );
03569 }
03570 }
03571
03572
03573 saveEmbeddedObjects( kwdoc, children() );
03574 return doc;
03575 }
03576
03577
03578 void KWDocument::saveEmbeddedObjects( QDomElement& parentElem, const QPtrList<KoDocumentChild>& childList )
03579 {
03580
03581 QPtrListIterator<KoDocumentChild> chl( childList );
03582 QDomDocument doc = parentElem.ownerDocument();
03583 for( ; chl.current(); ++chl ) {
03584 KWDocumentChild* curr = static_cast<KWDocumentChild*>(chl.current());
03585 if ( !curr->isDeleted() )
03586 {
03587 QDomElement embeddedElem = doc.createElement( "EMBEDDED" );
03588 parentElem.appendChild( embeddedElem );
03589
03590 QDomElement objectElem = curr->save( doc, true );
03591 embeddedElem.appendChild( objectElem );
03592
03593 QDomElement settingsElem = doc.createElement( "SETTINGS" );
03594 embeddedElem.appendChild( settingsElem );
03595
03596 curr->partFrameSet()->save( settingsElem );
03597 }
03598 }
03599 }
03600
03601
03602 void KWDocument::saveStyle( KoParagStyle *sty, QDomElement parentElem )
03603 {
03604 QDomDocument doc = parentElem.ownerDocument();
03605 QDomElement styleElem = doc.createElement( "STYLE" );
03606 parentElem.appendChild( styleElem );
03607
03608 sty->saveStyle( styleElem );
03609
03610 QDomElement formatElem = KWTextParag::saveFormat( doc, &sty->format(), 0L, 0, 0 );
03611 styleElem.appendChild( formatElem );
03612 }
03613
03614
03615 void KWDocument::saveFrameStyle( KWFrameStyle *sty, QDomElement parentElem )
03616 {
03617 QDomDocument doc = parentElem.ownerDocument();
03618 QDomElement frameStyleElem = doc.createElement( "FRAMESTYLE" );
03619 parentElem.appendChild( frameStyleElem );
03620
03621 sty->saveFrameStyle( frameStyleElem );
03622 }
03623
03624
03625 void KWDocument::saveTableStyle( KWTableStyle *sty, QDomElement parentElem )
03626 {
03627 QDomDocument doc = parentElem.ownerDocument();
03628 QDomElement tableStyleElem = doc.createElement( "TABLESTYLE" );
03629 parentElem.appendChild( tableStyleElem );
03630
03631 sty->saveTableStyle( tableStyleElem );
03632 }
03633
03634
03635 QValueList<KoPictureKey> KWDocument::savePictureList()
03636 {
03637 QValueList<KoPictureKey> savePictures;
03638
03639
03640
03641 QPtrListIterator<KWTextImage> textIt ( m_textImageRequests );
03642 for ( ; textIt.current() ; ++textIt )
03643 {
03644 KoPictureKey key = textIt.current()->getKey();
03645 kdDebug(32001) << "KWDocument::saveXML registering text image " << key.toString() << endl;
03646 if ( !savePictures.contains( key ) )
03647 savePictures.append( key );
03648 }
03649 m_textImageRequests.clear();
03650
03651
03652 QPtrListIterator<KWFrameSet> fit = framesetsIterator();
03653 for ( ; fit.current() ; ++fit )
03654 {
03655 KWFrameSet *frameSet = fit.current();
03656
03657 if ( !frameSet->isDeleted() && ( frameSet->type() == FT_PICTURE ) )
03658 {
03659 KoPictureKey key = static_cast<KWPictureFrameSet *>( frameSet )->key();
03660 if ( !savePictures.contains( key ) )
03661 savePictures.append( key );
03662 }
03663 }
03664 return savePictures;
03665 }
03666
03667
03668 bool KWDocument::completeSaving( KoStore *store )
03669 {
03670 if ( !store )
03671 return TRUE;
03672
03673 QString u = KURL( url() ).path();
03674
03675 QValueList<KoPictureKey> savePictures( savePictureList() );
03676
03677 return m_pictureCollection->saveToStore( KoPictureCollection::CollectionPicture, store, savePictures );
03678 }
03679
03680 int KWDocument::supportedSpecialFormats() const
03681 {
03682 return KoDocument::supportedSpecialFormats();
03683 }
03684
03685 void KWDocument::addView( KoView *view )
03686 {
03687 m_lstViews.append( (KWView*)view );
03688 KoDocument::addView( view );
03689 for( QValueList<KWView *>::Iterator it = m_lstViews.begin(); it != m_lstViews.end(); ++it ) {
03690 (*it)->deselectAllFrames();
03691 }
03692 }
03693
03694 void KWDocument::removeView( KoView *view )
03695 {
03696 m_lstViews.remove( static_cast<KWView*>(view) );
03697 KoDocument::removeView( view );
03698 }
03699
03700 void KWDocument::addShell( KoMainWindow *shell )
03701 {
03702 connect( shell, SIGNAL( documentSaved() ), m_commandHistory, SLOT( documentSaved() ) );
03703 connect( shell, SIGNAL( saveDialogShown() ), this, SLOT( saveDialogShown() ) );
03704 KoDocument::addShell( shell );
03705 }
03706
03707 KoView* KWDocument::createViewInstance( QWidget* parent, const char* name )
03708 {
03709 if ( isEmbedded() )
03710 return new KWView( "ModeEmbedded", parent, name, this );
03711 else
03712 return new KWView( m_viewModeType, parent, name, this );
03713 }
03714
03715
03716
03717 void KWDocument::paintContent( QPainter& painter, const QRect& rectangle, bool transparent, double zoomX, double zoomY )
03718 {
03719
03720 Q_ASSERT( zoomX != 0 );
03721 Q_ASSERT( zoomY != 0 );
03722
03723 setZoom( 100 );
03724 m_zoomMode = KoZoomMode::ZOOM_CONSTANT;
03725
03726
03727 zoomX *= POINT_TO_INCH( static_cast<double>( KoGlobal::dpiX() ) );
03728 zoomY *= POINT_TO_INCH( static_cast<double>( KoGlobal::dpiY() ) );
03729
03730 if ( m_zoomedResolutionX != zoomX || m_zoomedResolutionY != zoomY )
03731 {
03732
03733 int zoomLevel = qRound( 100 * zoomY / m_zoomedResolutionY );
03734 setZoom( zoomLevel );
03735 bool forPrint = painter.device() && painter.device()->devType() == QInternal::Printer;
03736 newZoomAndResolution( false, forPrint );
03737 if ( KFormula::Document* formulaDocument = m_formulaDocumentWrapper->document() )
03738 formulaDocument->setZoomAndResolution( zoomLevel, zoomX, zoomY, false, forPrint );
03739
03740 }
03741
03742 QRect rect( rectangle );
03743 painter.save();
03744 painter.translate( rect.x(), rect.y() );
03745 QRect clipRect( 0, 0, rect.width(), rect.height() );
03746
03747 KWViewModeEmbedded * viewMode = new KWViewModeEmbedded( this, 0 );
03748 viewMode->setDrawFrameBackground( !transparent );
03749 viewMode->setDrawSelections( false );
03750
03751 QColorGroup cg = QApplication::palette().active();
03752
03753 if (!transparent)
03754 {
03755 QRegion emptyRegion( rect );
03756 createEmptyRegion( rect, emptyRegion, viewMode );
03757 eraseEmptySpace( &painter, emptyRegion, cg.brush( QColorGroup::Base ) );
03758 }
03759
03760 QPtrListIterator<KWFrameSet> fit = framesetsIterator();
03761 for ( ; fit.current() ; ++fit )
03762 {
03763 KWFrameSet * frameset = fit.current();
03764 if ( frameset->isVisible( viewMode ) && !frameset->isFloating() )
03765 frameset->drawContents( &painter, clipRect, cg,
03766 false , true ,
03767 0L, viewMode, 0 );
03768 }
03769 delete viewMode;
03770
03771 painter.restore();
03772 }
03773
03774 QPixmap KWDocument::generatePreview( const QSize& size )
03775 {
03776 int oldZoom = m_zoom;
03777 double oldResolutionX = resolutionX();
03778 double oldResolutionY = resolutionY();
03779 double oldZoomX = zoomedResolutionX();
03780 double oldZoomY = zoomedResolutionY();
03781
03782
03783
03784
03785
03786
03787 for( QValueList<KWView *>::Iterator it = m_lstViews.begin(); it != m_lstViews.end(); ++it ) {
03788 (*it)->getGUI()->canvasWidget()->setUpdatesEnabled( false );
03789 }
03790 Q_ASSERT( !m_bGeneratingPreview );
03791 m_bGeneratingPreview = true;
03792 QPixmap pix = KoDocument::generatePreview(size);
03793
03794
03795 setResolution( oldResolutionX, oldResolutionY );
03796 setZoom( oldZoom );
03797
03798 for( QValueList<KWView *>::Iterator it = m_lstViews.begin(); it != m_lstViews.end(); ++it ) {
03799 (*it)->getGUI()->canvasWidget()->setUpdatesEnabled( true );
03800 }
03801 newZoomAndResolution( true , false );
03802 m_bGeneratingPreview = false;
03803 if ( KFormula::Document* formulaDocument = m_formulaDocumentWrapper->document() ) {
03804 formulaDocument->setZoomAndResolution( oldZoom, oldZoomX, oldZoomY );
03805 }
03806 return pix;
03807 }
03808
03809 void KWDocument::createEmptyRegion( const QRect & crect, QRegion & emptyRegion, KWViewMode * viewMode )
03810 {
03811 QPtrListIterator<KWFrameSet> fit = framesetsIterator();
03812 for ( ; fit.current() ; ++fit )
03813 {
03814 KWFrameSet *frameset = fit.current();
03815 if ( frameset->isVisible( viewMode ) )
03816 frameset->createEmptyRegion( crect, emptyRegion, viewMode );
03817 }
03818 }
03819
03820 void KWDocument::eraseEmptySpace( QPainter * painter, const QRegion & emptySpaceRegion, const QBrush & brush )
03821 {
03822 painter->save();
03823 painter->setClipRegion( emptySpaceRegion, QPainter::CoordPainter );
03824 painter->setPen( Qt::NoPen );
03825
03826
03827
03828 painter->fillRect( emptySpaceRegion.boundingRect(), brush );
03829 painter->restore();
03830 }
03831
03832 KWDocumentChild* KWDocument::createChildDoc( const KoRect& rect, KoDocument* childDoc )
03833 {
03834 KWDocumentChild* ch = new KWDocumentChild( this, rect.toQRect(), childDoc );
03835 insertChild( ch );
03836 return ch;
03837 }
03838
03839 KWPartFrameSet* KWDocument::insertObject( const KoRect& rect, KoDocumentEntry& e, QWidget* parentWidget )
03840 {
03841 KoDocument* doc = e.createDoc( this );
03842 if ( !doc )
03843 return 0;
03844 if ( !doc->showEmbedInitDialog( parentWidget ) )
03845 return 0;
03846
03847 KWDocumentChild* ch = createChildDoc( rect, doc );
03848 setModified( TRUE );
03849
03850 KWPartFrameSet *frameset = new KWPartFrameSet( this, ch, QString::null );
03851 KWFrame *frame = new KWFrame(frameset, rect.x(), rect.y(), rect.width(), rect.height() );
03852 frame->setZOrder( maxZOrder( frame->pageNumber(this) ) + 1 );
03853 frameset->addFrame( frame );
03854 addFrameSet( frameset );
03855
03856 KWCreateFrameCommand *cmd = new KWCreateFrameCommand( i18n("Create Part Frame"), frame);
03857 addCommand(cmd);
03858
03859 frameChanged( frame );
03860
03861 return frameset;
03862 }
03863
03864
03865 void KWDocument::delayedRepaintAllViews() {
03866 if (!m_repaintAllViewsPending) {
03867 QTimer::singleShot( 0, this, SLOT( slotRepaintAllViews() ) );
03868 m_repaintAllViewsPending=true;
03869 }
03870 }
03871
03872 void KWDocument::slotRepaintAllViews() {
03873 m_repaintAllViewsPending=false;
03874 repaintAllViews( false );
03875 }
03876
03877 void KWDocument::delayedRecalcFrames( int fromPage ) {
03878
03879 if ( m_recalcFramesPending == -1 || fromPage < m_recalcFramesPending )
03880 {
03881 m_recalcFramesPending = fromPage;
03882 QTimer::singleShot( 0, this, SLOT( slotRecalcFrames() ) );
03883 }
03884 }
03885
03886 void KWDocument::slotRecalcFrames() {
03887 int from = m_recalcFramesPending;
03888 kdDebug() << k_funcinfo << "from=" << from << endl;
03889 m_recalcFramesPending = -1;
03890 if ( from != -1 )
03891 recalcFrames( from );
03892 }
03893
03894 void KWDocument::repaintAllViewsExcept( KWView *view, bool erase )
03895 {
03896
03897 for( QValueList<KWView *>::Iterator it = m_lstViews.begin(); it != m_lstViews.end(); ++it ) {
03898 KWView* viewPtr = *it;
03899 if ( viewPtr != view ) {
03900 viewPtr->getGUI()->canvasWidget()->repaintAll( erase );
03901 }
03902 }
03903 }
03904
03905 void KWDocument::updateAllStyleLists()
03906 {
03907 for( QValueList<KWView *>::Iterator it = m_lstViews.begin(); it != m_lstViews.end(); ++it )
03908 (*it)->updateStyleList();
03909 }
03910
03911 void KWDocument::updateStyleListOrder( const QStringList &list )
03912 {
03913 styleCollection()->updateStyleListOrder( list );
03914 }
03915
03916 void KWDocument::applyStyleChange( KoStyleChangeDefMap changed )
03917 {
03918 QPtrList<KWTextFrameSet> textFramesets = allTextFramesets( true );
03919
03920 KWTextFrameSet *frm;
03921 for ( frm=textFramesets.first(); frm != 0; frm=textFramesets.next() ){
03922 frm->applyStyleChange( changed );
03923 }
03924 }
03925
03926 void KWDocument::updateAllFrameStyleLists()
03927 {
03928 for( QValueList<KWView *>::Iterator it = m_lstViews.begin(); it != m_lstViews.end(); ++it )
03929 (*it)->updateFrameStyleList();
03930 }
03931
03932 void KWDocument::updateAllTableStyleLists()
03933 {
03934 for( QValueList<KWView *>::Iterator it = m_lstViews.begin(); it != m_lstViews.end(); ++it )
03935 (*it)->updateTableStyleList();
03936 }
03937
03938 void KWDocument::repaintAllViews( bool erase )
03939 {
03940
03941 for( QValueList<KWView *>::Iterator it = m_lstViews.begin(); it != m_lstViews.end(); ++it )
03942 (*it)->getGUI()->canvasWidget()->repaintAll( erase );
03943 }
03944
03945 QPtrList<KWFrame> KWDocument::framesToCopyOnNewPage( int afterPageNum ) const {
03946
03947
03948
03949 QPtrList<KWFrame> framesToLookAt;
03950 if ( afterPageNum >= startPage() )
03951 framesToLookAt = framesInPage( afterPageNum, false );
03952
03953 if ( afterPageNum >= startPage() + 1 )
03954 {
03955 QPtrList<KWFrame> framesToAlsoLookAt = framesInPage( afterPageNum-1, false );
03956
03957
03958 QPtrListIterator<KWFrame> frameAlsoIt( framesToAlsoLookAt );
03959 for ( ; frameAlsoIt.current(); ++frameAlsoIt )
03960 framesToLookAt.append( frameAlsoIt.current() );
03961 }
03962
03963 QPtrList<KWFrame> framesToCopy;
03964
03965 QPtrListIterator<KWFrame> frameIt( framesToLookAt );
03966 for ( ; frameIt.current(); ++frameIt )
03967 {
03968 KWFrame * frame = frameIt.current();
03969 KWFrameSet* frameSet = frame->frameSet();
03970
03971
03972 if ( frameSet->type() == FT_TABLE ) continue;
03973
03974
03975
03976 if(frameSet->isAHeader() || frameSet->isAFooter()) continue;
03977
03978 #ifdef DEBUG_PAGES
03979 kdDebug(32002) << "KWDocument::framesToCopyOnNewPage looking at frame " << frame << ", pageNum=" << frame->pageNumber() << " from " << frameSet->name() << endl;
03980 static const char * newFrameBh[] = { "Reconnect", "NoFollowup", "Copy" };
03981 kdDebug(32002) << " frame->newFrameBehavior()==" << newFrameBh[frame->newFrameBehavior()] << endl;
03982 #endif
03983 const int frameIsOnPage = frame->pageNumber();
03984 if (frame->newFrameBehavior() == KWFrame::Copy &&
03985 (frameIsOnPage == afterPageNum && frame->sheetSide() == KWFrame::AnySide ||
03986 frameIsOnPage == afterPageNum -1 && frame->sheetSide() != KWFrame::AnySide))
03987 framesToCopy.append( frame );
03988 }
03989 return framesToCopy;
03990 }
03991
03992 KWPage* KWDocument::insertPage( int afterPageNum )
03993 {
03994 #ifdef DEBUG_PAGES
03995 kdDebug(32002) << "insertPage: afterPageNum=" << afterPageNum << endl;
03996 #endif
03997 if ( processingType() == WP )
03998 Q_ASSERT( afterPageNum == lastPage() );
03999
04000 double pageHeight = pageManager()->page( afterPageNum )->height();
04001
04002 for ( int pg = pageCount () -1 ; pg > afterPageNum ; --pg )
04003 {
04004
04005 QPtrList<KWFrame> frames = framesInPage( pg, false );
04006 #ifdef DEBUG_PAGES
04007 kdDebug(32002) << "insertPage: moving " << frames.count() << " frames down, from page " << pg << endl;
04008 #endif
04009 QPtrListIterator<KWFrame> frameIt( frames );
04010 for ( ; frameIt.current(); ++frameIt )
04011 frameIt.current()->moveBy( 0, pageHeight );
04012 }
04013
04014 KWPage *page = pageManager()->insertPage(afterPageNum+1);
04015
04016
04017 QPtrList<KWFrame> framesToCopy = framesToCopyOnNewPage( afterPageNum );
04018 QPtrListIterator<KWFrame> frameIt( framesToCopy );
04019 for ( ; frameIt.current(); ++frameIt )
04020 {
04021 KWFrame * frame = frameIt.current();
04022
04023 KWFrame *newFrame = frame->getCopy();
04024 newFrame->moveBy( 0, pageHeight );
04025 frame->frameSet()->addFrame( newFrame );
04026
04027 if ( frame->newFrameBehavior()==KWFrame::Copy )
04028 newFrame->setCopy( true );
04029
04030 }
04031 return page;
04032 }
04033
04034 KWPage* KWDocument::appendPage()
04035 {
04036 #ifdef DEBUG_PAGES
04037 kdDebug(32002) << "KWDocument::appendPage pageCount()=" << pageCount() << " -> insertPage(" << lastPage() << ")" << endl;
04038 #endif
04039 return insertPage( lastPage() );
04040 }
04041
04042 void KWDocument::afterInsertPage( int pageNum )
04043 {
04044 #ifdef DEBUG_PAGES
04045 kdDebug(32002) << "KWDocument::afterInsertPage " << pageNum << endl;
04046 #endif
04047 if ( !m_bGeneratingPreview )
04048 emit newContentsSize();
04049
04050
04051
04052 recalcFrames( pageNum, -1, KWFrameLayout::DontRemovePages );
04053
04054 updateAllFrames();
04055
04056 recalcVariables( VT_PGNUM );
04057 emit numPagesChanged();
04058 if ( m_viewModeType == "ModePreview" )
04059 repaintAllViews();
04060 }
04061
04062 bool KWDocument::canRemovePage( int num )
04063 {
04064 kdDebug() << "KWDocument::canRemovePage " << num<< endl;
04065 QPtrListIterator<KWFrameSet> fit = framesetsIterator();
04066 for ( ; fit.current() ; ++fit )
04067 {
04068 KWFrameSet * frameSet = fit.current();
04069 if ( frameSet->isHeaderOrFooter() )
04070 continue;
04071 if ( frameSet->isVisible() && !frameSet->canRemovePage( num ) )
04072 return false;
04073 }
04074 #ifdef DEBUG_PAGES
04075 kdDebug(32002) << "KWDocument::canRemovePage " << num << "-> TRUE" << endl;
04076 #endif
04077 return true;
04078 }
04079
04080 void KWDocument::removePage( int pageNum )
04081 {
04082 if ( processingType() == WP )
04083 Q_ASSERT( pageNum == lastPage() );
04084 Q_ASSERT( pageCount() > 1 );
04085 if ( pageCount() == 1 )
04086 return;
04087
04088
04089 QPtrList<KWFrame> framesToDelete = framesInPage( pageNum, false );
04090 #ifdef DEBUG_PAGES
04091 kdDebug(32002) << "KWDocument::removePage " << pageNum << ", " << framesToDelete.count() << " frames to delete" << endl;
04092 #endif
04093 QPtrListIterator<KWFrame> frameIt( framesToDelete );
04094 for ( ; frameIt.current(); ++frameIt )
04095 {
04096 KWFrame * frame = frameIt.current();
04097 KWFrameSet * frameSet = frame->frameSet();
04098 if ( frameSet->frameSetInfo() != KWFrameSet::FI_BODY )
04099 continue;
04100 frameSet->deleteFrame( frame, true );
04101 }
04102
04103
04104 for ( int pg = pageNum+1 ; pg < pageCount() ; ++pg )
04105 {
04106
04107 QPtrList<KWFrame> frames = framesInPage( pg, false );
04108 #ifdef DEBUG_PAGES
04109 kdDebug(32002) << "removePage: moving " << frames.count() << " frames up, from page " << pg << endl;
04110 #endif
04111 QPtrListIterator<KWFrame> frameIt( frames );
04112 for ( ; frameIt.current(); ++frameIt )
04113 frameIt.current()->moveBy( 0, pageManager()->page(0)->height() );
04114 }
04115
04116 pageManager()->removePage(pageNum);
04117 #ifdef DEBUG_PAGES
04118 kdDebug(32002) << "KWDocument::removePage -- -> " << pageCount() << endl;
04119 #endif
04120
04121 emit numPagesChanged();
04122 }
04123
04124 void KWDocument::afterRemovePages()
04125 {
04126
04127 recalcFrames();
04128
04129
04130
04131 QPtrListIterator<KWFrameSet> fit = framesetsIterator();
04132 for ( ; fit.current() ; ++fit )
04133 fit.current()->updateFrames();
04134
04135 recalcVariables( VT_PGNUM );
04136 if ( !m_bGeneratingPreview )
04137 emit newContentsSize();
04138 if ( m_viewModeType == "ModePreview" )
04139 repaintAllViews();
04140 }
04141
04142 bool KWDocument::tryRemovingPages()
04143 {
04144 int last = lastPage();
04145 bool removed = false;
04146
04147 while ( last > startPage() && canRemovePage( last ) )
04148 {
04149 removePage( last );
04150 if ( last <= lastPage() )
04151 {
04152 kdWarning() << "Didn't manage to remove page " << last << " (still having " << pageCount() << " pages ). Aborting" << endl;
04153 break;
04154 }
04155 removed = true;
04156 last = lastPage();
04157 }
04158
04159
04160 return removed;
04161 }
04162
04163
04164 KWFrameSet * KWDocument::frameSetByName( const QString & name )
04165 {
04166
04167 QPtrListIterator<KWFrameSet> fit = framesetsIterator();
04168 for ( ; fit.current() ; ++fit )
04169 if ( fit.current()->name() == name )
04170 return fit.current();
04171 return 0L;
04172 }
04173
04174
04175
04176 QString KWDocument::generateFramesetName( const QString & templateName )
04177 {
04178 QString name;
04179 int num = 1;
04180 bool exists;
04181 do {
04182 name = templateName.arg( num );
04183 exists = frameSetByName( name );
04184 ++num;
04185 } while ( exists );
04186 return name;
04187 }
04188
04189 void KWDocument::fixZOrders() {
04190
04191 for (int pgnum = startPage() ; pgnum <= lastPage() ; pgnum++) {
04192 QPtrList<KWFrame> frames = framesInPage(pgnum);
04193
04194
04195
04196 bool need_fixup = false;
04197 KWFrame *f = frames.last();
04198 if ( !f )
04199 continue;
04200 int lastZOrder = f->zOrder();
04201 f = frames.prev();
04202 for ( ; f ; f=frames.prev() ) {
04203 if ( !f->frameSet()->isFloating() &&
04204 ( f->zOrder() == lastZOrder || f->zOrder() < 0 ) ) {
04205 need_fixup = true;
04206 break;
04207 }
04208 lastZOrder = f->zOrder();
04209 }
04210 if ( need_fixup ) {
04211 int current_zorder=0;
04212 kdDebug() << "fixing page " << pgnum << " z-orders " << endl;
04213 for (KWFrame *fr = frames.first();fr;fr=frames.next()) {
04214
04215 if (fr->frameSet()->isFloating())
04216 continue;
04217 current_zorder++;
04218 fr->setZOrder(current_zorder);
04219
04220 }
04221 }
04222
04223 if ( m_processingType == KWDocument::WP )
04224 {
04225
04226
04227 lowerMainFrames( pgnum );
04228 }
04229 }
04230
04231
04232 KWFrameList::recalcAllFrames(this);
04233 }
04234
04235 void KWDocument::lowerMainFrames( int pageNum )
04236 {
04237 QPtrList<KWFrame> framesInPage = this->framesInPage(pageNum);
04238 int lowestZOrder=10000;
04239 for ( QPtrListIterator<KWFrame> frameIt( framesInPage ); frameIt.current(); ++frameIt )
04240 lowestZOrder=QMIN(lowestZOrder, frameIt.current()->zOrder());
04241 lowerMainFrames( pageNum, lowestZOrder );
04242 }
04243
04244
04245 void KWDocument::lowerMainFrames( int pageNum, int lowestZOrder )
04246 {
04247
04248 QPtrList<KWFrame> framesInPage = this->framesInPage(pageNum);
04249 for ( QPtrListIterator<KWFrame> frameIt( framesInPage ); frameIt.current(); ++frameIt ) {
04250 if(frameIt.current()->frameSet()->isMainFrameset()) {
04251 if(lowestZOrder <= frameIt.current()->zOrder())
04252 frameIt.current()->setZOrder(lowestZOrder-1);
04253
04254 }
04255 }
04256 }
04257
04258 QPtrList<KWFrame> KWDocument::framesInPage( int pageNum, bool sorted ) const {
04259
04260 ZOrderedFrameList frames;
04261 QPtrListIterator<KWFrameSet> fit = framesetsIterator();
04262 for ( ; fit.current() ; ++fit )
04263 {
04264 KWFrameSet *frameSet = fit.current();
04265 if ( !frameSet->isVisible() )
04266 continue;
04267
04268 QPtrListIterator<KWFrame> it( frameSet->framesInPage( pageNum ) );
04269 for ( ; it.current() ; ++it )
04270 frames.append( it.current() );
04271 }
04272 if (sorted) frames.sort();
04273 return frames;
04274 }
04275
04276 void KWDocument::updateAllFrames( int flags )
04277 {
04278 #ifdef DEBUG_SPEED
04279 QTime dt;
04280 dt.start();
04281 #endif
04282 QPtrListIterator<KWFrameSet> fit = framesetsIterator();
04283 for ( ; fit.current() ; ++fit )
04284 fit.current()->updateFrames( flags );
04285
04286 #ifdef DEBUG_SPEED
04287 kdDebug(32001) << "updateAllFrames(" << flags << ") took " << (float)(dt.elapsed()) / 1000 << " seconds" << endl;
04288 #endif
04289
04290
04291
04292
04293
04294
04295
04296 KWFrameList::recalcAllFrames(this);
04297 }
04298
04299
04300
04301 void KWDocument::frameChanged( KWFrame * frame )
04302 {
04303 if(! m_framesChangedHandler) {
04304 m_framesChangedHandler = new FramesChangedHandler(this);
04305 QTimer::singleShot( 0, this, SLOT( updateFramesChanged() ) );
04306 }
04307 m_framesChangedHandler->addFrame(frame);
04308 }
04309
04310 void KWDocument::framesChanged( const QPtrList<KWFrame> & frames, KWView * view )
04311 {
04312 Q_UNUSED( view );
04313 QPtrListIterator<KWFrame> it( frames );
04314 for ( ; it.current() ; ++it )
04315 frameChanged(it.current());
04316 }
04317
04318 void KWDocument::updateFramesChanged() {
04319 if(!m_framesChangedHandler) return;
04320 m_framesChangedHandler->execute();
04321 delete m_framesChangedHandler;
04322 m_framesChangedHandler = 0;
04323 }
04324
04325 void KWDocument::framesChanged( const QValueList<KWFrame*> &frames) {
04326 QValueListConstIterator<KWFrame*> framesIterator = frames.begin();
04327 for(;framesIterator != frames.end(); ++framesIterator)
04328 frameChanged(*framesIterator);
04329 }
04330
04331 void KWDocument::setHeaderVisible( bool h )
04332 {
04333 m_headerVisible = h;
04334 recalcFrames();
04335 updateAllFrames();
04336 layout();
04337 setModified(true);
04338 repaintAllViews( true );
04339 }
04340
04341 void KWDocument::setFooterVisible( bool f )
04342 {
04343 m_footerVisible = f;
04344 recalcFrames();
04345 updateAllFrames();
04346 layout();
04347 setModified(true);
04348 repaintAllViews( true );
04349 }
04350
04351 bool KWDocument::hasEndNotes() const
04352 {
04353 return m_bHasEndNotes;
04354 }
04355
04356 void KWDocument::updateHeaderButton()
04357 {
04358 for( QValueList<KWView *>::Iterator it = m_lstViews.begin(); it != m_lstViews.end(); ++it )
04359 {
04360 (*it)->updateHeaderFooterButton();
04361 (*it)->updateHeader();
04362 }
04363 }
04364
04365 void KWDocument::updateFooterButton()
04366 {
04367 for( QValueList<KWView *>::Iterator it = m_lstViews.begin(); it != m_lstViews.end(); ++it )
04368 {
04369 (*it)->updateHeaderFooterButton();
04370 (*it)->updateFooter();
04371 }
04372 }
04373
04374 void KWDocument::addTextImageRequest( KWTextImage *img )
04375 {
04376 m_textImageRequests.append( img );
04377 }
04378
04379 void KWDocument::addPictureRequest( KWPictureFrameSet *fs )
04380 {
04381 m_pictureRequests.append( fs );
04382 }
04383
04384 void KWDocument::addAnchorRequest( const QString &framesetName, const KWAnchorPosition &anchorPos )
04385 {
04386 m_anchorRequests.insert( framesetName, anchorPos );
04387 }
04388
04389 void KWDocument::addFootNoteRequest( const QString &framesetName, KWFootNoteVariable* var )
04390 {
04391 if ( var->noteType() == EndNote )
04392 m_bHasEndNotes = true;
04393 m_footnoteVarRequests.insert( framesetName, var );
04394 }
04395
04396 void KWDocument::refreshMenuCustomVariable()
04397 {
04398 emit sig_refreshMenuCustomVariable();
04399 }
04400
04401 void KWDocument::recalcVariables( int type )
04402 {
04403 const QValueList<KoVariable *> modifiedVariables = m_varColl->recalcVariables(type);
04404 if ( m_bGeneratingPreview )
04405 return;
04406
04407 QMap<KoTextDocument *, bool> modifiedTextDocuments;
04408 for ( QValueList<KoVariable *>::const_iterator it = modifiedVariables.begin(), end = modifiedVariables.end() ; it != end ; ++it ) {
04409 KoTextDocument* textdoc = (*it)->textDocument();
04410 if ( modifiedTextDocuments.find( textdoc ) != modifiedTextDocuments.end() )
04411 {
04412 modifiedTextDocuments.insert( textdoc, true );
04413 KWTextFrameSet * textfs = static_cast<KWTextDocument *>(textdoc)->textFrameSet();
04414 slotRepaintChanged( textfs );
04415 }
04416 }
04417 }
04418
04419 int KWDocument::mailMergeRecord() const
04420 {
04421 return slRecordNum;
04422 }
04423
04424 void KWDocument::setMailMergeRecord( int r )
04425 {
04426 slRecordNum = r;
04427 }
04428
04429 void KWDocument::getPageLayout( KoPageLayout& layout, KoColumns& cl, KoKWHeaderFooter& hf )
04430 {
04431 layout = m_pageLayout;
04432 cl = m_pageColumns;
04433 hf = m_pageHeaderFooter;
04434 }
04435
04436 void KWDocument::addFrameSet( KWFrameSet *f, bool finalize )
04437 {
04438 if(m_lstFrameSet.contains(f) > 0) {
04439 kdWarning(32001) << "Frameset " << f << " " << f->name() << " already in list!" << endl;
04440 return;
04441 }
04442 m_lstFrameSet.append(f);
04443
04444 KWFrameList::createFrameList(f, this);
04445
04446 if ( finalize )
04447 f->finalize();
04448 setModified( true );
04449 emit sigFrameSetAdded(f);
04450 }
04451
04452 void KWDocument::removeFrameSet( KWFrameSet *f )
04453 {
04454 emit sig_terminateEditing( f );
04455 m_lstFrameSet.take( m_lstFrameSet.find(f) );
04456 setModified( true );
04457 emit sigFrameSetRemoved(f);
04458 }
04459
04460 void KWDocument::addCommand( KCommand * cmd )
04461 {
04462 Q_ASSERT( cmd );
04463
04464 m_commandHistory->addCommand( cmd, false );
04465 setModified( true );
04466 }
04467
04468 void KWDocument::slotDocumentRestored()
04469 {
04470 setModified( false );
04471 }
04472
04473 void KWDocument::slotCommandExecuted()
04474 {
04475 setModified( true );
04476 }
04477
04478 #ifndef NDEBUG
04479 void KWDocument::printStyleDebug()
04480 {
04481 kdDebug() << "----------------------------------------"<<endl;
04482 m_styleColl->printDebug();
04483 kdDebug() << m_frameStyleColl->count() << " frame styles" << endl;
04484 kdDebug() << m_tableStyleColl->count() << " table-cell styles" << endl;
04485 }
04486
04487 void KWDocument::printDebug()
04488 {
04489 kdDebug() << "----------------------------------------"<<endl;
04490 kdDebug() << " Debug info"<<endl;
04491 kdDebug() << "Document:" << this <<endl;
04492 kdDebug() << "Type of document: (0=WP, 1=DTP) " << processingType() <<endl;
04493 kdDebug() << "Header visible: " << isHeaderVisible() << endl;
04494 kdDebug() << "Footer visible: " << isFooterVisible() << endl;
04495 kdDebug() << "Units: " << unit() <<endl;
04496 kdDebug() << "# Framesets: " << frameSetCount() <<endl;
04497 QPtrListIterator<KWFrameSet> fit = framesetsIterator();
04498 for ( unsigned int iFrameset = 0; fit.current() ; ++fit, iFrameset++ )
04499 {
04500 KWFrameSet * frameset = fit.current();
04501 kdDebug() << "Frameset " << iFrameset << ": '" <<
04502 frameset->name() << "' (" << frameset << ")" << (frameset->isDeleted()?" Deleted":"")<<endl;
04503 if ( frameset->isVisible())
04504 frameset->printDebug();
04505 else
04506 kdDebug() << " [hidden] #" << frameset->frameCount() << " frames" << endl;
04507 }
04508
04509 for ( uint pgNum = 0 ; pgNum < m_sectionTitles.size() ; ++pgNum ) {
04510 kdDebug() << "Page " << pgNum << " Section: '" << m_sectionTitles[ pgNum ] << "'"<< endl;
04511 }
04512
04513
04514
04515
04516
04517
04518
04519
04520
04521 kdDebug() << "PageManager holds "<< pageCount() << " pages in the range: " << startPage() <<
04522 "-" << lastPage() << endl;
04523 for (int pgnum = startPage() ; pgnum <= lastPage() ; pgnum++) {
04524 KWPage *page = pageManager()->page(pgnum);
04525 kdDebug() << "Page " << pgnum << " width=" << page->width() << " height=" << page->height() << endl;
04526 }
04527 kdDebug() << " The height of the doc (in pt) is: " << pageManager()->
04528 bottomOfPage(lastPage()) << endl;
04529 }
04530 #endif
04531
04532 void KWDocument::layout()
04533 {
04534 QPtrListIterator<KWFrameSet> it = framesetsIterator();
04535 for (; it.current(); ++it )
04536 if ( it.current()->isVisible() )
04537 it.current()->layout();
04538 }
04539
04540 void KWDocument::invalidate(const KWFrameSet *skipThisFrameSet)
04541 {
04542 QPtrListIterator<KWFrameSet> it = framesetsIterator();
04543 for (; it.current(); ++it )
04544 if(it.current()!=skipThisFrameSet)
04545 it.current()->invalidate();
04546 }
04547
04548 KFormula::Document* KWDocument::formulaDocument( bool init )
04549 {
04550 KFormula::Document* formulaDocument = m_formulaDocumentWrapper->document();
04551 if (!formulaDocument) {
04552 kdDebug() << k_funcinfo << endl;
04553 formulaDocument = new KFormula::Document;
04554 m_formulaDocumentWrapper->document( formulaDocument, init );
04555 if ( formulaDocument != 0 ) {
04556
04557 formulaDocument->setZoomAndResolution( m_zoom,
04558 qRound(INCH_TO_POINT( m_resolutionX )),
04559 qRound(INCH_TO_POINT( m_resolutionY )) );
04560 formulaDocument->newZoomAndResolution(false,false);
04561 }
04562 }
04563 return formulaDocument;
04564 }
04565
04566
04567 void KWDocument::slotRepaintChanged( KWFrameSet * frameset )
04568 {
04569
04570
04571 for( QValueList<KWView *>::Iterator it = m_lstViews.begin(); it != m_lstViews.end(); ++it ) {
04572 (*it)->getGUI()->canvasWidget()->repaintChanged( frameset, it == m_lstViews.fromLast() );
04573 }
04574 }
04575
04576 void KWDocument::deleteTable( KWTableFrameSet *table )
04577 {
04578 if ( !table )
04579 return;
04580 if ( table->isFloating() )
04581 {
04582 emit sig_terminateEditing( table );
04583 KWAnchor * anchor = table->findAnchor( 0 );
04584 addCommand( table->anchorFrameset()->deleteAnchoredFrame( anchor ) );
04585 }
04586 else
04587 {
04588 KWDeleteTableCommand *cmd = new KWDeleteTableCommand( i18n("Delete Table"), table );
04589 addCommand( cmd );
04590 cmd->execute();
04591 }
04592 }
04593
04594 void KWDocument::deleteFrame( KWFrame * frame )
04595 {
04596 KWFrameSet * fs = frame->frameSet();
04597 kdDebug(32002) << "KWDocument::deleteFrame frame=" << frame << " fs=" << fs << endl;
04598 QString cmdName;
04599 TypeStructDocItem docItem = (TypeStructDocItem) 0;
04600 switch (fs->type() ) {
04601 case FT_TEXT:
04602 cmdName=i18n("Delete Text Frame");
04603 docItem=TextFrames;
04604 break;
04605 case FT_FORMULA:
04606 cmdName=i18n("Delete Formula Frame");
04607 docItem=FormulaFrames;
04608 break;
04609 case FT_CLIPART:
04610 kdError(32001) << "FT_CLIPART used! (in KWDocument::deleteFrame)" << endl;
04611 case FT_PICTURE:
04612 cmdName=i18n("Delete Picture Frame");
04613 docItem=Pictures;
04614 break;
04615 case FT_PART:
04616 cmdName=i18n("Delete Object Frame");
04617 docItem=Embedded;
04618 break;
04619 case FT_TABLE:
04620 case FT_BASE:
04621 Q_ASSERT( 0 );
04622 break;
04623 }
04624 if ( fs->isFloating() )
04625 {
04626 KWAnchor * anchor = fs->findAnchor( 0 );
04627 addCommand( fs->anchorFrameset()->deleteAnchoredFrame( anchor ) );
04628 }
04629 else
04630 {
04631 KWDeleteFrameCommand *cmd = new KWDeleteFrameCommand( cmdName, frame );
04632 addCommand( cmd );
04633 cmd->execute();
04634 }
04635 emit docStructureChanged(docItem);
04636 }
04637
04638 void KWDocument::reorganizeGUI()
04639 {
04640 for( QValueList<KWView *>::Iterator it = m_lstViews.begin(); it != m_lstViews.end(); ++it )
04641 (*it)->getGUI()->reorganize();
04642 }
04643
04644 void KWDocument::slotDocumentInfoModifed()
04645 {
04646 if (!variableCollection()->variableSetting()->displayFieldCode())
04647 recalcVariables( VT_FIELD );
04648 }
04649
04650 void KWDocument::refreshDocStructure(int type)
04651 {
04652 emit docStructureChanged(type);
04653 }
04654
04655 int KWDocument::typeItemDocStructure(FrameSetType type)
04656 {
04657 int typeItem;
04658 switch(type)
04659 {
04660 case FT_TEXT:
04661 typeItem=(int)TextFrames;
04662 break;
04663 case FT_PICTURE:
04664 typeItem=(int)Pictures;
04665 break;
04666 case FT_PART:
04667 typeItem=(int)Embedded;
04668 break;
04669 case FT_FORMULA:
04670 typeItem=(int)FormulaFrames;
04671 break;
04672 case FT_TABLE:
04673 typeItem=(int)Tables;
04674 break;
04675 default:
04676 typeItem=(int)TextFrames;
04677 }
04678 return typeItem;
04679 }
04680
04681 void KWDocument::refreshDocStructure(FrameSetType type)
04682 {
04683 emit docStructureChanged(typeItemDocStructure(type));
04684 }
04685
04686 QBrush KWDocument::resolveBgBrush( const QBrush & brush, QPainter * painter )
04687 {
04688 if ( brush.color().isValid() )
04689 return brush;
04690 QBrush ret( brush );
04691 ret.setColor( defaultBgColor( painter ) );
04692 return ret;
04693 }
04694
04695 QColor KWDocument::resolveBgColor( const QColor & col, QPainter * painter )
04696 {
04697 if (col.isValid())
04698 return col;
04699
04700 return defaultBgColor( painter );
04701 }
04702
04703 QColor KWDocument::defaultBgColor( QPainter * painter )
04704 {
04705 if ( painter && painter->device()->devType() == QInternal::Printer )
04706 return Qt::white;
04707 return QApplication::palette().color( QPalette::Active, QColorGroup::Base );
04708 }
04709
04710
04711 void KWDocument::setTocPresent(bool hasToc)
04712 {
04713 m_hasTOC=hasToc;
04714 for( QValueList<KWView *>::Iterator it = m_lstViews.begin(); it != m_lstViews.end(); ++it )
04715 (*it)->updateTocActionText(hasToc);
04716 }
04717
04718 void KWDocument::refreshMenuExpression()
04719 {
04720 for( QValueList<KWView *>::Iterator it = m_lstViews.begin(); it != m_lstViews.end(); ++it )
04721 (*it)->refreshMenuExpression();
04722 }
04723
04724 void KWDocument::updateZoomRuler()
04725 {
04726 for( QValueList<KWView *>::Iterator it = m_lstViews.begin(); it != m_lstViews.end(); ++it ) {
04727 (*it)->getGUI()->getHorzRuler()->setZoom( zoomedResolutionX() );
04728 (*it)->getGUI()->getVertRuler()->setZoom( zoomedResolutionY() );
04729 (*it)->slotUpdateRuler();
04730 }
04731 }
04732
04733 void KWDocument::updateRulerFrameStartEnd()
04734 {
04735 for( QValueList<KWView *>::Iterator it = m_lstViews.begin(); it != m_lstViews.end(); ++it )
04736 (*it)->slotUpdateRuler();
04737 }
04738
04739 int KWDocument::undoRedoLimit() const
04740 {
04741 return m_commandHistory->undoLimit();
04742 }
04743
04744 void KWDocument::setUndoRedoLimit(int val)
04745 {
04746 m_commandHistory->setUndoLimit(val);
04747 m_commandHistory->setRedoLimit(val);
04748 }
04749
04750 void KWDocument::setGridX(double gridx) {
04751 m_gridX = gridx;
04752 for( QValueList<KWView *>::Iterator it = m_lstViews.begin(); it != m_lstViews.end(); ++it )
04753 (*it)->getGUI()->getHorzRuler()->setGridSize(gridx);
04754 }
04755
04756 QValueList<KoTextObject *> KWDocument::visibleTextObjects(KWViewMode *viewmode) const
04757 {
04758 QValueList<KoTextObject *> lst;
04759 QPtrList<KWTextFrameSet> textFramesets = allTextFramesets( true );
04760
04761 KWTextFrameSet *frm;
04762 for ( frm=textFramesets.first(); frm != 0; frm=textFramesets.next() ) {
04763 if ( frm && frm->isVisible(viewmode) && !frm->textObject()->protectContent() )
04764 {
04765 lst.append( frm->textObject() );
04766 }
04767 }
04768
04769 return lst;
04770 }
04771
04772 void KWDocument::refreshGUIButton()
04773 {
04774 for( QValueList<KWView *>::Iterator it = m_lstViews.begin(); it != m_lstViews.end(); ++it )
04775 (*it)->initGUIButton();
04776 }
04777
04778 void KWDocument::enableBackgroundSpellCheck( bool b )
04779 {
04780 m_bgSpellCheck->setEnabled(b);
04781 for( QValueList<KWView *>::Iterator it = m_lstViews.begin(); it != m_lstViews.end(); ++it )
04782 (*it)->updateBgSpellCheckingState();
04783 }
04784
04785 bool KWDocument::backgroundSpellCheckEnabled() const
04786 {
04787 return m_bgSpellCheck->enabled();
04788 }
04789
04790 void KWDocument::reactivateBgSpellChecking()
04791 {
04792 QPtrList<KWTextFrameSet> textFramesets = allTextFramesets( true );
04793
04794 KWTextFrameSet *frm;
04795 for ( frm=textFramesets.first(); frm != 0; frm=textFramesets.next() ){
04796 frm->textObject()->setNeedSpellCheck(true);
04797 }
04798 repaintAllViews();
04799 startBackgroundSpellCheck();
04800 }
04801
04802 void KWDocument::slotChapterParagraphFormatted( KoTextParag* )
04803 {
04804
04805
04806
04807
04808
04809
04810
04811
04812
04813
04814
04815
04816 m_sectionTitles.resize( 0 );
04817
04818
04819
04820
04821 }
04822
04823 QString KWDocument::checkSectionTitleInParag( KoTextParag* parag, KWTextFrameSet* frameset, int pageNum ) const
04824 {
04825 if ( parag->counter() && parag->counter()->numbering() == KoParagCounter::NUM_CHAPTER
04826 && parag->counter()->depth() == 0 )
04827 {
04828 QString txt = parag->string()->toString();
04829 txt = txt.left( txt.length() - 1 );
04830 #ifndef NDEBUG // not needed, just checking
04831 KoPoint p;
04832 KWFrame* frame = frameset->internalToDocument( parag->rect().topLeft(), p );
04833 Q_ASSERT( frame );
04834 if ( frame ) {
04835 int pgNum = frame->pageNumber();
04836 if( pgNum != pageNum )
04837 kdWarning() << "sectionTitle: was looking for pageNum " << pageNum << ", got frame " << frame << " page " << pgNum << endl;
04838 }
04839 kdDebug(32001) << "KWDocument::sectionTitle for " << pageNum << ":" << txt << endl;
04840 #endif
04841
04842 if ( pageNum > (int)m_sectionTitles.size()-1 )
04843 const_cast<KWDocument*>(this)->m_sectionTitles.resize( pageNum + 1 );
04844 const_cast<KWDocument*>(this)->m_sectionTitles[ pageNum ] = txt;
04845 return txt;
04846 }
04847 return QString::null;
04848 }
04849
04850 QString KWDocument::sectionTitle( int pageNum ) const
04851 {
04852
04853
04854 if ( (int)m_sectionTitles.size() > pageNum )
04855 {
04856
04857 for ( int i = pageNum; i >= 0 ; --i )
04858 {
04859 const QString& s = m_sectionTitles[i];
04860 if ( !s.isEmpty() )
04861 {
04862
04863 if ( pageNum > (int)m_sectionTitles.size()-1 )
04864 const_cast<KWDocument*>(this)->m_sectionTitles.resize( pageNum + 1 );
04865 const_cast<KWDocument*>(this)->m_sectionTitles[ pageNum ] = s;
04866 return s;
04867 }
04868 }
04869 }
04870
04871
04872
04873 if ( m_lstFrameSet.isEmpty() )
04874 return QString::null;
04875
04876 KWTextFrameSet *frameset = dynamic_cast<KWTextFrameSet *>( m_lstFrameSet.getFirst() );
04877 if ( !frameset )
04878 return QString::null;
04879
04880 int topLUpix, bottomLUpix;
04881 if ( !frameset->minMaxInternalOnPage( pageNum, topLUpix, bottomLUpix ) )
04882 return QString::null;
04883
04884 KoTextParag* parag = frameset->textDocument()->firstParag();
04885
04886
04887
04888 KoTextParag* lastParagOfPageAbove = parag;
04889 for ( ; parag ; parag = parag->next() )
04890 {
04891 if ( parag->rect().bottom() < topLUpix )
04892 {
04893 lastParagOfPageAbove = parag;
04894 continue;
04895 }
04896 if ( parag->rect().top() > bottomLUpix )
04897 break;
04898 QString txt = checkSectionTitleInParag( parag, frameset, pageNum );
04899 if ( !txt.isEmpty() )
04900 return txt;
04901 }
04902
04903
04904
04905 parag = lastParagOfPageAbove;
04906 for ( ; parag ; parag = parag->prev() )
04907 {
04908 QString txt = checkSectionTitleInParag( parag, frameset, pageNum );
04909 if ( !txt.isEmpty() )
04910 return txt;
04911 }
04912
04913
04914 return QString::null;
04915 }
04916
04917
04918 void KWDocument::setSpellCheckIgnoreList( const QStringList& lst )
04919 {
04920 m_spellCheckIgnoreList = lst;
04921 m_bgSpellCheck->settings()->setCurrentIgnoreList( m_spellCheckIgnoreList + m_spellCheckPersonalDict );
04922 setModified( true );
04923 }
04924
04925 void KWDocument::addSpellCheckIgnoreWord( const QString & word )
04926 {
04927
04928 if( m_spellCheckIgnoreList.findIndex( word ) == -1 )
04929 m_spellCheckIgnoreList.append( word );
04930 setSpellCheckIgnoreList( m_spellCheckIgnoreList );
04931 if ( backgroundSpellCheckEnabled() )
04932
04933 reactivateBgSpellChecking();
04934 }
04935
04936 int KWDocument::maxZOrder( int pageNum) const
04937 {
04938 bool first = true;
04939 int maxZOrder = 0;
04940 QPtrList<KWFrame> frames = framesInPage( pageNum );
04941 QPtrListIterator<KWFrame> frameIt( frames );
04942 for ( ; frameIt.current(); ++frameIt ) {
04943 if ( first || frameIt.current()->zOrder() > maxZOrder ) {
04944 maxZOrder = frameIt.current()->zOrder();
04945 first = false;
04946 }
04947 }
04948 return maxZOrder;
04949 }
04950
04951 QPtrList<KWTextFrameSet> KWDocument::allTextFramesets(bool onlyReadWrite) const
04952 {
04953 QPtrList<KWTextFrameSet> textFramesets;
04954 QPtrListIterator<KWFrameSet> fit = framesetsIterator();
04955 for ( ; fit.current() ; ++fit ) {
04956 if(fit.current()->isDeleted()) continue;
04957 fit.current()->addTextFrameSets(textFramesets, onlyReadWrite);
04958 }
04959 return textFramesets;
04960 }
04961
04962 QValueList<KoTextDocument *> KWDocument::allTextDocuments() const
04963 {
04964 QValueList<KoTextDocument *> lst;
04965 const QPtrList<KWTextFrameSet> textFramesets = allTextFramesets(false);
04966 QPtrListIterator<KWTextFrameSet> fit( textFramesets );
04967 for ( ; fit.current() ; ++fit ) {
04968 lst.append( fit.current()->textObject()->textDocument() );
04969 }
04970 return lst;
04971 }
04972
04973 int KWDocument::numberOfTextFrameSet( KWFrameSet* fs, bool onlyReadWrite )
04974 {
04975 QPtrList<KWTextFrameSet> textFramesets = allTextFramesets( onlyReadWrite );
04976 return textFramesets.findRef( static_cast<KWTextFrameSet*>(fs) );
04977 }
04978
04979 KWFrameSet * KWDocument::textFrameSetFromIndex( unsigned int num, bool onlyReadWrite )
04980 {
04981 return allTextFramesets( onlyReadWrite ).at( num );
04982 }
04983
04984 void KWDocument::updateTextFrameSetEdit()
04985 {
04986 for( QValueList<KWView *>::Iterator it = m_lstViews.begin(); it != m_lstViews.end(); ++it )
04987 (*it)->slotFrameSetEditChanged();
04988
04989 }
04990
04991 void KWDocument::displayFootNoteFieldCode()
04992 {
04993 QPtrListIterator<KoVariable> it( m_varColl->getVariables() );
04994 for ( ; it.current() ; ++it )
04995 {
04996 if ( it.current()->type() == VT_FOOTNOTE )
04997 {
04998 static_cast<KWFootNoteVariable *>(it.current())->resize();
04999 static_cast<KWFootNoteVariable *>(it.current())->frameSet()->setCounterText( static_cast<KWFootNoteVariable *>(it.current())->text() );
05000
05001 KoTextParag * parag = it.current()->paragraph();
05002 if ( parag )
05003 {
05004 parag->invalidate( 0 );
05005 parag->setChanged( true );
05006 }
05007 }
05008 }
05009 }
05010
05011 void KWDocument::changeFootNoteConfig()
05012 {
05013 QMap<KoTextDocument *, bool> modifiedTextDocuments;
05014 QPtrListIterator<KoVariable> it( m_varColl->getVariables() );
05015 for ( ; it.current() ; ++it )
05016 {
05017 if ( it.current()->type() == VT_FOOTNOTE )
05018 {
05019 KWFootNoteVariable* footNoteVar = static_cast<KWFootNoteVariable *>(it.current());
05020 footNoteVar->formatedNote();
05021 footNoteVar->resize();
05022 footNoteVar->frameSet()->setCounterText( footNoteVar->text() );
05023
05024 KoTextParag * parag = footNoteVar->paragraph();
05025 if ( parag )
05026 {
05027 parag->invalidate( 0 );
05028 parag->setChanged( true );
05029 }
05030 KoTextDocument* textdoc = parag->textDocument();
05031 if ( modifiedTextDocuments.find( textdoc ) != modifiedTextDocuments.end() )
05032 modifiedTextDocuments.insert( textdoc, true );
05033 }
05034 }
05035 for( QMap<KoTextDocument *,bool>::const_iterator it = modifiedTextDocuments.begin();
05036 it != modifiedTextDocuments.end(); ++it ) {
05037 KoTextDocument* textdoc = it.key();
05038 KWTextFrameSet * textfs = static_cast<KWTextDocument *>(textdoc)->textFrameSet();
05039 slotRepaintChanged( textfs );
05040 }
05041 }
05042
05043
05044 void KWDocument::setTabStopValue ( double tabStop )
05045 {
05046 m_tabStop = tabStop;
05047 QPtrList<KWTextFrameSet> textFramesets = allTextFramesets( true );
05048
05049 KWTextFrameSet *frm;
05050 for ( frm=textFramesets.first(); frm != 0; frm=textFramesets.next() ){
05051 frm->textDocument()->setTabStops( ptToLayoutUnitPixX( tabStop ));
05052 frm->layout();
05053 }
05054 repaintAllViews();
05055 }
05056
05057 void KWDocument::setGlobalHyphenation( bool hyphen )
05058 {
05059 m_bGlobalHyphenation = hyphen;
05060
05061
05062 }
05063
05064 void KWDocument::setViewFrameBorders( bool b )
05065 {
05066 m_viewFrameBorders = b;
05067 m_layoutViewMode->setDrawFrameBorders( b );
05068 for( QValueList<KWView *>::Iterator it = m_lstViews.begin(); it != m_lstViews.end(); ++it )
05069 (*it)->getGUI()->canvasWidget()->viewMode()->setDrawFrameBorders( b );
05070 }
05071
05072 void KWDocument::switchViewMode( const QString& newViewModeType )
05073 {
05074
05075
05076 m_viewModeType = newViewModeType;
05077 delete m_layoutViewMode;
05078 m_layoutViewMode = KWViewMode::create( m_viewModeType, this, 0 );
05079
05080
05081
05082 for( QValueList<KWView *>::Iterator it = m_lstViews.begin(); it != m_lstViews.end(); ++it )
05083 (*it)->getGUI()->canvasWidget()->switchViewMode( m_viewModeType );
05084
05085 for( QValueList<KWView *>::Iterator it = m_lstViews.begin(); it != m_lstViews.end(); ++it )
05086 (*it)->switchModeView();
05087 emit newContentsSize();
05088
05089
05090
05091
05092 updateAllFrames();
05093 layout();
05094
05095 repaintAllViews( true );
05096 for( QValueList<KWView *>::Iterator it = m_lstViews.begin(); it != m_lstViews.end(); ++it )
05097 (*it)->getGUI()->canvasWidget()->ensureCursorVisible();
05098 }
05099
05100 void KWDocument::changeBgSpellCheckingState( bool b )
05101 {
05102 enableBackgroundSpellCheck( b );
05103 reactivateBgSpellChecking();
05104 KConfig *config = KWFactory::instance()->config();
05105 config->setGroup("KSpell kword" );
05106 config->writeEntry( "SpellCheck", (int)b );
05107 }
05108
05109 QString KWDocument::initialFrameSet() const
05110 {
05111 return m_initialEditing ? m_initialEditing->m_initialFrameSet : QString::null;
05112 }
05113
05114 int KWDocument::initialCursorParag() const
05115 {
05116 return m_initialEditing ? m_initialEditing->m_initialCursorParag : 0;
05117 }
05118
05119 int KWDocument::initialCursorIndex() const
05120 {
05121 return m_initialEditing ? m_initialEditing->m_initialCursorIndex : 0;
05122 }
05123
05124 void KWDocument::deleteInitialEditingInfo()
05125 {
05126 delete m_initialEditing;
05127 m_initialEditing = 0L;
05128 }
05129
05130 bool KWDocument::cursorInProtectedArea()const
05131 {
05132 return m_cursorInProtectectedArea;
05133 }
05134
05135 void KWDocument::setCursorInProtectedArea( bool b )
05136 {
05137 m_cursorInProtectectedArea=b;
05138 testAndCloseAllFrameSetProtectedContent();
05139 }
05140
05141
05142 void KWDocument::testAndCloseAllFrameSetProtectedContent()
05143 {
05144 if ( !m_cursorInProtectectedArea )
05145 {
05146 for( QValueList<KWView *>::Iterator it = m_lstViews.begin(); it != m_lstViews.end(); ++it )
05147 (*it)->testAndCloseAllFrameSetProtectedContent();
05148 }
05149 }
05150
05151 void KWDocument::updateRulerInProtectContentMode()
05152 {
05153 for( QValueList<KWView *>::const_iterator it = m_lstViews.begin(); it != m_lstViews.end(); ++it )
05154 (*it)->updateRulerInProtectContentMode();
05155 }
05156
05157
05158 void KWDocument::insertBookmark( const QString &name, KoTextParag *startparag, KoTextParag *endparag, int start, int end )
05159 {
05160 m_bookmarkList->append( KoTextBookmark( name, startparag, endparag, start, end ) );
05161 }
05162
05163 void KWDocument::deleteBookmark( const QString &name )
05164 {
05165 if ( m_bookmarkList->removeByName( name ) )
05166 setModified(true);
05167 }
05168
05169 void KWDocument::renameBookmark( const QString &oldName, const QString &newName )
05170 {
05171 if ( oldName == newName )
05172 return;
05173
05174 KoTextBookmarkList::iterator it = m_bookmarkList->findByName( oldName );
05175 if ( it != m_bookmarkList->end() )
05176 {
05177 (*it).setBookmarkName( newName );
05178 setModified(true);
05179 }
05180 }
05181
05182 const KoTextBookmark * KWDocument::bookmarkByName( const QString & name ) const
05183 {
05184 KoTextBookmarkList::const_iterator it = m_bookmarkList->findByName( name );
05185 if ( it != m_bookmarkList->end() )
05186 return &(*it);
05187 return 0;
05188 }
05189
05190 QStringList KWDocument::listOfBookmarkName( KWViewMode * viewMode ) const
05191 {
05192 QStringList list;
05193 KoTextBookmarkList::const_iterator it = m_bookmarkList->begin();
05194 const KoTextBookmarkList::const_iterator end = m_bookmarkList->end();
05195 for ( ; it != end ; ++it )
05196 {
05197 const KoTextBookmark& book = *it;
05198 KWFrameSet* fs = static_cast<KWTextDocument *>(book.textDocument())->textFrameSet();
05199 if ( fs->isVisible( viewMode ) && !fs->isDeleted() )
05200 list.append( book.bookmarkName() );
05201 }
05202 return list;
05203 }
05204
05205 void KWDocument::paragraphModified(KoTextParag* , int , int , int )
05206 {
05207
05208 emit docStructureChanged( Tables | TextFrames );
05209 }
05210
05211
05212 void KWDocument::paragraphDeleted( KoTextParag *parag, KWFrameSet *frm )
05213 {
05214 KWTextFrameSet* textfs = dynamic_cast<KWTextFrameSet *>( frm );
05215 if ( textfs )
05216 {
05217
05218
05219
05220 KoTextBookmarkList::iterator it = m_bookmarkList->begin();
05221 const KoTextBookmarkList::iterator end = m_bookmarkList->end();
05222 for ( ; it != end ; ++it )
05223 {
05224 KoTextBookmark& book = *it;
05225
05226
05227
05228 if ( book.startParag() == parag )
05229 book.setStartParag( parag->next() ? parag->next() : parag->prev() );
05230 if ( book.endParag() == parag )
05231 book.setEndParag( parag->next() ? parag->next() : parag->prev() );
05232 }
05233 }
05234 }
05235
05236 void KWDocument::initBookmarkList()
05237 {
05238 Q_ASSERT( m_loadingInfo );
05239 if ( !m_loadingInfo )
05240 return;
05241 KWLoadingInfo::BookMarkList::Iterator it = m_loadingInfo->bookMarkList.begin();
05242 KWLoadingInfo::BookMarkList::Iterator end = m_loadingInfo->bookMarkList.end();
05243 for( ; it != end; ++it )
05244 {
05245 KWFrameSet * fs = 0L;
05246 QString fsName = (*it).frameSetName;
05247 if ( !fsName.isEmpty() )
05248 fs = frameSetByName( fsName );
05249 if ( fs )
05250 {
05251 KWTextFrameSet *frm = dynamic_cast<KWTextFrameSet *>(fs);
05252 if ( frm )
05253 {
05254 KoTextDocument* textdoc = frm->textDocument();
05255 KoTextParag* startparag = textdoc->paragAt( (*it).paragStartIndex );
05256 KoTextParag* endparag = textdoc->paragAt( (*it).paragEndIndex );
05257 if ( startparag && endparag )
05258 {
05259 m_bookmarkList->append( KoTextBookmark( (*it).bookname,
05260 startparag, endparag,
05261 (*it).cursorStartIndex, (*it).cursorEndIndex ) );
05262 }
05263 }
05264 }
05265 }
05266 }
05267
05268 QPixmap* KWDocument::doubleBufferPixmap( const QSize& s )
05269 {
05270 if ( !m_bufPixmap ) {
05271 int w = QABS( s.width() );
05272 int h = QABS( s.height() );
05273 m_bufPixmap = new QPixmap( w, h );
05274 } else {
05275 if ( m_bufPixmap->width() < s.width() ||
05276 m_bufPixmap->height() < s.height() ) {
05277 m_bufPixmap->resize( QMAX( s.width(), m_bufPixmap->width() ),
05278 QMAX( s.height(), m_bufPixmap->height() ) );
05279 }
05280 }
05281
05282 return m_bufPixmap;
05283 }
05284
05285 void KWDocument::maybeDeleteDoubleBufferPixmap()
05286 {
05287 if ( m_bufPixmap && m_bufPixmap->height() * m_bufPixmap->width() > 400*400 )
05288 {
05289 delete m_bufPixmap;
05290 m_bufPixmap = 0L;
05291 }
05292 }
05293
05294 void KWDocument::setPersonalExpressionPath( const QStringList & lst)
05295 {
05296 m_personalExpressionPath = lst;
05297 refreshMenuExpression();
05298 }
05299
05300 void KWDocument::updateDirectCursorButton()
05301 {
05302 for( QValueList<KWView *>::Iterator it = m_lstViews.begin(); it != m_lstViews.end(); ++it )
05303 (*it)->updateDirectCursorButton();
05304 }
05305
05306 void KWDocument::setInsertDirectCursor(bool b)
05307 {
05308 m_bInsertDirectCursor=b;
05309 KConfig *config = KWFactory::instance()->config();
05310 config->setGroup( "Interface" );
05311 config->writeEntry( "InsertDirectCursor", b );
05312 updateDirectCursorButton();
05313 }
05314
05315 void KWDocument::saveDialogShown()
05316 {
05317 if ( !textFrameSet(0) )
05318 return;
05319
05320
05321
05322 QString first_row = textFrameSet(0)->textDocument()->plainText().left(50);
05323 bool truncate = false;
05324 QChar ch;
05325 for (int i=0; i < (int)first_row.length(); i++)
05326 {
05327 ch = first_row.at(i);
05328 if (!truncate)
05329 if (ch.isPunct() || ch.isSpace() || ch == '.' )
05330 {
05331 first_row.remove(i,1);
05332 --i;
05333 }
05334 else
05335 truncate = true;
05336 else if ( truncate && (ch.isPunct() || ch == '.' || ch == '\n' ) )
05337 {
05338 first_row.truncate(i);
05339 break;
05340 }
05341 }
05342 first_row = first_row.stripWhiteSpace();
05343 kdDebug() << "Suggested filename:" << first_row << endl;
05344 setURL(first_row);
05345 }
05346
05347 void KWDocument::addWordToDictionary( const QString& word )
05348 {
05349 if ( m_bgSpellCheck )
05350 {
05351 if( m_spellCheckPersonalDict.findIndex( word ) == -1 )
05352 m_spellCheckPersonalDict.append( word );
05353 m_bgSpellCheck->settings()->setCurrentIgnoreList( m_spellCheckIgnoreList + m_spellCheckPersonalDict );
05354 if ( backgroundSpellCheckEnabled() )
05355
05356 reactivateBgSpellChecking();
05357 }
05358 }
05359
05360 void KWDocument::setEmpty()
05361 {
05362 KoDocument::setEmpty();
05363
05364 m_varColl->variableSetting()->setCreationDate(QDateTime::currentDateTime());
05365 recalcVariables( VT_DATE );
05366
05367 }
05368
05369 void KWDocument::updateGridButton()
05370 {
05371 QPtrListIterator<KoView> it( views() );
05372 for (; it.current(); ++it )
05373 ((KWView*)it.current())->updateGridButton();
05374
05375 }
05376
05377 unsigned int KWDocument::paperHeight(int pageNum) const {
05378 return static_cast<unsigned int>(zoomItY( pageManager()->pageLayout(pageNum).ptHeight ));
05379 }
05380
05381 unsigned int KWDocument::paperWidth(int pageNum) const {
05382 return static_cast<unsigned int>(zoomItX( pageManager()->pageLayout(pageNum).ptWidth ));
05383 }
05384
05385 unsigned int KWDocument::pageTop( int pgNum ) const {
05386 return zoomItY( pageManager()->topOfPage( pgNum ) );
05387 }
05388
05389 int KWDocument::pageCount() const {
05390 return pageManager()->pageCount();
05391 }
05392
05393 int KWDocument::startPage() const {
05394 return pageManager()->startPage();
05395 }
05396 int KWDocument::lastPage() const {
05397 return pageManager()->lastPageNumber();
05398 }
05399
05400 QWidget* KWDocument::createCustomDocumentWidget(QWidget *parent) {
05401 KoColumns columns;
05402 columns.columns = 1;
05403 columns.ptColumnSpacing = m_defaultColumnSpacing;
05404 return new KWStartupWidget(parent, this, columns);
05405 }
05406
05407 KWDocument::FramesChangedHandler::FramesChangedHandler(KWDocument *parent) {
05408 m_parent = parent;
05409 m_needLayout = false;
05410 }
05411
05412 void KWDocument::FramesChangedHandler::addFrame(KWFrame *frame) {
05413 if(frame == 0) return;
05414 if(m_frameSets.contains(frame->frameSet())) return;
05415 m_frameSets.append(frame->frameSet());
05416 if( frame->runAround() != KWFrame::RA_NO )
05417 m_needLayout = true;
05418 }
05419
05420 void KWDocument::FramesChangedHandler::addFrameSet(KWFrameSet *fs) {
05421 if(m_frameSets.contains(fs)) return;
05422 m_frameSets.append(fs);
05423 m_needLayout = true;
05424 }
05425
05426 void KWDocument::FramesChangedHandler::execute() {
05427 if(m_frameSets.count() == 0)
05428 m_parent->updateAllFrames();
05429 else {
05430 QValueListIterator<KWFrameSet*> iter = m_frameSets.begin();
05431 for(;iter != m_frameSets.end(); ++iter) {
05432 KWFrameSet *fs = *iter;
05433 fs->updateFrames();
05434 if(!m_needLayout)
05435 fs->layout();
05436 }
05437
05438 KWFrameList::recalcAllFrames(m_parent);
05439 }
05440
05441
05442 if ( m_needLayout)
05443 m_parent->layout();
05444
05445 m_parent->repaintAllViews();
05446 m_parent->updateRulerFrameStartEnd();
05447 }
05448
05449 #include "KWDocument.moc"