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