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