Files
libreoffice/sw/source/core/doc/docdesc.cxx

1018 lines
34 KiB
C++
Raw Normal View History

2000-09-18 23:08:29 +00:00
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
2000-09-18 23:08:29 +00:00
*
* Copyright 2000, 2010 Oracle and/or its affiliates.
2000-09-18 23:08:29 +00:00
*
* OpenOffice.org - a multi-platform office productivity suite
2000-09-18 23:08:29 +00:00
*
* This file is part of OpenOffice.org.
2000-09-18 23:08:29 +00:00
*
* 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.
2000-09-18 23:08:29 +00:00
*
* 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).
2000-09-18 23:08:29 +00:00
*
* 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.
2000-09-18 23:08:29 +00:00
*
************************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sw.hxx"
2000-09-18 23:08:29 +00:00
#include <hintids.hxx>
#include <vcl/virdev.hxx>
2000-09-18 23:08:29 +00:00
#include <svx/svdmodel.hxx>
#include <editeng/ulspitem.hxx>
#include <editeng/lrspitem.hxx>
#include <editeng/paperinf.hxx>
#include "editeng/frmdiritem.hxx"
2000-09-18 23:08:29 +00:00
#include <tools/urlobj.hxx>
#include <sfx2/docfile.hxx>
2009-06-04 08:23:53 +00:00
#include <sfx2/printer.hxx>
2000-11-20 08:16:31 +00:00
#include <unotools/localedatawrapper.hxx>
#include <com/sun/star/document/PrinterIndependentLayout.hpp>
2000-09-18 23:08:29 +00:00
#include <fmtfsize.hxx>
#include <fmthdft.hxx>
#include <fmtcntnt.hxx>
#include <fmtpdsc.hxx>
#include <ftninfo.hxx>
#include <fesh.hxx>
#include <ndole.hxx>
#include <mdiexp.hxx>
#include <doc.hxx>
#include <IDocumentUndoRedo.hxx>
2000-09-18 23:08:29 +00:00
#include <docary.hxx>
#include <pagefrm.hxx> //Fuer DelPageDesc
#include <rootfrm.hxx> //Fuer DelPageDesc
#include <ndtxt.hxx>
#include <frmtool.hxx>
#include <pagedesc.hxx>
#include <poolfmt.hxx>
#include <docsh.hxx>
#include <ndindex.hxx>
#include <ftnidx.hxx>
#include <fmtftn.hxx>
#include <txtftn.hxx>
#include <fntcache.hxx>
#include <viewsh.hxx>
#include <viewopt.hxx>
#include <fldbas.hxx>
#include <swwait.hxx>
#include <GetMetricVal.hxx>
#include <unotools/syslocale.hxx>
2000-09-18 23:08:29 +00:00
#include <statstr.hrc>
#include <SwUndoPageDesc.hxx>
#include <tgrditem.hxx>
using namespace com::sun::star;
static void lcl_DefaultPageFmt( sal_uInt16 nPoolFmtId,
SwFrmFmt &rFmt1,
SwFrmFmt &rFmt2 )
2000-09-18 23:08:29 +00:00
{
// --> FME 2005-01-21 #i41075# Printer on demand
// This function does not require a printer anymore.
// The default page size is obtained from the application
//locale
// <--
2000-09-18 23:08:29 +00:00
SwFmtFrmSize aFrmSize( ATT_FIX_SIZE );
CWS-TOOLING: integrate CWS unifypaper01 2009-05-27 17:14:41 +0200 cmc r272362 : #i92819#, psprint moved into vcl 2009-05-19 15:45:46 +0200 cmc r272083 : #i92819# having difficultly in getting this right under windows 2009-05-18 18:04:22 +0200 cmc r272043 : #i92819# missing some export magic somewhere 2009-05-18 15:34:18 +0200 cmc r272028 : #i92819# get depends right 2009-05-18 11:50:43 +0200 cmc r272010 : ##i92819# fix import/export stuff 2009-05-18 10:07:00 +0200 cmc r272000 : #i92819# fix window imp name 2009-05-16 15:17:23 +0200 cmc r271975 : #i92819# fix win paper names 2009-05-16 11:11:29 +0200 cmc r271974 : #i92819# std::abs prolematic for msvc 2009-05-15 15:36:56 +0200 cmc r271941 : #i92819# handle missing setting, at least on mac 2009-05-15 10:13:44 +0200 cmc r271927 : #i92819# adjust for moved page dialog 2009-05-14 13:47:14 +0200 cmc r271887 : remove dead files that reappeared 2009-05-14 09:57:17 +0200 cmc r271872 : CWS-TOOLING: rebase CWS unifypaper01 to trunk@271830 (milestone: DEV300:m48) 2009-05-11 12:27:18 +0200 cmc r271763 : #i92819# check return value 2009-05-06 17:28:25 +0200 cmc r271602 : #i92819# these B4/B5s are the JIS ones according to their dimensions 2009-05-06 17:17:03 +0200 cmc r271601 : #i92819# micro-optimization 2009-05-03 18:20:48 +0200 cmc r271434 : #i92819# paper libs 2009-05-03 16:08:32 +0200 cmc r271433 : CWS-TOOLING: rebase CWS unifypaper01 to trunk@271427 (milestone: DEV300:m47) 2009-04-06 15:33:37 +0200 cmc r270556 : CWS-TOOLING: rebase CWS unifypaper01 to trunk@270033 (milestone: DEV300:m45) 2009-03-12 14:36:35 +0100 cmc r269415 : #i92819# merge paper utilities 2009-03-11 13:44:27 +0100 cmc r269328 : CWS-TOOLING: rebase CWS unifypaper01 to trunk@269297 (milestone: DEV300:m43) 2009-03-09 14:42:07 +0100 cmc r269190 : remove config_office from synced version 2009-03-09 14:34:50 +0100 cmc r269187 : CWS-TOOLING: rebase CWS unifypaper01 to trunk@268395 (milestone: DEV300:m42) 2009-03-09 12:11:29 +0100 cmc r269077 : CWS-TOOLING: rebase CWS unifypaper01 to trunk@265758 (milestone: DEV300:m38) 2009-03-06 17:17:39 +0100 cmc r269027 : #i92819# paper goo 2008-12-04 11:29:30 +0100 cmc r264826 : CWS-TOOLING: rebase CWS unifypaper01 to trunk@264807 (milestone: DEV300:m37) 2008-11-26 10:33:06 +0100 cmc r264357 : CWS-TOOLING: rebase CWS unifypaper01 to trunk@264325 (milestone: DEV300:m36) 2008-11-21 14:09:36 +0100 cmc r264138 : #i92819# paper consolidation
2009-06-12 09:36:34 +00:00
const Size aPhysSize = SvxPaperInfo::GetDefaultPaperSize();
aFrmSize.SetSize( aPhysSize );
//Auf Default-Raender vorbereiten.
//Raender haben eine defaultmaessige Mindestgroesse.
//wenn der Drucker einen groesseren Rand vorgibt, so
//ist mir dass auch recht.
// MIB 06/25/2002, #99397#: The HTML page desc had A4 as page size
// always. This has been changed to take the page size from the printer.
// Unfortunately, the margins of the HTML page desc are smaller than
// the margins used here in general, so one extra case is required.
// In the long term, this needs to be changed to always keep the
// margins from the page desc.
sal_Int32 nMinTop, nMinBottom, nMinLeft, nMinRight;
if( RES_POOLPAGE_HTML == nPoolFmtId )
2000-09-18 23:08:29 +00:00
{
nMinRight = nMinTop = nMinBottom = GetMetricVal( CM_1 );
nMinLeft = nMinRight * 2;
2000-09-18 23:08:29 +00:00
}
CWS-TOOLING: integrate CWS oj18 2009-08-21 15:08:49 +0200 oj r275263 : wrong check 2009-08-21 08:56:01 +0200 oj r275215 : missing not 2009-08-20 07:27:13 +0200 oj r275164 : use new method from global 2009-08-19 10:22:35 +0200 oj r275138 : call GetLocale instead of pLocale 2009-08-18 10:39:32 +0200 oj r275082 : missing header include 2009-08-18 10:09:44 +0200 oj r275081 : new methods at global 2009-08-18 10:09:00 +0200 oj r275080 : unused var 2009-08-18 08:59:04 +0200 oj r275078 : move files from classes to xml 2009-08-17 14:58:16 +0200 oj r275056 : CWS-TOOLING: rebase CWS oj18 to trunk@275001 (milestone: DEV300:m55) 2009-08-17 13:29:44 +0200 oj r275047 : compile error 2009-08-17 13:27:47 +0200 oj r275045 : compile error 2009-08-17 11:44:54 +0200 oj r275040 : add dep 2009-07-22 14:26:05 +0200 oj r274240 : move unused services into fwl 2009-07-22 14:25:35 +0200 oj r274239 : move unused services into fwl 2009-07-22 13:47:45 +0200 oj r274233 : remove some unused code 2009-07-22 09:06:20 +0200 oj r274219 : export dbtoolsclient dbcharsethelper for sc 2009-07-22 08:48:58 +0200 oj r274218 : create NumberFormatter on demand 2009-07-22 08:39:23 +0200 oj r274217 : change char to sal_Char 2009-07-22 07:33:34 +0200 oj r274214 : export dbtoolsclient dbcharsethelper for sc 2009-07-22 07:30:04 +0200 oj r274213 : late init of numberformatter and breakiterator 2009-07-22 07:28:55 +0200 oj r274212 : export dbtoolsclient dbcharsethelper for sc 2009-07-21 13:43:28 +0200 oj r274196 : check if quick start is enbaled 2009-07-21 13:40:09 +0200 oj r274195 : check config entry for UiEventsLogger 2009-07-21 13:37:40 +0200 oj r274194 : code refactoring, remove of duplicate code and some late inits and removale of not needed files 2009-07-21 13:35:38 +0200 oj r274193 : code refactoring, remove of duplicate code and some late inits and removale of not needed files 2009-07-21 13:33:41 +0200 oj r274192 : doc meta data will now be created on demand 2009-07-21 13:13:40 +0200 oj r274187 : load ldap functions on demand 2009-07-21 13:03:17 +0200 oj r274183 : late init of TransliterationImpl 2009-07-21 12:36:10 +0200 oj r274180 : late init of charClass
2009-09-08 04:57:32 +00:00
else if( MEASURE_METRIC == SvtSysLocale().GetLocaleData().getMeasurementSystemEnum() )
2000-09-18 23:08:29 +00:00
{
nMinTop = nMinBottom = nMinLeft = nMinRight = 1134; //2 Zentimeter
2000-09-18 23:08:29 +00:00
}
else
2000-09-18 23:08:29 +00:00
{
nMinTop = nMinBottom = 1440; //al la WW: 1Inch
nMinLeft = nMinRight = 1800; // 1,25 Inch
2000-09-18 23:08:29 +00:00
}
//Raender einstellen.
SvxLRSpaceItem aLR( RES_LR_SPACE );
SvxULSpaceItem aUL( RES_UL_SPACE );
aUL.SetUpper( (USHORT)nMinTop );
aUL.SetLower( (USHORT)nMinBottom );
aLR.SetRight( nMinRight );
aLR.SetLeft( nMinLeft );
rFmt1.SetFmtAttr( aFrmSize );
rFmt1.SetFmtAttr( aLR );
rFmt1.SetFmtAttr( aUL );
rFmt2.SetFmtAttr( aFrmSize );
rFmt2.SetFmtAttr( aLR );
rFmt2.SetFmtAttr( aUL );
2000-09-18 23:08:29 +00:00
}
/*************************************************************************
|*
|* SwDoc::ChgPageDesc()
|*
|* Ersterstellung MA 25. Jan. 93
|* Letzte Aenderung MA 01. Mar. 95
|*
|*************************************************************************/
void lcl_DescSetAttr( const SwFrmFmt &rSource, SwFrmFmt &rDest,
const BOOL bPage = TRUE )
{
/////////////// !!!!!!!!!!!!!!!!
//JP 03.03.99:
// eigentlich sollte hier das Intersect von ItemSet benutzt werden, aber das
// funktioniert nicht richtig, wenn man unterschiedliche WhichRanges hat.
/////////////// !!!!!!!!!!!!!!!!
//Die interressanten Attribute uebernehmen.
USHORT __READONLY_DATA aIdArr[] = { RES_FRM_SIZE, RES_UL_SPACE,
RES_BACKGROUND, RES_SHADOW,
RES_COL, RES_COL,
RES_FRAMEDIR, RES_FRAMEDIR,
RES_TEXTGRID, RES_TEXTGRID,
// --> FME 2005-04-18 #i45539#
RES_HEADER_FOOTER_EAT_SPACING,
RES_HEADER_FOOTER_EAT_SPACING,
// <--
RES_UNKNOWNATR_CONTAINER,
RES_UNKNOWNATR_CONTAINER,
0 };
2000-09-18 23:08:29 +00:00
const SfxPoolItem* pItem;
for( USHORT n = 0; aIdArr[ n ]; n += 2 )
{
for( USHORT nId = aIdArr[ n ]; nId <= aIdArr[ n+1]; ++nId )
{
// --> FME 2005-04-18 #i45539#
// bPage == true:
// All in aIdArr except from RES_HEADER_FOOTER_EAT_SPACING
// bPage == false:
// All in aIdArr except from RES_COL and RES_PAPER_BIN:
// <--
if( ( bPage && RES_HEADER_FOOTER_EAT_SPACING != nId ) ||
( !bPage && RES_COL != nId && RES_PAPER_BIN != nId ))
2000-09-18 23:08:29 +00:00
{
if( SFX_ITEM_SET == rSource.GetItemState( nId, FALSE, &pItem ))
rDest.SetFmtAttr( *pItem );
2000-09-18 23:08:29 +00:00
else
rDest.ResetFmtAttr( nId );
2000-09-18 23:08:29 +00:00
}
}
}
// auch Pool-, Hilfe-Id's uebertragen
rDest.SetPoolFmtId( rSource.GetPoolFmtId() );
rDest.SetPoolHelpId( rSource.GetPoolHelpId() );
rDest.SetPoolHlpFileId( rSource.GetPoolHlpFileId() );
}
void SwDoc::ChgPageDesc( USHORT i, const SwPageDesc &rChged )
{
ASSERT( i < aPageDescs.Count(), "PageDescs ueberindiziert." );
SwPageDesc *pDesc = aPageDescs[i];
if (GetIDocumentUndoRedo().DoesUndo())
{
SwUndo *const pUndo(new SwUndoPageDesc(*pDesc, rChged, this));
GetIDocumentUndoRedo().AppendUndo(pUndo);
}
::sw::UndoGuard const undoGuard(GetIDocumentUndoRedo());
2000-09-18 23:08:29 +00:00
//Als erstes wird ggf. gespiegelt.
if ( rChged.GetUseOn() == nsUseOnPage::PD_MIRROR )
2000-09-18 23:08:29 +00:00
((SwPageDesc&)rChged).Mirror();
else
//sonst Werte aus Master nach Left uebertragen.
::lcl_DescSetAttr( ((SwPageDesc&)rChged).GetMaster(),
((SwPageDesc&)rChged).GetLeft() );
//NumType uebernehmen.
if( rChged.GetNumType().GetNumberingType() != pDesc->GetNumType().GetNumberingType() )
2000-09-18 23:08:29 +00:00
{
pDesc->SetNumType( rChged.GetNumType() );
// JP 30.03.99: Bug 64121 - den Seitennummernfeldern bescheid sagen,
// das sich das Num-Format geaendert hat
GetSysFldType( RES_PAGENUMBERFLD )->UpdateFlds();
GetSysFldType( RES_REFPAGEGETFLD )->UpdateFlds();
// Wenn sich die Numerierungsart geaendert hat, koennte es QuoVadis/
// ErgoSum-Texte geben, die sich auf eine geaenderte Seite beziehen,
// deshalb werden die Fussnoten invalidiert
SwFtnIdxs& rFtnIdxs = GetFtnIdxs();
for( USHORT nPos = 0; nPos < rFtnIdxs.Count(); ++nPos )
{
SwTxtFtn *pTxtFtn = rFtnIdxs[ nPos ];
const SwFmtFtn &rFtn = pTxtFtn->GetFtn();
pTxtFtn->SetNumber( rFtn.GetNumber(), &rFtn.GetNumStr());
}
}
//Orientierung uebernehmen
pDesc->SetLandscape( rChged.GetLandscape() );
// #i46909# no undo if header or footer changed
bool bHeaderFooterChanged = false;
2000-09-18 23:08:29 +00:00
//Header abgleichen.
const SwFmtHeader &rHead = rChged.GetMaster().GetHeader();
if (undoGuard.UndoWasEnabled())
2000-09-18 23:08:29 +00:00
{
// #i46909# no undo if header or footer changed
2000-09-18 23:08:29 +00:00
// hat sich an den Nodes etwas veraendert ?
const SwFmtHeader &rOldHead = pDesc->GetMaster().GetHeader();
bHeaderFooterChanged |=
( rHead.IsActive() != rOldHead.IsActive() ||
rChged.IsHeaderShared() != pDesc->IsHeaderShared() );
2000-09-18 23:08:29 +00:00
}
pDesc->GetMaster().SetFmtAttr( rHead );
2000-09-18 23:08:29 +00:00
if ( rChged.IsHeaderShared() || !rHead.IsActive() )
{
//Left teilt sich den Header mit dem Master.
pDesc->GetLeft().SetFmtAttr( pDesc->GetMaster().GetHeader() );
2000-09-18 23:08:29 +00:00
}
else if ( rHead.IsActive() )
{ //Left bekommt einen eigenen Header verpasst wenn das Format nicht
//bereits einen hat.
//Wenn er bereits einen hat und dieser auf die gleiche Section
//wie der Rechte zeigt, so muss er einen eigenen bekommen. Der
//Inhalt wird sinnigerweise kopiert.
const SwFmtHeader &rLeftHead = pDesc->GetLeft().GetHeader();
if ( !rLeftHead.IsActive() )
{
SwFmtHeader aHead( MakeLayoutFmt( RND_STD_HEADERL, 0 ) );
pDesc->GetLeft().SetFmtAttr( aHead );
2000-09-18 23:08:29 +00:00
//Weitere Attribute (Raender, Umrandung...) uebernehmen.
::lcl_DescSetAttr( *rHead.GetHeaderFmt(), *aHead.GetHeaderFmt(), FALSE);
}
else
{
const SwFrmFmt *pRight = rHead.GetHeaderFmt();
const SwFmtCntnt &aRCnt = pRight->GetCntnt();
const SwFmtCntnt &aLCnt = rLeftHead.GetHeaderFmt()->GetCntnt();
if( !aLCnt.GetCntntIdx() )
pDesc->GetLeft().SetFmtAttr( rChged.GetLeft().GetHeader() );
else if( (*aRCnt.GetCntntIdx()) == (*aLCnt.GetCntntIdx()) )
2000-09-18 23:08:29 +00:00
{
SwFrmFmt *pFmt = new SwFrmFmt( GetAttrPool(), "Header",
GetDfltFrmFmt() );
::lcl_DescSetAttr( *pRight, *pFmt, FALSE );
//Der Bereich auf den das rechte Kopfattribut zeigt wird
//kopiert und der Index auf den StartNode in das linke
//Kopfattribut gehaengt.
SwNodeIndex aTmp( GetNodes().GetEndOfAutotext() );
SwStartNode* pSttNd = GetNodes().MakeEmptySection( aTmp, SwHeaderStartNode );
SwNodeRange aRange( aRCnt.GetCntntIdx()->GetNode(), 0,
*aRCnt.GetCntntIdx()->GetNode().EndOfSectionNode() );
aTmp = *pSttNd->EndOfSectionNode();
GetNodes()._Copy( aRange, aTmp, FALSE );
pFmt->SetFmtAttr( SwFmtCntnt( pSttNd ) );
pDesc->GetLeft().SetFmtAttr( SwFmtHeader( pFmt ) );
2000-09-18 23:08:29 +00:00
}
else
::lcl_DescSetAttr( *pRight,
*(SwFrmFmt*)rLeftHead.GetHeaderFmt(), FALSE );
}
}
pDesc->ChgHeaderShare( rChged.IsHeaderShared() );
//Footer abgleichen.
const SwFmtFooter &rFoot = rChged.GetMaster().GetFooter();
if (undoGuard.UndoWasEnabled())
2000-09-18 23:08:29 +00:00
{
// #i46909# no undo if header or footer changed
2000-09-18 23:08:29 +00:00
// hat sich an den Nodes etwas veraendert ?
const SwFmtFooter &rOldFoot = pDesc->GetMaster().GetFooter();
bHeaderFooterChanged |=
( rFoot.IsActive() != rOldFoot.IsActive() ||
rChged.IsFooterShared() != pDesc->IsFooterShared() );
2000-09-18 23:08:29 +00:00
}
pDesc->GetMaster().SetFmtAttr( rFoot );
2000-09-18 23:08:29 +00:00
if ( rChged.IsFooterShared() || !rFoot.IsActive() )
//Left teilt sich den Header mit dem Master.
pDesc->GetLeft().SetFmtAttr( pDesc->GetMaster().GetFooter() );
2000-09-18 23:08:29 +00:00
else if ( rFoot.IsActive() )
{ //Left bekommt einen eigenen Footer verpasst wenn das Format nicht
//bereits einen hat.
//Wenn er bereits einen hat und dieser auf die gleiche Section
//wie der Rechte zeigt, so muss er einen eigenen bekommen. Der
//Inhalt wird sinnigerweise kopiert.
const SwFmtFooter &rLeftFoot = pDesc->GetLeft().GetFooter();
if ( !rLeftFoot.IsActive() )
{
SwFmtFooter aFoot( MakeLayoutFmt( RND_STD_FOOTER, 0 ) );
pDesc->GetLeft().SetFmtAttr( aFoot );
2000-09-18 23:08:29 +00:00
//Weitere Attribute (Raender, Umrandung...) uebernehmen.
::lcl_DescSetAttr( *rFoot.GetFooterFmt(), *aFoot.GetFooterFmt(), FALSE);
}
else
{
const SwFrmFmt *pRight = rFoot.GetFooterFmt();
const SwFmtCntnt &aRCnt = pRight->GetCntnt();
const SwFmtCntnt &aLCnt = rLeftFoot.GetFooterFmt()->GetCntnt();
if( !aLCnt.GetCntntIdx() )
pDesc->GetLeft().SetFmtAttr( rChged.GetLeft().GetFooter() );
else if( (*aRCnt.GetCntntIdx()) == (*aLCnt.GetCntntIdx()) )
2000-09-18 23:08:29 +00:00
{
SwFrmFmt *pFmt = new SwFrmFmt( GetAttrPool(), "Footer",
GetDfltFrmFmt() );
::lcl_DescSetAttr( *pRight, *pFmt, FALSE );
//Der Bereich auf den das rechte Kopfattribut zeigt wird
//kopiert und der Index auf den StartNode in das linke
//Kopfattribut gehaengt.
SwNodeIndex aTmp( GetNodes().GetEndOfAutotext() );
SwStartNode* pSttNd = GetNodes().MakeEmptySection( aTmp, SwFooterStartNode );
SwNodeRange aRange( aRCnt.GetCntntIdx()->GetNode(), 0,
*aRCnt.GetCntntIdx()->GetNode().EndOfSectionNode() );
aTmp = *pSttNd->EndOfSectionNode();
GetNodes()._Copy( aRange, aTmp, FALSE );
pFmt->SetFmtAttr( SwFmtCntnt( pSttNd ) );
pDesc->GetLeft().SetFmtAttr( SwFmtFooter( pFmt ) );
2000-09-18 23:08:29 +00:00
}
else
::lcl_DescSetAttr( *pRight,
*(SwFrmFmt*)rLeftFoot.GetFooterFmt(), FALSE );
}
}
pDesc->ChgFooterShare( rChged.IsFooterShared() );
if ( pDesc->GetName() != rChged.GetName() )
pDesc->SetName( rChged.GetName() );
// Dadurch wird ein RegisterChange ausgeloest, wenn notwendig
pDesc->SetRegisterFmtColl( rChged.GetRegisterFmtColl() );
//Wenn sich das UseOn oder der Follow aendern muessen die
//Absaetze das erfahren.
BOOL bUseOn = FALSE;
BOOL bFollow = FALSE;
if ( pDesc->GetUseOn() != rChged.GetUseOn() )
{ pDesc->SetUseOn( rChged.GetUseOn() );
bUseOn = TRUE;
}
if ( pDesc->GetFollow() != rChged.GetFollow() )
{ if ( rChged.GetFollow() == &rChged )
{ if ( pDesc->GetFollow() != pDesc )
{ pDesc->SetFollow( pDesc );
bFollow = TRUE;
}
}
else
{ pDesc->SetFollow( rChged.pFollow );
bFollow = TRUE;
}
}
if ( (bUseOn || bFollow) && GetRootFrm() )
//Layot benachrichtigen!
GetRootFrm()->CheckPageDescs( (SwPageFrm*)GetRootFrm()->Lower() );
//Jetzt noch die Seiten-Attribute uebernehmen.
::lcl_DescSetAttr( rChged.GetMaster(), pDesc->GetMaster() );
::lcl_DescSetAttr( rChged.GetLeft(), pDesc->GetLeft() );
//Wenn sich FussnotenInfo veraendert, so werden die Seiten
//angetriggert.
if( !(pDesc->GetFtnInfo() == rChged.GetFtnInfo()) )
{
pDesc->SetFtnInfo( rChged.GetFtnInfo() );
SwMsgPoolItem aInfo( RES_PAGEDESC_FTNINFO );
{
SwClientIter aIter( pDesc->GetMaster() );
for( SwClient* pLast = aIter.First(TYPE(SwFrm)); pLast;
pLast = aIter.Next() )
pLast->Modify( &aInfo, 0 );
}
{
SwClientIter aIter( pDesc->GetLeft() );
for( SwClient* pLast = aIter.First(TYPE(SwFrm)); pLast;
pLast = aIter.Next() )
pLast->Modify( &aInfo, 0 );
}
}
SetModified();
// #i46909# no undo if header or footer changed
if( bHeaderFooterChanged )
{
GetIDocumentUndoRedo().DelAllUndoObj();
}
2000-09-18 23:08:29 +00:00
}
/*************************************************************************
|*
|* SwDoc::DelPageDesc()
|*
|* Beschreibung Alle Descriptoren, deren Follow auf den zu loeschenden
|* zeigen muessen angepasst werden.
|* Ersterstellung MA 25. Jan. 93
|* Letzte Aenderung JP 04.09.95
|*
|*************************************************************************/
void lcl_RemoveFrms( SwFrmFmt& rFmt, BOOL& rbFtnsRemoved )
2000-09-18 23:08:29 +00:00
{
SwClientIter aIter( rFmt );
SwFrm *pFrm;
for( pFrm = (SwFrm*)aIter.First(TYPE(SwFrm)); pFrm;
pFrm = (SwFrm*)aIter.Next() )
if ( !rbFtnsRemoved && pFrm->IsPageFrm() &&
((SwPageFrm*)pFrm)->IsFtnPage() )
{
rFmt.getIDocumentLayoutAccess()->GetRootFrm()->RemoveFtns( 0, FALSE, TRUE );
2000-09-18 23:08:29 +00:00
rbFtnsRemoved = TRUE;
}
else
{
pFrm->Cut();
delete pFrm;
}
}
// #i7983#
void SwDoc::PreDelPageDesc(SwPageDesc * pDel)
2000-09-18 23:08:29 +00:00
{
if (0 == pDel)
2000-09-18 23:08:29 +00:00
return;
SwFmtPageDesc aDfltDesc( aPageDescs[0] );
SwClientIter aIter( *pDel );
SwClient* pLast;
while( 0 != ( pLast = aIter.GoRoot() ))
{
if( pLast->ISA( SwFmtPageDesc ) )
{
const SwModify* pMod = ((SwFmtPageDesc*)pLast)->GetDefinedIn();
if ( pMod )
{
if( pMod->ISA( SwCntntNode ) )
((SwCntntNode*)pMod)->SetAttr( aDfltDesc );
else if( pMod->ISA( SwFmt ))
((SwFmt*)pMod)->SetFmtAttr( aDfltDesc );
2000-09-18 23:08:29 +00:00
else
{
ASSERT( !this, "was ist das fuer ein Mofify-Obj?" );
aPageDescs[0]->Add( pLast );
}
}
else //Es kann noch eine Undo-Kopie existieren
aPageDescs[0]->Add( pLast );
}
BOOL bFtnInf = FALSE;
if ( TRUE == (bFtnInf = pLast == pFtnInfo->GetPageDescDep()) ||
pLast == pEndNoteInfo->GetPageDescDep() )
{
aPageDescs[0]->Add( pLast );
if ( GetRootFrm() )
GetRootFrm()->CheckFtnPageDescs( !bFtnInf );
}
}
for ( USHORT j = 0; j < aPageDescs.Count(); ++j )
{
if ( aPageDescs[j]->GetFollow() == pDel )
{
aPageDescs[j]->SetFollow( 0 );
//Clients des PageDesc sind die Attribute, denen sagen wir bescheid.
//die Attribute wiederum reichen die Meldung an die Absaetze weiter.
//Layot benachrichtigen!
if( GetRootFrm() ) // ist nicht immer vorhanden!! (Orginizer)
GetRootFrm()->CheckPageDescs( (SwPageFrm*)GetRootFrm()->Lower() );
}
}
if( GetRootFrm() ) // ist nicht immer vorhanden!! (Orginizer)
{
//Wenn jetzt noch irgendwelche Seiten auf die FrmFmt'e (Master und Left)
//Zeigen (z.B. irgendwelche Fussnotenseiten), so muessen die Seiten
//vernichtet werden.
// Wenn wir auf Endnotenseiten stossen, schmeissen wir alle Fussnoten weg,
// anders kann die Reihenfolge der Seiten (FollowsPageDescs usw.)
// nicht garantiert werden.
BOOL bFtnsRemoved = FALSE;
2000-09-18 23:08:29 +00:00
::lcl_RemoveFrms( pDel->GetMaster(), bFtnsRemoved );
::lcl_RemoveFrms( pDel->GetLeft(), bFtnsRemoved );
}
}
// #116530#
void SwDoc::BroadcastStyleOperation(String rName, SfxStyleFamily eFamily,
USHORT nOp)
{
if (pDocShell)
{
SfxStyleSheetBasePool * pPool = pDocShell->GetStyleSheetPool();
if (pPool)
{
pPool->SetSearchMask(eFamily, SFXSTYLEBIT_ALL );
SfxStyleSheetBase * pBase = pPool->Find(rName);
if (pBase != NULL)
pPool->Broadcast(SfxStyleSheetHint( nOp, *pBase ));
}
}
}
void SwDoc::DelPageDesc( USHORT i, BOOL bBroadcast )
{
ASSERT( i < aPageDescs.Count(), "PageDescs ueberindiziert." );
ASSERT( i != 0, "Default Pagedesc loeschen is nicht." );
if ( i == 0 )
return;
SwPageDesc *pDel = aPageDescs[i];
// -> #116530#
if (bBroadcast)
BroadcastStyleOperation(pDel->GetName(), SFX_STYLE_FAMILY_PAGE,
SFX_STYLESHEET_ERASED);
// <- #116530#
if (GetIDocumentUndoRedo().DoesUndo())
{
SwUndo *const pUndo(new SwUndoPageDescDelete(*pDel, this));
GetIDocumentUndoRedo().AppendUndo(pUndo);
}
PreDelPageDesc(pDel); // #i7983#
2000-09-18 23:08:29 +00:00
aPageDescs.Remove( i );
delete pDel;
SetModified();
}
2002-12-04 13:34:31 +00:00
2000-09-18 23:08:29 +00:00
/*************************************************************************
|*
|* SwDoc::MakePageDesc()
|*
|* Ersterstellung MA 25. Jan. 93
|* Letzte Aenderung MA 20. Aug. 93
|*
|*************************************************************************/
2002-12-04 13:34:31 +00:00
USHORT SwDoc::MakePageDesc( const String &rName, const SwPageDesc *pCpy,
BOOL bRegardLanguage, BOOL bBroadcast) // #116530#
2000-09-18 23:08:29 +00:00
{
SwPageDesc *pNew;
if( pCpy )
{
pNew = new SwPageDesc( *pCpy );
pNew->SetName( rName );
if( rName != pCpy->GetName() )
{
pNew->SetPoolFmtId( USHRT_MAX );
pNew->SetPoolHelpId( USHRT_MAX );
pNew->SetPoolHlpFileId( UCHAR_MAX );
}
}
else
{
pNew = new SwPageDesc( rName, GetDfltFrmFmt(), this );
//Default-Seitenformat einstellen.
lcl_DefaultPageFmt( USHRT_MAX, pNew->GetMaster(), pNew->GetLeft() );
2002-12-04 13:34:31 +00:00
SvxFrameDirection aFrameDirection = bRegardLanguage ?
GetDefaultFrameDirection(GetAppLanguage())
2002-12-04 13:34:31 +00:00
: FRMDIR_HORI_LEFT_TOP;
pNew->GetMaster().SetFmtAttr( SvxFrameDirectionItem(aFrameDirection, RES_FRAMEDIR) );
pNew->GetLeft().SetFmtAttr( SvxFrameDirectionItem(aFrameDirection, RES_FRAMEDIR) );
2000-09-18 23:08:29 +00:00
}
aPageDescs.Insert( pNew, aPageDescs.Count() );
// -> #116530#
if (bBroadcast)
BroadcastStyleOperation(rName, SFX_STYLE_FAMILY_PAGE,
SFX_STYLESHEET_CREATED);
// <- #116530#
if (GetIDocumentUndoRedo().DoesUndo())
{
// #116530#
GetIDocumentUndoRedo().AppendUndo(new SwUndoPageDescCreate(pNew, this));
}
2000-09-18 23:08:29 +00:00
SetModified();
return (aPageDescs.Count()-1);
}
SwPageDesc* SwDoc::FindPageDescByName( const String& rName, USHORT* pPos ) const
{
SwPageDesc* pRet = 0;
if( pPos ) *pPos = USHRT_MAX;
for( USHORT n = 0, nEnd = aPageDescs.Count(); n < nEnd; ++n )
if( aPageDescs[ n ]->GetName() == rName )
{
pRet = aPageDescs[ n ];
if( pPos )
*pPos = n;
break;
}
return pRet;
}
/******************************************************************************
* Methode : void SwDoc::PrtDataChanged()
2000-09-18 23:08:29 +00:00
* Beschreibung:
* Erstellt : OK 27.10.94 10:20
* Aenderung : MA 26. Mar. 98
******************************************************************************/
void SwDoc::PrtDataChanged()
{
//!!!!!!!! Bei Aenderungen hier bitte ggf. InJobSetup im Sw3io mitpflegen
// --> FME 2005-01-21 #i41075#
ASSERT( get(IDocumentSettingAccess::USE_VIRTUAL_DEVICE) ||
0 != getPrinter( sal_False ), "PrtDataChanged will be called recursive!" )
// <--
2000-09-18 23:08:29 +00:00
SwWait *pWait = 0;
BOOL bEndAction = FALSE;
if( GetDocShell() )
GetDocShell()->UpdateFontList();
BOOL bDraw = TRUE;
if ( GetRootFrm() )
{
ViewShell *pSh = GetRootFrm()->GetCurrShell();
if( !get(IDocumentSettingAccess::BROWSE_MODE) ||
( pSh && pSh->GetViewOptions()->IsPrtFormat() ) )
2000-09-18 23:08:29 +00:00
{
if ( GetDocShell() )
pWait = new SwWait( *GetDocShell(), TRUE );
GetRootFrm()->StartAllAction();
bEndAction = TRUE;
bDraw = FALSE;
if( pDrawModel )
{
pDrawModel->SetAddExtLeading( get(IDocumentSettingAccess::ADD_EXT_LEADING) );
pDrawModel->SetRefDevice( getReferenceDevice( false ) );
}
2000-09-18 23:08:29 +00:00
pFntCache->Flush();
GetRootFrm()->InvalidateAllCntnt();
if ( pSh )
{
do
{
pSh->InitPrt( pPrt );
2000-09-18 23:08:29 +00:00
pSh = (ViewShell*)pSh->GetNext();
}
while ( pSh != GetRootFrm()->GetCurrShell() );
2000-09-18 23:08:29 +00:00
}
}
}
if ( bDraw && pDrawModel )
{
const sal_Bool bTmpAddExtLeading = get(IDocumentSettingAccess::ADD_EXT_LEADING);
if ( bTmpAddExtLeading != pDrawModel->IsAddExtLeading() )
pDrawModel->SetAddExtLeading( bTmpAddExtLeading );
OutputDevice* pOutDev = getReferenceDevice( false );
if ( pOutDev != pDrawModel->GetRefDevice() )
pDrawModel->SetRefDevice( pOutDev );
}
2000-09-18 23:08:29 +00:00
PrtOLENotify( TRUE );
if ( bEndAction )
GetRootFrm()->EndAllAction();
delete pWait;
}
//Zur Laufzeit sammeln wir die GlobalNames der Server, die keine
//Benachrichtigung zu Druckerwechseln wuenschen. Dadurch sparen wir
//das Laden vieler Objekte (gluecklicherweise werden obendrein alle
//Fremdobjekte unter einer ID abgebuildet). Init und DeInit vom Array
//ist in init.cxx zu finden.
extern SvPtrarr *pGlobalOLEExcludeList;
void SwDoc::PrtOLENotify( BOOL bAll )
{
SwFEShell *pShell = 0;
if ( GetRootFrm() && GetRootFrm()->GetCurrShell() )
{
ViewShell *pSh = GetRootFrm()->GetCurrShell();
if ( !pSh->ISA(SwFEShell) )
do
{ pSh = (ViewShell*)pSh->GetNext();
} while ( !pSh->ISA(SwFEShell) &&
pSh != GetRootFrm()->GetCurrShell() );
if ( pSh->ISA(SwFEShell) )
pShell = (SwFEShell*)pSh;
}
if ( !pShell )
{
//Das hat ohne Shell und damit ohne Client keinen Sinn, weil nur darueber
//die Kommunikation bezueglich der Groessenaenderung implementiert ist.
//Da wir keine Shell haben, merken wir uns diesen unguenstigen
//Zustand am Dokument, dies wird dann beim Erzeugen der ersten Shell
//nachgeholt.
mbOLEPrtNotifyPending = TRUE;
2000-09-18 23:08:29 +00:00
if ( bAll )
mbAllOLENotify = TRUE;
2000-09-18 23:08:29 +00:00
}
else
{
if ( mbAllOLENotify )
2000-09-18 23:08:29 +00:00
bAll = TRUE;
mbOLEPrtNotifyPending = mbAllOLENotify = FALSE;
2000-09-18 23:08:29 +00:00
SwOLENodes *pNodes = 0;
SwClientIter aIter( *(SwModify*)GetDfltGrfFmtColl() );
for( SwCntntNode* pNd = (SwCntntNode*)aIter.First( TYPE( SwCntntNode ) );
pNd;
pNd = (SwCntntNode*)aIter.Next() )
{
SwOLENode *pONd;
if ( 0 != (pONd = pNd->GetOLENode()) &&
(bAll || pONd->IsOLESizeInvalid()) )
{
if ( !pNodes )
pNodes = new SwOLENodes;
pNodes->Insert( pONd, pNodes->Count() );
}
}
if ( pNodes )
{
::StartProgress( STR_STATSTR_SWGPRTOLENOTIFY,
0, pNodes->Count(), GetDocShell());
GetRootFrm()->StartAllAction();
for( USHORT i = 0; i < pNodes->Count(); ++i )
{
::SetProgressState( i, GetDocShell() );
SwOLENode* pOLENd = (*pNodes)[i];
pOLENd->SetOLESizeInvalid( FALSE );
//Ersteinmal die Infos laden und festellen ob das Teil nicht
//schon in der Exclude-Liste steht
SvGlobalName aName;
svt::EmbeddedObjectRef& xObj = pOLENd->GetOLEObj().GetObject();
if ( xObj.is() )
aName = SvGlobalName( xObj->getClassID() );
else //Noch nicht geladen
2000-09-18 23:08:29 +00:00
{
// TODO/LATER: retrieve ClassID of an unloaded object
// aName = ????
2000-09-18 23:08:29 +00:00
}
BOOL bFound = FALSE;
for ( USHORT j = 0;
j < pGlobalOLEExcludeList->Count() && !bFound;
++j )
2000-09-18 23:08:29 +00:00
{
bFound = *(SvGlobalName*)(*pGlobalOLEExcludeList)[j] ==
2000-09-18 23:08:29 +00:00
aName;
}
if ( bFound )
continue;
//Kennen wir nicht, also muss das Objekt geladen werden.
//Wenn es keine Benachrichtigung wuenscht
if ( xObj.is() )
2000-09-18 23:08:29 +00:00
{
//TODO/LATER: needs MiscStatus for ResizeOnPrinterChange
/*
2000-09-18 23:08:29 +00:00
if ( SVOBJ_MISCSTATUS_RESIZEONPRINTERCHANGE & xRef->GetMiscStatus())
{
if ( pOLENd->GetFrm() )
{
xObj->OnDocumentPrinterChanged( pPrt );
pShell->CalcAndSetScale( xObj );//Client erzeugen lassen.
2000-09-18 23:08:29 +00:00
}
else
pOLENd->SetOLESizeInvalid( TRUE );
}
else */
2000-09-18 23:08:29 +00:00
pGlobalOLEExcludeList->Insert(
new SvGlobalName( aName ),
2000-09-18 23:08:29 +00:00
pGlobalOLEExcludeList->Count() );
}
}
delete pNodes;
GetRootFrm()->EndAllAction();
::EndProgress( GetDocShell() );
}
}
}
IMPL_LINK( SwDoc, DoUpdateModifiedOLE, Timer *, )
2000-09-18 23:08:29 +00:00
{
SwFEShell* pSh = (SwFEShell*)GetEditShell();
if( pSh )
{
mbOLEPrtNotifyPending = mbAllOLENotify = FALSE;
2000-09-18 23:08:29 +00:00
SwOLENodes aOLENodes;
SwClientIter aIter( *(SwModify*)GetDfltGrfFmtColl() );
for( SwCntntNode* pNd = (SwCntntNode*)aIter.First( TYPE( SwCntntNode ) );
pNd;
pNd = (SwCntntNode*)aIter.Next() )
{
SwOLENode *pONd = pNd->GetOLENode();
if( pONd && pONd->IsOLESizeInvalid() )
{
aOLENodes.Insert( pONd, aOLENodes.Count() );
}
}
if( aOLENodes.Count() )
{
::StartProgress( STR_STATSTR_SWGPRTOLENOTIFY,
0, aOLENodes.Count(), GetDocShell());
GetRootFrm()->StartAllAction();
SwMsgPoolItem aMsgHint( RES_UPDATE_ATTR );
for( USHORT i = 0; i < aOLENodes.Count(); ++i )
{
::SetProgressState( i, GetDocShell() );
SwOLENode* pOLENd = aOLENodes[i];
pOLENd->SetOLESizeInvalid( FALSE );
//Kennen wir nicht, also muss das Objekt geladen werden.
//Wenn es keine Benachrichtigung wuenscht
if( pOLENd->GetOLEObj().GetOleRef().is() ) //Kaputt?
2000-09-18 23:08:29 +00:00
{
//TODO/LATER: needs MiscStatus for ResizeOnPrinterChange
/*
2000-09-18 23:08:29 +00:00
if( SVOBJ_MISCSTATUS_RESIZEONPRINTERCHANGE &
xRef->GetMiscStatus() )
{
if( pOLENd->GetFrm() )
{
xRef->OnDocumentPrinterChanged( pPrt );
pSh->CalcAndSetScale( xRef );//Client erzeugen lassen.
}
else
pOLENd->SetOLESizeInvalid( TRUE );
}*/
2000-09-18 23:08:29 +00:00
// repaint it
pOLENd->Modify( &aMsgHint, &aMsgHint );
}
}
GetRootFrm()->EndAllAction();
::EndProgress( GetDocShell() );
}
}
return 0;
}
BOOL SwDoc::FindPageDesc( const String & rName, sal_uInt16 * pFound)
{
BOOL bResult = FALSE;
sal_uInt16 nI;
for (nI = 0; nI < aPageDescs.Count(); nI++)
{
if (aPageDescs[nI]->GetName() == rName)
{
*pFound = nI;
bResult = TRUE;
break;
}
}
2000-09-18 23:08:29 +00:00
return bResult;
}
2000-09-18 23:08:29 +00:00
SwPageDesc * SwDoc::GetPageDesc( const String & rName )
{
SwPageDesc * aResult = NULL;
sal_uInt16 nI;
if (FindPageDesc(rName, &nI))
aResult = aPageDescs[nI];
return aResult;
}
void SwDoc::DelPageDesc( const String & rName, BOOL bBroadcast ) // #116530#
{
sal_uInt16 nI;
if (FindPageDesc(rName, &nI))
DelPageDesc(nI, bBroadcast); // #116530#
}
2000-09-18 23:08:29 +00:00
void SwDoc::ChgPageDesc( const String & rName, const SwPageDesc & rDesc)
{
sal_uInt16 nI;
if (FindPageDesc(rName, &nI))
ChgPageDesc(nI, rDesc);
}
/*
* The HTML import cannot resist changing the page descriptions, I don't
* know why. This function is meant to check the page descriptors for invalid
* values.
*/
void SwDoc::CheckDefaultPageFmt()
{
for ( USHORT i = 0; i < GetPageDescCnt(); ++i )
{
SwPageDesc& rDesc = _GetPageDesc( i );
SwFrmFmt& rMaster = rDesc.GetMaster();
SwFrmFmt& rLeft = rDesc.GetLeft();
const SwFmtFrmSize& rMasterSize = rMaster.GetFrmSize();
const SwFmtFrmSize& rLeftSize = rLeft.GetFrmSize();
const bool bSetSize = LONG_MAX == rMasterSize.GetWidth() ||
LONG_MAX == rMasterSize.GetHeight() ||
LONG_MAX == rLeftSize.GetWidth() ||
LONG_MAX == rLeftSize.GetHeight();
if ( bSetSize )
lcl_DefaultPageFmt( rDesc.GetPoolFmtId(), rDesc.GetMaster(), rDesc.GetLeft() );
}
}
void SwDoc::SetDefaultPageMode(bool bSquaredPageMode)
{
if( !bSquaredPageMode == !IsSquaredPageMode() )
return;
const SwTextGridItem& rGrid =
(const SwTextGridItem&)GetDefault( RES_TEXTGRID );
SwTextGridItem aNewGrid = rGrid;
aNewGrid.SetSquaredMode(bSquaredPageMode);
aNewGrid.Init();
SetDefault(aNewGrid);
for ( USHORT i = 0; i < GetPageDescCnt(); ++i )
{
SwPageDesc& rDesc = _GetPageDesc( i );
SwFrmFmt& rMaster = rDesc.GetMaster();
SwFrmFmt& rLeft = rDesc.GetLeft();
SwTextGridItem aGrid((SwTextGridItem&)rMaster.GetFmtAttr(RES_TEXTGRID));
aGrid.SwitchPaperMode( bSquaredPageMode );
rMaster.SetFmtAttr(aGrid);
rLeft.SetFmtAttr(aGrid);
}
}
sal_Bool SwDoc::IsSquaredPageMode() const
{
const SwTextGridItem& rGrid =
(const SwTextGridItem&)GetDefault( RES_TEXTGRID );
return rGrid.IsSquaredMode();
}