diff options
Diffstat (limited to 'sw/source/core/doc/doc.cxx')
-rw-r--r-- | sw/source/core/doc/doc.cxx | 2742 |
1 files changed, 2742 insertions, 0 deletions
diff --git a/sw/source/core/doc/doc.cxx b/sw/source/core/doc/doc.cxx new file mode 100644 index 000000000000..e9ea7e9f30b0 --- /dev/null +++ b/sw/source/core/doc/doc.cxx @@ -0,0 +1,2742 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sw.hxx" + +#include <doc.hxx> +#include <UndoManager.hxx> +#include <hintids.hxx> + +#include <tools/shl.hxx> +#include <tools/globname.hxx> +#include <svx/svxids.hrc> +#include <com/sun/star/i18n/WordType.hdl> +#include <com/sun/star/i18n/ForbiddenCharacters.hdl> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/beans/NamedValue.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp> +#include <com/sun/star/document/XDocumentProperties.hpp> +#include <comphelper/processfactory.hxx> +#include <tools/urlobj.hxx> +#include <tools/poly.hxx> +#include <tools/multisel.hxx> +#include <rtl/ustring.hxx> +#include <vcl/virdev.hxx> +#include <svl/itemiter.hxx> +#include <svl/poolitem.hxx> +#include <unotools/syslocale.hxx> +#include <sfx2/printer.hxx> +#include <editeng/keepitem.hxx> +#include <editeng/cscoitem.hxx> +#include <editeng/brkitem.hxx> +#include <sfx2/linkmgr.hxx> +#include <editeng/forbiddencharacterstable.hxx> +#include <svx/svdmodel.hxx> +#include <editeng/pbinitem.hxx> +#include <unotools/charclass.hxx> +#include <unotools/localedatawrapper.hxx> + +#include <swatrset.hxx> +#include <swmodule.hxx> +#include <fmtpdsc.hxx> +#include <fmtanchr.hxx> +#include <fmtrfmrk.hxx> +#include <fmtinfmt.hxx> +#include <fmtfld.hxx> +#include <txtfld.hxx> +#include <dbfld.hxx> +#include <txtinet.hxx> +#include <txtrfmrk.hxx> +#include <frmatr.hxx> +#include <linkenum.hxx> +#include <pagefrm.hxx> +#include <rootfrm.hxx> +#include <swtable.hxx> +#include <pam.hxx> +#include <ndtxt.hxx> +#include <swundo.hxx> // fuer die UndoIds +#include <UndoCore.hxx> +#include <UndoInsert.hxx> +#include <UndoSplitMove.hxx> +#include <UndoTable.hxx> +#include <pagedesc.hxx> //DTor +#include <breakit.hxx> +#include <ndole.hxx> +#include <ndgrf.hxx> +#include <rolbck.hxx> // Undo-Attr +#include <doctxm.hxx> // fuer die Verzeichnisse +#include <grfatr.hxx> +#include <poolfmt.hxx> // PoolVorlagen-Id's +#include <mvsave.hxx> // fuer Server-Funktionalitaet +#include <SwGrammarMarkUp.hxx> +#include <scriptinfo.hxx> +#include <acorrect.hxx> // Autokorrektur +#include <mdiexp.hxx> // Statusanzeige +#include <docstat.hxx> +#include <docary.hxx> +#include <redline.hxx> +#include <fldupde.hxx> +#include <swbaslnk.hxx> +#include <printdata.hxx> +#include <cmdid.h> // fuer den dflt - Printer in SetJob +#include <statstr.hrc> // StatLine-String +#include <comcore.hrc> +#include <SwUndoTOXChange.hxx> +#include <SwUndoFmt.hxx> +#include <unocrsr.hxx> +#include <docsh.hxx> +#include <viewopt.hxx> +#include <docfld.hxx> // _SetGetExpFld +#include <docufld.hxx> // SwPostItField +#include <viewsh.hxx> +#include <shellres.hxx> +#include <txtfrm.hxx> +#include <attrhint.hxx> + +#include <wdocsh.hxx> // SwWebDocShell +#include <prtopt.hxx> // SwPrintOptions + +#include <vector> +#include <map> + +#include <osl/diagnose.h> +#include <osl/interlck.h> +#include <vbahelper/vbaaccesshelper.hxx> + +#include "switerator.hxx" + +/* @@@MAINTAINABILITY-HORROR@@@ + Probably unwanted dependency on SwDocShell +*/ +#include <layouter.hxx> + +using namespace ::com::sun::star; +using ::rtl::OUString; + +// Seiten-Deskriptoren +SV_IMPL_PTRARR(SwPageDescs,SwPageDescPtr); +// Verzeichnisse +SV_IMPL_PTRARR( SwTOXTypes, SwTOXTypePtr ) +// FeldTypen +SV_IMPL_PTRARR( SwFldTypes, SwFldTypePtr) + +/* IInterface */ +sal_Int32 SwDoc::acquire() +{ + OSL_ENSURE(mReferenceCount >= 0, "Negative reference count detected! This is a sign for unbalanced acquire/release calls."); + return osl_incrementInterlockedCount(&mReferenceCount); +} + +sal_Int32 SwDoc::release() +{ + OSL_PRECOND(mReferenceCount >= 1, "Object is already released! Releasing it again leads to a negative reference count."); + return osl_decrementInterlockedCount(&mReferenceCount); +} + +sal_Int32 SwDoc::getReferenceCount() const +{ + OSL_ENSURE(mReferenceCount >= 0, "Negative reference count detected! This is a sign for unbalanced acquire/release calls."); + return mReferenceCount; +} + +/* IDocumentSettingAccess */ +bool SwDoc::get(/*[in]*/ DocumentSettingId id) const +{ + switch (id) + { + // COMPATIBILITY FLAGS START + case PARA_SPACE_MAX: return mbParaSpaceMax; //(n8Dummy1 & DUMMY_PARASPACEMAX); + case PARA_SPACE_MAX_AT_PAGES: return mbParaSpaceMaxAtPages; //(n8Dummy1 & DUMMY_PARASPACEMAX_AT_PAGES); + case TAB_COMPAT: return mbTabCompat; //(n8Dummy1 & DUMMY_TAB_COMPAT); + case ADD_FLY_OFFSETS: return mbAddFlyOffsets; //(n8Dummy2 & DUMMY_ADD_FLY_OFFSETS); + case ADD_EXT_LEADING: return mbAddExternalLeading; //(n8Dummy2 & DUMMY_ADD_EXTERNAL_LEADING); + case USE_VIRTUAL_DEVICE: return mbUseVirtualDevice; //(n8Dummy1 & DUMMY_USE_VIRTUAL_DEVICE); + case USE_HIRES_VIRTUAL_DEVICE: return mbUseHiResolutionVirtualDevice; //(n8Dummy2 & DUMMY_USE_HIRES_VIR_DEV); + case OLD_NUMBERING: return mbOldNumbering; + case OLD_LINE_SPACING: return mbOldLineSpacing; + case ADD_PARA_SPACING_TO_TABLE_CELLS: return mbAddParaSpacingToTableCells; + case USE_FORMER_OBJECT_POS: return mbUseFormerObjectPos; + case USE_FORMER_TEXT_WRAPPING: return mbUseFormerTextWrapping; + case CONSIDER_WRAP_ON_OBJECT_POSITION: return mbConsiderWrapOnObjPos; + case DO_NOT_JUSTIFY_LINES_WITH_MANUAL_BREAK: return mbDoNotJustifyLinesWithManualBreak; + case IGNORE_FIRST_LINE_INDENT_IN_NUMBERING: return mbIgnoreFirstLineIndentInNumbering; + case OUTLINE_LEVEL_YIELDS_OUTLINE_RULE: return mbOutlineLevelYieldsOutlineRule; + case TABLE_ROW_KEEP: return mbTableRowKeep; + case IGNORE_TABS_AND_BLANKS_FOR_LINE_CALCULATION: return mbIgnoreTabsAndBlanksForLineCalculation; + case DO_NOT_CAPTURE_DRAW_OBJS_ON_PAGE: return mbDoNotCaptureDrawObjsOnPage; + // #i68949# + case CLIP_AS_CHARACTER_ANCHORED_WRITER_FLY_FRAME: return mbClipAsCharacterAnchoredWriterFlyFrames; + case UNIX_FORCE_ZERO_EXT_LEADING: return mbUnixForceZeroExtLeading; + case USE_OLD_PRINTER_METRICS: return mbOldPrinterMetrics; + case TABS_RELATIVE_TO_INDENT : return mbTabRelativeToIndent; + case PROTECT_FORM: return mbProtectForm; + // #i89181# + case TAB_AT_LEFT_INDENT_FOR_PARA_IN_LIST: return mbTabAtLeftIndentForParagraphsInList; + case INVERT_BORDER_SPACING: return mbInvertBorderSpacing; + case COLLAPSE_EMPTY_CELL_PARA: return mbCollapseEmptyCellPara; + case SMALL_CAPS_PERCENTAGE_66: return mbSmallCapsPercentage66; + + case BROWSE_MODE: return mbLastBrowseMode; // Attention: normally the ViewShell has to be asked! + case HTML_MODE: return mbHTMLMode; + case GLOBAL_DOCUMENT: return mbIsGlobalDoc; + case GLOBAL_DOCUMENT_SAVE_LINKS: return mbGlblDocSaveLinks; + case LABEL_DOCUMENT: return mbIsLabelDoc; + case PURGE_OLE: return mbPurgeOLE; + case KERN_ASIAN_PUNCTUATION: return mbKernAsianPunctuation; + case DO_NOT_RESET_PARA_ATTRS_FOR_NUM_FONT: return mbDoNotResetParaAttrsForNumFont; + case MATH_BASELINE_ALIGNMENT: return mbMathBaselineAlignment; + default: + OSL_FAIL("Invalid setting id"); + } + return false; +} + +void SwDoc::set(/*[in]*/ DocumentSettingId id, /*[in]*/ bool value) +{ + switch (id) + { + // COMPATIBILITY FLAGS START + case PARA_SPACE_MAX: + mbParaSpaceMax = value; + break; + case PARA_SPACE_MAX_AT_PAGES: + mbParaSpaceMaxAtPages = value; + break; + case TAB_COMPAT: + mbTabCompat = value; + break; + case ADD_FLY_OFFSETS: + mbAddFlyOffsets = value; + break; + case ADD_EXT_LEADING: + mbAddExternalLeading = value; + break; + case USE_VIRTUAL_DEVICE: + mbUseVirtualDevice = value; + break; + case USE_HIRES_VIRTUAL_DEVICE: + mbUseHiResolutionVirtualDevice = value; + break; + case OLD_NUMBERING: + if (mbOldNumbering != value) + { + mbOldNumbering = value; + + const SwNumRuleTbl& rNmTbl = GetNumRuleTbl(); + for( sal_uInt16 n = 0; n < rNmTbl.Count(); ++n ) + rNmTbl[n]->SetInvalidRule(sal_True); + + UpdateNumRule(); + + if (pOutlineRule) + { + pOutlineRule->Validate(); + // counting of phantoms depends on <IsOldNumbering()> + pOutlineRule->SetCountPhantoms( !mbOldNumbering ); + } + } + break; + case OLD_LINE_SPACING: + mbOldLineSpacing = value; + break; + case ADD_PARA_SPACING_TO_TABLE_CELLS: + mbAddParaSpacingToTableCells = value; + break; + case USE_FORMER_OBJECT_POS: + mbUseFormerObjectPos = value; + break; + case USE_FORMER_TEXT_WRAPPING: + mbUseFormerTextWrapping = value; + break; + case CONSIDER_WRAP_ON_OBJECT_POSITION: + mbConsiderWrapOnObjPos = value; + break; + case DO_NOT_JUSTIFY_LINES_WITH_MANUAL_BREAK: + mbDoNotJustifyLinesWithManualBreak = value; + break; + case IGNORE_FIRST_LINE_INDENT_IN_NUMBERING: + mbIgnoreFirstLineIndentInNumbering = value; + break; + + case OUTLINE_LEVEL_YIELDS_OUTLINE_RULE: + mbOutlineLevelYieldsOutlineRule = value; + break; + + case TABLE_ROW_KEEP: + mbTableRowKeep = value; + break; + + case IGNORE_TABS_AND_BLANKS_FOR_LINE_CALCULATION: + mbIgnoreTabsAndBlanksForLineCalculation = value; + break; + + case DO_NOT_CAPTURE_DRAW_OBJS_ON_PAGE: + mbDoNotCaptureDrawObjsOnPage = value; + break; + + // #i68949# + case CLIP_AS_CHARACTER_ANCHORED_WRITER_FLY_FRAME: + mbClipAsCharacterAnchoredWriterFlyFrames = value; + break; + + case UNIX_FORCE_ZERO_EXT_LEADING: + mbUnixForceZeroExtLeading = value; + break; + + case PROTECT_FORM: + mbProtectForm = value; + break; + + case USE_OLD_PRINTER_METRICS: + mbOldPrinterMetrics = value; + break; + case TABS_RELATIVE_TO_INDENT: + mbTabRelativeToIndent = value; + break; + // #i89181# + case TAB_AT_LEFT_INDENT_FOR_PARA_IN_LIST: + mbTabAtLeftIndentForParagraphsInList = value; + break; + + case INVERT_BORDER_SPACING: + mbInvertBorderSpacing = value; + break; + + case COLLAPSE_EMPTY_CELL_PARA: + mbCollapseEmptyCellPara = value; + break; + + case SMALL_CAPS_PERCENTAGE_66: + mbSmallCapsPercentage66 = value; + break; + // COMPATIBILITY FLAGS END + + case BROWSE_MODE: //can be used temporary (load/save) when no ViewShell is avaiable + mbLastBrowseMode = value; + break; + + case HTML_MODE: + mbHTMLMode = value; + break; + + case GLOBAL_DOCUMENT: + mbIsGlobalDoc = value; + break; + + case GLOBAL_DOCUMENT_SAVE_LINKS: + mbGlblDocSaveLinks = value; + break; + + case LABEL_DOCUMENT: + mbIsLabelDoc = value; + break; + + case PURGE_OLE: + mbPurgeOLE = value; + break; + + case KERN_ASIAN_PUNCTUATION: + mbKernAsianPunctuation = value; + break; + + case DO_NOT_RESET_PARA_ATTRS_FOR_NUM_FONT: + mbDoNotResetParaAttrsForNumFont = value; + break; + case MATH_BASELINE_ALIGNMENT: + mbMathBaselineAlignment = value; + break; + default: + OSL_FAIL("Invalid setting id"); + } +} + +const i18n::ForbiddenCharacters* + SwDoc::getForbiddenCharacters(/*[in]*/ sal_uInt16 nLang, /*[in]*/ bool bLocaleData ) const +{ + const i18n::ForbiddenCharacters* pRet = 0; + if( xForbiddenCharsTable.is() ) + pRet = xForbiddenCharsTable->GetForbiddenCharacters( nLang, sal_False ); + if( bLocaleData && !pRet && pBreakIt ) + pRet = &pBreakIt->GetForbidden( (LanguageType)nLang ); + return pRet; +} + +void SwDoc::setForbiddenCharacters(/*[in]*/ sal_uInt16 nLang, + /*[in]*/ const com::sun::star::i18n::ForbiddenCharacters& rFChars ) +{ + if( !xForbiddenCharsTable.is() ) + { + uno::Reference< + lang::XMultiServiceFactory > xMSF = + ::comphelper::getProcessServiceFactory(); + xForbiddenCharsTable = new SvxForbiddenCharactersTable( xMSF ); + } + xForbiddenCharsTable->SetForbiddenCharacters( nLang, rFChars ); + if( pDrawModel ) + { + pDrawModel->SetForbiddenCharsTable( xForbiddenCharsTable ); + if( !mbInReading ) + pDrawModel->ReformatAllTextObjects(); + } + + SwRootFrm* pTmpRoot = GetCurrentLayout(); + if( pTmpRoot && !mbInReading ) + { + pTmpRoot->StartAllAction(); + std::set<SwRootFrm*> aAllLayouts = GetAllLayouts(); + std::for_each( aAllLayouts.begin(), aAllLayouts.end(), std::bind2nd(std::mem_fun(&SwRootFrm::InvalidateAllCntnt), INV_SIZE)); + pTmpRoot->EndAllAction(); + }//swmod 080310 + SetModified(); +} + +rtl::Reference<SvxForbiddenCharactersTable>& SwDoc::getForbiddenCharacterTable() +{ + if( !xForbiddenCharsTable.is() ) + { + uno::Reference< + lang::XMultiServiceFactory > xMSF = + ::comphelper::getProcessServiceFactory(); + xForbiddenCharsTable = new SvxForbiddenCharactersTable( xMSF ); + } + return xForbiddenCharsTable; +} + +const rtl::Reference<SvxForbiddenCharactersTable>& SwDoc::getForbiddenCharacterTable() const +{ + return xForbiddenCharsTable; +} + +sal_uInt16 SwDoc::getLinkUpdateMode( /*[in]*/bool bGlobalSettings ) const +{ + sal_uInt16 nRet = nLinkUpdMode; + if( bGlobalSettings && GLOBALSETTING == nRet ) + nRet = SW_MOD()->GetLinkUpdMode(get(IDocumentSettingAccess::HTML_MODE)); + return nRet; +} + +void SwDoc::setLinkUpdateMode( /*[in]*/sal_uInt16 eMode ) +{ + nLinkUpdMode = eMode; +} + +SwFldUpdateFlags SwDoc::getFieldUpdateFlags( /*[in]*/bool bGlobalSettings ) const +{ + SwFldUpdateFlags eRet = eFldUpdMode; + if( bGlobalSettings && AUTOUPD_GLOBALSETTING == eRet ) + eRet = SW_MOD()->GetFldUpdateFlags(get(IDocumentSettingAccess::HTML_MODE)); + return eRet; +} + +void SwDoc::setFieldUpdateFlags(/*[in]*/SwFldUpdateFlags eMode ) +{ + eFldUpdMode = eMode; +} + +SwCharCompressType SwDoc::getCharacterCompressionType() const +{ + return eChrCmprType; +} + +void SwDoc::setCharacterCompressionType( /*[in]*/SwCharCompressType n ) +{ + if( eChrCmprType != n ) + { + eChrCmprType = n; + if( pDrawModel ) + { + pDrawModel->SetCharCompressType( static_cast<sal_uInt16>(n) ); + if( !mbInReading ) + pDrawModel->ReformatAllTextObjects(); + } + + SwRootFrm* pTmpRoot = GetCurrentLayout(); + if( pTmpRoot && !mbInReading ) + { + pTmpRoot->StartAllAction(); + std::set<SwRootFrm*> aAllLayouts = GetAllLayouts(); + std::for_each( aAllLayouts.begin(), aAllLayouts.end(), std::bind2nd(std::mem_fun(&SwRootFrm::InvalidateAllCntnt), INV_SIZE)); + pTmpRoot->EndAllAction(); + }//swmod 080310 + SetModified(); + } +} + +/* IDocumentDeviceAccess */ +SfxPrinter* SwDoc::getPrinter(/*[in]*/ bool bCreate ) const +{ + SfxPrinter* pRet = 0; + if ( !bCreate || pPrt ) + pRet = pPrt; + else + pRet = &CreatePrinter_(); + + return pRet; +} + +void SwDoc::setPrinter(/*[in]*/ SfxPrinter *pP,/*[in]*/ bool bDeleteOld,/*[in]*/ bool bCallPrtDataChanged ) +{ + if ( pP != pPrt ) + { + if ( bDeleteOld ) + delete pPrt; + pPrt = pP; + + // our printer should always use TWIP. Don't rely on this being set in ViewShell::InitPrt, there + // are situations where this isn't called. + // #i108712# / 2010-02-26 / frank.schoenheit@sun.com + if ( pPrt ) + { + MapMode aMapMode( pPrt->GetMapMode() ); + aMapMode.SetMapUnit( MAP_TWIP ); + pPrt->SetMapMode( aMapMode ); + } + + if ( pDrawModel && !get( IDocumentSettingAccess::USE_VIRTUAL_DEVICE ) ) + pDrawModel->SetRefDevice( pPrt ); + } + + if ( bCallPrtDataChanged && + // #i41075# Do not call PrtDataChanged() if we do not + // use the printer for formatting: + !get(IDocumentSettingAccess::USE_VIRTUAL_DEVICE) ) + PrtDataChanged(); +} + +VirtualDevice* SwDoc::getVirtualDevice(/*[in]*/ bool bCreate ) const +{ + VirtualDevice* pRet = 0; + if ( !bCreate || pVirDev ) + pRet = pVirDev; + else + pRet = &CreateVirtualDevice_(); + + return pRet; +} + +void SwDoc::setVirtualDevice(/*[in]*/ VirtualDevice* pVd,/*[in]*/ bool bDeleteOld, /*[in]*/ bool ) +{ + if ( pVirDev != pVd ) + { + if ( bDeleteOld ) + delete pVirDev; + pVirDev = pVd; + + if ( pDrawModel && get( IDocumentSettingAccess::USE_VIRTUAL_DEVICE ) ) + pDrawModel->SetRefDevice( pVirDev ); + } +} + +OutputDevice* SwDoc::getReferenceDevice(/*[in]*/ bool bCreate ) const +{ + OutputDevice* pRet = 0; + if ( !get(IDocumentSettingAccess::USE_VIRTUAL_DEVICE) ) + { + pRet = getPrinter( bCreate ); + + if ( bCreate && !pPrt->IsValid() ) + { + pRet = getVirtualDevice( sal_True ); + } + } + else + { + pRet = getVirtualDevice( bCreate ); + } + + return pRet; +} + +void SwDoc::setReferenceDeviceType(/*[in]*/ bool bNewVirtual,/*[in]*/ bool bNewHiRes ) +{ + if ( get(IDocumentSettingAccess::USE_VIRTUAL_DEVICE) != bNewVirtual || + get(IDocumentSettingAccess::USE_HIRES_VIRTUAL_DEVICE) != bNewHiRes ) + { + if ( bNewVirtual ) + { + VirtualDevice* pMyVirDev = getVirtualDevice( true ); + if ( !bNewHiRes ) + pMyVirDev->SetReferenceDevice( VirtualDevice::REFDEV_MODE06 ); + else + pMyVirDev->SetReferenceDevice( VirtualDevice::REFDEV_MODE_MSO1 ); + + if( pDrawModel ) + pDrawModel->SetRefDevice( pMyVirDev ); + } + else + { + // #i41075# + // We have to take care that a printer exists before calling + // PrtDataChanged() in order to prevent that PrtDataChanged() + // triggers this funny situation: + // getReferenceDevice()->getPrinter()->CreatePrinter_() + // ->setPrinter()-> PrtDataChanged() + SfxPrinter* pPrinter = getPrinter( true ); + if( pDrawModel ) + pDrawModel->SetRefDevice( pPrinter ); + } + + set(IDocumentSettingAccess::USE_VIRTUAL_DEVICE, bNewVirtual ); + set(IDocumentSettingAccess::USE_HIRES_VIRTUAL_DEVICE, bNewHiRes ); + PrtDataChanged(); + SetModified(); + } +} + +const JobSetup* SwDoc::getJobsetup() const +{ + return pPrt ? &pPrt->GetJobSetup() : 0; +} + +void SwDoc::setJobsetup(/*[in]*/ const JobSetup &rJobSetup ) +{ + sal_Bool bCheckPageDescs = 0 == pPrt; + sal_Bool bDataChanged = sal_False; + + if ( pPrt ) + { + if ( pPrt->GetName() == rJobSetup.GetPrinterName() ) + { + if ( pPrt->GetJobSetup() != rJobSetup ) + { + pPrt->SetJobSetup( rJobSetup ); + bDataChanged = sal_True; + } + } + else + delete pPrt, pPrt = 0; + } + + if( !pPrt ) + { + //Das ItemSet wird vom Sfx geloescht! + SfxItemSet *pSet = new SfxItemSet( GetAttrPool(), + FN_PARAM_ADDPRINTER, FN_PARAM_ADDPRINTER, + SID_HTML_MODE, SID_HTML_MODE, + SID_PRINTER_NOTFOUND_WARN, SID_PRINTER_NOTFOUND_WARN, + SID_PRINTER_CHANGESTODOC, SID_PRINTER_CHANGESTODOC, + 0 ); + SfxPrinter *p = new SfxPrinter( pSet, rJobSetup ); + if ( bCheckPageDescs ) + setPrinter( p, true, true ); + else + { + pPrt = p; + bDataChanged = sal_True; + } + } + if ( bDataChanged && !get(IDocumentSettingAccess::USE_VIRTUAL_DEVICE) ) + PrtDataChanged(); +} + +const SwPrintData & SwDoc::getPrintData() const +{ + if(!pPrtData) + { + SwDoc * pThis = const_cast< SwDoc * >(this); + pThis->pPrtData = new SwPrintData; + + // SwPrintData should be initialized from the configuration, + // the respective config item is implememted by SwPrintOptions which + // is also derived from SwPrintData + const SwDocShell *pDocSh = GetDocShell(); + DBG_ASSERT( pDocSh, "pDocSh is 0, can't determine if this is a WebDoc or not" ); + bool bWeb = 0 != dynamic_cast< const SwWebDocShell * >(pDocSh); + SwPrintOptions aPrintOptions( bWeb ); + *pThis->pPrtData = aPrintOptions; + } + return *pPrtData; +} + +void SwDoc::setPrintData(/*[in]*/ const SwPrintData& rPrtData ) +{ + if(!pPrtData) + pPrtData = new SwPrintData; + *pPrtData = rPrtData; +} + +/* Implementations the next Interface here */ + +/* + * Dokumenteditieren (Doc-SS) zum Fuellen des Dokuments + * durch den RTF Parser und fuer die EditShell. + */ +void SwDoc::ChgDBData(const SwDBData& rNewData) +{ + if( rNewData != aDBData ) + { + aDBData = rNewData; + SetModified(); + } + GetSysFldType(RES_DBNAMEFLD)->UpdateFlds(); +} + +bool SwDoc::SplitNode( const SwPosition &rPos, bool bChkTableStart ) +{ + SwCntntNode *pNode = rPos.nNode.GetNode().GetCntntNode(); + if(0 == pNode) + return false; + + { + // BUG 26675: DataChanged vorm loeschen verschicken, dann bekommt + // man noch mit, welche Objecte sich im Bereich befinden. + // Danach koennen sie vor/hinter der Position befinden. + SwDataChanged aTmp( this, rPos, 0 ); + } + + SwUndoSplitNode* pUndo = 0; + if (GetIDocumentUndoRedo().DoesUndo()) + { + GetIDocumentUndoRedo().ClearRedo(); + // einfuegen vom Undo-Object, z.Z. nur beim TextNode + if( pNode->IsTxtNode() ) + { + pUndo = new SwUndoSplitNode( this, rPos, bChkTableStart ); + GetIDocumentUndoRedo().AppendUndo(pUndo); + } + } + + //JP 28.01.97: Sonderfall fuer SplitNode am Tabellenanfang: + // steht die am Doc/Fly/Footer/..-Anfang oder direkt + // hinter einer Tabelle, dann fuege davor + // einen Absatz ein + if( bChkTableStart && !rPos.nContent.GetIndex() && pNode->IsTxtNode() ) + { + sal_uLong nPrevPos = rPos.nNode.GetIndex() - 1; + const SwTableNode* pTblNd; + const SwNode* pNd = GetNodes()[ nPrevPos ]; + if( pNd->IsStartNode() && + SwTableBoxStartNode == ((SwStartNode*)pNd)->GetStartNodeType() && + 0 != ( pTblNd = GetNodes()[ --nPrevPos ]->GetTableNode() ) && + ((( pNd = GetNodes()[ --nPrevPos ])->IsStartNode() && + SwTableBoxStartNode != ((SwStartNode*)pNd)->GetStartNodeType() ) + || ( pNd->IsEndNode() && pNd->StartOfSectionNode()->IsTableNode() ) + || pNd->IsCntntNode() )) + { + if( pNd->IsCntntNode() ) + { + //JP 30.04.99 Bug 65660: + // ausserhalb des normalen BodyBereiches gibt es keine + // Seitenumbrueche, also ist das hier kein gueltige + // Bedingung fuers einfuegen eines Absatzes + if( nPrevPos < GetNodes().GetEndOfExtras().GetIndex() ) + pNd = 0; + else + { + // Dann nur, wenn die Tabelle Umbrueche traegt! + const SwFrmFmt* pFrmFmt = pTblNd->GetTable().GetFrmFmt(); + if( SFX_ITEM_SET != pFrmFmt->GetItemState(RES_PAGEDESC, sal_False) && + SFX_ITEM_SET != pFrmFmt->GetItemState( RES_BREAK, sal_False ) ) + pNd = 0; + } + } + + if( pNd ) + { + SwTxtNode* pTxtNd = GetNodes().MakeTxtNode( + SwNodeIndex( *pTblNd ), + GetTxtCollFromPool( RES_POOLCOLL_TEXT )); + if( pTxtNd ) + { + ((SwPosition&)rPos).nNode = pTblNd->GetIndex()-1; + ((SwPosition&)rPos).nContent.Assign( pTxtNd, 0 ); + + // nur im BodyBereich den SeitenUmbruch/-Vorlage umhaengem + if( nPrevPos > GetNodes().GetEndOfExtras().GetIndex() ) + { + SwFrmFmt* pFrmFmt = pTblNd->GetTable().GetFrmFmt(); + const SfxPoolItem *pItem; + if( SFX_ITEM_SET == pFrmFmt->GetItemState( RES_PAGEDESC, + sal_False, &pItem ) ) + { + pTxtNd->SetAttr( *pItem ); + pFrmFmt->ResetFmtAttr( RES_PAGEDESC ); + } + if( SFX_ITEM_SET == pFrmFmt->GetItemState( RES_BREAK, + sal_False, &pItem ) ) + { + pTxtNd->SetAttr( *pItem ); + pFrmFmt->ResetFmtAttr( RES_BREAK ); + } + } + + if( pUndo ) + pUndo->SetTblFlag(); + SetModified(); + return true; + } + } + } + } + + SvULongs aBkmkArr( 15, 15 ); + _SaveCntntIdx( this, rPos.nNode.GetIndex(), rPos.nContent.GetIndex(), + aBkmkArr, SAVEFLY_SPLIT ); + // FIXME: only SwTxtNode has a valid implementation of SplitCntntNode! + OSL_ENSURE(pNode->IsTxtNode(), "splitting non-text node?"); + pNode = pNode->SplitCntntNode( rPos ); + if (pNode) + { + // verschiebe noch alle Bookmarks/TOXMarks/FlyAtCnt + if( aBkmkArr.Count() ) + _RestoreCntntIdx( this, aBkmkArr, rPos.nNode.GetIndex()-1, 0, sal_True ); + + if( IsRedlineOn() || (!IsIgnoreRedline() && pRedlineTbl->Count() )) + { + SwPaM aPam( rPos ); + aPam.SetMark(); + aPam.Move( fnMoveBackward ); + if( IsRedlineOn() ) + AppendRedline( new SwRedline( nsRedlineType_t::REDLINE_INSERT, aPam ), true); + else + SplitRedline( aPam ); + } + } + + SetModified(); + return true; +} + +bool SwDoc::AppendTxtNode( SwPosition& rPos ) +{ + // create new node before EndOfContent + SwTxtNode * pCurNode = rPos.nNode.GetNode().GetTxtNode(); + if( !pCurNode ) + { + // dann kann ja einer angelegt werden! + SwNodeIndex aIdx( rPos.nNode, 1 ); + pCurNode = GetNodes().MakeTxtNode( aIdx, + GetTxtCollFromPool( RES_POOLCOLL_STANDARD )); + } + else + pCurNode = (SwTxtNode*)pCurNode->AppendNode( rPos ); + + rPos.nNode++; + rPos.nContent.Assign( pCurNode, 0 ); + + if (GetIDocumentUndoRedo().DoesUndo()) + { + GetIDocumentUndoRedo().AppendUndo( new SwUndoInsert( rPos.nNode ) ); + } + + if( IsRedlineOn() || (!IsIgnoreRedline() && pRedlineTbl->Count() )) + { + SwPaM aPam( rPos ); + aPam.SetMark(); + aPam.Move( fnMoveBackward ); + if( IsRedlineOn() ) + AppendRedline( new SwRedline( nsRedlineType_t::REDLINE_INSERT, aPam ), true); + else + SplitRedline( aPam ); + } + + SetModified(); + return sal_True; +} + +bool SwDoc::InsertString( const SwPaM &rRg, const String &rStr, + const enum InsertFlags nInsertMode ) +{ + if (GetIDocumentUndoRedo().DoesUndo()) + { + GetIDocumentUndoRedo().ClearRedo(); // AppendUndo not always called! + } + + const SwPosition& rPos = *rRg.GetPoint(); + + if( pACEWord ) // Aufnahme in die Autokorrektur + { + if( 1 == rStr.Len() && pACEWord->IsDeleted() ) + { + pACEWord->CheckChar( rPos, rStr.GetChar( 0 ) ); + } + delete pACEWord, pACEWord = 0; + } + + SwTxtNode *const pNode = rPos.nNode.GetNode().GetTxtNode(); + if(!pNode) + { + return false; + } + + SwDataChanged aTmp( rRg, 0 ); + + if (!GetIDocumentUndoRedo().DoesUndo() || + !GetIDocumentUndoRedo().DoesGroupUndo()) + { + pNode->InsertText( rStr, rPos.nContent, nInsertMode ); + + if (GetIDocumentUndoRedo().DoesUndo()) + { + SwUndoInsert * const pUndo( new SwUndoInsert( + rPos.nNode, rPos.nContent.GetIndex(), rStr.Len(), nInsertMode)); + GetIDocumentUndoRedo().AppendUndo(pUndo); + } + } + else + { // ist Undo und Gruppierung eingeschaltet, ist alles anders ! + SwUndoInsert * pUndo = NULL; + + // don't group the start if hints at the start should be expanded + if (!(nInsertMode & IDocumentContentOperations::INS_FORCEHINTEXPAND)) + { + SwUndo *const pLastUndo = GetUndoManager().GetLastUndo(); + SwUndoInsert *const pUndoInsert( + dynamic_cast<SwUndoInsert *>(pLastUndo) ); + if (pUndoInsert && pUndoInsert->CanGrouping(rPos)) + { + pUndo = pUndoInsert; + } + } + + CharClass const& rCC = GetAppCharClass(); + xub_StrLen nInsPos = rPos.nContent.GetIndex(); + + if (!pUndo) + { + pUndo = new SwUndoInsert( rPos.nNode, nInsPos, 0, nInsertMode, + !rCC.isLetterNumeric( rStr, 0 ) ); + GetIDocumentUndoRedo().AppendUndo( pUndo ); + } + + pNode->InsertText( rStr, rPos.nContent, nInsertMode ); + + for( xub_StrLen i = 0; i < rStr.Len(); ++i ) + { + nInsPos++; + // wenn CanGrouping() sal_True returnt, ist schon alles erledigt + if( !pUndo->CanGrouping( rStr.GetChar( i ) )) + { + pUndo = new SwUndoInsert( rPos.nNode, nInsPos, 1, nInsertMode, + !rCC.isLetterNumeric( rStr, i ) ); + GetIDocumentUndoRedo().AppendUndo( pUndo ); + } + } + } + + if( IsRedlineOn() || (!IsIgnoreRedline() && pRedlineTbl->Count() )) + { + SwPaM aPam( rPos.nNode, aTmp.GetCntnt(), + rPos.nNode, rPos.nContent.GetIndex()); + if( IsRedlineOn() ) + { + AppendRedline( + new SwRedline( nsRedlineType_t::REDLINE_INSERT, aPam ), true); + } + else + { + SplitRedline( aPam ); + } + } + + SetModified(); + return true; +} + +SwFlyFrmFmt* SwDoc::_InsNoTxtNode( const SwPosition& rPos, SwNoTxtNode* pNode, + const SfxItemSet* pFlyAttrSet, + const SfxItemSet* pGrfAttrSet, + SwFrmFmt* pFrmFmt) +{ + SwFlyFrmFmt *pFmt = 0; + if( pNode ) + { + pFmt = _MakeFlySection( rPos, *pNode, FLY_AT_PARA, + pFlyAttrSet, pFrmFmt ); + if( pGrfAttrSet ) + pNode->SetAttr( *pGrfAttrSet ); + } + return pFmt; +} + +SwFlyFrmFmt* SwDoc::Insert( const SwPaM &rRg, + const String& rGrfName, + const String& rFltName, + const Graphic* pGraphic, + const SfxItemSet* pFlyAttrSet, + const SfxItemSet* pGrfAttrSet, + SwFrmFmt* pFrmFmt ) +{ + if( !pFrmFmt ) + pFrmFmt = GetFrmFmtFromPool( RES_POOLFRM_GRAPHIC ); + return _InsNoTxtNode( *rRg.GetPoint(), GetNodes().MakeGrfNode( + SwNodeIndex( GetNodes().GetEndOfAutotext() ), + rGrfName, rFltName, pGraphic, + pDfltGrfFmtColl ), + pFlyAttrSet, pGrfAttrSet, pFrmFmt ); +} + +SwFlyFrmFmt* SwDoc::Insert( const SwPaM &rRg, const GraphicObject& rGrfObj, + const SfxItemSet* pFlyAttrSet, + const SfxItemSet* pGrfAttrSet, + SwFrmFmt* pFrmFmt ) +{ + if( !pFrmFmt ) + pFrmFmt = GetFrmFmtFromPool( RES_POOLFRM_GRAPHIC ); + return _InsNoTxtNode( *rRg.GetPoint(), GetNodes().MakeGrfNode( + SwNodeIndex( GetNodes().GetEndOfAutotext() ), + rGrfObj, pDfltGrfFmtColl ), + pFlyAttrSet, pGrfAttrSet, pFrmFmt ); +} + +SwFlyFrmFmt* SwDoc::Insert(const SwPaM &rRg, const svt::EmbeddedObjectRef& xObj, + const SfxItemSet* pFlyAttrSet, + const SfxItemSet* pGrfAttrSet, + SwFrmFmt* pFrmFmt ) +{ + if( !pFrmFmt ) + { + sal_uInt16 nId = RES_POOLFRM_OLE; + SvGlobalName aClassName( xObj->getClassID() ); + if (SotExchange::IsMath(aClassName)) + nId = RES_POOLFRM_FORMEL; + + pFrmFmt = GetFrmFmtFromPool( nId ); + } + return _InsNoTxtNode( *rRg.GetPoint(), GetNodes().MakeOLENode( + SwNodeIndex( GetNodes().GetEndOfAutotext() ), + xObj, + pDfltGrfFmtColl ), + pFlyAttrSet, pGrfAttrSet, + pFrmFmt ); +} + +SwFlyFrmFmt* SwDoc::InsertOLE(const SwPaM &rRg, const String& rObjName, + sal_Int64 nAspect, + const SfxItemSet* pFlyAttrSet, + const SfxItemSet* pGrfAttrSet, + SwFrmFmt* pFrmFmt ) +{ + if( !pFrmFmt ) + pFrmFmt = GetFrmFmtFromPool( RES_POOLFRM_OLE ); + + return _InsNoTxtNode( *rRg.GetPoint(), + GetNodes().MakeOLENode( + SwNodeIndex( GetNodes().GetEndOfAutotext() ), + rObjName, + nAspect, + pDfltGrfFmtColl, + 0 ), + pFlyAttrSet, pGrfAttrSet, + pFrmFmt ); +} + +/************************************************************************* +|* SwDoc::GetFldType() +|* Beschreibung: liefert den am Doc eingerichteten Feldtypen zurueck +*************************************************************************/ +SwFieldType *SwDoc::GetSysFldType( const sal_uInt16 eWhich ) const +{ + for( sal_uInt16 i = 0; i < INIT_FLDTYPES; ++i ) + if( eWhich == (*pFldTypes)[i]->Which() ) + return (*pFldTypes)[i]; + return 0; +} + +/************************************************************************* + * void SetDocStat( const SwDocStat& rStat ); + *************************************************************************/ +void SwDoc::SetDocStat( const SwDocStat& rStat ) +{ + *pDocStat = rStat; +} + +const SwDocStat& SwDoc::GetDocStat() const +{ + return *pDocStat; +} + +struct _PostItFld : public _SetGetExpFld +{ + _PostItFld( const SwNodeIndex& rNdIdx, const SwTxtFld* pFld, const SwIndex* pIdx = 0 ) + : _SetGetExpFld( rNdIdx, pFld, pIdx ) {} + + sal_uInt16 GetPageNo( const StringRangeEnumerator &rRangeEnum, + const std::set< sal_Int32 > &rPossiblePages, + sal_uInt16& rVirtPgNo, sal_uInt16& rLineNo ); + + SwPostItField* GetPostIt() const + { + return (SwPostItField*) GetFld()->GetFld().GetFld(); + } +}; + +sal_uInt16 _PostItFld::GetPageNo( + const StringRangeEnumerator &rRangeEnum, + const std::set< sal_Int32 > &rPossiblePages, + /* out */ sal_uInt16& rVirtPgNo, /* out */ sal_uInt16& rLineNo ) +{ + //Problem: Wenn ein PostItFld in einem Node steht, der von mehr als + //einer Layout-Instanz repraesentiert wird, steht die Frage im Raum, + //ob das PostIt nur ein- oder n-mal gedruck werden soll. + //Wahrscheinlich nur einmal, als Seitennummer soll hier keine Zufaellige + //sondern die des ersten Auftretens des PostIts innerhalb des selektierten + //Bereichs ermittelt werden. + rVirtPgNo = 0; + sal_uInt16 nPos = GetCntnt(); + SwIterator<SwTxtFrm,SwTxtNode> aIter( GetFld()->GetTxtNode() ); + for( SwTxtFrm* pFrm = aIter.First(); pFrm; pFrm = aIter.Next() ) + { + if( pFrm->GetOfst() > nPos || + (pFrm->HasFollow() && pFrm->GetFollow()->GetOfst() <= nPos) ) + continue; + sal_uInt16 nPgNo = pFrm->GetPhyPageNum(); + if( rRangeEnum.hasValue( nPgNo, &rPossiblePages )) + { + rLineNo = (sal_uInt16)(pFrm->GetLineCount( nPos ) + + pFrm->GetAllLines() - pFrm->GetThisLines()); + rVirtPgNo = pFrm->GetVirtPageNum(); + return nPgNo; + } + } + return 0; +} + +bool lcl_GetPostIts( + IDocumentFieldsAccess* pIDFA, + _SetGetExpFlds * pSrtLst ) +{ + bool bHasPostIts = false; + + SwFieldType* pFldType = pIDFA->GetSysFldType( RES_POSTITFLD ); + DBG_ASSERT( pFldType, "kein PostItType ? "); + + if( pFldType->GetDepends() ) + { + // Modify-Object gefunden, trage alle Felder ins Array ein + SwIterator<SwFmtFld,SwFieldType> aIter( *pFldType ); + const SwTxtFld* pTxtFld; + for( SwFmtFld* pFld = aIter.First(); pFld; pFld = aIter.Next() ) + { + if( 0 != ( pTxtFld = pFld->GetTxtFld() ) && + pTxtFld->GetTxtNode().GetNodes().IsDocNodes() ) + { + bHasPostIts = true; + if (pSrtLst) + { + SwNodeIndex aIdx( pTxtFld->GetTxtNode() ); + _PostItFld* pNew = new _PostItFld( aIdx, pTxtFld ); + pSrtLst->Insert( pNew ); + } + else + break; // we just wanted to check for the existence of postits ... + } + } + } + + return bHasPostIts; +} + +static void lcl_FormatPostIt( + IDocumentContentOperations* pIDCO, + SwPaM& aPam, + SwPostItField* pField, + bool bNewPage, bool bIsFirstPostIt, + sal_uInt16 nPageNo, sal_uInt16 nLineNo ) +{ + static char const sTmp[] = " : "; + + DBG_ASSERT( ViewShell::GetShellRes(), "missing ShellRes" ); + + if (bNewPage) + { + pIDCO->InsertPoolItem( aPam, SvxFmtBreakItem( SVX_BREAK_PAGE_AFTER, RES_BREAK ), 0 ); + pIDCO->SplitNode( *aPam.GetPoint(), false ); + } + else if (!bIsFirstPostIt) + { + // add an empty line between different notes + pIDCO->SplitNode( *aPam.GetPoint(), false ); + pIDCO->SplitNode( *aPam.GetPoint(), false ); + } + + String aStr( ViewShell::GetShellRes()->aPostItPage ); + aStr.AppendAscii(sTmp); + + aStr += XubString::CreateFromInt32( nPageNo ); + aStr += ' '; + if( nLineNo ) + { + aStr += ViewShell::GetShellRes()->aPostItLine; + aStr.AppendAscii(sTmp); + aStr += XubString::CreateFromInt32( nLineNo ); + aStr += ' '; + } + aStr += ViewShell::GetShellRes()->aPostItAuthor; + aStr.AppendAscii(sTmp); + aStr += pField->GetPar1(); + aStr += ' '; + SvtSysLocale aSysLocale; + aStr += /*(LocaleDataWrapper&)*/aSysLocale.GetLocaleData().getDate( pField->GetDate() ); + pIDCO->InsertString( aPam, aStr ); + + pIDCO->SplitNode( *aPam.GetPoint(), false ); + aStr = pField->GetPar2(); +#if defined( WNT ) || defined( PM2 ) + // Bei Windows und Co alle CR rausschmeissen + aStr.EraseAllChars( '\r' ); +#endif + pIDCO->InsertString( aPam, aStr ); +} + +// provide the paper tray to use according to the page style in use, +// but do that only if the respective item is NOT just the default item +static sal_Int32 lcl_GetPaperBin( const SwPageFrm *pStartFrm ) +{ + sal_Int32 nRes = -1; + + const SwFrmFmt &rFmt = pStartFrm->GetPageDesc()->GetMaster(); + const SfxPoolItem *pItem = NULL; + SfxItemState eState = rFmt.GetItemState( RES_PAPER_BIN, sal_False, &pItem ); + const SvxPaperBinItem *pPaperBinItem = dynamic_cast< const SvxPaperBinItem * >(pItem); + if (eState > SFX_ITEM_DEFAULT && pPaperBinItem) + nRes = pPaperBinItem->GetValue(); + + return nRes; +} + +void SwDoc::CalculatePagesForPrinting( + const SwRootFrm& rLayout, + /* out */ SwRenderData &rData, + const SwPrintUIOptions &rOptions, + bool bIsPDFExport, + sal_Int32 nDocPageCount ) +{ + const sal_Int32 nContent = rOptions.getIntValue( "PrintContent", 0 ); + const bool bPrintSelection = nContent == 2; + + // properties to take into account when calcualting the set of pages + // (PDF export UI does not allow for selecting left or right pages only) + bool bPrintLeftPages = bIsPDFExport ? true : rOptions.IsPrintLeftPages(); + bool bPrintRightPages = bIsPDFExport ? true : rOptions.IsPrintRightPages(); + // #i103700# printing selections should not allow for automatic inserting empty pages + bool bPrintEmptyPages = bPrintSelection ? false : rOptions.IsPrintEmptyPages( bIsPDFExport ); + + Range aPages( 1, nDocPageCount ); + + MultiSelection aMulti( aPages ); + aMulti.SetTotalRange( Range( 0, RANGE_MAX ) ); + aMulti.Select( aPages ); + + const SwPageFrm *pStPage = dynamic_cast<const SwPageFrm*>( rLayout.Lower() ); + const SwFrm *pEndPage = pStPage; + + sal_uInt16 nFirstPageNo = 0; + sal_uInt16 nLastPageNo = 0; + + for( sal_uInt16 i = 1; i <= (sal_uInt16)aPages.Max(); ++i ) + { + if( i < (sal_uInt16)aPages.Min() ) + { + if( !pStPage->GetNext() ) + break; + pStPage = (SwPageFrm*)pStPage->GetNext(); + pEndPage= pStPage; + } + else if( i == (sal_uInt16)aPages.Min() ) + { + nFirstPageNo = i; + nLastPageNo = nFirstPageNo; + if( !pStPage->GetNext() || (i == (sal_uInt16)aPages.Max()) ) + break; + pEndPage = pStPage->GetNext(); + } + else if( i > (sal_uInt16)aPages.Min() ) + { + nLastPageNo = i; + if( !pEndPage->GetNext() || (i == (sal_uInt16)aPages.Max()) ) + break; + pEndPage = pEndPage->GetNext(); + } + } + + DBG_ASSERT( nFirstPageNo, "first page not found! Should not happen!" ); + if (nFirstPageNo) + { +// HACK: Hier muss von der MultiSelection noch eine akzeptable Moeglichkeit +// geschaffen werden, alle Seiten von Seite x an zu deselektieren. +// Z.B. durch SetTotalRange .... + +// aMulti.Select( Range( nLastPageNo+1, SELECTION_MAX ), sal_False ); + MultiSelection aTmpMulti( Range( 1, nLastPageNo ) ); + long nTmpIdx = aMulti.FirstSelected(); + static long nEndOfSelection = SFX_ENDOFSELECTION; + while ( nEndOfSelection != nTmpIdx && nTmpIdx <= long(nLastPageNo) ) + { + aTmpMulti.Select( nTmpIdx ); + nTmpIdx = aMulti.NextSelected(); + } + aMulti = aTmpMulti; +// Ende des HACKs + + sal_uInt16 nPageNo = nFirstPageNo; + + std::map< sal_Int32, sal_Int32 > &rPrinterPaperTrays = rData.GetPrinterPaperTrays(); + std::set< sal_Int32 > &rValidPages = rData.GetValidPagesSet(); + std::map< sal_Int32, const SwPageFrm * > &rValidStartFrms = rData.GetValidStartFrames(); + rValidPages.clear(); + rValidStartFrms.clear(); + while ( pStPage ) + { + const sal_Bool bRightPg = pStPage->OnRightPage(); + if ( aMulti.IsSelected( nPageNo ) && + ( (bRightPg && bPrintRightPages) || + (!bRightPg && bPrintLeftPages) ) ) + { + // Feature - Print empty pages + if ( bPrintEmptyPages || pStPage->Frm().Height() ) + { + rValidPages.insert( nPageNo ); + rValidStartFrms[ nPageNo ] = pStPage; + + rPrinterPaperTrays[ nPageNo ] = lcl_GetPaperBin( pStPage ); + } + } + + if ( pStPage == pEndPage ) + { + pStPage = 0; + } + else + { ++nPageNo; + pStPage = (SwPageFrm*)pStPage->GetNext(); + } + } + } + + + // + // now that we have identified the valid pages for printing according + // to the print settings we need to get the PageRange to use and + // use both results to get the actual pages to be printed + // (post-it settings need to be taken into account later on!) + // + + // get PageRange value to use + OUString aPageRange; + // #i116085# - adjusting fix for i113919 + if ( !bIsPDFExport ) + { + // PageContent : + // 0 -> print all pages (default if aPageRange is empty) + // 1 -> print range according to PageRange + // 2 -> print selection + if (1 == nContent) + aPageRange = rOptions.getStringValue( "PageRange", OUString() ); + if (2 == nContent) + { + // note that printing selections is actually implemented by copying + // the selection to a new temporary document and printing all of that one. + // Thus for Writer "PrintContent" must never be 2. + // See SwXTextDocument::GetRenderDoc for evaluating if a selection is to be + // printed and for creating the temporary document. + } + + // please note + } + if (aPageRange.getLength() == 0) // empty string -> print all + { + // set page range to print to 'all pages' + aPageRange = OUString::valueOf( (sal_Int32)1 ); + aPageRange += OUString::valueOf( (sal_Unicode)'-'); + aPageRange += OUString::valueOf( nDocPageCount ); + } + rData.SetPageRange( aPageRange ); + + // get vector of pages to print according to PageRange and valid pages set from above + // (result may be an empty vector, for example if the range string is not correct) + StringRangeEnumerator::getRangesFromString( + aPageRange, rData.GetPagesToPrint(), + 1, nDocPageCount, 0, &rData.GetValidPagesSet() ); +} + +void SwDoc::UpdatePagesForPrintingWithPostItData( + /* out */ SwRenderData &rData, + const SwPrintUIOptions &rOptions, + bool /*bIsPDFExport*/, + sal_Int32 nDocPageCount ) +{ + + sal_Int16 nPostItMode = (sal_Int16) rOptions.getIntValue( "PrintAnnotationMode", 0 ); + DBG_ASSERT(nPostItMode == POSTITS_NONE || rData.HasPostItData(), + "print post-its without post-it data?" ); + const sal_uInt16 nPostItCount = rData.HasPostItData() ? rData.m_pPostItFields->Count() : 0; + if (nPostItMode != POSTITS_NONE && nPostItCount > 0) + { + SET_CURR_SHELL( rData.m_pPostItShell ); + + // clear document and move to end of it + SwPaM aPam( rData.m_pPostItDoc->GetNodes().GetEndOfContent() ); + aPam.Move( fnMoveBackward, fnGoDoc ); + aPam.SetMark(); + aPam.Move( fnMoveForward, fnGoDoc ); + rData.m_pPostItDoc->DeleteRange( aPam ); + + const StringRangeEnumerator aRangeEnum( rData.GetPageRange(), 1, nDocPageCount, 0 ); + + // For mode POSTITS_ENDPAGE: + // maps a physical page number to the page number in post-it document that holds + // the first post-it for that physical page . Needed to relate the correct start frames + // from the post-it doc to the physical page of the document + std::map< sal_Int32, sal_Int32 > aPostItLastStartPageNum; + + // add all post-its on valid pages within the the page range to the + // temporary post-it document. + // Since the array of post-it fileds is sorted by page and line number we will + // already get them in the correct order + sal_uInt16 nVirtPg = 0, nLineNo = 0, nLastPageNum = 0, nPhyPageNum = 0; + bool bIsFirstPostIt = true; + for (sal_uInt16 i = 0; i < nPostItCount; ++i) + { + _PostItFld& rPostIt = (_PostItFld&)*(*rData.m_pPostItFields)[ i ]; + nLastPageNum = nPhyPageNum; + nPhyPageNum = rPostIt.GetPageNo( + aRangeEnum, rData.GetValidPagesSet(), nVirtPg, nLineNo ); + if (nPhyPageNum) + { + // need to insert a page break? + // In POSTITS_ENDPAGE mode for each document page the following + // post-it page needs to start on a new page + const bool bNewPage = nPostItMode == POSTITS_ENDPAGE && + !bIsFirstPostIt && nPhyPageNum != nLastPageNum; + + lcl_FormatPostIt( rData.m_pPostItShell->GetDoc(), aPam, + rPostIt.GetPostIt(), bNewPage, bIsFirstPostIt, nVirtPg, nLineNo ); + bIsFirstPostIt = false; + + if (nPostItMode == POSTITS_ENDPAGE) + { + // get the correct number of current pages for the post-it document + rData.m_pPostItShell->CalcLayout(); + const sal_Int32 nPages = rData.m_pPostItShell->GetPageCount(); + aPostItLastStartPageNum[ nPhyPageNum ] = nPages; + } + } + } + + // format post-it doc to get correct number of pages + rData.m_pPostItShell->CalcLayout(); + const sal_Int32 nPostItDocPageCount = rData.m_pPostItShell->GetPageCount(); + + if (nPostItMode == POSTITS_ONLY || nPostItMode == POSTITS_ENDDOC) + { + // now add those post-it pages to the vector of pages to print + // or replace them if only post-its should be printed + + rData.GetPostItStartFrames().clear(); + if (nPostItMode == POSTITS_ENDDOC) + { + // set all values up to number of pages to print currently known to NULL, + // meaning none of the pages currently in the vector is from the + // post-it document, they are the documents pages. + rData.GetPostItStartFrames().resize( rData.GetPagesToPrint().size() ); + } + else if (nPostItMode == POSTITS_ONLY) + { + // no document page to be printed + rData.GetPagesToPrint().clear(); + } + + // now we just need to add the post-it pages to be printed to the end + // of the vector of pages to print and keep the GetValidStartFrames + // data conform with it + sal_Int32 nPageNum = 0; + const SwPageFrm * pPageFrm = (SwPageFrm*)rData.m_pPostItShell->GetLayout()->Lower(); + while( pPageFrm && nPageNum < nPostItDocPageCount ) + { + DBG_ASSERT( pPageFrm, "Empty page frame. How are we going to print this?" ); + ++nPageNum; + rData.GetPagesToPrint().push_back( 0 ); // a page number of 0 indicates this page is from the post-it doc + DBG_ASSERT( pPageFrm, "pPageFrm is NULL!" ); + rData.GetPostItStartFrames().push_back( pPageFrm ); + pPageFrm = (SwPageFrm*)pPageFrm->GetNext(); + } + DBG_ASSERT( nPageNum == nPostItDocPageCount, "unexpected number of pages" ); + } + else if (nPostItMode == POSTITS_ENDPAGE) + { + // the next step is to find all the start frames from the post-it + // document that should be printed for a given physical page of the document + std::map< sal_Int32, std::vector< const SwPageFrm * > > aPhysPageToPostItFrames; + + // ... thus, first collect all post-it doc start frames in a vector + sal_Int32 nPostItPageNum = 0; + std::vector< const SwPageFrm * > aAllPostItStartFrames; + const SwPageFrm * pPageFrm = (SwPageFrm*)rData.m_pPostItShell->GetLayout()->Lower(); + while( pPageFrm && sal_Int32(aAllPostItStartFrames.size()) < nPostItDocPageCount ) + { + DBG_ASSERT( pPageFrm, "Empty page frame. How are we going to print this?" ); + ++nPostItPageNum; + aAllPostItStartFrames.push_back( pPageFrm ); + pPageFrm = (SwPageFrm*)pPageFrm->GetNext(); + } + DBG_ASSERT( sal_Int32(aAllPostItStartFrames.size()) == nPostItDocPageCount, + "unexpected number of frames; does not match number of pages" ); + + // get a map that holds all post-it frames to be printed for a + // given physical page from the document + sal_Int32 nLastStartPageNum = 0; + std::map< sal_Int32, sal_Int32 >::const_iterator aIt; + for (aIt = aPostItLastStartPageNum.begin(); aIt != aPostItLastStartPageNum.end(); ++aIt) + { + const sal_Int32 nFrames = aIt->second - nLastStartPageNum; + const sal_Int32 nFirstStartPageNum = aIt == aPostItLastStartPageNum.begin() ? + 1 : aIt->second - nFrames + 1; + DBG_ASSERT( 1 <= nFirstStartPageNum && nFirstStartPageNum <= nPostItDocPageCount, + "page number for first frame out of range" ); + std::vector< const SwPageFrm * > aStartFrames; + for (sal_Int32 i = 0; i < nFrames; ++i) + { + const sal_Int32 nIdx = nFirstStartPageNum - 1 + i; // -1 because lowest page num is 1 + DBG_ASSERT( 0 <= nIdx && nIdx < sal_Int32(aAllPostItStartFrames.size()), + "index out of range" ); + aStartFrames.push_back( aAllPostItStartFrames[ nIdx ] ); + } + aPhysPageToPostItFrames[ aIt->first /* phys page num */ ] = aStartFrames; + nLastStartPageNum = aIt->second; + } + + + // ok, now that aPhysPageToPostItFrames can give the start frames for all + // post-it pages to be printed we need to merge those at the correct + // position into the GetPagesToPrint vector and build and maintain the + // GetValidStartFrames vector as well. + // Since inserting a larger number of entries in the middle of a vector + // isn't that efficient we will create new vectors by copying the required data + std::vector< sal_Int32 > aTmpPagesToPrint; + std::vector< const SwPageFrm * > aTmpPostItStartFrames; + const size_t nNum = rData.GetPagesToPrint().size(); + for (size_t i = 0 ; i < nNum; ++i) + { + // add the physical page to print from the document + const sal_Int32 nPhysPage = rData.GetPagesToPrint()[i]; + aTmpPagesToPrint.push_back( nPhysPage ); + aTmpPostItStartFrames.push_back( NULL ); + + // add the post-it document pages to print, i.e those + // post-it pages that have the data for the above physical page + const std::vector< const SwPageFrm * > &rPostItFrames = aPhysPageToPostItFrames[ nPhysPage ]; + const size_t nPostItFrames = rPostItFrames.size(); + for (size_t k = 0; k < nPostItFrames; ++k) + { + aTmpPagesToPrint.push_back( 0 ); + aTmpPostItStartFrames.push_back( rPostItFrames[k] ); + } + } + + // finally we need to assign those vectors to the resulting ones. + // swapping the data should be more efficient than assigning since + // we won't need the temporary vectors anymore + rData.GetPagesToPrint().swap( aTmpPagesToPrint ); + rData.GetPostItStartFrames().swap( aTmpPostItStartFrames ); + } + } +} + +void SwDoc::CalculatePagePairsForProspectPrinting( + const SwRootFrm& rLayout, + /* out */ SwRenderData &rData, + const SwPrintUIOptions &rOptions, + sal_Int32 nDocPageCount ) +{ + std::map< sal_Int32, sal_Int32 > &rPrinterPaperTrays = rData.GetPrinterPaperTrays(); + std::set< sal_Int32 > &rValidPagesSet = rData.GetValidPagesSet(); + std::map< sal_Int32, const SwPageFrm * > &rValidStartFrms = rData.GetValidStartFrames(); + std::vector< std::pair< sal_Int32, sal_Int32 > > &rPagePairs = rData.GetPagePairsForProspectPrinting(); + + rPagePairs.clear(); + rValidPagesSet.clear(); + rValidStartFrms.clear(); + + rtl::OUString aPageRange = rOptions.getStringValue( "PageRange", rtl::OUString() ); + // PageContent : + // 0 -> print all pages (default if aPageRange is empty) + // 1 -> print range according to PageRange + // 2 -> print selection + const sal_Int32 nContent = rOptions.getIntValue( "PrintContent", 0 ); + if (0 == nContent) + { + // set page range to print to 'all pages' + aPageRange = OUString::valueOf( (sal_Int32)1 ); + aPageRange += OUString::valueOf( (sal_Unicode)'-'); + aPageRange += OUString::valueOf( nDocPageCount ); + } + StringRangeEnumerator aRange( aPageRange, 1, nDocPageCount, 0 ); + + if ( aRange.size() <= 0) + return; + + const SwPageFrm *pStPage = dynamic_cast<const SwPageFrm*>( rLayout.Lower() ); + sal_Int32 i = 0; + for ( i = 1; pStPage && i < nDocPageCount; ++i ) + pStPage = (SwPageFrm*)pStPage->GetNext(); + if ( !pStPage ) // dann wars das + return; + + // currently for prospect printing all pages are valid to be printed + // thus we add them all to the respective map and set for later use + sal_Int32 nPageNum = 0; + const SwPageFrm *pPageFrm = dynamic_cast<const SwPageFrm*>( rLayout.Lower() ); + while( pPageFrm && nPageNum < nDocPageCount ) + { + DBG_ASSERT( pPageFrm, "Empty page frame. How are we going to print this?" ); + ++nPageNum; + rValidPagesSet.insert( nPageNum ); + rValidStartFrms[ nPageNum ] = pPageFrm; + pPageFrm = (SwPageFrm*)pPageFrm->GetNext(); + + rPrinterPaperTrays[ nPageNum ] = lcl_GetPaperBin( pStPage ); + } + DBG_ASSERT( nPageNum == nDocPageCount, "unexpected number of pages" ); + + // properties to take into account when calcualting the set of pages + // Note: here bPrintLeftPages and bPrintRightPages refer to the (virtual) resulting pages + // of the prospect! + bool bPrintLeftPages = rOptions.IsPrintLeftPages(); + bool bPrintRightPages = rOptions.IsPrintRightPages(); + bool bPrintProspectRTL = rOptions.getIntValue( "PrintProspectRTL", 0 ) ? true : false; + + // get pages for prospect printing according to the 'PageRange' + // (duplicates and any order allowed!) + std::vector< sal_Int32 > aPagesToPrint; + StringRangeEnumerator::getRangesFromString( + aPageRange, aPagesToPrint, 1, nDocPageCount, 0 ); + + // now fill the vector for calculating the page pairs with the start frames + // from the above obtained vector + std::vector< const SwPageFrm * > aVec; + for ( i = 0; i < sal_Int32(aPagesToPrint.size()); ++i) + { + const sal_Int32 nPage = aPagesToPrint[i]; + const SwPageFrm *pFrm = rValidStartFrms[ nPage ]; + aVec.push_back( pFrm ); + } + + // just one page is special ... + if ( 1 == aVec.size() ) + aVec.insert( aVec.begin() + 1, 0 ); // insert a second empty page + else + { + // now extend the number of pages to fit a multiple of 4 + // (4 'normal' pages are needed for a single prospect paper + // with back and front) + while( aVec.size() & 3 ) + aVec.push_back( 0 ); + } + + // dann sorge mal dafuer, das alle Seiten in der richtigen + // Reihenfolge stehen: + sal_uInt16 nSPg = 0, nEPg = aVec.size(), nStep = 1; + if ( 0 == (nEPg & 1 )) // ungerade gibt es nicht! + --nEPg; + + if ( !bPrintLeftPages ) + ++nStep; + else if ( !bPrintRightPages ) + { + ++nStep; + ++nSPg, --nEPg; + } + + // the number of 'virtual' pages to be printed + sal_Int32 nCntPage = (( nEPg - nSPg ) / ( 2 * nStep )) + 1; + + for ( sal_uInt16 nPrintCount = 0; nSPg < nEPg && + nPrintCount < nCntPage; ++nPrintCount ) + { + pStPage = aVec[ nSPg ]; + const SwPageFrm* pNxtPage = nEPg < aVec.size() ? aVec[ nEPg ] : 0; + + short nRtlOfs = bPrintProspectRTL ? 1 : 0; + if ( 0 == (( nSPg + nRtlOfs) & 1 ) ) // switch for odd number in LTR, even number in RTL + { + const SwPageFrm* pTmp = pStPage; + pStPage = pNxtPage; + pNxtPage = pTmp; + } + + sal_Int32 nFirst = -1, nSecond = -1; + for ( int nC = 0; nC < 2; ++nC ) + { + sal_Int32 nPage = -1; + if ( pStPage ) + nPage = pStPage->GetPhyPageNum(); + if (nC == 0) + nFirst = nPage; + else + nSecond = nPage; + + pStPage = pNxtPage; + } + rPagePairs.push_back( std::pair< sal_Int32, sal_Int32 >(nFirst, nSecond) ); + + nSPg = nSPg + nStep; + nEPg = nEPg - nStep; + } + DBG_ASSERT( size_t(nCntPage) == rPagePairs.size(), "size mismatch for number of page pairs" ); + + // luckily prospect printing does not make use of post-its so far, + // thus we are done here. +} + +/************************************************************************* + * void UpdateDocStat( const SwDocStat& rStat ); + *************************************************************************/ +void SwDoc::UpdateDocStat( SwDocStat& rStat ) +{ + if( rStat.bModified ) + { + rStat.Reset(); + rStat.nPara = 0; // Default ist auf 1 !! + SwNode* pNd; + + for( sal_uLong i = GetNodes().Count(); i; ) + { + switch( ( pNd = GetNodes()[ --i ])->GetNodeType() ) + { + case ND_TEXTNODE: + ((SwTxtNode*)pNd)->CountWords( rStat, 0, ((SwTxtNode*)pNd)->GetTxt().Len() ); + break; + case ND_TABLENODE: ++rStat.nTbl; break; + case ND_GRFNODE: ++rStat.nGrf; break; + case ND_OLENODE: ++rStat.nOLE; break; + case ND_SECTIONNODE: break; + } + } + + // #i93174#: notes contain paragraphs that are not nodes + { + SwFieldType * const pPostits( GetSysFldType(RES_POSTITFLD) ); + SwIterator<SwFmtFld,SwFieldType> aIter( *pPostits ); + for( SwFmtFld* pFmtFld = aIter.First(); pFmtFld; pFmtFld = aIter.Next() ) + { + if (pFmtFld->IsFldInDoc()) + { + SwPostItField const * const pField( + static_cast<SwPostItField const*>(pFmtFld->GetFld())); + rStat.nAllPara += pField->GetNumberOfParagraphs(); + } + } + } + + rStat.nPage = GetCurrentLayout() ? GetCurrentLayout()->GetPageNum() : 0; //swmod 080218 + rStat.bModified = sal_False; + SetDocStat( rStat ); + + com::sun::star::uno::Sequence < com::sun::star::beans::NamedValue > aStat( rStat.nPage ? 8 : 7); + sal_Int32 n=0; + aStat[n].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TableCount")); + aStat[n++].Value <<= (sal_Int32)rStat.nTbl; + aStat[n].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ImageCount")); + aStat[n++].Value <<= (sal_Int32)rStat.nGrf; + aStat[n].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ObjectCount")); + aStat[n++].Value <<= (sal_Int32)rStat.nOLE; + if ( rStat.nPage ) + { + aStat[n].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("PageCount")); + aStat[n++].Value <<= (sal_Int32)rStat.nPage; + } + aStat[n].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ParagraphCount")); + aStat[n++].Value <<= (sal_Int32)rStat.nPara; + aStat[n].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("WordCount")); + aStat[n++].Value <<= (sal_Int32)rStat.nWord; + aStat[n].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharacterCount")); + aStat[n++].Value <<= (sal_Int32)rStat.nChar; + aStat[n].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("NonWhitespaceCharacterCount")); + aStat[n++].Value <<= (sal_Int32)rStat.nCharExcludingSpaces; + + // For e.g. autotext documents there is no pSwgInfo (#i79945) + SfxObjectShell * const pObjShell( GetDocShell() ); + if (pObjShell) + { + const uno::Reference<document::XDocumentPropertiesSupplier> xDPS( + pObjShell->GetModel(), uno::UNO_QUERY_THROW); + const uno::Reference<document::XDocumentProperties> xDocProps( + xDPS->getDocumentProperties()); + // #i96786#: do not set modified flag when updating statistics + const bool bDocWasModified( IsModified() ); + const ModifyBlocker_Impl b(pObjShell); + xDocProps->setDocumentStatistics(aStat); + if (!bDocWasModified) + { + ResetModified(); + } + } + + // event. Stat. Felder Updaten + SwFieldType *pType = GetSysFldType(RES_DOCSTATFLD); + pType->UpdateFlds(); + } +} + +// Dokument - Info +void SwDoc::DocInfoChgd( ) +{ + GetSysFldType( RES_DOCINFOFLD )->UpdateFlds(); + GetSysFldType( RES_TEMPLNAMEFLD )->UpdateFlds(); + SetModified(); +} + +// returne zum Namen die im Doc gesetzte Referenz +const SwFmtRefMark* SwDoc::GetRefMark( const String& rName ) const +{ + const SfxPoolItem* pItem; + sal_uInt32 nMaxItems = GetAttrPool().GetItemCount2( RES_TXTATR_REFMARK ); + for( sal_uInt32 n = 0; n < nMaxItems; ++n ) + { + if( 0 == (pItem = GetAttrPool().GetItem2( RES_TXTATR_REFMARK, n ) )) + continue; + + const SwFmtRefMark* pFmtRef = (SwFmtRefMark*)pItem; + const SwTxtRefMark* pTxtRef = pFmtRef->GetTxtRefMark(); + if( pTxtRef && &pTxtRef->GetTxtNode().GetNodes() == &GetNodes() && + rName.Equals( pFmtRef->GetRefName() ) ) + return pFmtRef; + } + return 0; +} + +// returne die RefMark per Index - fuer Uno +const SwFmtRefMark* SwDoc::GetRefMark( sal_uInt16 nIndex ) const +{ + const SfxPoolItem* pItem; + const SwTxtRefMark* pTxtRef; + const SwFmtRefMark* pRet = 0; + + sal_uInt32 nMaxItems = GetAttrPool().GetItemCount2( RES_TXTATR_REFMARK ); + sal_uInt32 nCount = 0; + for( sal_uInt32 n = 0; n < nMaxItems; ++n ) + if( 0 != (pItem = GetAttrPool().GetItem2( RES_TXTATR_REFMARK, n )) && + 0 != (pTxtRef = ((SwFmtRefMark*)pItem)->GetTxtRefMark()) && + &pTxtRef->GetTxtNode().GetNodes() == &GetNodes() ) + { + if(nCount == nIndex) + { + pRet = (SwFmtRefMark*)pItem; + break; + } + nCount++; + } + return pRet; +} + +// returne die Namen aller im Doc gesetzten Referenzen +//JP 24.06.96: Ist der ArrayPointer 0 dann returne nur, ob im Doc. eine +// RefMark gesetzt ist +// OS 25.06.96: ab jetzt wird immer die Anzahl der Referenzen returnt +sal_uInt16 SwDoc::GetRefMarks( SvStringsDtor* pNames ) const +{ + const SfxPoolItem* pItem; + const SwTxtRefMark* pTxtRef; + + sal_uInt32 nMaxItems = GetAttrPool().GetItemCount2( RES_TXTATR_REFMARK ); + sal_uInt32 nCount = 0; + for( sal_uInt32 n = 0; n < nMaxItems; ++n ) + if( 0 != (pItem = GetAttrPool().GetItem2( RES_TXTATR_REFMARK, n )) && + 0 != (pTxtRef = ((SwFmtRefMark*)pItem)->GetTxtRefMark()) && + &pTxtRef->GetTxtNode().GetNodes() == &GetNodes() ) + { + if( pNames ) + { + String* pTmp = new String( ((SwFmtRefMark*)pItem)->GetRefName() ); + pNames->Insert( pTmp, nCount ); + } + nCount ++; + } + + return nCount; +} + +bool SwDoc::IsLoaded() const +{ + return mbLoaded; +} + +bool SwDoc::IsUpdateExpFld() const +{ + return mbUpdateExpFld; +} + +bool SwDoc::IsNewDoc() const +{ + return mbNewDoc; +} + +bool SwDoc::IsPageNums() const +{ + return mbPageNums; +} + +void SwDoc::SetPageNums(bool b) +{ + mbPageNums = b; +} + +void SwDoc::SetNewDoc(bool b) +{ + mbNewDoc = b; +} + +void SwDoc::SetUpdateExpFldStat(bool b) +{ + mbUpdateExpFld = b; +} + +void SwDoc::SetLoaded(bool b) +{ + mbLoaded = b; +} + +bool SwDoc::IsModified() const +{ + return mbModified; +} + +void SwDoc::SetModified() +{ + SwLayouter::ClearMovedFwdFrms( *this ); + SwLayouter::ClearObjsTmpConsiderWrapInfluence( *this ); + SwLayouter::ClearFrmsNotToWrap( *this ); + // #i65250# + SwLayouter::ClearMoveBwdLayoutInfo( *this ); + // dem Link wird der Status returnt, wie die Flags waren und werden + // Bit 0: -> alter Zustand + // Bit 1: -> neuer Zustand + long nCall = mbModified ? 3 : 2; + mbModified = sal_True; + pDocStat->bModified = sal_True; + if( aOle2Link.IsSet() ) + { + mbInCallModified = sal_True; + aOle2Link.Call( (void*)nCall ); + mbInCallModified = sal_False; + } + + if( pACEWord && !pACEWord->IsDeleted() ) + delete pACEWord, pACEWord = 0; +} + +void SwDoc::ResetModified() +{ + // dem Link wird der Status returnt, wie die Flags waren und werden + // Bit 0: -> alter Zustand + // Bit 1: -> neuer Zustand + long nCall = mbModified ? 1 : 0; + mbModified = sal_False; + // If there is already a document statistic, we assume that + // it is correct. In this case we reset the modified flag. + if ( 0 != pDocStat->nCharExcludingSpaces ) + pDocStat->bModified = sal_False; + GetIDocumentUndoRedo().SetUndoNoModifiedPosition(); + if( nCall && aOle2Link.IsSet() ) + { + mbInCallModified = sal_True; + aOle2Link.Call( (void*)nCall ); + mbInCallModified = sal_False; + } +} + +void SwDoc::ReRead( SwPaM& rPam, const String& rGrfName, + const String& rFltName, const Graphic* pGraphic, + const GraphicObject* pGrafObj ) +{ + SwGrfNode *pGrfNd; + if( ( !rPam.HasMark() + || rPam.GetPoint()->nNode.GetIndex() == rPam.GetMark()->nNode.GetIndex() ) + && 0 != ( pGrfNd = rPam.GetPoint()->nNode.GetNode().GetGrfNode() ) ) + { + if (GetIDocumentUndoRedo().DoesUndo()) + { + GetIDocumentUndoRedo().AppendUndo(new SwUndoReRead(rPam, *pGrfNd)); + } + + // Weil nicht bekannt ist, ob sich die Grafik spiegeln laesst, + // immer das SpiegelungsAttribut zuruecksetzen + if( RES_MIRROR_GRAPH_DONT != pGrfNd->GetSwAttrSet(). + GetMirrorGrf().GetValue() ) + pGrfNd->SetAttr( SwMirrorGrf() ); + + pGrfNd->ReRead( rGrfName, rFltName, pGraphic, pGrafObj, sal_True ); + SetModified(); + } +} + +sal_Bool lcl_SpellAndGrammarAgain( const SwNodePtr& rpNd, void* pArgs ) +{ + SwTxtNode *pTxtNode = (SwTxtNode*)rpNd->GetTxtNode(); + sal_Bool bOnlyWrong = *(sal_Bool*)pArgs; + if( pTxtNode ) + { + if( bOnlyWrong ) + { + if( pTxtNode->GetWrong() && + pTxtNode->GetWrong()->InvalidateWrong() ) + pTxtNode->SetWrongDirty( true ); + if( pTxtNode->GetGrammarCheck() && + pTxtNode->GetGrammarCheck()->InvalidateWrong() ) + pTxtNode->SetGrammarCheckDirty( true ); + } + else + { + pTxtNode->SetWrongDirty( true ); + if( pTxtNode->GetWrong() ) + pTxtNode->GetWrong()->SetInvalid( 0, STRING_LEN ); + pTxtNode->SetGrammarCheckDirty( true ); + if( pTxtNode->GetGrammarCheck() ) + pTxtNode->GetGrammarCheck()->SetInvalid( 0, STRING_LEN ); + } + } + return sal_True; +} + +sal_Bool lcl_CheckSmartTagsAgain( const SwNodePtr& rpNd, void* ) +{ + SwTxtNode *pTxtNode = (SwTxtNode*)rpNd->GetTxtNode(); +// sal_Bool bOnlyWrong = *(sal_Bool*)pArgs; + if( pTxtNode ) + { + pTxtNode->SetSmartTagDirty( true ); + if( pTxtNode->GetSmartTags() ) + { +// if ( bOnlyWrong ) // only some smart tag types have been enabled or disabled +// pTxtNode->GetSmartTags()->SetInvalid( 0, STRING_LEN ); +// else // smart tags all have been enabled or disabled + pTxtNode->SetSmartTags( NULL ); + } + } + return sal_True; +} + +/************************************************************************* + * SwDoc::SpellItAgainSam( sal_Bool bInvalid, sal_Bool bOnlyWrong ) + * + * stoesst das Spelling im Idle-Handler wieder an. + * Wird bInvalid als sal_True uebergeben, so werden zusaetzlich die WrongListen + * an allen Nodes invalidiert und auf allen Seiten das SpellInvalid-Flag + * gesetzt. + * Mit bOnlyWrong kann man dann steuern, ob nur die Bereiche mit falschen + * Woertern oder die kompletten Bereiche neu ueberprueft werden muessen. + ************************************************************************/ +void SwDoc::SpellItAgainSam( sal_Bool bInvalid, sal_Bool bOnlyWrong, sal_Bool bSmartTags ) +{ + std::set<SwRootFrm*> aAllLayouts = GetAllLayouts();//swmod 080307 + OSL_ENSURE( GetCurrentLayout(), "SpellAgain: Where's my RootFrm?" ); + if( bInvalid ) + { + std::for_each( aAllLayouts.begin(), aAllLayouts.end(),std::bind2nd(std::mem_fun(&SwRootFrm::AllInvalidateSmartTagsOrSpelling),bSmartTags));//swmod 080305 + std::for_each( aAllLayouts.begin(), aAllLayouts.end(),std::bind2nd(std::mem_fun(&SwRootFrm::SetNeedGrammarCheck), true) ); + if ( bSmartTags ) + GetNodes().ForEach( lcl_CheckSmartTagsAgain, &bOnlyWrong ); + GetNodes().ForEach( lcl_SpellAndGrammarAgain, &bOnlyWrong ); + } + + std::for_each( aAllLayouts.begin(), aAllLayouts.end(),std::mem_fun(&SwRootFrm::SetIdleFlags));//swmod 080307 +} + +void SwDoc::InvalidateAutoCompleteFlag() +{ + SwRootFrm* pTmpRoot = GetCurrentLayout(); + if( pTmpRoot ) + { + std::set<SwRootFrm*> aAllLayouts = GetAllLayouts(); + std::for_each( aAllLayouts.begin(), aAllLayouts.end(),std::mem_fun(&SwRootFrm::AllInvalidateAutoCompleteWords));//swmod 080305 + for( sal_uLong nNd = 1, nCnt = GetNodes().Count(); nNd < nCnt; ++nNd ) + { + SwTxtNode* pTxtNode = GetNodes()[ nNd ]->GetTxtNode(); + if ( pTxtNode ) pTxtNode->SetAutoCompleteWordDirty( true ); + } + + std::for_each( aAllLayouts.begin(), aAllLayouts.end(),std::mem_fun(&SwRootFrm::SetIdleFlags));//swmod 080228 + } //swmod 080219 +} + +const SwFmtINetFmt* SwDoc::FindINetAttr( const String& rName ) const +{ + const SwFmtINetFmt* pItem; + const SwTxtINetFmt* pTxtAttr; + const SwTxtNode* pTxtNd; + sal_uInt32 n, nMaxItems = GetAttrPool().GetItemCount2( RES_TXTATR_INETFMT ); + for( n = 0; n < nMaxItems; ++n ) + if( 0 != (pItem = (SwFmtINetFmt*)GetAttrPool().GetItem2( + RES_TXTATR_INETFMT, n ) ) && + pItem->GetName().Equals( rName ) && + 0 != ( pTxtAttr = pItem->GetTxtINetFmt()) && + 0 != ( pTxtNd = pTxtAttr->GetpTxtNode() ) && + &pTxtNd->GetNodes() == &GetNodes() ) + { + return pItem; + } + + return 0; +} + +void SwDoc::Summary( SwDoc* pExtDoc, sal_uInt8 nLevel, sal_uInt8 nPara, sal_Bool bImpress ) +{ + const SwOutlineNodes& rOutNds = GetNodes().GetOutLineNds(); + if( pExtDoc && rOutNds.Count() ) + { + sal_uInt16 i; + ::StartProgress( STR_STATSTR_SUMMARY, 0, rOutNds.Count(), GetDocShell() ); + SwNodeIndex aEndOfDoc( pExtDoc->GetNodes().GetEndOfContent(), -1 ); + for( i = 0; i < rOutNds.Count(); ++i ) + { + ::SetProgressState( i, GetDocShell() ); + const sal_uLong nIndex = rOutNds[ i ]->GetIndex(); + + const int nLvl = ((SwTxtNode*)GetNodes()[ nIndex ])->GetAttrOutlineLevel()-1;//<-end,zhaojianwei + if( nLvl > nLevel ) + continue; + sal_uInt16 nEndOfs = 1; + sal_uInt8 nWish = nPara; + sal_uLong nNextOutNd = i + 1 < rOutNds.Count() ? + rOutNds[ i + 1 ]->GetIndex() : GetNodes().Count(); + sal_Bool bKeep = sal_False; + while( ( nWish || bKeep ) && nIndex + nEndOfs < nNextOutNd && + GetNodes()[ nIndex + nEndOfs ]->IsTxtNode() ) + { + SwTxtNode* pTxtNode = (SwTxtNode*)GetNodes()[ nIndex+nEndOfs ]; + if( pTxtNode->GetTxt().Len() && nWish ) + --nWish; + bKeep = pTxtNode->GetSwAttrSet().GetKeep().GetValue(); + ++nEndOfs; + } + + SwNodeRange aRange( *rOutNds[ i ], 0, *rOutNds[ i ], nEndOfs ); + GetNodes()._Copy( aRange, aEndOfDoc ); + } + const SwTxtFmtColls *pColl = pExtDoc->GetTxtFmtColls(); + for( i = 0; i < pColl->Count(); ++i ) + (*pColl)[ i ]->ResetFmtAttr( RES_PAGEDESC, RES_BREAK ); + SwNodeIndex aIndx( pExtDoc->GetNodes().GetEndOfExtras() ); + ++aEndOfDoc; + while( aIndx < aEndOfDoc ) + { + SwNode *pNode; + sal_Bool bDelete = sal_False; + if( (pNode = &aIndx.GetNode())->IsTxtNode() ) + { + SwTxtNode *pNd = (SwTxtNode*)pNode; + if( pNd->HasSwAttrSet() ) + pNd->ResetAttr( RES_PAGEDESC, RES_BREAK ); + if( bImpress ) + { + SwTxtFmtColl* pMyColl = pNd->GetTxtColl(); + + const sal_uInt16 nHeadLine = static_cast<sal_uInt16>( + !pMyColl->IsAssignedToListLevelOfOutlineStyle() //<-end,zhaojianwei + ? RES_POOLCOLL_HEADLINE2 + : RES_POOLCOLL_HEADLINE1 ); + pMyColl = pExtDoc->GetTxtCollFromPool( nHeadLine ); + pNd->ChgFmtColl( pMyColl ); + } + if( !pNd->Len() && + pNd->StartOfSectionIndex()+2 < pNd->EndOfSectionIndex() ) + { + bDelete = sal_True; + pExtDoc->GetNodes().Delete( aIndx ); + } + } + if( !bDelete ) + ++aIndx; + } + ::EndProgress( GetDocShell() ); + } +} + +// loesche den nicht sichtbaren Content aus dem Document, wie z.B.: +// versteckte Bereiche, versteckte Absaetze +bool SwDoc::RemoveInvisibleContent() +{ + sal_Bool bRet = sal_False; + GetIDocumentUndoRedo().StartUndo( UNDO_UI_DELETE_INVISIBLECNTNT, NULL ); + + { + SwTxtNode* pTxtNd; + SwIterator<SwFmtFld,SwFieldType> aIter( *GetSysFldType( RES_HIDDENPARAFLD ) ); + for( SwFmtFld* pFmtFld = aIter.First(); pFmtFld; pFmtFld = aIter.Next() ) + { + if( pFmtFld->GetTxtFld() && + 0 != ( pTxtNd = (SwTxtNode*)pFmtFld->GetTxtFld()->GetpTxtNode() ) && + pTxtNd->GetpSwpHints() && pTxtNd->HasHiddenParaField() && + &pTxtNd->GetNodes() == &GetNodes() ) + { + bRet = sal_True; + SwPaM aPam( *pTxtNd, 0, *pTxtNd, pTxtNd->GetTxt().Len() ); + + // Remove hidden paragraph or delete contents: + // Delete contents if + // 1. removing the paragraph would result in an empty section or + // 2. if the paragraph is the last paragraph in the section and + // there is no paragraph in front of the paragraph: + if ( ( 2 == pTxtNd->EndOfSectionIndex() - pTxtNd->StartOfSectionIndex() ) || + ( 1 == pTxtNd->EndOfSectionIndex() - pTxtNd->GetIndex() && + !GetNodes()[ pTxtNd->GetIndex() - 1 ]->GetTxtNode() ) ) + { + DeleteRange( aPam ); + } + else + { + aPam.DeleteMark(); + DelFullPara( aPam ); + } + } + } + } + + // + // Remove any hidden paragraph (hidden text attribute) + // + for( sal_uLong n = GetNodes().Count(); n; ) + { + SwTxtNode* pTxtNd = GetNodes()[ --n ]->GetTxtNode(); + if ( pTxtNd ) + { + bool bRemoved = false; + SwPaM aPam( *pTxtNd, 0, *pTxtNd, pTxtNd->GetTxt().Len() ); + if ( pTxtNd->HasHiddenCharAttribute( true ) ) + { + bRemoved = sal_True; + bRet = sal_True; + + // Remove hidden paragraph or delete contents: + // Delete contents if + // 1. removing the paragraph would result in an empty section or + // 2. if the paragraph is the last paragraph in the section and + // there is no paragraph in front of the paragraph: + + if ( ( 2 == pTxtNd->EndOfSectionIndex() - pTxtNd->StartOfSectionIndex() ) || + ( 1 == pTxtNd->EndOfSectionIndex() - pTxtNd->GetIndex() && + !GetNodes()[ pTxtNd->GetIndex() - 1 ]->GetTxtNode() ) ) + { + DeleteRange( aPam ); + } + else + { + aPam.DeleteMark(); + DelFullPara( aPam ); + } + } + else if ( pTxtNd->HasHiddenCharAttribute( false ) ) + { + bRemoved = sal_True; + bRet = sal_True; + SwScriptInfo::DeleteHiddenRanges( *pTxtNd ); + } + + // Footnotes/Frames may have been removed, therefore we have + // to reset n: + if ( bRemoved ) + n = aPam.GetPoint()->nNode.GetIndex(); + } + } + + { + // dann noch alle versteckten Bereiche loeschen/leeren + SwSectionFmts aSectFmts; + SwSectionFmts& rSectFmts = GetSections(); + sal_uInt16 n; + + for( n = rSectFmts.Count(); n; ) + { + SwSectionFmt* pSectFmt = rSectFmts[ --n ]; + // don't add sections in Undo/Redo + if( !pSectFmt->IsInNodesArr()) + continue; + SwSection* pSect = pSectFmt->GetSection(); + if( pSect->CalcHiddenFlag() ) + { + SwSection* pParent = pSect, *pTmp; + while( 0 != (pTmp = pParent->GetParent() )) + { + if( pTmp->IsHiddenFlag() ) + pSect = pTmp; + pParent = pTmp; + } + + if( USHRT_MAX == aSectFmts.GetPos( pSect->GetFmt() ) ) + aSectFmts.Insert( pSect->GetFmt(), 0 ); + } + if( pSect->GetCondition().Len() ) + { + SwSectionData aSectionData( *pSect ); + aSectionData.SetCondition( aEmptyStr ); + aSectionData.SetHidden( false ); + UpdateSection( n, aSectionData ); + } + } + + if( 0 != ( n = aSectFmts.Count() )) + { + while( n ) + { + SwSectionFmt* pSectFmt = aSectFmts[ --n ]; + SwSectionNode* pSectNd = pSectFmt->GetSectionNode(); + if( pSectNd ) + { + bRet = sal_True; + SwPaM aPam( *pSectNd ); + + if( pSectNd->StartOfSectionNode()->StartOfSectionIndex() == + pSectNd->GetIndex() - 1 && + pSectNd->StartOfSectionNode()->EndOfSectionIndex() == + pSectNd->EndOfSectionIndex() + 1 ) + { + // nur den Inhalt loeschen + SwCntntNode* pCNd = GetNodes().GoNext( + &aPam.GetPoint()->nNode ); + aPam.GetPoint()->nContent.Assign( pCNd, 0 ); + aPam.SetMark(); + aPam.GetPoint()->nNode = *pSectNd->EndOfSectionNode(); + pCNd = GetNodes().GoPrevious( + &aPam.GetPoint()->nNode ); + aPam.GetPoint()->nContent.Assign( pCNd, pCNd->Len() ); + + DeleteRange( aPam ); + } + else + { + // die gesamte Section loeschen + aPam.SetMark(); + aPam.GetPoint()->nNode = *pSectNd->EndOfSectionNode(); + DelFullPara( aPam ); + } + + } + } + aSectFmts.Remove( 0, aSectFmts.Count() ); + } + } + + if( bRet ) + SetModified(); + GetIDocumentUndoRedo().EndUndo( UNDO_UI_DELETE_INVISIBLECNTNT, NULL ); + return bRet; +} +/*-- 25.08.2010 14:18:12--------------------------------------------------- + + -----------------------------------------------------------------------*/ +bool SwDoc::HasInvisibleContent() const +{ + sal_Bool bRet = sal_False; + + SwClientIter aIter( *GetSysFldType( RES_HIDDENPARAFLD ) ); + if( aIter.First( TYPE( SwFmtFld ) ) ) + bRet = sal_True; + + // + // Search for any hidden paragraph (hidden text attribute) + // + if( ! bRet ) + { + for( sal_uLong n = GetNodes().Count(); !bRet && (n > 0); ) + { + SwTxtNode* pTxtNd = GetNodes()[ --n ]->GetTxtNode(); + if ( pTxtNd ) + { + SwPaM aPam( *pTxtNd, 0, *pTxtNd, pTxtNd->GetTxt().Len() ); + if( pTxtNd->HasHiddenCharAttribute( true ) || ( pTxtNd->HasHiddenCharAttribute( false ) ) ) + { + bRet = sal_True; + } + } + } + } + + if( ! bRet ) + { + const SwSectionFmts& rSectFmts = GetSections(); + sal_uInt16 n; + + for( n = rSectFmts.Count(); !bRet && (n > 0); ) + { + SwSectionFmt* pSectFmt = rSectFmts[ --n ]; + // don't add sections in Undo/Redo + if( !pSectFmt->IsInNodesArr()) + continue; + SwSection* pSect = pSectFmt->GetSection(); + if( pSect->IsHidden() ) + bRet = sal_True; + } + } + return bRet; +} + +bool SwDoc::RestoreInvisibleContent() +{ + bool bRet = false; + SwUndoId nLastUndoId(UNDO_EMPTY); + if (GetIDocumentUndoRedo().GetLastUndoInfo(0, & nLastUndoId) + && (UNDO_UI_DELETE_INVISIBLECNTNT == nLastUndoId)) + { + GetIDocumentUndoRedo().Undo(); + GetIDocumentUndoRedo().ClearRedo(); + bRet = true; + } + return bRet; +} + + +sal_Bool SwDoc::ConvertFieldsToText() +{ + sal_Bool bRet = sal_False; + LockExpFlds(); + GetIDocumentUndoRedo().StartUndo( UNDO_UI_REPLACE, NULL ); + + const SwFldTypes* pMyFldTypes = GetFldTypes(); + sal_uInt16 nCount = pMyFldTypes->Count(); + //go backward, field types are removed + for(sal_uInt16 nType = nCount; nType > 0; --nType) + { + const SwFieldType *pCurType = pMyFldTypes->GetObject(nType - 1); + + if ( RES_POSTITFLD == pCurType->Which() ) + continue; + + SwIterator<SwFmtFld,SwFieldType> aIter( *pCurType ); + ::std::vector<const SwFmtFld*> aFieldFmts; + for( SwFmtFld* pCurFldFmt = aIter.First(); pCurFldFmt; pCurFldFmt = aIter.Next() ) + aFieldFmts.push_back(pCurFldFmt); + + ::std::vector<const SwFmtFld*>::iterator aBegin = aFieldFmts.begin(); + ::std::vector<const SwFmtFld*>::iterator aEnd = aFieldFmts.end(); + while(aBegin != aEnd) + { + const SwTxtFld *pTxtFld = (*aBegin)->GetTxtFld(); + // skip fields that are currently not in the document + // e.g. fields in undo or redo array + + sal_Bool bSkip = !pTxtFld || + !pTxtFld->GetpTxtNode()->GetNodes().IsDocNodes(); + + if (!bSkip) + { + sal_Bool bInHeaderFooter = IsInHeaderFooter(SwNodeIndex(*pTxtFld->GetpTxtNode())); + const SwFmtFld& rFmtFld = pTxtFld->GetFld(); + const SwField* pField = rFmtFld.GetFld(); + + //#i55595# some fields have to be excluded in headers/footers + sal_uInt16 nWhich = pField->GetTyp()->Which(); + if(!bInHeaderFooter || + (nWhich != RES_PAGENUMBERFLD && + nWhich != RES_CHAPTERFLD && + nWhich != RES_GETEXPFLD&& + nWhich != RES_SETEXPFLD&& + nWhich != RES_INPUTFLD&& + nWhich != RES_REFPAGEGETFLD&& + nWhich != RES_REFPAGESETFLD)) + { + String sText = pField->ExpandField(true); + //database fields should not convert their command into text + if( RES_DBFLD == pCurType->Which() && !static_cast<const SwDBField*>(pField)->IsInitialized()) + sText.Erase(); + + //now remove the field and insert the string + SwPaM aPam1(*pTxtFld->GetpTxtNode(), *pTxtFld->GetStart()); + aPam1.Move(); + //insert first to keep the field's attributes + InsertString( aPam1, sText ); + SwPaM aPam2(*pTxtFld->GetpTxtNode(), *pTxtFld->GetStart()); + aPam2.SetMark(); + aPam2.Move(); + DeleteAndJoin(aPam2);//remove the field + } + } + ++aBegin; + } + } + + if( bRet ) + SetModified(); + GetIDocumentUndoRedo().EndUndo( UNDO_UI_REPLACE, NULL ); + UnlockExpFlds(); + return bRet; + +} + +bool SwDoc::IsVisibleLinks() const +{ + return mbVisibleLinks; +} + +void SwDoc::SetVisibleLinks(bool bFlag) +{ + mbVisibleLinks = bFlag; +} + +sfx2::LinkManager& SwDoc::GetLinkManager() +{ + return *pLinkMgr; +} + +const sfx2::LinkManager& SwDoc::GetLinkManager() const +{ + return *pLinkMgr; +} + +void SwDoc::SetLinksUpdated(const bool bNewLinksUpdated) +{ + mbLinksUpdated = bNewLinksUpdated; +} + +bool SwDoc::LinksUpdated() const +{ + return mbLinksUpdated; +} + +// embedded alle lokalen Links (Bereiche/Grafiken) +::sfx2::SvBaseLink* lcl_FindNextRemovableLink( const ::sfx2::SvBaseLinks& rLinks, sfx2::LinkManager& rLnkMgr ) +{ + for( sal_uInt16 n = 0; n < rLinks.Count(); ++n ) + { + ::sfx2::SvBaseLink* pLnk = &(*rLinks[ n ]); + if( pLnk && + ( OBJECT_CLIENT_GRF == pLnk->GetObjType() || + OBJECT_CLIENT_FILE == pLnk->GetObjType() ) && + pLnk->ISA( SwBaseLink ) ) + { + ::sfx2::SvBaseLinkRef xLink = pLnk; + + String sFName; + rLnkMgr.GetDisplayNames( xLink, 0, &sFName, 0, 0 ); + + INetURLObject aURL( sFName ); + if( INET_PROT_FILE == aURL.GetProtocol() || + INET_PROT_CID == aURL.GetProtocol() ) + return pLnk; + } + } + return 0; +} +bool SwDoc::EmbedAllLinks() +{ + sal_Bool bRet = sal_False; + sfx2::LinkManager& rLnkMgr = GetLinkManager(); + const ::sfx2::SvBaseLinks& rLinks = rLnkMgr.GetLinks(); + if( rLinks.Count() ) + { + ::sw::UndoGuard const undoGuard(GetIDocumentUndoRedo()); + + ::sfx2::SvBaseLink* pLnk = 0; + while( 0 != (pLnk = lcl_FindNextRemovableLink( rLinks, rLnkMgr ) ) ) + { + ::sfx2::SvBaseLinkRef xLink = pLnk; + // dem Link sagen, das er aufgeloest wird! + xLink->Closed(); + + // falls einer vergessen hat sich auszutragen + if( xLink.Is() ) + rLnkMgr.Remove( xLink ); + + bRet = sal_True; + } + + GetIDocumentUndoRedo().DelAllUndoObj(); + SetModified(); + } + return bRet; +} + +sal_Bool SwDoc::IsInsTblFormatNum() const +{ + return SW_MOD()->IsInsTblFormatNum(get(IDocumentSettingAccess::HTML_MODE)); +} + +sal_Bool SwDoc::IsInsTblChangeNumFormat() const +{ + return SW_MOD()->IsInsTblChangeNumFormat(get(IDocumentSettingAccess::HTML_MODE)); +} + +sal_Bool SwDoc::IsInsTblAlignNum() const +{ + return SW_MOD()->IsInsTblAlignNum(get(IDocumentSettingAccess::HTML_MODE)); +} + +// setze das InsertDB als Tabelle Undo auf: +void SwDoc::AppendUndoForInsertFromDB( const SwPaM& rPam, sal_Bool bIsTable ) +{ + if( bIsTable ) + { + const SwTableNode* pTblNd = rPam.GetPoint()->nNode.GetNode().FindTableNode(); + if( pTblNd ) + { + SwUndoCpyTbl* pUndo = new SwUndoCpyTbl; + pUndo->SetTableSttIdx( pTblNd->GetIndex() ); + GetIDocumentUndoRedo().AppendUndo( pUndo ); + } + } + else if( rPam.HasMark() ) + { + SwUndoCpyDoc* pUndo = new SwUndoCpyDoc( rPam ); + pUndo->SetInsertRange( rPam, sal_False ); + GetIDocumentUndoRedo().AppendUndo( pUndo ); + } +} + +void SwDoc::ChgTOX(SwTOXBase & rTOX, const SwTOXBase & rNew) +{ + if (GetIDocumentUndoRedo().DoesUndo()) + { + GetIDocumentUndoRedo().DelAllUndoObj(); + + SwUndo * pUndo = new SwUndoTOXChange(&rTOX, rNew); + + GetIDocumentUndoRedo().AppendUndo(pUndo); + } + + rTOX = rNew; + + if (rTOX.ISA(SwTOXBaseSection)) + { + static_cast<SwTOXBaseSection &>(rTOX).Update(); + static_cast<SwTOXBaseSection &>(rTOX).UpdatePageNum(); + } +} + +String SwDoc::GetPaMDescr(const SwPaM & rPam) const +{ + String aResult; + bool bOK = false; + + if (rPam.GetNode(sal_True) == rPam.GetNode(sal_False)) + { + SwTxtNode * pTxtNode = rPam.GetNode(sal_True)->GetTxtNode(); + + if (0 != pTxtNode) + { + xub_StrLen nStart = rPam.Start()->nContent.GetIndex(); + xub_StrLen nEnd = rPam.End()->nContent.GetIndex(); + + aResult += String(SW_RES(STR_START_QUOTE)); + aResult += ShortenString(pTxtNode->GetTxt(). + Copy(nStart, nEnd - nStart), + nUndoStringLength, + String(SW_RES(STR_LDOTS))); + aResult += String(SW_RES(STR_END_QUOTE)); + + bOK = true; + } + } + else if (0 != rPam.GetNode(sal_True)) + { + if (0 != rPam.GetNode(sal_False)) + aResult += String(SW_RES(STR_PARAGRAPHS)); + + bOK = true; + } + + if (! bOK) + aResult += String("??", RTL_TEXTENCODING_ASCII_US); + + return aResult; +} + +SwField * SwDoc::GetField(const SwPosition & rPos) +{ + SwTxtFld * const pAttr = GetTxtFld(rPos); + + return (pAttr) ? const_cast<SwField *>( pAttr->GetFld().GetFld() ) : 0; +} + +SwTxtFld * SwDoc::GetTxtFld(const SwPosition & rPos) +{ + SwTxtNode * const pNode = rPos.nNode.GetNode().GetTxtNode(); + + return (pNode) + ? static_cast<SwTxtFld*>( pNode->GetTxtAttrForCharAt( + rPos.nContent.GetIndex(), RES_TXTATR_FIELD) ) + : 0; +} + +bool SwDoc::ContainsHiddenChars() const +{ + for( sal_uLong n = GetNodes().Count(); n; ) + { + SwNode* pNd = GetNodes()[ --n ]; + if ( ND_TEXTNODE == pNd->GetNodeType() && + ((SwTxtNode*)pNd)->HasHiddenCharAttribute( false ) ) + return true; + } + + return false; +} + +SwUnoCrsr* SwDoc::CreateUnoCrsr( const SwPosition& rPos, sal_Bool bTblCrsr ) +{ + SwUnoCrsr* pNew; + if( bTblCrsr ) + pNew = new SwUnoTableCrsr( rPos ); + else + pNew = new SwUnoCrsr( rPos ); + + pUnoCrsrTbl->Insert( pNew, pUnoCrsrTbl->Count() ); + return pNew; +} + +void SwDoc::ChkCondColls() +{ + for (sal_uInt16 n = 0; n < pTxtFmtCollTbl->Count(); n++) + { + SwTxtFmtColl *pColl = (*pTxtFmtCollTbl)[n]; + if (RES_CONDTXTFMTCOLL == pColl->Which()) + pColl->CallSwClientNotify( SwAttrHint(RES_CONDTXTFMTCOLL) ); + } +} + +uno::Reference< script::vba::XVBAEventProcessor > +SwDoc::GetVbaEventProcessor() +{ + if( !mxVbaEvents.is() && pDocShell && ooo::vba::isAlienWordDoc( *pDocShell ) ) + { + try + { + uno::Reference< frame::XModel > xModel( pDocShell->GetModel(), uno::UNO_SET_THROW ); + uno::Sequence< uno::Any > aArgs(1); + aArgs[0] <<= xModel; + mxVbaEvents.set( ooo::vba::createVBAUnoAPIServiceWithArgs( pDocShell, "com.sun.star.script.vba.VBATextEventProcessor" , aArgs ), uno::UNO_QUERY_THROW ); + } + catch( uno::Exception& ) + { + } + } + return mxVbaEvents; +} + +void SwDoc::setExternalData(::sw::tExternalDataType eType, + ::sw::tExternalDataPointer pPayload) +{ + m_externalData[eType] = pPayload; +} + +::sw::tExternalDataPointer SwDoc::getExternalData(::sw::tExternalDataType eType) +{ + return m_externalData[eType]; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |