diff options
Diffstat (limited to 'binfilter/bf_sw/source/core/txtnode')
18 files changed, 9617 insertions, 0 deletions
diff --git a/binfilter/bf_sw/source/core/txtnode/makefile.mk b/binfilter/bf_sw/source/core/txtnode/makefile.mk new file mode 100644 index 000000000000..954f3a742126 --- /dev/null +++ b/binfilter/bf_sw/source/core/txtnode/makefile.mk @@ -0,0 +1,84 @@ +#************************************************************************* +# +# 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. +# +#************************************************************************* + +EXTERNAL_WARNINGS_NOT_ERRORS := TRUE + +PRJ=..$/..$/..$/.. +BFPRJ=..$/..$/.. + +PRJNAME=binfilter +TARGET=sw_txtnode + +NO_HIDS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : $(PRJ)$/inc$/bf_sw$/swpre.mk +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/inc$/bf_sw$/sw.mk +INC+= -I$(PRJ)$/inc$/bf_sw +.IF "$(GUI)"!="OS2" +INCEXT=s:$/solar$/inc$/hm +.ENDIF + +.IF "$(mydebug)" != "" +CDEFS+=-Dmydebug +.ENDIF + +.IF "$(GUI)$(COM)" == "WINMSC" +LIBFLAGS=/NOI /NOE /PAGE:512 +.ENDIF + +# --- Files -------------------------------------------------------- + +SLOFILES = \ + $(SLO)$/sw_atrfld.obj \ + $(SLO)$/sw_atrflyin.obj \ + $(SLO)$/sw_atrftn.obj \ + $(SLO)$/sw_atrref.obj \ + $(SLO)$/sw_atrtox.obj \ + $(SLO)$/sw_fmtatr1.obj \ + $(SLO)$/sw_fmtatr2.obj \ + $(SLO)$/sw_fntcap.obj \ + $(SLO)$/sw_fntcache.obj \ + $(SLO)$/sw_swfntcch.obj \ + $(SLO)$/sw_ndhints.obj \ + $(SLO)$/sw_ndtxt.obj \ + $(SLO)$/sw_swfont.obj \ + $(SLO)$/sw_thints.obj \ + $(SLO)$/sw_txatbase.obj \ + $(SLO)$/sw_txtatr2.obj \ + $(SLO)$/sw_txtedt.obj + +.IF "$(dbutil)" != "" +OFILES+=$(SLO)$/sw_dbchratr.$(QBJX) +.ENDIF + +# --- Tagets ------------------------------------------------------- + +.INCLUDE : target.mk + diff --git a/binfilter/bf_sw/source/core/txtnode/sw_atrfld.cxx b/binfilter/bf_sw/source/core/txtnode/sw_atrfld.cxx new file mode 100644 index 000000000000..e0f66961d7d3 --- /dev/null +++ b/binfilter/bf_sw/source/core/txtnode/sw_atrfld.cxx @@ -0,0 +1,278 @@ +/* -*- 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. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include <horiornt.hxx> + +#include "doc.hxx" // Update fuer UserFields + +#include <fmtfld.hxx> +#include <txtfld.hxx> +#include "reffld.hxx" +#include "ddefld.hxx" +#include "usrfld.hxx" +#include "expfld.hxx" +#include "ndtxt.hxx" // SwTxtNode +#include "hints.hxx" +namespace binfilter { + +/*N*/ TYPEINIT2( SwFmtFld, SfxPoolItem, SwClient ) + +/**************************************************************************** + * + * class SwFmtFld + * + ****************************************************************************/ + + // Konstruktor fuers Default vom Attribut-Pool +/*N*/ SwFmtFld::SwFmtFld() +/*N*/ : SfxPoolItem( RES_TXTATR_FIELD ), +/*N*/ SwClient( 0 ), +/*N*/ pField( 0 ), +/*N*/ pTxtAttr( 0 ) +/*N*/ { +/*N*/ } + +/*N*/ SwFmtFld::SwFmtFld( const SwField &rFld ) +/*N*/ : SfxPoolItem( RES_TXTATR_FIELD ), +/*N*/ SwClient( rFld.GetTyp() ), +/*N*/ pTxtAttr( 0 ) +/*N*/ { +/*N*/ pField = rFld.Copy(); +/*N*/ } + +/*N*/ SwFmtFld::SwFmtFld( const SwFmtFld& rAttr ) +/*N*/ : SfxPoolItem( RES_TXTATR_FIELD ), +/*N*/ SwClient( rAttr.GetFld()->GetTyp() ), +/*N*/ pTxtAttr( 0 ) +/*N*/ { +/*N*/ pField = rAttr.GetFld()->Copy(); +/*N*/ } + +/*N*/ SwFmtFld::~SwFmtFld() +/*N*/ { +/*N*/ SwFieldType* pType = pField ? pField->GetTyp() : 0; +/*N*/ +/*N*/ if (pType && pType->Which() == RES_DBFLD) +/*N*/ pType = 0; // DB-Feldtypen zerstoeren sich selbst +/*N*/ +/*N*/ delete pField; +/*N*/ +/*N*/ // bei einige FeldTypen muessen wir den FeldTypen noch loeschen +/*N*/ if( pType && pType->IsLastDepend() ) +/*N*/ { +/*N*/ BOOL bDel = FALSE; +/*N*/ switch( pType->Which() ) +/*N*/ { +/*N*/ case RES_USERFLD: +/*N*/ bDel = ((SwUserFieldType*)pType)->IsDeleted(); +/*N*/ break; +/*N*/ +/*N*/ case RES_SETEXPFLD: +/*N*/ bDel = ((SwSetExpFieldType*)pType)->IsDeleted(); +/*N*/ break; +/*N*/ +/*N*/ case RES_DDEFLD: +/*N*/ bDel = ((SwDDEFieldType*)pType)->IsDeleted(); +/*N*/ break; +/*N*/ } +/*N*/ +/*N*/ if( bDel ) +/*N*/ { +/*N*/ // vorm loeschen erstmal austragen +/*?*/ pType->Remove( this ); +/*?*/ delete pType; +/*N*/ } +/*N*/ } +/*N*/ } + +int SwFmtFld::operator==( const SfxPoolItem& rAttr ) const +{ + DBG_BF_ASSERT(0, "STRIP"); return 0; //STRIP001 ASSERT( SfxPoolItem::operator==( rAttr ), "keine gleichen Attribute" ); +} + +/*N*/ SfxPoolItem* SwFmtFld::Clone( SfxItemPool* ) const +/*N*/ { +/*N*/ return new SwFmtFld( *this ); +/*N*/ } + +/*N*/ void SwFmtFld::Modify( SfxPoolItem* pOld, SfxPoolItem* pNew ) +/*N*/ { +/*N*/ if( !pTxtAttr ) +/*N*/ return; +/*N*/ +/*N*/ SwTxtNode* pTxtNd = (SwTxtNode*)&pTxtAttr->GetTxtNode(); +/*N*/ ASSERT( pTxtNd, "wo ist denn mein Node?" ); +/*N*/ if( pNew ) +/*N*/ { +/*N*/ switch( pNew->Which() ) +/*N*/ { +/*?*/ case RES_TXTATR_FLDCHG: +/*?*/ // "Farbe hat sich geaendert !" +/*?*/ // this, this fuer "nur Painten" +/*?*/ pTxtNd->Modify( this, this ); +/*?*/ return; +/*?*/ case RES_REFMARKFLD_UPDATE: +/*?*/ // GetReferenz-Felder aktualisieren +/*?*/ if( RES_GETREFFLD == GetFld()->GetTyp()->Which() ) +/*?*/ ((SwGetRefField*)GetFld())->UpdateField(); +/*?*/ break; +/*N*/ case RES_DOCPOS_UPDATE: +/*N*/ // Je nach DocPos aktualisieren (SwTxtFrm::Modify()) +/*N*/ pTxtNd->Modify( pNew, this ); +/*N*/ return; +/*N*/ +/*N*/ case RES_ATTRSET_CHG: +/*N*/ case RES_FMT_CHG: +/*?*/ pTxtNd->Modify( pOld, pNew ); +/*?*/ return; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ switch (GetFld()->GetTyp()->Which()) +/*N*/ { +/*?*/ case RES_HIDDENPARAFLD: +/*?*/ if( !pOld || RES_HIDDENPARA_PRINT != pOld->Which() ) +/*?*/ break; +/*?*/ case RES_DBSETNUMBERFLD: +/*?*/ case RES_DBNUMSETFLD: +/*?*/ case RES_DBNEXTSETFLD: +/*?*/ case RES_DBNAMEFLD: +/*?*/ pTxtNd->Modify( 0, pNew); +/*?*/ return; +/*N*/ } +/*N*/ +/*N*/ if( RES_USERFLD == GetFld()->GetTyp()->Which() ) +/*N*/ { +/*?*/ SwUserFieldType* pType = (SwUserFieldType*)GetFld()->GetTyp(); +/*?*/ if(!pType->IsValid()) +/*?*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 SwCalc aCalc( *pTxtNd->GetDoc() ); +/*?*/ } +/*N*/ } +/*N*/ pTxtAttr->Expand(); +/*N*/ } + +/*N*/ BOOL SwFmtFld::GetInfo( SfxPoolItem& rInfo ) const +/*N*/ { +/*N*/ const SwTxtNode* pTxtNd; +/*N*/ if( RES_AUTOFMT_DOCNODE != rInfo.Which() || +/*N*/ !pTxtAttr || 0 == ( pTxtNd = pTxtAttr->GetpTxtNode() ) || +/*N*/ &pTxtNd->GetNodes() != ((SwAutoFmtGetDocNode&)rInfo).pNodes ) +/*N*/ return TRUE; +/*N*/ +/*N*/ ((SwAutoFmtGetDocNode&)rInfo).pCntntNode = pTxtNd; +/*N*/ return FALSE; +/*N*/ } + + +/*N*/ BOOL SwFmtFld::IsFldInDoc() const +/*N*/ { +/*N*/ const SwTxtNode* pTxtNd; +/*N*/ return pTxtAttr && 0 != ( pTxtNd = pTxtAttr->GetpTxtNode() ) && +/*N*/ pTxtNd->GetNodes().IsDocNodes(); +/*N*/ } + + +/************************************************************************* +|* +|* SwTxtFld::SwTxtFld() +|* +|* Beschreibung Attribut fuer automatischen Text, Ctor +|* Ersterstellung BP 30.04.92 +|* Letzte Aenderung JP 15.08.94 +|* +*************************************************************************/ + +/*N*/ SwTxtFld::SwTxtFld( const SwFmtFld& rAttr, xub_StrLen nStart ) +/*N*/ : SwTxtAttr( rAttr, nStart ), +/*N*/ aExpand( rAttr.GetFld()->Expand() ), +/*N*/ pMyTxtNd( 0 ) +/*N*/ { +/*N*/ ((SwFmtFld&)rAttr).pTxtAttr = this; +/*N*/ } + +/*N*/ SwTxtFld::~SwTxtFld( ) +/*N*/ { +/*N*/ } + +/************************************************************************* +|* +|* SwTxtFld::Expand() +|* +|* Beschreibung exandiert das Feld und tauscht den Text im Node +|* Ersterstellung BP 30.04.92 +|* Letzte Aenderung JP 15.08.94 +|* +*************************************************************************/ + +/*N*/ void SwTxtFld::Expand() +/*N*/ { +/*N*/ // Wenn das expandierte Feld sich nicht veraendert hat, wird returnt +/*N*/ ASSERT( pMyTxtNd, "wo ist denn mein Node?" ); +/*N*/ +/*N*/ const SwField* pFld = GetFld().GetFld(); +/*N*/ XubString aNewExpand( pFld->Expand() ); +/*N*/ +/*N*/ if( aNewExpand == aExpand ) +/*N*/ { +/*N*/ // Bei Seitennummernfeldern +/*N*/ const USHORT nWhich = pFld->GetTyp()->Which(); +/*N*/ if( RES_CHAPTERFLD != nWhich && RES_PAGENUMBERFLD != nWhich && +/*N*/ RES_REFPAGEGETFLD != nWhich && +/*N*/ ( RES_GETEXPFLD != nWhich || +/*N*/ ((SwGetExpField*)pFld)->IsInBodyTxt() ) ) +/*N*/ { +/*N*/ // BP: das muesste man noch optimieren! +/*N*/ //JP 12.06.97: stimmt, man sollte auf jedenfall eine Status- +/*N*/ // aenderung an die Frames posten +/*N*/ if( pMyTxtNd->CalcVisibleFlag() ) +/*?*/ pMyTxtNd->Modify( 0, 0 ); +/*N*/ return; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ aExpand = aNewExpand; +/*N*/ +/*N*/ // 0, this fuer Formatieren +/*N*/ pMyTxtNd->Modify( 0, (SfxPoolItem*)&GetFld() ); +/*N*/ } + +/************************************************************************* + * SwTxtFld::CopyFld() + *************************************************************************/ + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/txtnode/sw_atrflyin.cxx b/binfilter/bf_sw/source/core/txtnode/sw_atrflyin.cxx new file mode 100644 index 000000000000..791a7ed02bd7 --- /dev/null +++ b/binfilter/bf_sw/source/core/txtnode/sw_atrflyin.cxx @@ -0,0 +1,276 @@ +/* -*- 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. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include "cntfrm.hxx" // _GetFly + +#include <horiornt.hxx> + +#include "doc.hxx" +#include "pam.hxx" // fuer SwTxtFlyCnt +#include "ndtxt.hxx" // SwFlyFrmFmt +#include "frmfmt.hxx" // SwFlyFrmFmt + +#include <fmtflcnt.hxx> +#include <txtflcnt.hxx> +#include <fmtanchr.hxx> +#include "txtfrm.hxx" +#include "flyfrms.hxx" +namespace binfilter { + +/*N*/ SwFmtFlyCnt::SwFmtFlyCnt( SwFrmFmt *pFrmFmt ) +/*N*/ : SfxPoolItem( RES_TXTATR_FLYCNT ), +/*N*/ pFmt( pFrmFmt ), +/*N*/ pTxtAttr( 0 ) +/*N*/ { +/*N*/ } + +int __EXPORT SwFmtFlyCnt::operator==( const SfxPoolItem& rAttr ) const +{ + DBG_BF_ASSERT(0, "STRIP"); return 0; //STRIP001 ASSERT( SfxPoolItem::operator==( rAttr ), "keine gleichen Attribute" ); +} + +/*N*/ SfxPoolItem* __EXPORT SwFmtFlyCnt::Clone( SfxItemPool* ) const +/*N*/ { +/*N*/ return new SwFmtFlyCnt( pFmt ); +/*N*/ } + +/*N*/ SwTxtFlyCnt::SwTxtFlyCnt( const SwFmtFlyCnt& rAttr, xub_StrLen nStart ) +/*N*/ : SwTxtAttr( rAttr, nStart ) +/*N*/ { +/*N*/ ((SwFmtFlyCnt&)rAttr).pTxtAttr = this; +/*N*/ } + + + +/************************************************************************* + * SwTxtFlyCnt::MakeTxtHint() + * + * An dieser Stelle soll einmal der Gesamtzusammenhang bei der Erzeugung + * eines neuen SwTxtFlyCnt erlaeutert werden. + * Das MakeTxtHint() wird z.B. im SwTxtNode::Copy() gerufen. + * Fuer die komplette Verdopplung sind folgende Schritte notwendig: + * 1) Duplizieren des pFmt incl. Inhalt, Attributen etc. + * 2) Setzen des Ankers + * 3) Benachrichtigung + * Da fuer die Bewaeltigung der Aufgaben nicht immer alle Informationen + * bereitstehen und darueber hinaus bestimmte Methoden erst zu einem + * spaeteren Zeitpunkt gerufen werden duerfen (weil nocht nicht alle + * Nodeinformationen vorliegen), verteilt sich der Ablauf. + * ad 1) MakeTxtHint() wird durch den Aufruf von SwDoc::CopyLayout() + * der das neue FlyFrmFmt erzeugt und mit dem duplizierten Inhalt des + * FlyFrm verbunden. + * ad 2) SetAnchor() wird von SwTxtNode::Insert() gerufen und sorgt fuer das + * setzen des Ankers (die SwPosition des Dummy-Zeichens wird dem FlyFrmFmt + * per SetAttr bekannt gegeben). Dies kann nicht im MakeTxtHint erledigt + * werden, da der Zielnode unbestimmt ist. + * ad 3) _GetFlyFrm() wird im Formatierungsprozess vom LineIter gerufen + * und sucht den FlyFrm zum Dummyzeichen des aktuellen CntntFrm. Wird keiner + * gefunden, so wird ein neuer FlyFrm angelegt. + * Kritisch an diesem Vorgehen ist, dass das pCntnt->AppendFly() eine + * sofortige Neuformatierung von pCntnt anstoesst. Die Rekursion kommt + * allerdings durch den Lockmechanismus in SwTxtFrm::Format() nicht + * zu stande. + * Attraktiv ist der Umstand, dass niemand ueber die vom Node abhaengigen + * CntntFrms iterieren braucht, um die FlyInCntFrm anzulegen. Dies geschieht + * bei der Arbeit. + *************************************************************************/ + +/*N*/ void SwTxtFlyCnt::CopyFlyFmt( SwDoc* pDoc ) +/*N*/ { +/*N*/ SwFrmFmt* pFmt = GetFlyCnt().GetFrmFmt(); +/*N*/ ASSERT( pFmt, "von welchem Format soll ich eine Kopie erzeugen?" ) +/*N*/ // Das FlyFrmFmt muss dupliziert werden. +/*N*/ // In CopyLayoutFmt (siehe doclay.cxx) wird das FlyFrmFmt erzeugt +/*N*/ // und der Inhalt dupliziert. +/*N*/ +/*N*/ // fuers kopieren vom Attribut das Undo immer abschalten +/*N*/ SwFmtAnchor aAnchor( pFmt->GetAnchor() ); +/*N*/ if( FLY_PAGE != aAnchor.GetAnchorId() && +/*N*/ pDoc != pFmt->GetDoc() ) // Unterschiedliche Docs? +/*N*/ { +/*N*/ // JP 03.06.96: dann sorge dafuer, das der koperierte Anker auf +/*N*/ // gueltigen Content zeigt! Die Umsetzung auf die +/*N*/ // richtige Position erfolgt spaeter. +/*?*/ SwNodeIndex aIdx( pDoc->GetNodes().GetEndOfExtras(), +2 ); +/*?*/ SwCntntNode* pCNd = aIdx.GetNode().GetCntntNode(); +/*?*/ if( !pCNd ) +/*?*/ pCNd = pDoc->GetNodes().GoNext( &aIdx ); +/*?*/ +/*?*/ SwPosition* pPos = (SwPosition*)aAnchor.GetCntntAnchor(); +/*?*/ pPos->nNode = aIdx; +/*?*/ if( FLY_IN_CNTNT == aAnchor.GetAnchorId() ) +/*?*/ pPos->nContent.Assign( pCNd, 0 ); +/*?*/ else +/*?*/ { +/*?*/ pPos->nContent.Assign( 0, 0 ); +/*?*/ ASSERT( !this, "CopyFlyFmt: Was fuer ein Anker?" ); +/*?*/ } +/*N*/ } +/*N*/ +/*N*/ SwFrmFmt* pNew = pDoc->CopyLayoutFmt( *pFmt, aAnchor, FALSE, FALSE ); +/*N*/ ((SwFmtFlyCnt&)GetFlyCnt()).SetFlyFmt( pNew ); +/*N*/ } + +/************************************************************************* + * SwTxtFlyCnt::SetAnchor() + * + * SetAnchor() wird von SwTxtNode::Insert() gerufen und sorgt fuer das + * setzen des Ankers (die SwPosition des Dummy-Zeichens wird dem FlyFrmFmt + * per SetAttr bekannt gegeben). Dies kann nicht im MakeTxtHint erledigt + * werden, da der Zielnode unbestimmt ist. + * (siehe Kommentar in SwTxtFlyCnt::MakeTxtHint) + *************************************************************************/ + +/*N*/ void SwTxtFlyCnt::SetAnchor( const SwTxtNode *pNode ) +/*N*/ { +/*N*/ // Wir ermitteln den Index im Nodesarray zum Node +/*N*/ +/*N*/ SwDoc* pDoc = (SwDoc*)pNode->GetDoc(); +/*N*/ +/*N*/ SwIndex aIdx( (SwTxtNode*)pNode, *GetStart() ); +/*N*/ SwPosition aPos( *pNode->StartOfSectionNode(), aIdx ); +/*N*/ SwFrmFmt* pFmt = GetFlyCnt().GetFrmFmt(); +/*N*/ SwFmtAnchor aAnchor( pFmt->GetAnchor() ); +/*N*/ +/*N*/ if( !aAnchor.GetCntntAnchor() || +/*N*/ !aAnchor.GetCntntAnchor()->nNode.GetNode().GetNodes().IsDocNodes() || +/*N*/ &aAnchor.GetCntntAnchor()->nNode.GetNode() != (SwNode*)pNode ) +/*N*/ aPos.nNode = *pNode; +/*N*/ else +/*N*/ aPos.nNode = aAnchor.GetCntntAnchor()->nNode; +/*N*/ +/*N*/ aAnchor.SetType( FLY_IN_CNTNT ); // defaulten !! +/*N*/ aAnchor.SetAnchor( &aPos ); +/*N*/ +/*N*/ // beim Ankerwechsel werden immer alle FlyFrms vom Attribut geloescht +/*N*/ // JP 25.04.95: wird innerhalb des SplitNodes die Frames verschoben +/*N*/ // koennen die Frames erhalten bleiben. +/*N*/ if( ( !pNode->GetpSwpHints() || !pNode->GetpSwpHints()->IsInSplitNode() ) +/*N*/ && RES_DRAWFRMFMT != pFmt->Which() ) +/*N*/ pFmt->DelFrms(); +/*N*/ +/*N*/ // stehen wir noch im falschen Dokument ? +/*N*/ if( pDoc != pFmt->GetDoc() ) +/*N*/ { +/*?*/ SwFrmFmt* pNew = pDoc->CopyLayoutFmt( *pFmt, aAnchor, FALSE, FALSE ); +/*?*/ +/*?*/ pFmt->GetDoc()->DelLayoutFmt( pFmt ); +/*?*/ ((SwFmtFlyCnt&)GetFlyCnt()).SetFlyFmt( pNew ); +/*N*/ } +/*N*/ else if( pNode->GetpSwpHints() && +/*N*/ pNode->GetpSwpHints()->IsInSplitNode() && +/*N*/ RES_DRAWFRMFMT != pFmt->Which() ) +/*N*/ { +/*?*/ pFmt->LockModify(); +/*?*/ pFmt->SetAttr( aAnchor ); // nur den Anker neu setzen +/*?*/ pFmt->UnlockModify(); +/*N*/ } +/*N*/ else +/*N*/ pFmt->SetAttr( aAnchor ); // nur den Anker neu setzen +/*N*/ +/*N*/ // Am Node haengen u.a. abhaengige CntFrms. +/*N*/ // Fuer jeden CntFrm wird ein SwFlyInCntFrm angelegt. +/*N*/ } + +/************************************************************************* + * SwTxtFlyCnt::_GetFlyFrm() + * + * _GetFlyFrm() wird im Formatierungsprozess vom LineIter gerufen + * und sucht den FlyFrm zum Dummyzeichen des aktuellen CntntFrm. Wird keiner + * gefunden, so wird ein neuer FlyFrm angelegt. + * (siehe Kommentar ind SwTxtFlyCnt::MakeTxtHint) + *************************************************************************/ + +/*N*/ SwFlyInCntFrm *SwTxtFlyCnt::_GetFlyFrm( const SwFrm *pCurrFrm ) +/*N*/ { +/*N*/ SwFrmFmt* pFrmFmt = GetFlyCnt().GetFrmFmt(); +/*N*/ if( RES_DRAWFRMFMT == pFrmFmt->Which() ) +/*N*/ { +/*?*/ ASSERT( !this, "SwTxtFlyCnt::_GetFlyFrm: DrawInCnt-Baustelle!" ); +/*?*/ return NULL; +/*N*/ } +/*N*/ +/*N*/ SwClientIter aIter( *GetFlyCnt().pFmt ); +/*N*/ ASSERT( pCurrFrm->IsTxtFrm(), "SwTxtFlyCnt::_GetFlyFrm for TxtFrms only." ); +/*N*/ +/*N*/ if( aIter.GoStart() ) +/*N*/ { +/*N*/ SwTxtFrm *pFirst = (SwTxtFrm*)pCurrFrm; +/*N*/ while ( pFirst->IsFollow() ) +/*?*/ pFirst = pFirst->FindMaster(); +/*N*/ do +/*N*/ { SwFrm * pFrm = PTR_CAST( SwFrm, aIter() ); +/*N*/ if ( pFrm ) +/*N*/ { +/*N*/ SwTxtFrm *pTmp = pFirst; +/*N*/ do +/*N*/ { if( ( (SwFlyFrm*)pFrm )->GetAnchor() == (SwFrm*) pTmp ) +/*N*/ { +/*N*/ if ( pTmp != pCurrFrm ) +/*N*/ { +/*?*/ pTmp->RemoveFly( (SwFlyFrm*)pFrm ); +/*?*/ ((SwTxtFrm*)pCurrFrm)->AppendFly( (SwFlyFrm*)pFrm ); +/*N*/ } +/*N*/ return (SwFlyInCntFrm*)pFrm; +/*N*/ } +/*?*/ pTmp = pTmp->GetFollow(); +/*N*/ } while ( pTmp ); +/*N*/ } +/*N*/ } while( aIter++ ); +/*N*/ } +/*N*/ +/*N*/ // Wir haben keinen passenden FlyFrm gefunden, deswegen wird ein +/*N*/ // neuer angelegt. +/*N*/ // Dabei wird eine sofortige Neuformatierung von pCurrFrm angestossen. +/*N*/ // Die Rekursion wird durch den Lockmechanismus in SwTxtFrm::Format() +/*N*/ // abgewuergt. +/*N*/ SwFlyInCntFrm *pFly = new SwFlyInCntFrm( (SwFlyFrmFmt*)pFrmFmt, (SwFrm*)pCurrFrm ); +/*N*/ ((SwFrm*)pCurrFrm)->AppendFly( pFly ); +/*N*/ pFly->RegistFlys(); +/*N*/ +/*N*/ // 7922: Wir muessen dafuer sorgen, dass der Inhalt des FlyInCnt +/*N*/ // nach seiner Konstruktion stramm durchformatiert wird. +/*N*/ SwCntntFrm *pFrm = pFly->ContainsCntnt(); +/*N*/ while( pFrm ) +/*N*/ { +/*N*/ pFrm->Calc(); +/*N*/ pFrm = pFrm->GetNextCntntFrm(); +/*N*/ } +/*N*/ +/*N*/ return pFly; +/*N*/ } + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/txtnode/sw_atrftn.cxx b/binfilter/bf_sw/source/core/txtnode/sw_atrftn.cxx new file mode 100644 index 000000000000..0043556c3ba5 --- /dev/null +++ b/binfilter/bf_sw/source/core/txtnode/sw_atrftn.cxx @@ -0,0 +1,443 @@ +/* -*- 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. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#define _SVSTDARR_USHORTS +#define _SVSTDARR_USHORTSSORT + +#include <horiornt.hxx> + +#include <doc.hxx> +#include <cntfrm.hxx> // ASSERT in ~SwTxtFtn() +#include <pagefrm.hxx> // RemoveFtn() +#include <fmtftn.hxx> +#include <txtftn.hxx> +#include <ftnidx.hxx> +#include <ftninfo.hxx> +#include <ndtxt.hxx> +#include <poolfmt.hxx> +#include <ftnfrm.hxx> +#include <ndindex.hxx> +#include <fmtftntx.hxx> +#include <section.hxx> +namespace binfilter { + +/************************************************************************* +|* +|* class SwFmtFtn +|* +|* Beschreibung +|* Ersterstellung JP 09.08.94 +|* Letzte Aenderung JP 08.08.94 +|* +*************************************************************************/ + + +/*N*/ SwFmtFtn::SwFmtFtn( BOOL bEN ) +/*N*/ : SfxPoolItem( RES_TXTATR_FTN ), +/*N*/ nNumber( 0 ), +/*N*/ pTxtAttr( 0 ), +/*N*/ bEndNote( bEN ) +/*N*/ { +/*N*/ } + + +int SwFmtFtn::operator==( const SfxPoolItem& rAttr ) const +{ + {DBG_BF_ASSERT(0, "STRIP");} return 0;//STRIP001 ASSERT( SfxPoolItem::operator==( rAttr ), "keine gleichen Attribute" ); +} + + +/*N*/ SfxPoolItem* SwFmtFtn::Clone( SfxItemPool* ) const +/*N*/ { +/*N*/ SwFmtFtn* pNew = new SwFmtFtn; +/*N*/ pNew->aNumber = aNumber; +/*N*/ pNew->nNumber = nNumber; +/*N*/ pNew->bEndNote = bEndNote; +/*N*/ return pNew; +/*N*/ } + +void SwFmtFtn::SetEndNote( BOOL b ) +{ + if ( b != bEndNote ) + { + if ( GetTxtFtn() ) + GetTxtFtn()->DelFrms(); + bEndNote = b; + } +} + +/*N*/ SwFmtFtn::~SwFmtFtn() +/*N*/ { +/*N*/ } + + + + // returnt den anzuzeigenden String der Fuss-/Endnote +/*N*/ XubString SwFmtFtn::GetViewNumStr( const SwDoc& rDoc, BOOL bInclStrings ) const +/*N*/ { +/*N*/ XubString sRet( GetNumStr() ); +/*N*/ if( !sRet.Len() ) +/*N*/ { +/*N*/ // dann ist die Nummer von Interesse, also ueber die Info diese +/*N*/ // besorgen. +/*N*/ BOOL bMakeNum = TRUE; +/*N*/ const SwSectionNode* pSectNd = pTxtAttr +/*N*/ ? SwUpdFtnEndNtAtEnd::FindSectNdWithEndAttr( *pTxtAttr ) +/*N*/ : 0; +/*N*/ +/*N*/ if( pSectNd ) +/*N*/ { +/*N*/ const SwFmtFtnEndAtTxtEnd& rFtnEnd = (SwFmtFtnEndAtTxtEnd&) +/*N*/ pSectNd->GetSection().GetFmt()->GetAttr( +/*?*/ IsEndNote() ? RES_END_AT_TXTEND : RES_FTN_AT_TXTEND ); +/*N*/ +/*N*/ if( FTNEND_ATTXTEND_OWNNUMANDFMT == rFtnEnd.GetValue() ) +/*N*/ { +/*?*/ bMakeNum = FALSE; +/*?*/ sRet = rFtnEnd.GetSwNumType().GetNumStr( GetNumber() ); +/*?*/ if( bInclStrings ) +/*?*/ { +/*?*/ sRet.Insert( rFtnEnd.GetPrefix(), 0 ); +/*?*/ sRet += rFtnEnd.GetSuffix(); +/*?*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if( bMakeNum ) +/*N*/ { +/*N*/ const SwEndNoteInfo* pInfo; +/*N*/ if( IsEndNote() ) +/*?*/ pInfo = &rDoc.GetEndNoteInfo(); +/*N*/ else +/*N*/ pInfo = &rDoc.GetFtnInfo(); +/*N*/ sRet = pInfo->aFmt.GetNumStr( GetNumber() ); +/*N*/ if( bInclStrings ) +/*N*/ { +/*N*/ sRet.Insert( pInfo->GetPrefix(), 0 ); +/*N*/ sRet += pInfo->GetSuffix(); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ return sRet; +/*N*/ } + +/************************************************************************* + * class SwTxt/FmtFnt + *************************************************************************/ + +/*N*/ SwTxtFtn::SwTxtFtn( const SwFmtFtn& rAttr, xub_StrLen nStart ) +/*N*/ : SwTxtAttr( rAttr, nStart ), +/*N*/ pMyTxtNd( 0 ), +/*N*/ pStartNode( 0 ), +/*N*/ nSeqNo( USHRT_MAX ) +/*N*/ { +/*N*/ ((SwFmtFtn&)rAttr).pTxtAttr = this; +/*N*/ } + + +/*N*/ SwTxtFtn::~SwTxtFtn() +/*N*/ { +/*N*/ SetStartNode( 0 ); +/*N*/ } + + + +/*N*/ void SwTxtFtn::SetStartNode( const SwNodeIndex *pNewNode, BOOL bDelNode ) +/*N*/ { +/*N*/ if( pNewNode ) +/*N*/ { +/*N*/ if( !pStartNode ) +/*N*/ pStartNode = new SwNodeIndex( *pNewNode ); +/*N*/ else +/*N*/ *pStartNode = *pNewNode; +/*N*/ } +/*N*/ else if( pStartNode ) +/*N*/ { +/*N*/ // Zwei Dinge muessen erledigt werden: +/*N*/ // 1) Die Fussnoten muessen bei ihren Seiten abgemeldet werden +/*N*/ // 2) Die Fussnoten-Sektion in den Inserts muss geloescht werden. +/*N*/ SwDoc* pDoc; +/*N*/ if( pMyTxtNd ) +/*N*/ pDoc = pMyTxtNd->GetDoc(); +/*N*/ else +/*N*/ { +/*N*/ //JP 27.01.97: der sw3-Reader setzt einen StartNode aber das +/*N*/ // Attribut ist noch nicht im TextNode verankert. +/*N*/ // Wird es geloescht (z.B. bei Datei einfuegen mit +/*N*/ // Ftn in einen Rahmen), muss auch der Inhalt +/*N*/ // geloescht werden +/*?*/ pDoc = pStartNode->GetNodes().GetDoc(); +/*N*/ } +/*N*/ +/*N*/ // Wir duerfen die Fussnotennodes nicht loeschen +/*N*/ // und brauchen die Fussnotenframes nicht loeschen, wenn +/*N*/ // wir im ~SwDoc() stehen. +/*N*/ if( !pDoc->IsInDtor() ) +/*N*/ { +/*?*/ if( bDelNode ) +/*?*/ { +/*?*/ // 1) Die Section fuer die Fussnote wird beseitigt +/*?*/ // Es kann sein, dass die Inserts schon geloescht wurden. +/*?*/ pDoc->DeleteSection( &pStartNode->GetNode() ); +/*?*/ } +/*?*/ else +/*?*/ // Werden die Nodes nicht geloescht mussen sie bei den Seiten +/*?*/ // abmeldet (Frms loeschen) werden, denn sonst bleiben sie +/*?*/ // stehen (Undo loescht sie nicht!) + {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 /*?*/ DelFrms(); +/*N*/ } +/*N*/ DELETEZ( pStartNode ); +/*N*/ +/*N*/ // loesche die Fussnote noch aus dem Array am Dokument +/*N*/ for( USHORT n = 0; n < pDoc->GetFtnIdxs().Count(); ++n ) +/*?*/ if( this == pDoc->GetFtnIdxs()[n] ) +/*?*/ { +/*?*/ pDoc->GetFtnIdxs().Remove( n ); +/*?*/ // gibt noch weitere Fussnoten +/*?*/ if( !pDoc->IsInDtor() && n < pDoc->GetFtnIdxs().Count() ) +/*?*/ { +/*?*/ SwNodeIndex aTmp( pDoc->GetFtnIdxs()[n]->GetTxtNode() ); +/*?*/ pDoc->GetFtnIdxs().UpdateFtn( aTmp ); +/*?*/ } +/*?*/ break; +/*?*/ } +/*N*/ } +/*N*/ } + + +/*N*/ void SwTxtFtn::SetNumber( const USHORT nNewNum, const XubString* pStr ) +/*N*/ { +/*N*/ SwFmtFtn& rFtn = (SwFmtFtn&)GetFtn(); +/*N*/ if( pStr && pStr->Len() ) +/*N*/ rFtn.aNumber = *pStr; +/*N*/ else +/*N*/ { +/*N*/ rFtn.nNumber = nNewNum; +/*N*/ rFtn.aNumber = aEmptyStr; +/*N*/ } +/*N*/ +/*N*/ ASSERT( pMyTxtNd, "wo ist mein TextNode?" ); +/*N*/ SwNodes &rNodes = pMyTxtNd->GetDoc()->GetNodes(); +/*N*/ pMyTxtNd->Modify( 0, &rFtn ); +/*N*/ if( pStartNode ) +/*N*/ { +/*N*/ // Wir muessen ueber alle TxtNodes iterieren, wegen der +/*N*/ // Fussnoten, die auf anderen Seiten stehen. +/*N*/ SwNode* pNd; +/*N*/ ULONG nSttIdx = pStartNode->GetIndex() + 1, +/*N*/ nEndIdx = pStartNode->GetNode().EndOfSectionIndex(); +/*N*/ for( ; nSttIdx < nEndIdx; ++nSttIdx ) +/*N*/ { +/*N*/ // Es koennen ja auch Grafiken in der Fussnote stehen ... +/*N*/ if( ( pNd = rNodes[ nSttIdx ] )->IsTxtNode() ) +/*N*/ ((SwTxtNode*)pNd)->Modify( 0, &rFtn ); +/*N*/ } +/*N*/ } +/*N*/ } + +// Die Fussnoten duplizieren + + + // lege eine neue leere TextSection fuer diese Fussnote an +/*N*/ void SwTxtFtn::MakeNewTextSection( SwNodes& rNodes ) +/*N*/ { +/*N*/ if( pStartNode ) +/*N*/ return; +/*N*/ +/*N*/ // Nun verpassen wir dem TxtNode noch die Fussnotenvorlage. +/*N*/ SwTxtFmtColl *pFmtColl; +/*N*/ const SwEndNoteInfo* pInfo; +/*N*/ USHORT nPoolId; +/*N*/ +/*N*/ if( GetFtn().IsEndNote() ) +/*N*/ { +/*?*/ pInfo = &rNodes.GetDoc()->GetEndNoteInfo(); +/*?*/ nPoolId = RES_POOLCOLL_ENDNOTE; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ pInfo = &rNodes.GetDoc()->GetFtnInfo(); +/*N*/ nPoolId = RES_POOLCOLL_FOOTNOTE; +/*N*/ } +/*N*/ +/*N*/ if( 0 == (pFmtColl = pInfo->GetFtnTxtColl() ) ) +/*N*/ pFmtColl = rNodes.GetDoc()->GetTxtCollFromPool( nPoolId ); +/*N*/ +/*N*/ SwStartNode* pSttNd = rNodes.MakeTextSection( SwNodeIndex( rNodes.GetEndOfInserts() ), +/*N*/ SwFootnoteStartNode, pFmtColl ); +/*N*/ pStartNode = new SwNodeIndex( *pSttNd ); +/*N*/ } + + + void SwTxtFtn::DelFrms() + { + // loesche die Ftn-Frames aus den Seiten + ASSERT( pMyTxtNd, "wo ist mein TextNode?" ); + if( !pMyTxtNd ) + return ; + + BOOL bFrmFnd = FALSE; + { + SwClientIter aIter( *pMyTxtNd ); + for( SwCntntFrm* pFnd = (SwCntntFrm*)aIter.First( TYPE( SwCntntFrm )); + pFnd; pFnd = (SwCntntFrm*)aIter.Next() ) + { + SwPageFrm* pPage = pFnd->FindPageFrm(); + if( pPage ) + { + pPage->RemoveFtn( pFnd, this ); + bFrmFnd = TRUE; + } + } + } + //JP 13.05.97: falls das Layout vorm loeschen der Fussnoten entfernt + // wird, sollte man das ueber die Fussnote selbst tun + if( !bFrmFnd && pStartNode ) + { + SwNodeIndex aIdx( *pStartNode ); + SwCntntNode* pCNd = pMyTxtNd->GetNodes().GoNext( &aIdx ); + if( pCNd ) + { + SwClientIter aIter( *pCNd ); + for( SwCntntFrm* pFnd = (SwCntntFrm*)aIter.First( TYPE( SwCntntFrm )); + pFnd; pFnd = (SwCntntFrm*)aIter.Next() ) + { + SwPageFrm* pPage = pFnd->FindPageFrm(); + + SwFrm *pFrm = pFnd->GetUpper(); + while ( pFrm && !pFrm->IsFtnFrm() ) + pFrm = pFrm->GetUpper(); + + SwFtnFrm *pFtn = (SwFtnFrm*)pFrm; + while ( pFtn && pFtn->GetMaster() ) + pFtn = pFtn->GetMaster(); + ASSERT( pFtn->GetAttr() == this, "Ftn mismatch error." ); + + while ( pFtn ) + { + SwFtnFrm *pFoll = pFtn->GetFollow(); + pFtn->Cut(); + delete pFtn; + pFtn = pFoll; + } + pPage->UpdateFtnNum(); + } + } + } + } + + +/*N*/ USHORT SwTxtFtn::SetSeqRefNo() +/*N*/ { +/*N*/ if( !pMyTxtNd ) +/*N*/ return USHRT_MAX; +/*N*/ +/*N*/ SwDoc* pDoc = pMyTxtNd->GetDoc(); +/*N*/ if( pDoc->IsInReading() ) +/*N*/ return USHRT_MAX; +/*N*/ +/*N*/ USHORT n, nFtnCnt = pDoc->GetFtnIdxs().Count(); +/*N*/ +/*N*/ BYTE nTmp = 255 < nFtnCnt ? 255 : nFtnCnt; +/*N*/ SvUShortsSort aArr( nTmp, nTmp ); +/*N*/ +/*N*/ // dann testmal, ob die Nummer schon vergeben ist oder ob eine neue +/*N*/ // bestimmt werden muss. +/*N*/ SwTxtFtn* pTxtFtn; +/*N*/ for( n = 0; n < nFtnCnt; ++n ) +/*N*/ if( (pTxtFtn = pDoc->GetFtnIdxs()[ n ]) != this ) +/*?*/ aArr.Insert( pTxtFtn->nSeqNo ); +/*N*/ +/*N*/ // teste erstmal ob die Nummer schon vorhanden ist: +/*N*/ if( USHRT_MAX != nSeqNo ) +/*N*/ { +/*N*/ for( n = 0; n < aArr.Count(); ++n ) +/*?*/ if( aArr[ n ] > nSeqNo ) +/*?*/ return nSeqNo; // nicht vorhanden -> also benutzen +/*?*/ else if( aArr[ n ] == nSeqNo ) +/*?*/ break; // schon vorhanden -> neue erzeugen +/*N*/ +/*N*/ if( n == aArr.Count() ) +/*N*/ return nSeqNo; // nicht vorhanden -> also benutzen +/*N*/ } +/*N*/ +/*N*/ // alle Nummern entsprechend geflag, also bestimme die richtige Nummer +/*N*/ for( n = 0; n < aArr.Count(); ++n ) +/*N*/ if( n != aArr[ n ] ) +/*N*/ break; +/*N*/ +/*N*/ return nSeqNo = n; +/*N*/ } + +/*N*/ void SwTxtFtn::SetUniqueSeqRefNo( SwDoc& rDoc ) +/*N*/ { +/*N*/ USHORT n, nStt = 0, nFtnCnt = rDoc.GetFtnIdxs().Count(); +/*N*/ +/*N*/ BYTE nTmp = 255 < nFtnCnt ? 255 : nFtnCnt; +/*N*/ SvUShortsSort aArr( nTmp, nTmp ); +/*N*/ +/*N*/ // dann alle Nummern zusammensammeln die schon existieren +/*N*/ SwTxtFtn* pTxtFtn; +/*N*/ for( n = 0; n < nFtnCnt; ++n ) +/*N*/ if( USHRT_MAX != (pTxtFtn = rDoc.GetFtnIdxs()[ n ])->nSeqNo ) +/*N*/ aArr.Insert( pTxtFtn->nSeqNo ); +/*N*/ +/*N*/ +/*N*/ for( n = 0; n < nFtnCnt; ++n ) +/*N*/ if( USHRT_MAX == (pTxtFtn = rDoc.GetFtnIdxs()[ n ])->nSeqNo ) +/*N*/ { +/*N*/ for( ; nStt < aArr.Count(); ++nStt ) +/*?*/ if( nStt != aArr[ nStt ] ) +/*?*/ { +/*?*/ +/*?*/ pTxtFtn->nSeqNo = nStt; +/*?*/ break; +/*?*/ } +/*N*/ +/*N*/ if( USHRT_MAX == pTxtFtn->nSeqNo ) +/*N*/ break; // nichts mehr gefunden +/*N*/ } +/*N*/ +/*N*/ // alle Nummern schon vergeben, also mit nStt++ weitermachen +/*N*/ for( ; n < nFtnCnt; ++n ) +/*N*/ if( USHRT_MAX == (pTxtFtn = rDoc.GetFtnIdxs()[ n ])->nSeqNo ) +/*N*/ pTxtFtn->nSeqNo = nStt++; +/*N*/ } + + + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/txtnode/sw_atrref.cxx b/binfilter/bf_sw/source/core/txtnode/sw_atrref.cxx new file mode 100644 index 000000000000..efb670407ae3 --- /dev/null +++ b/binfilter/bf_sw/source/core/txtnode/sw_atrref.cxx @@ -0,0 +1,103 @@ +/* -*- 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. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include <txtrfmrk.hxx> +#include <fmtrfmrk.hxx> +namespace binfilter { + + +/**************************************************************************** + * + * class SwFmtRefMark + * + ****************************************************************************/ + +/*N*/ SwFmtRefMark::~SwFmtRefMark( ) +/*N*/ { +/*N*/ } + +/*N*/ SwFmtRefMark::SwFmtRefMark( const XubString& rName ) +/*N*/ : SfxPoolItem( RES_TXTATR_REFMARK ), +/*N*/ aRefName( rName ), +/*N*/ pTxtAttr( 0 ) +/*N*/ { +/*N*/ } + +/*N*/ SwFmtRefMark::SwFmtRefMark( const SwFmtRefMark& rAttr ) +/*N*/ : SfxPoolItem( RES_TXTATR_REFMARK ), +/*N*/ aRefName( rAttr.aRefName ), +/*N*/ pTxtAttr( 0 ) +/*N*/ { +/*N*/ } + +int SwFmtRefMark::operator==( const SfxPoolItem& rAttr ) const +{ + {DBG_BF_ASSERT(0, "STRIP");} return 0;//STRIP001 ASSERT( SfxPoolItem::operator==( rAttr ), "keine gleichen Attribute" ); +} + +/*N*/ SfxPoolItem* SwFmtRefMark::Clone( SfxItemPool* ) const +/*N*/ { +/*N*/ return new SwFmtRefMark( *this ); +/*N*/ } + +/************************************************************************* + * class SwTxtRefMark + *************************************************************************/ + +// Attribut fuer Inhalts-/Positions-Referenzen im Text + +/*N*/ SwTxtRefMark::SwTxtRefMark( const SwFmtRefMark& rAttr, +/*N*/ xub_StrLen nStart, xub_StrLen* pEnde ) +/*N*/ : SwTxtAttrEnd( rAttr, nStart, nStart ), +/*N*/ pEnd( 0 ), +/*N*/ pMyTxtNd( 0 ) +/*N*/ { +/*N*/ ((SwFmtRefMark&)rAttr).pTxtAttr = this; +/*N*/ if( pEnde ) +/*N*/ { +/*N*/ nEnd = *pEnde; +/*N*/ pEnd = &nEnd; +/*N*/ } +/*N*/ SetDontMergeAttr( TRUE ); +/*N*/ SetDontMoveAttr( TRUE ); +/*N*/ SetOverlapAllowedAttr( TRUE ); +/*N*/ } + +/*N*/ xub_StrLen* SwTxtRefMark::GetEnd() +/*N*/ { +/*N*/ return pEnd; +/*N*/ } + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/txtnode/sw_atrtox.cxx b/binfilter/bf_sw/source/core/txtnode/sw_atrtox.cxx new file mode 100644 index 000000000000..de3ed2a13511 --- /dev/null +++ b/binfilter/bf_sw/source/core/txtnode/sw_atrtox.cxx @@ -0,0 +1,99 @@ +/* -*- 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. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include <horiornt.hxx> + +#include <doc.hxx> +#include <txttxmrk.hxx> +#include <tox.hxx> +namespace binfilter { + +/*N*/ SwTxtTOXMark::SwTxtTOXMark( const SwTOXMark& rAttr, +/*N*/ xub_StrLen nStart, xub_StrLen* pEnde ) +/*N*/ : SwTxtAttrEnd( rAttr, nStart, nStart ), +/*N*/ pEnd( 0 ), +/*N*/ pMyTxtNd( 0 ) +/*N*/ { +/*N*/ ((SwTOXMark&)rAttr).pTxtAttr = this; +/*N*/ if( !rAttr.GetAlternativeText().Len() ) +/*N*/ { +/*N*/ nEnd = *pEnde; +/*N*/ pEnd = &nEnd; +/*N*/ } +/*N*/ SetDontMergeAttr( TRUE ); +/*N*/ SetDontMoveAttr( TRUE ); +/*N*/ SetOverlapAllowedAttr( TRUE ); +/*N*/ } + +/*N*/ SwTxtTOXMark::~SwTxtTOXMark() +/*N*/ { +/*N*/ } + +/*N*/ xub_StrLen* SwTxtTOXMark::GetEnd() +/*N*/ { +/*N*/ return pEnd; +/*N*/ } + +/*N*/ void SwTxtTOXMark::CopyTOXMark( SwDoc* pDoc ) +/*N*/ { +/*N*/ SwTOXMark& rTOX = (SwTOXMark&)GetTOXMark(); +/*N*/ TOXTypes eType = rTOX.GetTOXType()->GetType(); +/*N*/ USHORT nCount = pDoc->GetTOXTypeCount( eType ); +/*N*/ const SwTOXType* pType = 0; +/*N*/ const XubString& rNm = rTOX.GetTOXType()->GetTypeName(); +/*N*/ +/*N*/ // kein entsprechender Verzeichnistyp vorhanden -> anlegen +/*N*/ // sonst verwenden +/*N*/ for(USHORT i=0; i < nCount; ++i) +/*N*/ { +/*N*/ const SwTOXType* pSrcType = pDoc->GetTOXType(eType, i); +/*N*/ if(pSrcType->GetTypeName() == rNm ) +/*N*/ { +/*N*/ pType = pSrcType; +/*N*/ break; +/*N*/ } +/*N*/ } +/*N*/ // kein entsprechender Typ vorhanden -> neu erzeugen +/*N*/ // +/*N*/ if(!pType) +/*N*/ { +/*N*/ pDoc->InsertTOXType( SwTOXType( eType, rNm ) ); +/*N*/ pType = pDoc->GetTOXType(eType, 0); +/*N*/ } +/*N*/ // Verzeichnistyp umhaengen +/*N*/ // +/*N*/ ((SwTOXType*)pType)->Add( &rTOX ); +/*N*/ } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/txtnode/sw_fmtatr1.cxx b/binfilter/bf_sw/source/core/txtnode/sw_fmtatr1.cxx new file mode 100644 index 000000000000..e542813bf342 --- /dev/null +++ b/binfilter/bf_sw/source/core/txtnode/sw_fmtatr1.cxx @@ -0,0 +1,81 @@ +/* -*- 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. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include <hintids.hxx> +#include <errhdl.hxx> +#include <fmthbsh.hxx> +namespace binfilter { + + +/************************************************************************* +|* +|* class SwFmtHardBlank +|* +|* Beschreibung Dokument 1.20 +|* Ersterstellung JP 23.11.90 +|* Letzte Aenderung JP 20.02.91 +|* +*************************************************************************/ + +/*N*/ SwFmtHardBlank::SwFmtHardBlank( sal_Unicode cCh, BOOL bCheck ) +/*N*/ : SfxPoolItem( RES_TXTATR_HARDBLANK ), +/*N*/ cChar( cCh ) +/*N*/ { +/*N*/ ASSERT( !bCheck || (' ' != cCh && '-' != cCh), +/*N*/ "Invalid character for the HardBlank attribute - " +/*N*/ "must be a normal unicode character" ); +/*N*/ } + + + +/************************************************************************* +|* +|* class SwFmtSoftHyph +|* +|* Beschreibung Dokument 1.20 +|* Ersterstellung JP 23.11.90 +|* Letzte Aenderung JP 20.02.91 +|* +*************************************************************************/ + +/*N*/ SwFmtSoftHyph::SwFmtSoftHyph() +/*N*/ : SfxPoolItem( RES_TXTATR_SOFTHYPH ) +/*N*/ { +/*N*/ } + + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/txtnode/sw_fmtatr2.cxx b/binfilter/bf_sw/source/core/txtnode/sw_fmtatr2.cxx new file mode 100644 index 000000000000..5f8c188babfd --- /dev/null +++ b/binfilter/bf_sw/source/core/txtnode/sw_fmtatr2.cxx @@ -0,0 +1,507 @@ +/* -*- 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. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include "unomid.h" + +#include <bf_svtools/macitem.hxx> + +#include <fchrfmt.hxx> +#include <fmtinfmt.hxx> +#include <txtatr.hxx> +#include <fmtruby.hxx> +#include <charfmt.hxx> + +#include <horiornt.hxx> + + +#include <cppuhelper/implbase4.hxx> + +#include <unoevent.hxx> // SwHyperlinkEventDescriptor +#include <com/sun/star/text/RubyAdjust.hdl> + +#include <cmdid.h> +#include <com/sun/star/uno/Any.h> +#include <SwStyleNameMapper.hxx> +namespace binfilter { + +using namespace ::com::sun::star; +using namespace ::rtl; + +/************************************************************************* +|* +|* class SwFmtCharFmt +|* Beschreibung +|* Ersterstellung JP 23.11.90 +|* Letzte Aenderung JP 09.08.94 +|* +*************************************************************************/ + +/*N*/ TYPEINIT1_AUTOFACTORY(SwFmtINetFmt, SfxPoolItem); + +/*N*/ SwFmtCharFmt::SwFmtCharFmt( SwCharFmt *pFmt ) +/*N*/ : SfxPoolItem( RES_TXTATR_CHARFMT ), +/*N*/ SwClient(pFmt), +/*N*/ pTxtAttr( 0 ) +/*N*/ { +/*N*/ } + + + +/*N*/ SwFmtCharFmt::SwFmtCharFmt( const SwFmtCharFmt& rAttr ) +/*N*/ : SfxPoolItem( RES_TXTATR_CHARFMT ), +/*N*/ SwClient( rAttr.GetCharFmt() ), +/*N*/ pTxtAttr( 0 ) +/*N*/ { +/*N*/ } + + + +/*N*/ SwFmtCharFmt::~SwFmtCharFmt() {} + + + +/*N*/ int SwFmtCharFmt::operator==( const SfxPoolItem& rAttr ) const +/*N*/ { +/*N*/ ASSERT( SfxPoolItem::operator==( rAttr ), "keine gleichen Attribute" ); +/*N*/ return GetCharFmt() == ((SwFmtCharFmt&)rAttr).GetCharFmt(); +/*N*/ } + + + +/*N*/ SfxPoolItem* SwFmtCharFmt::Clone( SfxItemPool* ) const +/*N*/ { +/*N*/ return new SwFmtCharFmt( *this ); +/*N*/ } + + + + + + +/*N*/ // weiterleiten an das TextAttribut +/*N*/ BOOL SwFmtCharFmt::GetInfo( SfxPoolItem& rInfo ) const +/*N*/ { +/*N*/ return pTxtAttr ? pTxtAttr->GetInfo( rInfo ) : FALSE; +/*N*/ } +/*N*/ bool SwFmtCharFmt::QueryValue( uno::Any& rVal, BYTE nMemberId ) const +/*N*/ { +/*N*/ String sCharFmtName; +/*N*/ if(GetCharFmt()) +/*N*/ SwStyleNameMapper::FillProgName(GetCharFmt()->GetName(), sCharFmtName, GET_POOLID_CHRFMT, sal_True ); +/*N*/ rVal <<= OUString( sCharFmtName ); +/*N*/ return true; +/*N*/ } + +/************************************************************************* +|* +|* class SwFmtINetFmt +|* Beschreibung +|* Ersterstellung AMA 02.08.96 +|* Letzte Aenderung AMA 02.08.96 +|* +*************************************************************************/ + +/*N*/ SwFmtINetFmt::SwFmtINetFmt() +/*N*/ : SfxPoolItem( RES_TXTATR_INETFMT ), +/*N*/ pTxtAttr( 0 ), +/*N*/ pMacroTbl( 0 ), +/*N*/ nINetId( 0 ), +/*N*/ nVisitedId( 0 ) +/*N*/ {} + +/*N*/ SwFmtINetFmt::SwFmtINetFmt( const XubString& rURL, const XubString& rTarget ) +/*N*/ : SfxPoolItem( RES_TXTATR_INETFMT ), +/*N*/ aURL( rURL ), +/*N*/ aTargetFrame( rTarget ), +/*N*/ pTxtAttr( 0 ), +/*N*/ pMacroTbl( 0 ), +/*N*/ nINetId( 0 ), +/*N*/ nVisitedId( 0 ) +/*N*/ { +/*N*/ } + + + +/*N*/ SwFmtINetFmt::SwFmtINetFmt( const SwFmtINetFmt& rAttr ) +/*N*/ : SfxPoolItem( RES_TXTATR_INETFMT ), +/*N*/ aURL( rAttr.GetValue() ), +/*N*/ aName( rAttr.aName ), +/*N*/ aTargetFrame( rAttr.aTargetFrame ), +/*N*/ aINetFmt( rAttr.aINetFmt ), +/*N*/ aVisitedFmt( rAttr.aVisitedFmt ), +/*N*/ pTxtAttr( 0 ), +/*N*/ pMacroTbl( 0 ), +/*N*/ nINetId( rAttr.nINetId ), +/*N*/ nVisitedId( rAttr.nVisitedId ) +/*N*/ { +/*N*/ if( rAttr.GetMacroTbl() ) +/*?*/ pMacroTbl = new SvxMacroTableDtor( *rAttr.GetMacroTbl() ); +/*N*/ } + + + +/*N*/ SwFmtINetFmt::~SwFmtINetFmt() +/*N*/ { +/*N*/ delete pMacroTbl; +/*N*/ } + + + +/*N*/ int SwFmtINetFmt::operator==( const SfxPoolItem& rAttr ) const +/*N*/ { +/*N*/ ASSERT( SfxPoolItem::operator==( rAttr ), "keine gleichen Attribute" ); +/*N*/ BOOL bRet = SfxPoolItem::operator==( (SfxPoolItem&) rAttr ) +/*N*/ && aURL == ((SwFmtINetFmt&)rAttr).aURL +/*N*/ && aName == ((SwFmtINetFmt&)rAttr).aName +/*N*/ && aTargetFrame == ((SwFmtINetFmt&)rAttr).aTargetFrame +/*N*/ && aINetFmt == ((SwFmtINetFmt&)rAttr).aINetFmt +/*N*/ && aVisitedFmt == ((SwFmtINetFmt&)rAttr).aVisitedFmt +/*N*/ && nINetId == ((SwFmtINetFmt&)rAttr).nINetId +/*N*/ && nVisitedId == ((SwFmtINetFmt&)rAttr).nVisitedId; +/*N*/ +/*N*/ if( !bRet ) +/*N*/ return FALSE; +/*N*/ +/*N*/ const SvxMacroTableDtor* pOther = ((SwFmtINetFmt&)rAttr).pMacroTbl; +/*N*/ if( !pMacroTbl ) +/*N*/ return ( !pOther || !pOther->Count() ); +/*N*/ if( !pOther ) +/*?*/ return 0 == pMacroTbl->Count(); +/*?*/ +/*?*/ const SvxMacroTableDtor& rOwn = *pMacroTbl; +/*?*/ const SvxMacroTableDtor& rOther = *pOther; +/*?*/ +/*?*/ // Anzahl unterschiedlich => auf jeden Fall ungleich +/*?*/ if( rOwn.Count() != rOther.Count() ) +/*?*/ return FALSE; +/*?*/ +/*?*/ // einzeln vergleichen; wegen Performance ist die Reihenfolge wichtig +/*?*/ for( USHORT nNo = 0; nNo < rOwn.Count(); ++nNo ) +/*?*/ { +/*?*/ const SvxMacro *pOwnMac = rOwn.GetObject(nNo); +/*?*/ const SvxMacro *pOtherMac = rOther.GetObject(nNo); +/*?*/ if ( rOwn.GetKey(pOwnMac) != rOther.GetKey(pOtherMac) || +/*?*/ pOwnMac->GetLibName() != pOtherMac->GetLibName() || +/*?*/ pOwnMac->GetMacName() != pOtherMac->GetMacName() ) +/*?*/ return FALSE; +/*?*/ } +/*?*/ return TRUE; +/*N*/ } + + + +/*N*/ SfxPoolItem* SwFmtINetFmt::Clone( SfxItemPool* ) const +/*N*/ { +/*N*/ return new SwFmtINetFmt( *this ); +/*N*/ } + + + + + + +/*N #i27164#*/ void SwFmtINetFmt::SetMacro( USHORT nEvent, const SvxMacro& rMacro ) +/*N #i27164#*/ { +/*N #i27164#*/ if( !pMacroTbl ) +/*N #i27164#*/ pMacroTbl = new SvxMacroTableDtor; +/*N #i27164#*/ +/*N #i27164#*/ SvxMacro *pOldMacro; +/*N #i27164#*/ if( 0 != ( pOldMacro = pMacroTbl->Get( nEvent )) ) +/*N #i27164#*/ { +/*N #i27164#*/ delete pOldMacro; +/*N #i27164#*/ pMacroTbl->Replace( nEvent, new SvxMacro( rMacro ) ); +/*N #i27164#*/ } +/*N #i27164#*/ else +/*N #i27164#*/ pMacroTbl->Insert( nEvent, new SvxMacro( rMacro ) ); +/*N #i27164#*/ } + + + +/*N*/ const SvxMacro* SwFmtINetFmt::GetMacro( USHORT nEvent ) const +/*N*/ { +/*N*/ const SvxMacro* pRet = 0; +/*N*/ if( pMacroTbl && pMacroTbl->IsKeyValid( nEvent ) ) +/*?*/ pRet = pMacroTbl->Get( nEvent ); +/*N*/ return pRet; +/*N*/ } + + + +/*N*/ bool SwFmtINetFmt::QueryValue( uno::Any& rVal, BYTE nMemberId ) const +/*N*/ { +/*N*/ bool bRet = true; +/*N*/ XubString sVal; +/*N*/ nMemberId &= ~CONVERT_TWIPS; +/*N*/ switch(nMemberId) +/*N*/ { +/*N*/ case MID_URL_URL: +/*N*/ sVal = aURL; +/*N*/ break; +/*N*/ case MID_URL_TARGET: +/*N*/ sVal = aTargetFrame; +/*N*/ break; +/*N*/ case MID_URL_HYPERLINKNAME: +/*N*/ sVal = aName; +/*N*/ break; +/*N*/ case MID_URL_VISITED_FMT: +/*N*/ sVal = aVisitedFmt; +/*N*/ if( !sVal.Len() && nVisitedId != 0 ) +/*?*/ SwStyleNameMapper::FillUIName( nVisitedId, sVal ); +/*N*/ if( sVal.Len() ) +/*?*/ SwStyleNameMapper::FillProgName( sVal, sVal, GET_POOLID_CHRFMT, sal_True ); +/*N*/ break; +/*N*/ case MID_URL_UNVISITED_FMT: +/*N*/ sVal = aINetFmt; +/*N*/ if( !sVal.Len() && nINetId != 0 ) +/*?*/ SwStyleNameMapper::FillUIName( nINetId, sVal ); +/*N*/ if( sVal.Len() ) +/*?*/ SwStyleNameMapper::FillProgName( sVal, sVal, GET_POOLID_CHRFMT, sal_True ); +/*N*/ break; +/*N*/ case MID_URL_HYPERLINKEVENTS: +/*N*/ { +/*N*/ // create (and return) event descriptor +/*N*/ SwHyperlinkEventDescriptor* pEvents = +/*N*/ new SwHyperlinkEventDescriptor(); +/*N*/ pEvents->copyMacrosFromINetFmt(*this); +/*N*/ uno::Reference<container::XNameReplace> xNameReplace(pEvents); +/*N*/ +/*N*/ // all others return a string; so we just set rVal here and exit +/*N*/ rVal <<= xNameReplace; +/*N*/ return bRet; +/*N*/ } +/*N*/ break; +/*N*/ default: +/*N*/ bRet = false; +/*N*/ } +/*N*/ rVal <<= OUString(sVal); +/*N*/ return bRet; +/*N*/ } +/*N*/ bool SwFmtINetFmt::PutValue( const uno::Any& rVal, BYTE nMemberId ) +/*N*/ { +/*N*/ bool bRet = TRUE; +/*N*/ nMemberId &= ~CONVERT_TWIPS; +/*N*/ +/*N*/ // all properties except HyperlinkEvents are of type string, hence +/*N*/ // we treat HyperlinkEvents specially +/*N*/ if (MID_URL_HYPERLINKEVENTS == nMemberId) +/*N*/ { +/*?*/ uno::Reference<container::XNameReplace> xReplace; +/*?*/ rVal >>= xReplace; +/*?*/ if (xReplace.is()) +/*?*/ { +/*?*/ // Create hyperlink event descriptor. Then copy events +/*?*/ // from argument into descriptor. Then copy events from +/*?*/ // the descriptor into the format. +/*?*/ SwHyperlinkEventDescriptor* pEvents = new SwHyperlinkEventDescriptor(); +/*?*/ uno::Reference< ::com::sun::star::lang::XServiceInfo> xHold = pEvents; +/*?*/ pEvents->copyMacrosFromNameReplace(xReplace); +/*?*/ pEvents->copyMacrosIntoINetFmt(*this); +/*?*/ } +/*?*/ else +/*?*/ { +/*?*/ // wrong type! +/*?*/ bRet = false; +/*?*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ // all string properties: +/*N*/ if(rVal.getValueType() != ::getCppuType((::rtl::OUString*)0)) +/*N*/ return false; +/*N*/ XubString sVal = *(::rtl::OUString*)rVal.getValue(); +/*N*/ switch(nMemberId) +/*N*/ { +/*N*/ case MID_URL_URL: +/*N*/ aURL = sVal; +/*N*/ break; +/*N*/ case MID_URL_TARGET: +/*N*/ aTargetFrame = sVal; +/*N*/ break; +/*N*/ case MID_URL_HYPERLINKNAME: +/*N*/ aName = sVal; +/*N*/ break; +/*?*/ case MID_URL_VISITED_FMT: +/*?*/ { +/*?*/ String aString; +/*?*/ SwStyleNameMapper::FillUIName( sVal, aString, GET_POOLID_CHRFMT, sal_True ); +/*?*/ aVisitedFmt = OUString ( aString ); +/*?*/ nVisitedId = SwStyleNameMapper::GetPoolIdFromUIName( aVisitedFmt, +/*?*/ GET_POOLID_CHRFMT ); +/*?*/ } +/*?*/ break; +/*?*/ case MID_URL_UNVISITED_FMT: +/*?*/ { +/*?*/ String aString; +/*?*/ SwStyleNameMapper::FillUIName( sVal, aString, GET_POOLID_CHRFMT, sal_True ); +/*?*/ aINetFmt = OUString ( aString ); +/*?*/ nINetId = SwStyleNameMapper::GetPoolIdFromUIName( aINetFmt, GET_POOLID_CHRFMT ); +/*?*/ } +/*?*/ break; +/*?*/ default: +/*?*/ bRet = false; +/*N*/ } +/*N*/ } +/*N*/ return bRet; +/*N*/ } + + +/************************************************************************* +|* class SwFmtRuby +*************************************************************************/ + +/*N*/ SwFmtRuby::SwFmtRuby( const String& rRubyTxt ) +/*N*/ : SfxPoolItem( RES_TXTATR_CJK_RUBY ), +/*N*/ sRubyTxt( rRubyTxt ), +/*N*/ nCharFmtId( 0 ), +/*N*/ nPosition( 0 ), nAdjustment( 0 ), +/*N*/ pTxtAttr( 0 ) +/*N*/ { +/*N*/ } + +/*?*/ SwFmtRuby::SwFmtRuby( const SwFmtRuby& rAttr ) +/*?*/ : SfxPoolItem( RES_TXTATR_CJK_RUBY ), +/*?*/ sRubyTxt( rAttr.sRubyTxt ), +/*?*/ sCharFmtName( rAttr.sCharFmtName ), +/*?*/ nCharFmtId( rAttr.nCharFmtId), +/*?*/ nPosition( rAttr.nPosition ), nAdjustment( rAttr.nAdjustment ), +/*?*/ pTxtAttr( 0 ) +/*?*/ { +/*?*/ } + +/*N*/ SwFmtRuby::~SwFmtRuby() +/*N*/ { +/*N*/ } + +/*N*/ SwFmtRuby& SwFmtRuby::operator=( const SwFmtRuby& rAttr ) +/*N*/ { +/*N*/ sRubyTxt = rAttr.sRubyTxt; +/*N*/ sCharFmtName = rAttr.sCharFmtName; +/*N*/ nCharFmtId = rAttr.nCharFmtId; +/*N*/ nPosition = rAttr.nPosition; +/*N*/ nAdjustment = rAttr.nAdjustment; +/*N*/ pTxtAttr = 0; +/*N*/ return *this; +/*N*/ } + +int SwFmtRuby::operator==( const SfxPoolItem& rAttr ) const +{ + ASSERT( SfxPoolItem::operator==( rAttr ), "keine gleichen Attribute" ); + return sRubyTxt == ((SwFmtRuby&)rAttr).sRubyTxt && + sCharFmtName == ((SwFmtRuby&)rAttr).sCharFmtName && + nCharFmtId == ((SwFmtRuby&)rAttr).nCharFmtId && + nPosition == ((SwFmtRuby&)rAttr).nPosition && + nAdjustment == ((SwFmtRuby&)rAttr).nAdjustment; +} + +SfxPoolItem* SwFmtRuby::Clone( SfxItemPool* ) const +{ + return new SwFmtRuby( *this ); +} + +bool SwFmtRuby::QueryValue( ::com::sun::star::uno::Any& rVal, + BYTE nMemberId ) const +{ + bool bRet = true; + nMemberId &= ~CONVERT_TWIPS; + switch( nMemberId ) + { + case MID_RUBY_TEXT: rVal <<= (OUString)sRubyTxt; break; + case MID_RUBY_ADJUST: rVal <<= (sal_Int16)nAdjustment; break; + case MID_RUBY_CHARSTYLE: + { + String aString; + SwStyleNameMapper::FillProgName(sCharFmtName, aString, GET_POOLID_CHRFMT, sal_True ); + rVal <<= OUString ( aString ); + } + break; + case MID_RUBY_ABOVE: + { + sal_Bool bAbove = !nPosition; + rVal.setValue(&bAbove, ::getBooleanCppuType()); + } + break; + default: + bRet = false; + } + return bRet; +} +/*N*/ bool SwFmtRuby::PutValue( const ::com::sun::star::uno::Any& rVal, +/*N*/ BYTE nMemberId ) +/*N*/ { +/*N*/ bool bRet = TRUE; +/*N*/ nMemberId &= ~CONVERT_TWIPS; +/*N*/ switch( nMemberId ) +/*N*/ { +/*N*/ case MID_RUBY_TEXT: +/*N*/ { +/*N*/ OUString sTmp; +/*N*/ bRet = rVal >>= sTmp; +/*N*/ sRubyTxt = sTmp; +/*N*/ } +/*N*/ break; +/*N*/ case MID_RUBY_ADJUST: +/*N*/ { +/*N*/ sal_Int16 nSet; rVal >>= nSet; +/*N*/ if(nSet >= 0 && nSet <= ::com::sun::star::text::RubyAdjust_INDENT_BLOCK) +/*N*/ nAdjustment = nSet; +/*N*/ else +/*N*/ bRet = sal_False; +/*N*/ } +/*N*/ break; +/*N*/ case MID_RUBY_ABOVE: +/*N*/ { +/*N*/ const uno::Type& rType = ::getBooleanCppuType(); +/*N*/ if(rVal.hasValue() && rVal.getValueType() == rType) +/*N*/ { +/*N*/ sal_Bool bAbove = *(sal_Bool*)rVal.getValue(); +/*N*/ nPosition = bAbove ? 0 : 1; +/*N*/ } +/*N*/ } +/*N*/ break; +/*N*/ case MID_RUBY_CHARSTYLE: +/*N*/ { +/*N*/ OUString sTmp; +/*N*/ bRet = rVal >>= sTmp; +/*N*/ if(bRet) +/*N*/ sCharFmtName = SwStyleNameMapper::GetUIName(sTmp, GET_POOLID_CHRFMT ); +/*N*/ } +/*N*/ break; +/*N*/ default: +/*N*/ bRet = false; +/*N*/ } +/*N*/ return bRet; +/*N*/ } + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/txtnode/sw_fntcache.cxx b/binfilter/bf_sw/source/core/txtnode/sw_fntcache.cxx new file mode 100644 index 000000000000..6412152ed523 --- /dev/null +++ b/binfilter/bf_sw/source/core/txtnode/sw_fntcache.cxx @@ -0,0 +1,785 @@ +/* -*- 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. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include <vcl/metric.hxx> +#include <vcl/window.hxx> +#include <vcl/svapp.hxx> +#include <com/sun/star/i18n/CharacterIteratorMode.hdl> +#include <com/sun/star/i18n/WordType.hdl> +#include <breakit.hxx> +#include <viewsh.hxx> // Bildschirmabgleich +#include <viewopt.hxx> // Bildschirmabgleich abschalten, ViewOption +#include <fntcache.hxx> + +#include <horiornt.hxx> + +#include <swfont.hxx> // CH_BLANK + CH_BULLET +#include <txtfrm.hxx> // SwTxtFrm +#include <pagefrm.hxx> +#include <pagedesc.hxx> // SwPageDesc +#include <tgrditem.hxx> + +// Enable this to use the helpclass SwRVPMark +#if OSL_DEBUG_LEVEL > 1 +#endif +namespace binfilter { + +// globale Variablen, werden in FntCache.Hxx bekanntgegeben +// Der FontCache wird in TxtInit.Cxx _TXTINIT erzeugt und in _TXTEXIT geloescht +SwFntCache *pFntCache = NULL; +// Letzter Font, der durch ChgFntCache eingestellt wurde. +SwFntObj *pLastFont = NULL; +// Die "MagicNumber", die den Fonts zur Identifizierung verpasst wird +BYTE* pMagicNo = NULL; + +Color *pWaveCol = 0; + +long SwFntObj::nPixWidth; +MapMode* SwFntObj::pPixMap = NULL; +OutputDevice* SwFntObj::pPixOut = NULL; + +extern USHORT UnMapDirection( USHORT nDir, const BOOL bVertFormat ); + +#ifdef _RVP_MARK_HXX + + +#endif + +/************************************************************************* +|* +|* SwFntCache::Flush() +|* +|* Ersterstellung AMA 16. Dez. 94 +|* Letzte Aenderung AMA 16. Dez. 94 +|* +|*************************************************************************/ + +/*N*/ void SwFntCache::Flush( ) +/*N*/ { +/*N*/ if ( pLastFont ) +/*N*/ { +/*N*/ pLastFont->Unlock(); +/*N*/ pLastFont = NULL; +/*N*/ } +/*N*/ SwCache::Flush( ); +/*N*/ } + +/************************************************************************* +|* +|* SwFntObj::SwFntObj(), ~SwFntObj() +|* +|* Ersterstellung AMA 7. Nov. 94 +|* Letzte Aenderung AMA 7. Nov. 94 +|* +|*************************************************************************/ + +/*N*/ SwFntObj::SwFntObj( const SwSubFont &rFont, const void *pOwner, ViewShell *pSh ) : +/*N*/ SwCacheObj( (void*)pOwner ), +/*N*/ aFont( rFont ), +/*N*/ pScrFont( NULL ), +/*N*/ pPrtFont( &aFont ), +/*N*/ pPrinter( NULL ), +/*N*/ nPropWidth( rFont.GetPropWidth() ) +/*N*/ { +/*N*/ nZoom = pSh ? pSh->GetViewOptions()->GetZoom() : USHRT_MAX; +/*N*/ nLeading = USHRT_MAX; +/*N*/ nPrtAscent = USHRT_MAX; +/*N*/ nPrtHeight = USHRT_MAX; +/*N*/ bPaintBlank = ( UNDERLINE_NONE != aFont.GetUnderline() +/*N*/ || STRIKEOUT_NONE != aFont.GetStrikeout() ) +/*N*/ && !aFont.IsWordLineMode(); +/*N*/ } + +/*N*/ SwFntObj::~SwFntObj() +/*N*/ { +/*N*/ if ( pScrFont != pPrtFont ) +/*N*/ delete pScrFont; +/*N*/ if ( pPrtFont != &aFont ) +/*?*/ delete pPrtFont; +/*N*/ } + +/*N*/ void SwFntObj::CreatePrtFont( const OutputDevice& rPrt ) +/*N*/ { +/*N*/ if ( nPropWidth != 100 && pPrinter != &rPrt ) +/*N*/ { +/*?*/ if( pScrFont != pPrtFont ) +/*?*/ delete pScrFont; +/*?*/ if( pPrtFont != &aFont ) +/*?*/ delete pPrtFont; +/*?*/ +/*?*/ const Font aOldFnt( rPrt.GetFont() ); +/*?*/ ((OutputDevice&)rPrt).SetFont( aFont ); +/*?*/ const FontMetric aWinMet( rPrt.GetFontMetric() ); +/*?*/ ((OutputDevice&)rPrt).SetFont( aOldFnt ); +/*?*/ long nWidth = ( aWinMet.GetSize().Width() * nPropWidth ) / 100; +/*?*/ +/*?*/ if( !nWidth ) +/*?*/ ++nWidth; +/*?*/ pPrtFont = new Font( aFont ); +/*?*/ pPrtFont->SetSize( Size( nWidth, aFont.GetSize().Height() ) ); +/*?*/ pScrFont = NULL; +/*N*/ } +/*N*/ } + +/************************************************************************* + * + * USHORT SwFntObj::GetAscent( const OutputDevice *pOut ) + * + * Ersterstellung AMA 7. Nov. 94 + * Letzte Aenderung AMA 7. Nov. 94 + * + * Beschreibung: liefern den Ascent des Fonts auf dem + * gewuenschten Outputdevice zurueck, ggf. muss der Bildschirmfont erst + * erzeugt werden. + *************************************************************************/ + +/*N*/ USHORT SwFntObj::GetAscent( const ViewShell *pSh, const OutputDevice *pOut ) +/*N*/ { +/*N*/ // Condition for output font / refdev font adjustment +/*N*/ // 1. RefDef == OutDev (common printing, online layout) +/*N*/ // 2. Prospect/PagePreview pringing +/*N*/ // 3. PDF export from online layout +/*N*/ const OutputDevice* pRefDev = pOut; +/*N*/ if ( !pSh || ( pRefDev = &pSh->GetRefDev() ) == pOut || +/*N*/ ( OUTDEV_PRINTER == pRefDev->GetOutDevType() && +/*N*/ OUTDEV_PRINTER == pOut->GetOutDevType() ) || +/*N*/ OUTDEV_WINDOW == pRefDev->GetOutDevType() ) +/*N*/ { +/*N*/ if ( nPrtAscent == USHRT_MAX ) // DruckerAscent noch nicht bekannt? +/*N*/ { +/*N*/ CreatePrtFont( *pOut ); +/*N*/ const Font aOldFnt( pRefDev->GetFont() ); +/*N*/ ((OutputDevice*)pRefDev)->SetFont( *pPrtFont ); +/*N*/ const FontMetric aOutMet( pRefDev->GetFontMetric() ); +/*N*/ nPrtAscent = (USHORT) aOutMet.GetAscent(); +/*N*/ ( (OutputDevice *)pRefDev )->SetFont( aOldFnt ); +/*N*/ } +/*N*/ return nPrtAscent + nLeading; +/*N*/ } +/*N*/ +/*N*/ CreateScrFont( pSh, *pOut ); // eventuell Bildschirmanpassung durchfuehren +/*N*/ return nScrAscent; +/*N*/ } + +/*N*/ USHORT SwFntObj::GetHeight( const ViewShell *pSh, const OutputDevice *pOut ) +/*N*/ { +/*N*/ // Condition for output font / refdev font adjustment +/*N*/ // 1. RefDef == OutDev (common printing, online layout) +/*N*/ // 2. Prospect/PagePreview pringing +/*N*/ // 3. PDF export from online layout +/*N*/ const OutputDevice* pRefDev = pOut; +/*N*/ if ( ! pSh || ( pRefDev = &pSh->GetRefDev() ) == pOut || +/*N*/ ( OUTDEV_PRINTER == pRefDev->GetOutDevType() && +/*N*/ OUTDEV_PRINTER == pOut->GetOutDevType() ) || +/*N*/ OUTDEV_WINDOW == pRefDev->GetOutDevType() ) +/*N*/ { +/*N*/ if ( nPrtHeight == USHRT_MAX ) // PrinterHeight noch nicht bekannt? +/*N*/ { +/*N*/ CreatePrtFont( *pOut ); +/*N*/ const Font aOldFnt( pRefDev->GetFont() ); +/*N*/ ((OutputDevice*)pRefDev)->SetFont( *pPrtFont ); +/*N*/ nPrtHeight = (USHORT)pRefDev->GetTextHeight(); +/*N*/ ((OutputDevice *)pRefDev)->SetFont( aOldFnt ); +/*N*/ } +/*N*/ return nPrtHeight + nLeading; +/*N*/ } +/*N*/ +/*N*/ CreateScrFont( pSh, *pOut ); // eventuell Bildschirmanpassung durchfuehren +/*N*/ if ( nScrHeight == USHRT_MAX ) // ScreenHeight noch nicht bekannt? +/*N*/ { +/*N*/ const Font aOldFnt( pOut->GetFont() ); +/*N*/ ((OutputDevice*)pOut)->SetFont( *pPrtFont ); +/*N*/ nScrHeight = (USHORT)pOut->GetTextHeight(); +/*N*/ ((OutputDevice*)pOut)->SetFont( aOldFnt ); +/*N*/ } +/*N*/ return nScrHeight; +/*N*/ } + +/************************************************************************* + * + * SwFntObj::CreateScrFont( const ViewShell *pSh, const OutputDevice& rOut ) + * + * Ersterstellung AMA 7. Nov. 94 + * Letzte Aenderung AMA 7. Nov. 94 + * + * pOut is the output device, not the reference device + * + *************************************************************************/ + +/*N*/ void SwFntObj::CreateScrFont( const ViewShell *pSh, const OutputDevice& rOut ) +/*N*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 +/*N*/ } + + +/*N*/ void SwFntObj::GuessLeading( const ViewShell *pSh, const FontMetric& rMet ) +/*N*/ { +/*N*/ // Wie waere es mit 50% des Descents (StarMath??): +/*N*/ // nLeading = USHORT( aMet.GetDescent() / 2 ); +/*N*/ +/*N*/ #if defined(WNT) || defined(WIN) || defined(PM2) +/*N*/ OutputDevice *pWin = ( pSh && pSh->GetWin() ) ? pSh->GetWin() : +/*N*/ GetpApp()->GetDefaultDevice(); +/*N*/ if ( pWin ) +/*N*/ { +/*N*/ MapMode aTmpMap( MAP_TWIP ); +/*N*/ MapMode aOldMap = pWin->GetMapMode( ); +/*N*/ pWin->SetMapMode( aTmpMap ); +/*N*/ const Font aOldFnt( pWin->GetFont() ); +/*N*/ pWin->SetFont( *pPrtFont ); +/*N*/ const FontMetric aWinMet( pWin->GetFontMetric() ); +/*N*/ const USHORT nWinHeight = USHORT( aWinMet.GetSize().Height() ); +/*N*/ if( pPrtFont->GetName().Search( aWinMet.GetName() ) < USHRT_MAX ) +/*N*/ { +/*N*/ // Wenn das Leading auf dem Window auch 0 ist, dann +/*N*/ // muss es auch so bleiben (vgl. StarMath!). +/*N*/ long nTmpLeading = (long)aWinMet.GetIntLeading(); +/*N*/ // einen Versuch haben wir noch wg. 31003: +/*N*/ if( nTmpLeading <= 0 ) +/*N*/ { +/*N*/ pWin->SetFont( rMet ); +/*N*/ nTmpLeading = (long)pWin->GetFontMetric().GetIntLeading(); +/*N*/ if( nTmpLeading < 0 ) +/*N*/ nLeading = 0; +/*N*/ else +/*N*/ nLeading = USHORT(nTmpLeading); +/*N*/ } +/*N*/ else +/*N*/ { +/*?*/ nLeading = USHORT(nTmpLeading); +/*?*/ // Manta-Hack #50153#: +/*?*/ // Wer beim Leading luegt, luegt moeglicherweise auch beim +/*?*/ // Ascent/Descent, deshalb wird hier ggf. der Font ein wenig +/*?*/ // tiefergelegt, ohne dabei seine Hoehe zu aendern. +/*?*/ long nDiff = Min( rMet.GetDescent() - aWinMet.GetDescent(), +/*?*/ aWinMet.GetAscent() - rMet.GetAscent() - nTmpLeading ); +/*?*/ if( nDiff > 0 ) +/*?*/ { +/*?*/ ASSERT( nPrtAscent < USHRT_MAX, "GuessLeading: PrtAscent-Fault" ); +/*?*/ nPrtAscent += (USHORT)(( 2 * nDiff ) / 5); +/*?*/ } +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ // Wenn alle Stricke reissen, nehmen wir 15% der +/*N*/ // Hoehe, ein von CL empirisch ermittelter Wert. +/*?*/ nLeading = (nWinHeight * 15) / 100; +/*N*/ } +/*N*/ pWin->SetFont( aOldFnt ); +/*N*/ pWin->SetMapMode( aOldMap ); +/*N*/ } +/*N*/ else +/*N*/ #endif +/*N*/ #ifdef MAC +/*N*/ nLeading = (pPrtFont->GetSize().Height() * 15) / 100; +/*N*/ #else +/*N*/ nLeading = 0; +/*N*/ #endif +/*N*/ } + +/************************************************************************* + * + * void SwFntObj::SetDeviceFont( const OutputDevice *pOut ), + * + * Ersterstellung AMA 7. Nov. 94 + * Letzte Aenderung AMA 7. Nov. 94 + * + * Beschreibung: stellt den Font am gewuenschten OutputDevice ein, + * am Bildschirm muss eventuell erst den Abgleich durchgefuehrt werden. + * + *************************************************************************/ + +/*N*/ void SwFntObj::SetDevFont( const ViewShell *pSh, OutputDevice *pOut ) +/*N*/ { +/*N*/ // Condition for output font / refdev font adjustment + // 1. RefDef == OutDev (common printing, online layout) + // 2. Prospect/PagePreview pringing + // 3. PDF export from online layout +/*N*/ const OutputDevice* pRefDev = pOut; +/*N*/ if ( pSh && ( pRefDev = &pSh->GetRefDev() ) != pOut && +/*N*/ ( OUTDEV_PRINTER != pRefDev->GetOutDevType() || +/*N*/ OUTDEV_PRINTER != pOut->GetOutDevType() ) && +/*N*/ OUTDEV_WINDOW != pRefDev->GetOutDevType() ) +/*N*/ { +/*?*/ CreateScrFont( pSh, *pOut ); +/*?*/ if( !GetScrFont()->IsSameInstance( pOut->GetFont() ) ) +/*?*/ pOut->SetFont( *pScrFont ); +/*?*/ if( pPrinter && ( !pPrtFont->IsSameInstance( pPrinter->GetFont() ) ) ) +/*?*/ pPrinter->SetFont( *pPrtFont ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ CreatePrtFont( *pOut ); +/*N*/ if( !pPrtFont->IsSameInstance( pOut->GetFont() ) ) +/*N*/ pOut->SetFont( *pPrtFont ); +/*N*/ if ( nLeading == USHRT_MAX ) +/*N*/ { +/*N*/ FontMetric aMet( pOut->GetFontMetric() ); +/*N*/ bSymbol = RTL_TEXTENCODING_SYMBOL == aMet.GetCharSet(); +/*N*/ long nTmpLead = (long)aMet.GetIntLeading(); +/*N*/ if ( nTmpLead < 5 ) +/*N*/ { +/*N*/ GetAscent( pSh, pOut ); +/*N*/ GuessLeading( pSh, aMet ); +/*N*/ } +/*N*/ else +/*N*/ nLeading = 0; +/*N*/ } +/*N*/ } +/*N*/ } + +#define WRONG_SHOW_MIN 5 +#define WRONG_SHOW_SMALL 11 +#define WRONG_SHOW_MEDIUM 15 + +/************************************************************************* + * + * void SwFntObj::DrawText( ... ) + * + * Ersterstellung AMA 16. Dez. 94 + * Letzte Aenderung AMA 16. Dez. 94 + * + * Beschreibung: Textausgabe + * auf dem Bildschirm => DrawTextArray + * auf dem Drucker, !Kerning => DrawText + * auf dem Drucker + Kerning => DrawStretchText + * + *************************************************************************/ + + +/*N*/ sal_Bool lcl_IsMonoSpaceFont( const OutputDevice* pOut ) +/*N*/ {DBG_BF_ASSERT(0, "STRIP"); return sal_False; //STRIP001 +/*N*/ } + +// ER 09.07.95 20:34 +// mit -Ox Optimierung stuerzt's unter win95 ab +// JP 12.07.95: unter WNT auch (i386); Alpha ?? +// global optimization off +#ifdef _MSC_VER +#pragma optimize("g",off) +#endif + + + +// Optimierung war fuer DrawText() ausgeschaltet +#ifdef _MSC_VER +#pragma optimize("",on) +#endif + + +/************************************************************************* + * + * Size SwFntObj::GetTextSize( const OutputDevice *pOut, const String &rTxt, + * const USHORT nIdx, const USHORT nLen, const short nKern = 0 ); + * + * Ersterstellung AMA 16. Dez. 94 + * Letzte Aenderung AMA 16. Dez. 94 + * + * Beschreibung: ermittelt die TextSize (des Druckers) + * + *************************************************************************/ + +/*N*/ Size SwFntObj::GetTextSize( SwDrawTextInfo& rInf ) +/*N*/ { +/*N*/ Size aTxtSize; +/*N*/ const xub_StrLen nLn = ( STRING_LEN != rInf.GetLen() ) ? rInf.GetLen() : +/*N*/ rInf.GetText().Len(); +/*N*/ +/*N*/ // be sure to have the correct layout mode at the printer +/*N*/ if ( pPrinter ) +/*N*/ { +/*N*/ pPrinter->SetLayoutMode( rInf.GetpOut()->GetLayoutMode() ); +/*N*/ pPrinter->SetDigitLanguage( rInf.GetpOut()->GetDigitLanguage() ); +/*N*/ } +/*N*/ +/*N*/ if ( rInf.GetFrm() && nLn && rInf.SnapToGrid() && rInf.GetFont() && +/*N*/ SW_CJK == rInf.GetFont()->GetActual() ) +/*N*/ { +/*?*/ GETGRID( rInf.GetFrm()->FindPageFrm() ) +/*?*/ if ( pGrid && GRID_LINES_CHARS == pGrid->GetGridType() ) +/*?*/ { +/*?*/ const USHORT nGridWidth = pGrid->GetBaseHeight(); +/*?*/ +/*?*/ OutputDevice* pOutDev; +/*?*/ +/*?*/ if ( pPrinter ) +/*?*/ { +/*?*/ if( !pPrtFont->IsSameInstance( pPrinter->GetFont() ) ) +/*?*/ pPrinter->SetFont(*pPrtFont); +/*?*/ pOutDev = pPrinter; +/*?*/ } +/*?*/ else +/*?*/ pOutDev = rInf.GetpOut(); +/*?*/ +/*?*/ aTxtSize.Width() = +/*?*/ pOutDev->GetTextWidth( rInf.GetText(), rInf.GetIdx(), nLn ); +/*?*/ aTxtSize.Height() = pOutDev->GetTextHeight() + nLeading; +/*?*/ +/*?*/ long nWidthPerChar = aTxtSize.Width() / nLn; +/*?*/ +/*?*/ const ULONG i = nWidthPerChar ? +/*?*/ ( nWidthPerChar - 1 ) / nGridWidth + 1: +/*?*/ 1; +/*?*/ +/*?*/ aTxtSize.Width() = i * nGridWidth * nLn; +/*?*/ +/*?*/ rInf.SetKanaDiff( 0 ); +/*?*/ return aTxtSize; +/*?*/ } +/*N*/ } +/*N*/ +/*N*/ const BOOL bCompress = rInf.GetKanaComp() && nLn && +/*N*/ rInf.GetFont() && +/*N*/ SW_CJK == rInf.GetFont()->GetActual() && +/*N*/ rInf.GetScriptInfo() && +/*N*/ rInf.GetScriptInfo()->CountCompChg() && +/*N*/ lcl_IsMonoSpaceFont( rInf.GetpOut() ); +/*N*/ +/*N*/ ASSERT( !bCompress || ( rInf.GetScriptInfo() && rInf.GetScriptInfo()-> +/*N*/ CountCompChg()), "Compression without info" ); +/*N*/ +/*N*/ // This is the part used e.g., for cursor travelling +/*N*/ // See condition for DrawText or DrawTextArray (bDirectPrint) +/*N*/ if ( pPrinter && pPrinter != rInf.GetpOut() ) +/*N*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if( !pPrtFont->IsSameInstance( rInf.GetpOut()->GetFont() ) ) +/*N*/ rInf.GetpOut()->SetFont( *pPrtFont ); +/*N*/ if( bCompress ) +/*N*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ aTxtSize.Width() = rInf.GetpOut()->GetTextWidth( rInf.GetText(), +/*N*/ rInf.GetIdx(), nLn ); +/*N*/ rInf.SetKanaDiff( 0 ); +/*N*/ } +/*N*/ +/*N*/ aTxtSize.Height() = rInf.GetpOut()->GetTextHeight(); +/*N*/ } +/*N*/ +/*N*/ if ( rInf.GetKern() && nLn ) +/*N*/ aTxtSize.Width() += ( nLn - 1 ) * long( rInf.GetKern() ); +/*N*/ +/*N*/ aTxtSize.Height() += nLeading; +/*N*/ return aTxtSize; +/*N*/ } + + + + +/************************************************************************* +|* +|* SwFntAccess::SwFntAccess() +|* +|* Ersterstellung AMA 9. Nov. 94 +|* Letzte Aenderung AMA 9. Nov. 94 +|* +|*************************************************************************/ + +/*N*/ SwFntAccess::SwFntAccess( const void* &rMagic, +/*N*/ USHORT &rIndex, const void *pOwner, ViewShell *pSh, +/*N*/ BOOL bCheck ) : +/*N*/ SwCacheAccess( *pFntCache, rMagic, rIndex ), +/*N*/ pShell( pSh ) +/*N*/ { +/*N*/ // Der benutzte CTor von SwCacheAccess sucht anhand rMagic+rIndex im Cache +/*N*/ if ( IsAvail() ) +/*N*/ { +/*N*/ // Der schnellste Fall: ein bekannter Font ( rMagic ), +/*N*/ // bei dem Drucker und Zoom nicht ueberprueft werden brauchen. +/*N*/ if ( !bCheck ) +/*N*/ return; +/*N*/ +/*N*/ // Hier ist zwar der Font bekannt, muss aber noch ueberprueft werden. +/*N*/ +/*N*/ } +/*N*/ else +/*N*/ // Hier ist der Font nicht bekannt, muss also gesucht werden. +/*N*/ bCheck = FALSE; +/*N*/ +/*N*/ +/*N*/ { +/*N*/ OutputDevice* pOut = 0; +/*N*/ USHORT nZoom = USHRT_MAX; +/*N*/ +/*N*/ // Get the reference device +/*N*/ if ( pSh ) +/*N*/ { +/*N*/ pOut = &pSh->GetRefDev(); +/*N*/ nZoom = pSh->GetViewOptions()->GetZoom(); +/*N*/ } +/*N*/ +/*N*/ SwFntObj *pFntObj; +/*N*/ if ( bCheck ) +/*N*/ { +/*N*/ pFntObj = Get(); +/*N*/ if ( ( pFntObj->GetZoom( ) == nZoom ) && +/*N*/ ( pFntObj->pPrinter == pOut ) && +/*N*/ pFntObj->GetPropWidth() == +/*N*/ ((SwSubFont*)pOwner)->GetPropWidth() ) +/*N*/ return; // Die Ueberpruefung ergab: Drucker+Zoom okay. +/*N*/ pFntObj->Unlock( ); // Vergiss dies Objekt, es wurde leider +/*N*/ pObj = NULL; // eine Drucker/Zoomaenderung festgestellt. +/*N*/ } +/*N*/ +/*N*/ // Search by font comparison, quite expensive! +/*N*/ // Look for same font and same printer +/*N*/ pFntObj = pFntCache->First(); +/*N*/ while ( pFntObj && !( pFntObj->aFont == *(Font *)pOwner && +/*N*/ pFntObj->GetZoom() == nZoom && +/*N*/ pFntObj->GetPropWidth() == +/*N*/ ((SwSubFont*)pOwner)->GetPropWidth() && +/*N*/ ( !pFntObj->pPrinter || pFntObj->pPrinter == pOut ) ) ) +/*N*/ pFntObj = pFntCache->Next( pFntObj ); +/*N*/ +/*N*/ if( pFntObj && pFntObj->pPrinter != pOut ) +/*N*/ { +/*N*/ // Wir haben zwar einen ohne Drucker gefunden, mal sehen, ob es +/*N*/ // auch noch einen mit identischem Drucker gibt. +/*N*/ SwFntObj *pTmpObj = pFntObj; +/*N*/ while( pTmpObj && !( pTmpObj->aFont == *(Font *)pOwner && +/*N*/ pTmpObj->GetZoom()==nZoom && pTmpObj->pPrinter==pOut && +/*N*/ pTmpObj->GetPropWidth() == +/*N*/ ((SwSubFont*)pOwner)->GetPropWidth() ) ) +/*N*/ pTmpObj = pFntCache->Next( pTmpObj ); +/*N*/ if( pTmpObj ) +/*N*/ pFntObj = pTmpObj; +/*N*/ } +/*N*/ +/*N*/ if ( !pFntObj ) // Font has not been found, create one +/*N*/ { +/*N*/ // Das Objekt muss neu angelegt werden, deshalb muss der Owner ein +/*N*/ // SwFont sein, spaeter wird als Owner die "MagicNumber" gehalten. +/*N*/ SwCacheAccess::pOwner = pOwner; +/*N*/ pFntObj = Get(); // hier wird via NewObj() angelegt und gelockt. +/*N*/ ASSERT(pFntObj, "No Font, no Fun."); +/*N*/ } +/*N*/ else // Font has been found, so we lock it. +/*N*/ { +/*N*/ pFntObj->Lock(); +/*N*/ if( pFntObj->pPrinter != pOut ) // Falls bis dato kein Drucker bekannt +/*N*/ { +/*N*/ ASSERT( !pFntObj->pPrinter, "SwFntAccess: Printer Changed" ); +/*N*/ pFntObj->CreatePrtFont( *pOut ); +/*N*/ pFntObj->pPrinter = pOut; +/*N*/ pFntObj->pScrFont = NULL; +/*N*/ pFntObj->nLeading = USHRT_MAX; +/*N*/ pFntObj->nPrtAscent = USHRT_MAX; +/*N*/ pFntObj->nPrtHeight = USHRT_MAX; +/*N*/ } +/*N*/ pObj = pFntObj; +/*N*/ } +/*N*/ +/*N*/ // egal, ob neu oder gefunden, ab jetzt ist der Owner vom Objekt eine +/*N*/ // MagicNumber und wird auch dem aufrufenden SwFont bekanntgegeben, +/*N*/ // ebenso der Index fuer spaetere direkte Zugriffe +/*N*/ rMagic = pFntObj->GetOwner(); +/*N*/ SwCacheAccess::pOwner = rMagic; +/*N*/ rIndex = pFntObj->GetCachePos(); +/*N*/ } +/*N*/ } + +/*N*/ SwCacheObj *SwFntAccess::NewObj( ) +/*N*/ { +/*N*/ // Ein neuer Font, eine neue "MagicNumber". +/*N*/ return new SwFntObj( *(SwSubFont *)pOwner, ++pMagicNo, pShell ); +/*N*/ } + +/*N*/ extern xub_StrLen lcl_CalcCaseMap( const SwFont& rFnt, +/*N*/ const XubString& rOrigString, +/*N*/ xub_StrLen nOfst, +/*N*/ xub_StrLen nLen, +/*N*/ xub_StrLen nIdx ); + +/*N*/ xub_StrLen SwFont::GetTxtBreak( SwDrawTextInfo& rInf, long nTextWidth ) +/*N*/ { +/*N*/ ChgFnt( rInf.GetShell(), rInf.GetpOut() ); +/*N*/ +/*N*/ const BOOL bCompress = rInf.GetKanaComp() && rInf.GetLen() && +/*N*/ SW_CJK == GetActual() && +/*N*/ rInf.GetScriptInfo() && +/*N*/ rInf.GetScriptInfo()->CountCompChg() && +/*N*/ lcl_IsMonoSpaceFont( rInf.GetpOut() ); +/*N*/ +/*N*/ ASSERT( !bCompress || ( rInf.GetScriptInfo() && rInf.GetScriptInfo()-> +/*N*/ CountCompChg()), "Compression without info" ); +/*N*/ +/*N*/ USHORT nTxtBreak = 0; +/*N*/ long nKern = 0; +/*N*/ +/*N*/ USHORT nLn = ( rInf.GetLen() == STRING_LEN ? rInf.GetText().Len() +/*N*/ : rInf.GetLen() ); +/*N*/ +/*N*/ if ( rInf.GetFrm() && nLn && rInf.SnapToGrid() && +/*N*/ rInf.GetFont() && SW_CJK == rInf.GetFont()->GetActual() ) +/*N*/ { +/*?*/ GETGRID( rInf.GetFrm()->FindPageFrm() ) +/*?*/ if ( pGrid && GRID_LINES_CHARS == pGrid->GetGridType() ) +/*?*/ { +/*?*/ const USHORT nGridWidth = pGrid->GetBaseHeight(); +/*?*/ +/*?*/ sal_Int32* pKernArray = new sal_Int32[rInf.GetLen()]; +/*?*/ rInf.GetOut().GetTextArray( rInf.GetText(), pKernArray, +/*?*/ rInf.GetIdx(), rInf.GetLen() ); +/*?*/ +/*?*/ long nWidthPerChar = pKernArray[ rInf.GetLen() - 1 ] / rInf.GetLen(); +/*?*/ +/*?*/ const ULONG i = nWidthPerChar ? +/*?*/ ( nWidthPerChar - 1 ) / nGridWidth + 1: +/*?*/ 1; +/*?*/ +/*?*/ nWidthPerChar = i * nGridWidth; +/*?*/ long nCurrPos = nWidthPerChar; +/*?*/ +/*?*/ while( nTxtBreak < rInf.GetLen() && nTextWidth >= nCurrPos ) +/*?*/ { +/*?*/ nCurrPos += nWidthPerChar; +/*?*/ ++nTxtBreak; +/*?*/ } +/*?*/ +/*?*/ delete[] pKernArray; +/*?*/ return nTxtBreak + rInf.GetIdx(); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if( aSub[nActual].IsCapital() && nLn ) +/*?*/ {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 nTxtBreak = GetCapitalBreak( rInf.GetShell(), rInf.GetpOut(), +/*N*/ else +/*N*/ { +/*N*/ nKern = CheckKerning(); +/*N*/ +/*N*/ const XubString* pTmpText; +/*N*/ XubString aTmpText; +/*N*/ xub_StrLen nTmpIdx; +/*N*/ xub_StrLen nTmpLen; +/*N*/ bool bTextReplaced = false; +/*N*/ +/*N*/ if ( !aSub[nActual].IsCaseMap() ) +/*N*/ { +/*N*/ pTmpText = &rInf.GetText(); +/*N*/ nTmpIdx = rInf.GetIdx(); +/*N*/ nTmpLen = nLn; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ const XubString aSnippet( rInf.GetText(), rInf.GetIdx(), nLn ); +/*N*/ aTmpText = aSub[nActual].CalcCaseMap( aSnippet ); +/*N*/ const bool bTitle = SVX_CASEMAP_TITEL == aSub[nActual].GetCaseMap() && +/*N*/ pBreakIt->xBreak.is(); +/*N*/ +/*N*/ // Uaaaaahhhh!!! In title case mode, we would get wrong results +/*N*/ if ( bTitle && nLn ) +/*N*/ { +/*N*/ // check if rInf.GetIdx() is begin of word +/*N*/ if ( !pBreakIt->xBreak->isBeginWord( +/*N*/ rInf.GetText(), rInf.GetIdx(), +/*N*/ pBreakIt->GetLocale( aSub[nActual].GetLanguage() ), +/*N*/ ::com::sun::star::i18n::WordType::ANYWORD_IGNOREWHITESPACES ) ) +/*N*/ { +/*N*/ // In this case, the beginning of aTmpText is wrong. +/*N*/ XubString aSnippetTmp( aSnippet, 0, 1 ); +/*N*/ aSnippetTmp = aSub[nActual].CalcCaseMap( aSnippetTmp ); +/*N*/ aTmpText.Erase( 0, aSnippetTmp.Len() ); +/*N*/ aTmpText.Insert( aSnippet.GetChar( 0 ), 0 ); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ pTmpText = &aTmpText; +/*N*/ nTmpIdx = 0; +/*N*/ nTmpLen = aTmpText.Len(); +/*N*/ bTextReplaced = true; +/*N*/ } +/*N*/ +/*N*/ if( rInf.GetHyphPos() ) +/*N*/ nTxtBreak = rInf.GetpOut()->GetTextBreak( *pTmpText, nTextWidth, +/*N*/ '-', *rInf.GetHyphPos(), +/*N*/ nTmpIdx, nTmpLen, nKern ); +/*N*/ else +/*N*/ nTxtBreak = rInf.GetpOut()->GetTextBreak( *pTmpText, nTextWidth, +/*N*/ nTmpIdx, nTmpLen, nKern ); +/*N*/ +/*N*/ if ( bTextReplaced && STRING_LEN != nTxtBreak ) +/*N*/ { +/*N*/ if ( nTmpLen != nLn ) +/*N*/ nTxtBreak = lcl_CalcCaseMap( *this, rInf.GetText(), +/*N*/ rInf.GetIdx(), nLn, nTxtBreak ); +/*N*/ else +/*N*/ nTxtBreak += rInf.GetIdx(); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if ( ! bCompress ) +/*N*/ return nTxtBreak; +/*N*/ +/*N*/ nTxtBreak -= rInf.GetIdx(); +/*N*/ +/*N*/ if( nTxtBreak < nLn ) +/*N*/ { +/*N*/ if( !nTxtBreak && nLn ) +/*N*/ nLn = 1; +/*N*/ else if( nLn > 2 * nTxtBreak ) +/*N*/ nLn = 2 * nTxtBreak; +/*N*/ sal_Int32 *pKernArray = new sal_Int32[ nLn ]; +/*N*/ rInf.GetOut().GetTextArray( rInf.GetText(), pKernArray, +/*N*/ rInf.GetIdx(), nLn ); +/*N*/ if( rInf.GetScriptInfo()->Compress( pKernArray, rInf.GetIdx(), nLn, +/*N*/ rInf.GetKanaComp(), (USHORT)GetHeight( nActual ) ) ) +/*N*/ { +/*N*/ long nKernAdd = nKern; +/*N*/ xub_StrLen nTmpBreak = nTxtBreak; +/*N*/ if( nKern && nTxtBreak ) +/*N*/ nKern *= nTxtBreak - 1; +/*N*/ while( nTxtBreak<nLn && nTextWidth >= pKernArray[nTxtBreak] +nKern ) +/*N*/ { +/*N*/ nKern += nKernAdd; +/*N*/ ++nTxtBreak; +/*N*/ } +/*N*/ if( rInf.GetHyphPos() ) +/*N*/ *rInf.GetHyphPos() += nTxtBreak - nTmpBreak; // It's not perfect +/*N*/ } +/*N*/ delete[] pKernArray; +/*N*/ } +/*N*/ nTxtBreak += rInf.GetIdx(); +/*N*/ +/*N*/ return nTxtBreak; +/*N*/ } + +extern Color aGlobalRetoucheColor; + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/txtnode/sw_fntcap.cxx b/binfilter/bf_sw/source/core/txtnode/sw_fntcap.cxx new file mode 100644 index 000000000000..7c95478fac76 --- /dev/null +++ b/binfilter/bf_sw/source/core/txtnode/sw_fntcap.cxx @@ -0,0 +1,550 @@ +/* -*- 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. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include <hintids.hxx> + + +#include <com/sun/star/i18n/CharType.hdl> +#include <com/sun/star/i18n/WordType.hdl> + +#include <vcl/print.hxx> + +#include <fntcache.hxx> +#include <swfont.hxx> +#include <breakit.hxx> +namespace binfilter { + +using namespace ::com::sun::star::i18n; + + +#define KAPITAELCHENPROP 80 +/************************************************************************* + * class SwCapitalInfo + * + * The information encapsulated in SwCapitalInfo is required + * by the ::Do functions. They contain the information about + * the original string, whereas rDo.GetInf() contains information + * about the display string. + *************************************************************************/ + +class SwCapitalInfo +{ +public: + explicit SwCapitalInfo( const XubString& rOrigText ) : + rString( rOrigText ), nIdx( 0 ), nLen( 0 ) {}; + const XubString& rString; + xub_StrLen nIdx; + xub_StrLen nLen; +}; + +/************************************************************************* + * xub_StrLen lcl_CalcCaseMap() + * + * rFnt: required for CalcCaseMap + * rOrigString: The original string + * nOfst: Position of the substring in rOrigString + * nLen: Length if the substring in rOrigString + * nIdx: Referes to a position in the display string and should be mapped + * to a position in rOrigString + *************************************************************************/ + +xub_StrLen lcl_CalcCaseMap( const SwFont& rFnt, + const XubString& rOrigString, + xub_StrLen nOfst, + xub_StrLen nLen, + xub_StrLen nIdx ) +{ + int j = 0; + const xub_StrLen nEnd = nOfst + nLen; + ASSERT( nEnd <= rOrigString.Len(), "lcl_CalcCaseMap: Wrong parameters" ) + + // special case for title case: + const bool bTitle = SVX_CASEMAP_TITEL == rFnt.GetCaseMap() && + pBreakIt->xBreak.is(); + for ( int i = nOfst; i < nEnd; ++i ) + { + XubString aTmp( rOrigString, i, 1 ); + + if ( !bTitle || + pBreakIt->xBreak->isBeginWord( + rOrigString, i, + pBreakIt->GetLocale( rFnt.GetLanguage() ), + WordType::ANYWORD_IGNOREWHITESPACES ) ) + aTmp = rFnt.GetActualFont().CalcCaseMap( aTmp ); + + j += aTmp.Len(); + + if ( j > nIdx ) + return i; + } + + return nOfst + nLen; +} + +/************************************************************************* + * class SwDoCapitals + *************************************************************************/ + +class SwDoCapitals +{ +protected: + SwDrawTextInfo &rInf; + SwCapitalInfo* pCapInf; // referes to additional information + // required by the ::Do function +public: + SwDoCapitals ( SwDrawTextInfo &rInfo ) : rInf( rInfo ), pCapInf( 0 ) { } + virtual void Init( SwFntObj *pUpperFont, SwFntObj *pLowerFont ) = 0; + virtual void Do() = 0; + inline OutputDevice *GetOut() { return rInf.GetpOut(); } + inline SwDrawTextInfo& GetInf() { return rInf; } + inline SwCapitalInfo* GetCapInf() const { return pCapInf; } + inline void SetCapInf( SwCapitalInfo& rNew ) { pCapInf = &rNew; } +}; + +/************************************************************************* + * class SwDoGetCapitalSize + *************************************************************************/ + +class SwDoGetCapitalSize : public SwDoCapitals +{ +protected: + Size aTxtSize; +public: + SwDoGetCapitalSize( SwDrawTextInfo &rInfo ) : SwDoCapitals ( rInfo ) { } + virtual void Init( SwFntObj *pUpperFont, SwFntObj *pLowerFont ); + virtual void Do(); + const Size &GetSize() const { return aTxtSize; } +}; + +/*N*/ void SwDoGetCapitalSize::Init( SwFntObj *pUpperFont, SwFntObj *pLowerFont ) +/*N*/ { +/*N*/ aTxtSize.Height() = 0; +/*N*/ aTxtSize.Width() = 0; +/*N*/ } + +/*N*/ void SwDoGetCapitalSize::Do() +/*N*/ { +/*N*/ aTxtSize.Width() += rInf.GetSize().Width(); +/*N*/ if( rInf.GetUpper() ) +/*N*/ aTxtSize.Height() = rInf.GetSize().Height(); +/*N*/ } + +/************************************************************************* + * SwSubFont::GetCapitalSize() + *************************************************************************/ + +/*N*/ Size SwSubFont::GetCapitalSize( SwDrawTextInfo& rInf ) +/*N*/ { +/*N*/ // Start: +/*N*/ short nOldKern = rInf.GetKern(); +/*N*/ rInf.SetKern( CheckKerning() ); +/*N*/ Point aPos; +/*N*/ rInf.SetPos( aPos ); +/*N*/ rInf.SetSpace( 0 ); +/*N*/ rInf.SetDrawSpace( FALSE ); +/*N*/ SwDoGetCapitalSize aDo( rInf ); +/*N*/ DoOnCapitals( aDo ); +/*N*/ Size aTxtSize( aDo.GetSize() ); +/*N*/ +/*N*/ // End: +/*N*/ if( !aTxtSize.Height() ) +/*N*/ { +/*N*/ SV_STAT( nGetTextSize ); +/*N*/ aTxtSize.Height() = short ( rInf.GetpOut()->GetTextHeight() ); +/*N*/ } +/*N*/ rInf.SetKern( nOldKern ); +/*N*/ return aTxtSize; +/*N*/ } + +/************************************************************************* + * class SwDoGetCapitalBreak + *************************************************************************/ + +class SwDoGetCapitalBreak : public SwDoCapitals +{ +protected: + xub_StrLen *pExtraPos; + long nTxtWidth; + xub_StrLen nBreak; +public: + SwDoGetCapitalBreak( SwDrawTextInfo &rInfo, long nWidth, xub_StrLen *pExtra) + : SwDoCapitals ( rInfo ), nTxtWidth( nWidth ), + nBreak( STRING_LEN ), pExtraPos( pExtra ) + { } + xub_StrLen GetBreak() const { return nBreak; } +}; + + + +/************************************************************************* + * SwFont::GetCapitalBreak() + *************************************************************************/ + + +/************************************************************************* + * class SwDoDrawCapital + *************************************************************************/ + +class SwDoDrawCapital : public SwDoCapitals +{ +protected: + SwFntObj *pUpperFnt; + SwFntObj *pLowerFnt; +public: + SwDoDrawCapital( SwDrawTextInfo &rInfo ) : + SwDoCapitals( rInfo ) + { } +}; + + + +/************************************************************************* + * SwDoDrawCapital::DrawSpace() + *************************************************************************/ + + +/************************************************************************* + * SwSubFont::DrawCapital() + *************************************************************************/ + + +/************************************************************************* + * class SwDoDrawCapital + *************************************************************************/ + +class SwDoCapitalCrsrOfst : public SwDoCapitals +{ +protected: + SwFntObj *pUpperFnt; + SwFntObj *pLowerFnt; + xub_StrLen nCrsr; + USHORT nOfst; +public: + SwDoCapitalCrsrOfst( SwDrawTextInfo &rInfo, const USHORT nOfs ) : + SwDoCapitals( rInfo ), nOfst( nOfs ), nCrsr( 0 ) + { } + + void DrawSpace( const Point &rPos ); + inline xub_StrLen GetCrsr(){ return nCrsr; } +}; + + + +/************************************************************************* + * SwSubFont::GetCapitalCrsrOfst() + *************************************************************************/ + + +/************************************************************************* + * class SwDoDrawStretchCapital + *************************************************************************/ + +class SwDoDrawStretchCapital : public SwDoDrawCapital +{ + const xub_StrLen nStrLen; + const USHORT nCapWidth; + const USHORT nOrgWidth; +public: + + SwDoDrawStretchCapital( SwDrawTextInfo &rInfo, const USHORT nCapWidth ) + : SwDoDrawCapital( rInfo ), + nCapWidth( nCapWidth ), + nOrgWidth( rInfo.GetWidth() ), + nStrLen( rInfo.GetLen() ) + { } +}; + +/************************************************************************* + * SwDoDrawStretchCapital + *************************************************************************/ + + +/************************************************************************* + * SwSubFont::DrawStretchCapital() + *************************************************************************/ + + +/************************************************************************* + * SwSubFont::DoOnCapitals() const + *************************************************************************/ + +// JP 22.8.2001 - global optimization off - Bug 91245 / 91223 +#ifdef _MSC_VER +#pragma optimize("g",off) +#endif + +/*N*/ void SwSubFont::DoOnCapitals( SwDoCapitals &rDo ) +/*N*/ { +/*N*/ ASSERT( pLastFont, "SwFont::DoOnCapitals: No LastFont?!" ); +/*N*/ +/*N*/ Size aPartSize; +/*N*/ long nKana = 0; +/*N*/ const XubString aTxt( CalcCaseMap( rDo.GetInf().GetText() ) ); +/*N*/ xub_StrLen nMaxPos = Min( USHORT(rDo.GetInf().GetText().Len() +/*N*/ - rDo.GetInf().GetIdx()), rDo.GetInf().GetLen() ); +/*N*/ rDo.GetInf().SetLen( nMaxPos ); +/*N*/ +/*N*/ const XubString& rOldText = rDo.GetInf().GetText(); +/*N*/ rDo.GetInf().SetText( aTxt ); +/*N*/ rDo.GetInf().SetSize( aPartSize ); +/*N*/ xub_StrLen nPos = rDo.GetInf().GetIdx(); +/*N*/ xub_StrLen nOldPos = nPos; +/*N*/ nMaxPos += nPos; +/*N*/ +/*N*/ // #107816# +/*N*/ // Look if the length of the original text and the ToUpper-converted +/*N*/ // text is different. If yes, do special handling. +/*N*/ XubString aNewText; +/*N*/ SwCapitalInfo aCapInf( rOldText ); +/*N*/ sal_Bool bCaseMapLengthDiffers( aTxt.Len() != rOldText.Len() ); +/*N*/ if ( bCaseMapLengthDiffers ) +/*N*/ rDo.SetCapInf( aCapInf ); +/*N*/ +/*N*/ SwFntObj *pOldLast = pLastFont; +/*N*/ SwFntAccess *pBigFontAccess = NULL; +/*N*/ SwFntObj *pBigFont; +/*N*/ SwFntAccess *pSpaceFontAccess = NULL; +/*N*/ SwFntObj *pSpaceFont = NULL; +/*N*/ +/*N*/ const void *pMagic2 = NULL; +/*N*/ USHORT nIndex2 = 0; +/*N*/ SwSubFont aFont( *this ); +/*N*/ Point aStartPos( rDo.GetInf().GetPos() ); +/*N*/ +/*N*/ const BOOL bUnderStriked = aFont.GetUnderline() != UNDERLINE_NONE +/*N*/ || aFont.GetStrikeout() != STRIKEOUT_NONE; +/*N*/ const BOOL bWordWise = bUnderStriked && aFont.IsWordLineMode() && +/*N*/ rDo.GetInf().GetDrawSpace(); +/*N*/ const short nKern = rDo.GetInf().GetKern(); +/*N*/ +/*N*/ if ( bUnderStriked ) +/*N*/ { +/*N*/ if ( bWordWise ) +/*N*/ { +/*?*/ aFont.SetWordLineMode( FALSE ); +/*?*/ pSpaceFontAccess = new SwFntAccess( pMagic2, nIndex2, &aFont, +/*?*/ rDo.GetInf().GetShell() ); +/*?*/ pSpaceFont = pSpaceFontAccess->Get(); +/*N*/ } +/*N*/ else +/*N*/ pSpaceFont = pLastFont; +/*N*/ +/*N*/ // Wir basteln uns einen Font fuer die Grossbuchstaben: +/*N*/ aFont.SetUnderline( UNDERLINE_NONE ); +/*N*/ aFont.SetStrikeout( STRIKEOUT_NONE ); +/*N*/ pMagic2 = NULL; +/*N*/ nIndex2 = 0; +/*N*/ pBigFontAccess = new SwFntAccess( pMagic2, nIndex2, &aFont, +/*N*/ rDo.GetInf().GetShell() ); +/*N*/ pBigFont = pBigFontAccess->Get(); +/*N*/ } +/*N*/ else +/*N*/ pBigFont = pLastFont; +/*N*/ +/*N*/ // Hier entsteht der Kleinbuchstabenfont: +/*N*/ aFont.SetProportion( BYTE( (aFont.GetPropr()*KAPITAELCHENPROP) / 100L) ); +/*N*/ pMagic2 = NULL; +/*N*/ nIndex2 = 0; +/*N*/ SwFntAccess *pSmallFontAccess = new SwFntAccess( pMagic2, nIndex2, &aFont, +/*N*/ rDo.GetInf().GetShell() ); +/*N*/ SwFntObj *pSmallFont = pSmallFontAccess->Get(); +/*N*/ +/*N*/ rDo.Init( pBigFont, pSmallFont ); +/*N*/ OutputDevice* pOutSize = pSmallFont->GetPrt(); +/*N*/ if( !pOutSize ) +/*N*/ pOutSize = rDo.GetOut(); +/*N*/ OutputDevice* pOldOut = rDo.GetOut(); +/*N*/ +/*N*/ const LanguageType eLng = LANGUAGE_DONTKNOW == GetLanguage() +/*N*/ ? LANGUAGE_SYSTEM : GetLanguage(); +/*N*/ +/*N*/ if( nPos < nMaxPos ) +/*N*/ { +/*N*/ nPos = (xub_StrLen)pBreakIt->xBreak->endOfCharBlock( rOldText, nPos, +/*N*/ pBreakIt->GetLocale( eLng ), CharType::LOWERCASE_LETTER); +/*N*/ if( nPos == STRING_LEN ) +/*N*/ nPos = nOldPos; +/*N*/ else if( nPos > nMaxPos ) +/*N*/ nPos = nMaxPos; +/*N*/ } +/*N*/ +/*N*/ while( nOldPos < nMaxPos ) +/*N*/ { +/*N*/ +/*N*/ // The lower ones... +/*N*/ if( nOldPos != nPos ) +/*N*/ { +/*N*/ SV_STAT( nGetTextSize ); +/*N*/ pLastFont = pSmallFont; +/*N*/ pLastFont->SetDevFont( rDo.GetInf().GetShell(), rDo.GetOut() ); +/*N*/ +/*N*/ // #107816#, #i14820# +/*N*/ if( bCaseMapLengthDiffers ) +/*N*/ { +/*N*/ // Build an own 'changed' string for the given part of the +/*N*/ // source string and use it. That new string may differ in length +/*N*/ // from the source string. +/*N*/ const XubString aSnippet( rOldText, nOldPos, nPos - nOldPos); +/*N*/ aNewText = CalcCaseMap( aSnippet ); +/*N*/ aCapInf.nIdx = nOldPos; +/*N*/ aCapInf.nLen = nPos - nOldPos; +/*N*/ rDo.GetInf().SetIdx( 0 ); +/*N*/ rDo.GetInf().SetLen( aNewText.Len() ); +/*N*/ rDo.GetInf().SetText( aNewText ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ rDo.GetInf().SetIdx( nOldPos ); +/*N*/ rDo.GetInf().SetLen( nPos - nOldPos ); +/*N*/ } +/*N*/ +/*N*/ rDo.GetInf().SetUpper( FALSE ); +/*N*/ rDo.GetInf().SetOut( *pOutSize ); +/*N*/ aPartSize = pSmallFont->GetTextSize( rDo.GetInf() ); +/*N*/ nKana += rDo.GetInf().GetKanaDiff(); +/*N*/ rDo.GetInf().SetOut( *pOldOut ); +/*N*/ if( nKern && nPos < nMaxPos ) +/*?*/ aPartSize.Width() += nKern; +/*N*/ rDo.Do(); +/*N*/ nOldPos = nPos; +/*N*/ } +/*N*/ nPos = (xub_StrLen)pBreakIt->xBreak->nextCharBlock( rOldText, nPos, +/*N*/ pBreakIt->GetLocale( eLng ), CharType::LOWERCASE_LETTER); +/*N*/ if( nPos == STRING_LEN || nPos > nMaxPos ) +/*N*/ nPos = nMaxPos; +/*N*/ ASSERT( nPos, "nextCharBlock not implemented?" ); +/*N*/ #ifdef DBG_UTIL +/*N*/ if( !nPos ) +/*N*/ nPos = nMaxPos; +/*N*/ #endif +/*N*/ // The upper ones... +/*N*/ if( nOldPos != nPos ) +/*N*/ { +/*N*/ do +/*N*/ { +/*N*/ rDo.GetInf().SetUpper( TRUE ); +/*N*/ pLastFont = pBigFont; +/*N*/ pLastFont->SetDevFont( rDo.GetInf().GetShell(), rDo.GetOut() ); +/*N*/ xub_StrLen nTmp; +/*N*/ if( bWordWise ) +/*N*/ { +/*?*/ nTmp = nOldPos; +/*?*/ while( nTmp < nPos && CH_BLANK == rOldText.GetChar( nTmp ) ) +/*?*/ ++nTmp; +/*?*/ if( nOldPos < nTmp ) +/*?*/ { + DBG_BF_ASSERT(0, "STRIP"); //STRIP001 /*?*/ pLastFont = pSpaceFont; +/*?*/ } +/*?*/ while( nTmp < nPos && CH_BLANK != rOldText.GetChar( nTmp ) ) +/*?*/ ++nTmp; +/*N*/ } +/*N*/ else +/*N*/ nTmp = nPos; +/*N*/ if( nTmp > nOldPos ) +/*N*/ { +/*N*/ // #107816#, #i14820# +/*N*/ if( bCaseMapLengthDiffers ) +/*N*/ { +/*N*/ // Build an own 'changed' string for the given part of the +/*N*/ // source string and use it. That new string may differ in length +/*N*/ // from the source string. +/*N*/ const XubString aSnippet( rOldText, nOldPos, nTmp - nOldPos); +/*N*/ aNewText = CalcCaseMap( aSnippet ); +/*N*/ aCapInf.nIdx = nOldPos; +/*N*/ aCapInf.nLen = nTmp - nOldPos; +/*N*/ rDo.GetInf().SetIdx( 0 ); +/*N*/ rDo.GetInf().SetLen( aNewText.Len() ); +/*N*/ rDo.GetInf().SetText( aNewText ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ rDo.GetInf().SetIdx( nOldPos ); +/*N*/ rDo.GetInf().SetLen( nPos - nOldPos ); +/*N*/ } +/*N*/ +/*N*/ rDo.GetInf().SetOut( *pOutSize ); +/*N*/ aPartSize = pBigFont->GetTextSize( rDo.GetInf() ); +/*N*/ nKana += rDo.GetInf().GetKanaDiff(); +/*N*/ rDo.GetInf().SetOut( *pOldOut ); +/*N*/ if( !bWordWise && rDo.GetInf().GetSpace() ) +/*?*/ for( xub_StrLen nI = nOldPos; nI < nPos; ++nI ) +/*?*/ if( CH_BLANK == rOldText.GetChar( nI ) ) +/*?*/ aPartSize.Width() += rDo.GetInf().GetSpace(); +/*N*/ if( nKern && nPos < nMaxPos ) +/*?*/ aPartSize.Width() += nKern; +/*N*/ rDo.Do(); +/*N*/ nOldPos = nTmp; +/*N*/ } +/*N*/ } while( nOldPos != nPos ); +/*N*/ } +/*N*/ nPos = (xub_StrLen)pBreakIt->xBreak->endOfCharBlock( rOldText, nPos, +/*N*/ pBreakIt->GetLocale( eLng ), CharType::LOWERCASE_LETTER); +/*N*/ if( nPos == STRING_LEN || nPos > nMaxPos ) +/*N*/ nPos = nMaxPos; +/*N*/ ASSERT( nPos, "endOfCharBlock not implemented?" ); +/*N*/ #ifdef DBG_UTIL +/*N*/ if( !nPos ) +/*N*/ nPos = nMaxPos; +/*N*/ #endif +/*N*/ } +/*N*/ +/*N*/ // Aufraeumen: +/*N*/ if( pBigFont != pOldLast ) +/*N*/ delete pBigFontAccess; +/*N*/ +/*N*/ if( bUnderStriked ) +/*N*/ { +/*N*/ if( rDo.GetInf().GetDrawSpace() ) +/*N*/ { + DBG_BF_ASSERT(0, "STRIP"); //STRIP001 /*?*/ pLastFont = pSpaceFont; +/*N*/ } +/*N*/ if ( bWordWise ) +/*?*/ delete pSpaceFontAccess; +/*N*/ } +/*N*/ pLastFont = pOldLast; +/*N*/ pLastFont->SetDevFont( rDo.GetInf().GetShell(), rDo.GetOut() ); +/*N*/ +/*N*/ delete pSmallFontAccess; +/*N*/ rDo.GetInf().SetText( rOldText ); +/*N*/ rDo.GetInf().SetKanaDiff( nKana ); +/*N*/ } + +// JP 22.8.2001 - global optimization off - Bug 91245 / 91223 +#ifdef _MSC_VER +#pragma optimize("g",on) +#endif + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/txtnode/sw_ndhints.cxx b/binfilter/bf_sw/source/core/txtnode/sw_ndhints.cxx new file mode 100644 index 000000000000..9ebfb8f2b7d3 --- /dev/null +++ b/binfilter/bf_sw/source/core/txtnode/sw_ndhints.cxx @@ -0,0 +1,405 @@ +/* -*- 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. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include "txatbase.hxx" +#include "ndhints.hxx" +namespace binfilter { + +/*N*/ _SV_IMPL_SORTAR_ALG( SwpHtStart, SwTxtAttr* ) +/*N*/ _SV_IMPL_SORTAR_ALG( SwpHtEnd, SwTxtAttr* ) + +#ifdef NIE + +/*N*/ void DumpHints( const SwpHtStart &rHtStart, +/*N*/ const SwpHtEnd &rHtEnd ) +/*N*/ { +#ifdef DBG_UTIL + DBG_BF_ASSERT(0, "STRIP");//STRIP001 aDbstream << "DumpHints:" << endl; +/*N*/ #endif +/*N*/ } +/*N*/ #else +/*N*/ inline void DumpHints(const SwpHtStart &, const SwpHtEnd &) { } +/*N*/ #endif + +/************************************************************************* + * inline IsEqual() + *************************************************************************/ + +/*N*/ inline BOOL IsEqual( const SwTxtAttr &rHt1, const SwTxtAttr &rHt2 ) +/*N*/ { +/*N*/ return (long)(&rHt1) == (long)(&rHt2); +/*N*/ } + +/************************************************************************* + * IsLessStart() + *************************************************************************/ + +// SV_IMPL_OP_PTRARR_SORT( SwpHtStart, SwTxtAttr* ) +// kein SV_IMPL_PTRARR_SORT( name,ArrElement ) +// unser SEEK_PTR_TO_OBJECT_NOTL( name,ArrElement ) + +// Sortierreihenfolge: Start, Ende (umgekehrt!), Which-Wert (umgekehrt!), +// als letztes die Adresse selbst + +/*N*/ BOOL lcl_IsLessStart( const SwTxtAttr &rHt1, const SwTxtAttr &rHt2 ) +/*N*/ { +/*N*/ if ( *rHt1.GetStart() == *rHt2.GetStart() ) +/*N*/ { +/*N*/ xub_StrLen nHt1 = *rHt1.GetAnyEnd(); +/*N*/ xub_StrLen nHt2 = *rHt2.GetAnyEnd(); +/*N*/ if ( nHt1 == nHt2 ) +/*N*/ { +/*N*/ nHt1 = rHt1.Which(); +/*N*/ nHt2 = rHt2.Which(); +/*N*/ return nHt1 > nHt2 || +/*N*/ (nHt1 == nHt2 && (long)&rHt1 < (long)&rHt2); +/*N*/ } +/*N*/ else +/*N*/ return ( nHt1 > nHt2 ); +/*N*/ } +/*N*/ return ( *rHt1.GetStart() < *rHt2.GetStart() ); +/*N*/ } + +/************************************************************************* + * inline IsLessEnd() + *************************************************************************/ + +// Zuerst nach Ende danach nach Ptr +/*N*/ #ifdef HP9000 +/*N*/ BOOL lcl_IsLessEnd( const SwTxtAttr &rHt1, const SwTxtAttr &rHt2 ) +/*N*/ #else +/*N*/ inline BOOL lcl_IsLessEnd( const SwTxtAttr &rHt1, const SwTxtAttr &rHt2 ) +/*N*/ #endif +/*N*/ { +/*N*/ xub_StrLen nHt1 = *rHt1.GetAnyEnd(); +/*N*/ xub_StrLen nHt2 = *rHt2.GetAnyEnd(); +/*N*/ if ( nHt1 == nHt2 ) +/*N*/ { +/*N*/ if ( *rHt1.GetStart() == *rHt2.GetStart() ) +/*N*/ { +/*N*/ nHt1 = rHt1.Which(); +/*N*/ nHt2 = rHt2.Which(); +/*N*/ return nHt1 < nHt2 || +/*N*/ (nHt1 == nHt2 && (long)&rHt1 > (long)&rHt2); +/*N*/ } +/*N*/ else +/*N*/ return ( *rHt1.GetStart() > *rHt2.GetStart() ); +/*N*/ } +/*N*/ return ( nHt1 < nHt2 ); +/*N*/ } + +/************************************************************************* + * SwpHtStart::Seek_Entry() + *************************************************************************/ + +/*N*/ BOOL SwpHtStart::Seek_Entry( const SwTxtAttr *pElement, USHORT *pPos ) const +/*N*/ { +/*N*/ register USHORT nOben = Count(), nMitte, nUnten = 0; +/*N*/ if( nOben > 0 ) +/*N*/ { +/*N*/ nOben--; +/*N*/ while( nUnten <= nOben ) +/*N*/ { +/*N*/ nMitte = nUnten + ( nOben - nUnten ) / 2; +/*N*/ const SwTxtAttr *pMitte = (*this)[nMitte]; +/*N*/ if( IsEqual( *pMitte, *pElement ) ) +/*N*/ { +/*N*/ *pPos = nMitte; +/*N*/ return TRUE; +/*N*/ } +/*N*/ else +/*N*/ if( lcl_IsLessStart( *pMitte, *pElement ) ) +/*N*/ nUnten = nMitte + 1; +/*N*/ else +/*N*/ if( nMitte == 0 ) +/*N*/ { +/*N*/ *pPos = nUnten; +/*N*/ return FALSE; +/*N*/ } +/*N*/ else +/*N*/ nOben = nMitte - 1; +/*N*/ } +/*N*/ } +/*N*/ *pPos = nUnten; +/*N*/ return FALSE; +/*N*/ } + +/************************************************************************* + * SwpHtEnd::Seek_Entry() + *************************************************************************/ + +/*N*/ BOOL SwpHtEnd::Seek_Entry( const SwTxtAttr *pElement, USHORT *pPos ) const +/*N*/ { +/*N*/ register USHORT nOben = Count(), nMitte, nUnten = 0; +/*N*/ if( nOben > 0 ) +/*N*/ { +/*N*/ nOben--; +/*N*/ while( nUnten <= nOben ) +/*N*/ { +/*N*/ nMitte = nUnten + ( nOben - nUnten ) / 2; +/*N*/ const SwTxtAttr *pMitte = (*this)[nMitte]; +/*N*/ if( IsEqual( *pMitte, *pElement ) ) +/*N*/ { +/*N*/ *pPos = nMitte; +/*N*/ return TRUE; +/*N*/ } +/*N*/ else +/*N*/ if( lcl_IsLessEnd( *pMitte, *pElement ) ) +/*N*/ nUnten = nMitte + 1; +/*N*/ else +/*N*/ if( nMitte == 0 ) +/*N*/ { +/*N*/ *pPos = nUnten; +/*N*/ return FALSE; +/*N*/ } +/*N*/ else +/*N*/ nOben = nMitte - 1; +/*N*/ } +/*N*/ } +/*N*/ *pPos = nUnten; +/*N*/ return FALSE; +/*N*/ } + +/************************************************************************* + * class SwpHintsArr + *************************************************************************/ + +/*N*/ void SwpHintsArr::Insert( const SwTxtAttr *pHt ) +/*N*/ { +/*N*/ Resort(); +/*N*/ #ifdef DBG_UTIL +/*N*/ USHORT nPos; +/*N*/ ASSERT(!SwpHtStart::Seek_Entry( pHt, &nPos ), "Insert: hint already in HtStart"); +/*N*/ ASSERT(!aHtEnd.Seek_Entry( pHt, &nPos ), "Insert: hint already in HtEnd"); +/*N*/ #endif +/*N*/ SwpHtStart::Insert( pHt ); +/*N*/ aHtEnd.Insert( pHt ); +/*N*/ #ifdef DBG_UTIL +/*N*/ #ifdef NIE +/*N*/ (aDbstream << "Insert: " ).WriteNumber( long( pHt ) )<< endl; +/*N*/ DumpHints( *this, aHtEnd ); +/*N*/ #endif +/*N*/ #endif +/*N*/ } + +/*N*/ void SwpHintsArr::DeleteAtPos( const USHORT nPos ) +/*N*/ { +/*N*/ // Optimierung: nPos bezieht sich auf die Position im StartArray, also: +/*N*/ const SwTxtAttr *pHt = SwpHtStart::operator[]( nPos ); +/*N*/ SwpHtStart::Remove( nPos ); +/*N*/ +/*N*/ Resort(); +/*N*/ +/*N*/ USHORT nEndPos; +/*N*/ aHtEnd.Seek_Entry( pHt, &nEndPos ); +/*N*/ aHtEnd.Remove( nEndPos ); +/*N*/ #ifdef DBG_UTIL +/*N*/ #ifdef NIE +/*N*/ (aDbstream << "DeleteAtPos: " ).WriteNumber( long( pHt ) )<< endl; +/*N*/ DumpHints( *this, aHtEnd ); +/*N*/ #endif +/*N*/ #endif +/*N*/ } + +#ifdef DBG_UTIL + +/************************************************************************* + * SwpHintsArr::Check() + *************************************************************************/ + + +/*N*/ #define CHECK_ERR(cond, text) \ +/*N*/ if(!(cond)) \ +/*N*/ { \ +/*N*/ ASSERT(!this, text); \ +/*N*/ DumpHints(*(SwpHtStart*)this,aHtEnd); \ +/*N*/ const BOOL bErr = 0 == (cond); /* fuer den CV */ \ +/*N*/ return !((SwpHintsArr*)this)->Resort(); \ +/*N*/ } +/*N*/ +/*N*/ BOOL SwpHintsArr::Check() const +/*N*/ { +/*N*/ // 1) gleiche Anzahl in beiden Arrays +/*N*/ CHECK_ERR( Count() == aHtEnd.Count(), "HintsCheck: wrong sizes" ); +/*N*/ xub_StrLen nLastStart = 0; +/*N*/ xub_StrLen nLastEnd = 0; +/*N*/ +/*N*/ const SwTxtAttr *pLastStart = 0; +/*N*/ const SwTxtAttr *pLastEnd = 0; +/*N*/ +/*N*/ for( USHORT i = 0; i < Count(); ++i ) +/*N*/ { +/*N*/ // --- Start-Kontrolle --- +/*N*/ +/*N*/ // 2a) gueltiger Pointer? vgl. DELETEFF +/*N*/ const SwTxtAttr *pHt = (*this)[i]; +/*N*/ CHECK_ERR( 0xFF != *(char*)pHt, "HintsCheck: start ptr was deleted" ); +/*N*/ +/*N*/ // 3a) Stimmt die Start-Sortierung? +/*N*/ xub_StrLen nIdx = *pHt->GetStart(); +/*N*/ CHECK_ERR( nIdx >= nLastStart, "HintsCheck: starts are unsorted" ); +/*N*/ +/*N*/ // 4a) IsLessStart-Konsistenz +/*N*/ if( pLastStart ) +/*N*/ CHECK_ERR( lcl_IsLessStart( *pLastStart, *pHt ), "HintsCheck: IsLastStart" ); +/*N*/ +/*N*/ nLastStart = nIdx; +/*N*/ pLastStart = pHt; +/*N*/ +/*N*/ // --- End-Kontrolle --- +/*N*/ +/*N*/ // 2b) gueltiger Pointer? vgl. DELETEFF +/*N*/ const SwTxtAttr *pHtEnd = aHtEnd[i]; +/*N*/ CHECK_ERR( 0xFF != *(char*)pHtEnd, "HintsCheck: end ptr was deleted" ); +/*N*/ +/*N*/ // 3b) Stimmt die End-Sortierung? +/*N*/ nIdx = *pHtEnd->GetAnyEnd(); +/*N*/ CHECK_ERR( nIdx >= nLastEnd, "HintsCheck: ends are unsorted" ); +/*N*/ nLastEnd = nIdx; +/*N*/ +/*N*/ // 4b) IsLessEnd-Konsistenz +/*N*/ if( pLastEnd ) +/*N*/ CHECK_ERR( lcl_IsLessEnd( *pLastEnd, *pHtEnd ), "HintsCheck: IsLastEnd" ); +/*N*/ +/*N*/ nLastEnd = nIdx; +/*N*/ pLastEnd = pHtEnd; +/*N*/ +/*N*/ // --- Ueberkreuzungen --- +/*N*/ +/*N*/ // 5) gleiche Pointer in beiden Arrays +/*N*/ nIdx = GetStartOf( pHtEnd ); +/*N*/ CHECK_ERR( STRING_LEN != nIdx, "HintsCheck: no GetStartOf" ); +/*N*/ +/*N*/ // 6) gleiche Pointer in beiden Arrays +/*N*/ nIdx = GetEndOf( pHt ); +/*N*/ CHECK_ERR( STRING_LEN != nIdx, "HintsCheck: no GetEndOf" ); +/*N*/ } +/*N*/ return TRUE; +/*N*/ } + +#endif /* PRODUCT */ + +/************************************************************************* + * SwpHintsArr::Resort() + *************************************************************************/ + +// Resort() wird vor jedem Insert und Delete gerufen. +// Wenn Textmasse geloescht wird, so werden die Indizes in +// ndtxt.cxx angepasst. Leider erfolgt noch keine Neusortierung +// auf gleichen Positionen. + +/*N*/ BOOL SwpHintsArr::Resort() +/*N*/ { +/*N*/ BOOL bResort = FALSE; +/*N*/ const SwTxtAttr *pLast = 0; + USHORT i=0; +/*N*/ for( i = 0; i < SwpHtStart::Count(); ++i ) +/*N*/ { +/*N*/ const SwTxtAttr *pHt = (*this)[i]; +/*N*/ if( pLast && !lcl_IsLessStart( *pLast, *pHt ) ) +/*N*/ { +/*N*/ #ifdef NIE +/*N*/ #ifdef DBG_UTIL +/*N*/ // ASSERT( bResort, "!Resort/Start: correcting hints-array" ); +/*N*/ aDbstream << "Resort: Starts" << endl; +/*N*/ DumpHints( *this, aHtEnd ); +/*N*/ #endif +/*N*/ #endif +/*N*/ // Aufpassen: nicht die unsere SwpHintsArr-Methoden rufen, +/*N*/ // weil dort ein Resort steht! +/*N*/ // AMA: Bisher ( -> USED ) wurde ein Arrayinhalt [3,4,4,3] nur in +/*N*/ // [3,4,3,4] sortiert, nicht in [3,3,4,4] +/*N*/ #ifdef USED +/*N*/ SwpHtStart::Delete( i - 1 ); +/*N*/ SwpHtStart::Insert( pLast ); +/*N*/ USHORT nPos; +/*N*/ if( SwpHtStart::Seek_Entry( pLast, &nPos ) && nPos > i ) +/*N*/ --i; +/*N*/ #else +/*N*/ SwpHtStart::Remove( i ); +/*N*/ SwpHtStart::Insert( pHt ); +/*N*/ pHt = (*this)[i]; +/*N*/ if ( pHt != pLast ) +/*N*/ --i; +/*N*/ #endif //!USED +/*N*/ bResort = TRUE; +/*N*/ } +/*N*/ pLast = pHt; +/*N*/ } +/*N*/ +/*N*/ pLast = 0; +/*N*/ for( i = 0; i < aHtEnd.Count(); ++i ) +/*N*/ { +/*N*/ const SwTxtAttr *pHt = aHtEnd[i]; +/*N*/ if( pLast && !lcl_IsLessEnd( *pLast, *pHt ) ) +/*N*/ { +/*N*/ #ifdef NIE +/*N*/ #ifdef DBG_UTIL +/*N*/ // ASSERT( bResort, "!Resort/Ends: correcting hints-array" ); +/*N*/ aDbstream << "Resort: Ends" << endl; +/*N*/ DumpHints( *this, aHtEnd ); +/*N*/ #endif +/*N*/ #endif +/*N*/ // AMA: siehe oben +/*N*/ #ifdef USED +/*N*/ aHtEnd.Delete( i - 1 ); +/*N*/ aHtEnd.Insert( pLast ); +/*N*/ USHORT nPos; +/*N*/ if( aHtEnd.Seek_Entry( pLast, &nPos ) && nPos > i ) +/*N*/ --i; +/*N*/ #else +/*N*/ aHtEnd.Remove( i ); +/*N*/ aHtEnd.Insert( pHt ); +/*N*/ pHt = aHtEnd[i]; // normalerweise == pLast +/*N*/ // Wenn die Unordnung etwas groesser ist (24200), +/*N*/ // muessen wir Position i erneut vergleichen. +/*N*/ if ( pLast != pHt ) +/*N*/ --i; +/*N*/ #endif //!USED +/*N*/ bResort = TRUE; +/*N*/ } +/*N*/ pLast = pHt; +/*N*/ } +/*N*/ #ifdef DBG_UTIL +/*N*/ #ifdef NIE +/*N*/ aDbstream << "Resorted:" << endl; +/*N*/ DumpHints( *this, aHtEnd ); +/*N*/ #endif +/*N*/ #endif +/*N*/ return bResort; +/*N*/ } + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/txtnode/sw_ndtxt.cxx b/binfilter/bf_sw/source/core/txtnode/sw_ndtxt.cxx new file mode 100644 index 000000000000..d98eff9d394b --- /dev/null +++ b/binfilter/bf_sw/source/core/txtnode/sw_ndtxt.cxx @@ -0,0 +1,2355 @@ +/* -*- 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. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include <hintids.hxx> + +#include <com/sun/star/i18n/ScriptType.hdl> +#include <com/sun/star/i18n/InputSequenceCheckMode.hpp> +#include <bf_svx/lrspitem.hxx> +#include <bf_svtools/urihelper.hxx> +#include <bf_svtools/ctloptions.hxx> +#include <swmodule.hxx> +#include <tools/shl.hxx> + +#include <txtfld.hxx> +#include <txtinet.hxx> +#include <fmtinfmt.hxx> +#include <fmthbsh.hxx> +#include <fmtrfmrk.hxx> +#include <txttxmrk.hxx> +#include <fchrfmt.hxx> +#include <txtftn.hxx> +#include <fmtflcnt.hxx> +#include <fmtfld.hxx> +#include <frmatr.hxx> +#include <ftnidx.hxx> +#include <ftninfo.hxx> +#include <fmtftn.hxx> +#include <charfmt.hxx> +#include <ndtxt.hxx> + +#include <horiornt.hxx> + +#include <doc.hxx> +#include <docary.hxx> +#include <paratr.hxx> +#include <txtfrm.hxx> +#include <ftnfrm.hxx> +#include <rootfrm.hxx> +#include <hints.hxx> // fuer SwFmtChg in ChgTxtColl +#include <expfld.hxx> // fuer SwTblField +#include <mvsave.hxx> +#include <swcache.hxx> +#include <wrong.hxx> // fuer die WrongList des OnlineSpellings +#include <redline.hxx> +#include <doctxm.hxx> +#include <bookmrk.hxx> +#include <breakit.hxx> +#include <checkit.hxx> +namespace binfilter { + + +SV_DECL_PTRARR( TmpHints, SwTxtAttr*, 0, 4 ) + +/*N*/ TYPEINIT1( SwTxtNode, SwCntntNode ) + +SV_DECL_PTRARR(SwpHts,SwTxtAttr*,1,1) + +// Leider ist das SwpHints nicht ganz wasserdicht: +// Jeder darf an den Hints rumfummeln, ohne die Sortierreihenfolge +// und Verkettung sicherstellen zu muessen. +#ifdef DBG_UTIL +#define CHECK_SWPHINTS(pNd) { if( pNd->GetpSwpHints() && \ + !pNd->GetDoc()->IsInReading() ) \ + pNd->GetpSwpHints()->Check(); } +#else +#define CHECK_SWPHINTS(pNd) +#endif + +/*N*/ SwTxtNode *SwNodes::MakeTxtNode( const SwNodeIndex & rWhere, +/*N*/ SwTxtFmtColl *pColl, +/*N*/ SwAttrSet* pAutoAttr ) +/*N*/ { +/*N*/ ASSERT( pColl, "Collectionpointer ist 0." ); +/*N*/ +/*N*/ SwTxtNode *pNode = new SwTxtNode( rWhere, pColl, pAutoAttr ); +/*N*/ +/*N*/ SwNodeIndex aIdx( *pNode ); +/*N*/ +/*N*/ if( pColl && NO_NUMBERING != pColl->GetOutlineLevel() && IsDocNodes() ) +/*N*/ UpdateOutlineNode( *pNode, NO_NUMBERING, pColl->GetOutlineLevel() ); +/*N*/ +/*N*/ //Wenn es noch kein Layout gibt oder in einer versteckten Section +/*N*/ // stehen, brauchen wir uns um das MakeFrms nicht bemuehen. +/*N*/ const SwSectionNode* pSectNd; +/*N*/ if( !GetDoc()->GetRootFrm() || +/*N*/ ( 0 != (pSectNd = pNode->FindSectionNode()) && +/*N*/ pSectNd->GetSection().IsHiddenFlag() )) +/*N*/ return pNode; +/*N*/ +/*N*/ SwNodeIndex aTmp( rWhere ); +/*N*/ do { +/*N*/ // max. 2 Durchlaeufe: +/*N*/ // 1. den Nachfolger nehmen +/*N*/ // 2. den Vorgaenger +/*N*/ +/*N*/ SwNode *pNd; +/*N*/ switch( ( pNd = (*this)[aTmp] )->GetNodeType() ) +/*N*/ { +/*?*/ case ND_TABLENODE: +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 ((SwTableNode*)pNd)->MakeFrms( aIdx ); +/*?*/ return pNode; +/*?*/ +/*?*/ case ND_SECTIONNODE: +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 if( ((SwSectionNode*)pNd)->GetSection().IsHidden() || +/*?*/ return pNode; +/*N*/ +/*N*/ case ND_TEXTNODE: +/*N*/ case ND_GRFNODE: +/*N*/ case ND_OLENODE: +/*N*/ ((SwCntntNode*)pNd)->MakeFrms( *pNode ); +/*N*/ return pNode; +/*N*/ +/*N*/ case ND_ENDNODE: +/*N*/ if( pNd->FindStartNode()->IsSectionNode() && +/*N*/ aTmp.GetIndex() < rWhere.GetIndex() ) +/*N*/ { +/*?*/ if( pNd->FindStartNode()->GetSectionNode()->GetSection().IsHiddenFlag()) +/*?*/ { +/*?*/ if( !GoPrevSection( &aTmp, TRUE, FALSE ) || +/*?*/ aTmp.GetNode().FindTableNode() != +/*?*/ pNode->FindTableNode() ) +/*?*/ return pNode; // schade, das wars +/*?*/ } +/*?*/ else +/*?*/ aTmp = *pNd->FindStartNode(); +/*?*/ break; +/*N*/ } +/*N*/ else if( pNd->FindStartNode()->IsTableNode() && +/*N*/ aTmp.GetIndex() < rWhere.GetIndex() ) +/*N*/ { +/*N*/ // wir stehen hinter einem TabellenNode +/*?*/ aTmp = *pNd->FindStartNode(); +/*?*/ break; +/*N*/ } +/*N*/ // kein break !!! +/*N*/ default: +/*N*/ if( rWhere == aTmp ) +/*N*/ aTmp -= 2; +/*N*/ else +/*N*/ return pNode; +/*N*/ break; +/*N*/ } +/*N*/ } while( TRUE ); +/*N*/ } + + + +// -------------------- +// SwTxtNode +// -------------------- + +/*N*/ SwTxtNode::SwTxtNode( const SwNodeIndex &rWhere, +/*N*/ SwTxtFmtColl *pTxtColl, +/*N*/ SwAttrSet* pAutoAttr ) +/*N*/ : SwCntntNode( rWhere, ND_TEXTNODE, pTxtColl ), +/*N*/ pSwpHints( 0 ), pWrong( 0 ), pNdNum( 0 ), pNdOutl( 0 ) +/*N*/ { +/*N*/ // soll eine Harte-Attributierung gesetzt werden? +/*N*/ if( pAutoAttr ) +/*N*/ SwCntntNode::SetAttr( *pAutoAttr ); +/*N*/ +/*N*/ const SfxPoolItem* pItem; +/*N*/ if( GetNodes().IsDocNodes() && +/*N*/ SFX_ITEM_SET == GetSwAttrSet().GetItemState( RES_PARATR_NUMRULE, +/*N*/ TRUE, &pItem ) && ((SwNumRuleItem*)pItem)->GetValue().Len() ) +/*N*/ { +/*?*/ pNdNum = new SwNodeNum( 0 ); +/*?*/ SwNumRule* pRule = GetDoc()->FindNumRulePtr( +/*?*/ ((SwNumRuleItem*)pItem)->GetValue() ); +/*?*/ if( pRule ) +/*?*/ pRule->SetInvalidRule( TRUE ); +/*N*/ } +/*N*/ } + +/*N*/ SwTxtNode::~SwTxtNode() +/*N*/ { +/*N*/ // delete loescht nur die Pointer, nicht die Arrayelemente! +/*N*/ if( pSwpHints ) +/*N*/ { +/*N*/ // damit Attribute die ihren Inhalt entfernen nicht doppelt +/*N*/ // geloescht werden. +/*N*/ SwpHints* pTmpHints = pSwpHints; +/*N*/ pSwpHints = 0; +/*N*/ +/*N*/ for( register USHORT j = pTmpHints->Count(); j; ) +/*N*/ // erst muss das Attribut aus dem Array entfernt werden, +/*N*/ // denn sonst wuerde es sich selbst loeschen (Felder) !!!! +/*N*/ DestroyAttr( pTmpHints->GetHt( --j ) ); +/*N*/ +/*N*/ delete pTmpHints; +/*N*/ } +/*N*/ delete pWrong; +/*N*/ // Achtung. im Dtor von SwCntntNode kann DelFrms gerufen werden, wo +/*N*/ // ggf. pWrong nochmal deletet wird, deshalb diese Zuweisung +/*N*/ pWrong = NULL; // hier nicht wegoptimieren! +/*N*/ +/*N*/ delete pNdNum, pNdNum = 0; // ggfs. wird in der BasisKlasse noch +/*N*/ delete pNdOutl, pNdOutl = 0; // darauf zugegriffen?? +/*N*/ } + +/*N*/ SwCntntFrm *SwTxtNode::MakeFrm() +/*N*/ { +/*N*/ SwCntntFrm *pFrm = new SwTxtFrm(this); +/*N*/ return pFrm; +/*N*/ } + +/*N*/ xub_StrLen SwTxtNode::Len() const +/*N*/ { +/*N*/ return aText.Len(); +/*N*/ } + +/*--------------------------------------------------------------------------- + * lcl_ChangeFtnRef + * After a split node, it's necessary to actualize the ref-pointer of the + * ftnfrms. + * --------------------------------------------------------------------------*/ + +/*N*/ void lcl_ChangeFtnRef( SwTxtNode &rNode ) +/*N*/ { +/*N*/ SwpHints *pSwpHints = rNode.GetpSwpHints(); +/*N*/ if( pSwpHints && rNode.GetDoc()->GetRootFrm() ) +/*N*/ { +/*N*/ SwTxtAttr* pHt; +/*N*/ SwCntntFrm* pFrm = NULL; +/*N*/ // OD 07.11.2002 #104840# - local variable to remember first footnote +/*N*/ // of node <rNode> in order to invalidate position of its first content. +/*N*/ // Thus, in its <MakeAll()> it will checked its position relative to its reference. +/*N*/ SwFtnFrm* pFirstFtnOfNode = 0; +/*N*/ for( register USHORT j = pSwpHints->Count(); j; ) +/*N*/ { +/*N*/ if( RES_TXTATR_FTN == (pHt = pSwpHints->GetHt(--j))->Which() ) +/*N*/ { +/*N*/ if( !pFrm ) +/*N*/ { +/*N*/ SwClientIter aNew( rNode ); +/*N*/ pFrm = (SwCntntFrm*)aNew.First( TYPE(SwCntntFrm) ); +/*N*/ //JP 11.07.00: the assert's shows incorrect an error when nodes are converted +/*N*/ // to a table. Then no layout exist! +/*N*/ // ASSERT( pFrm, "lcl_ChangeFtnRef: No TxtFrm" ); +/*N*/ // ASSERT( pFrm && !aNew.Next(),"lcl_ChangeFtnRef: Doublefault"); +/*N*/ if( !pFrm ) +/*N*/ return; +/*N*/ } +/*N*/ SwTxtFtn *pAttr = (SwTxtFtn*)pHt; +/*N*/ ASSERT( pAttr->GetStartNode(), "FtnAtr ohne StartNode." ); +/*N*/ SwNodeIndex aIdx( *pAttr->GetStartNode(), 1 ); +/*N*/ SwCntntNode *pNd = aIdx.GetNode().GetCntntNode(); +/*N*/ if ( !pNd ) +/*N*/ pNd = pFrm->GetAttrSet()->GetDoc()-> +/*N*/ GetNodes().GoNextSection( &aIdx, TRUE, FALSE ); +/*N*/ if ( !pNd ) +/*N*/ continue; +/*N*/ SwClientIter aIter( *pNd ); +/*N*/ SwCntntFrm* pCntnt = (SwCntntFrm*)aIter.First(TYPE(SwCntntFrm)); +/*N*/ if( pCntnt ) +/*N*/ { +/*N*/ ASSERT( pCntnt->FindRootFrm() == pFrm->FindRootFrm(), +/*N*/ "lcl_ChangeFtnRef: Layout double?" ); +/*N*/ SwFtnFrm *pFtn = pCntnt->FindFtnFrm(); +/*N*/ if( pFtn && pFtn->GetAttr() == pAttr ) +/*N*/ { +/*N*/ while( pFtn->GetMaster() ) +/*N*/ pFtn = pFtn->GetMaster(); +/*N*/ // OD 07.11.2002 #104840# - remember footnote frame +/*N*/ pFirstFtnOfNode = pFtn; +/*N*/ while ( pFtn ) +/*N*/ { +/*N*/ pFtn->SetRef( pFrm ); +/*N*/ pFtn = pFtn->GetFollow(); +/*N*/ ((SwTxtFrm*)pFrm)->SetFtn( TRUE ); +/*N*/ } +/*N*/ } +/*N*/ #ifdef DBG_UTIL +/*N*/ while( 0 != (pCntnt = (SwCntntFrm*)aIter.Next()) ) +/*N*/ { +/*N*/ SwFtnFrm *pFtn = pCntnt->FindFtnFrm(); +/*N*/ ASSERT( !pFtn || pFtn->GetRef() == pFrm, +/*N*/ "lcl_ChangeFtnRef: Who's that guy?" ); +/*N*/ } +/*N*/ #endif +/*N*/ } +/*N*/ } +/*N*/ } // end of for-loop on <SwpHints> +/*N*/ // OD 08.11.2002 #104840# - invalidate +/*N*/ if ( pFirstFtnOfNode ) +/*N*/ { +/*N*/ SwCntntFrm* pCntnt = pFirstFtnOfNode->ContainsCntnt(); +/*N*/ if ( pCntnt ) +/*N*/ { +/*N*/ pCntnt->_InvalidatePos(); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } + +/*N*/ SwCntntNode *SwTxtNode::SplitNode( const SwPosition &rPos ) +/*N*/ { +/*N*/ // lege den Node "vor" mir an +/*N*/ register xub_StrLen nSplitPos = rPos.nContent.GetIndex(), +/*N*/ nTxtLen = aText.Len(); +/*N*/ SwTxtNode* pNode = _MakeNewTxtNode( rPos.nNode, FALSE, nSplitPos==nTxtLen ); +/*N*/ +/*N*/ if( GetDepends() && aText.Len() && (nTxtLen / 2) < nSplitPos ) +/*N*/ { +/*?*/ // JP 25.04.95: Optimierung fuer SplitNode: +/*?*/ // Wird am Ende vom Node gesplittet, dann verschiebe die +/*?*/ // Frames vom akt. auf den neuen und erzeuge fuer den akt. +/*?*/ // neue. Dadurch entfaellt das neu aufbauen vom Layout. +/*?*/ +/*?*/ LockModify(); // Benachrichtigungen abschalten +/*?*/ +/*?*/ // werden FlyFrames mit verschoben, so muessen diese nicht ihre +/*?*/ // Frames zerstoeren. Im SwTxtFly::SetAnchor wird es abgefragt! +/*?*/ if( pSwpHints ) +/*?*/ { +/*?*/ if( !pNode->pSwpHints ) +/*?*/ pNode->pSwpHints = new SwpHints; +/*?*/ pNode->pSwpHints->bInSplitNode = TRUE; +/*?*/ } +/*?*/ +/*?*/ //Ersten Teil des Inhalts in den neuen Node uebertragen und +/*?*/ //im alten Node loeschen. +/*?*/ SwIndex aIdx( this ); +/*?*/ Cut( pNode, aIdx, nSplitPos ); +/*?*/ +/*?*/ if( GetWrong() ) + {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 /*?*/ pNode->SetWrong( GetWrong()->SplitList( nSplitPos ) ); +/*?*/ +/*?*/ SetWrongDirty( TRUE ); +/*?*/ +/*?*/ if( pNode->pSwpHints ) +/*?*/ { +/*?*/ if ( pNode->pSwpHints->CanBeDeleted() ) +/*?*/ { +/*?*/ delete pNode->pSwpHints; +/*?*/ pNode->pSwpHints = 0; +/*?*/ } +/*?*/ else +/*?*/ pNode->pSwpHints->bInSplitNode = FALSE; +/*?*/ +/*?*/ // alle zeichengebundenen Rahmen, die im neuen Absatz laden +/*?*/ // muessen aus den alten Frame entfernt werden: +/*?*/ // JP 01.10.96: alle leeren und nicht zu expandierenden +/*?*/ // Attribute loeschen +/*?*/ if( pSwpHints ) +/*?*/ { +/*?*/ SwTxtAttr* pHt; +/*?*/ xub_StrLen* pEnd; +/*?*/ for( register USHORT j = pSwpHints->Count(); j; ) +/*?*/ if( RES_TXTATR_FLYCNT == +/*?*/ ( pHt = pSwpHints->GetHt( --j ) )->Which() ) +/*?*/ pHt->GetFlyCnt().GetFrmFmt()->DelFrms(); +/*?*/ else if( pHt->DontExpand() && 0 != ( pEnd = pHt->GetEnd() ) +/*?*/ && *pHt->GetStart() == *pEnd ) +/*?*/ { +/*?*/ // loeschen! +/*?*/ pSwpHints->DeleteAtPos( j ); +/*?*/ DestroyAttr( pHt ); +/*?*/ } +/*?*/ } +/*?*/ +/*?*/ } +/*?*/ +/*?*/ SwClientIter aIter( *this ); +/*?*/ SwClient* pLast = aIter.GoStart(); +/*?*/ if( pLast ) +/*?*/ do +/*?*/ { SwCntntFrm *pFrm = PTR_CAST( SwCntntFrm, pLast ); +/*?*/ if ( pFrm ) +/*?*/ { +/*?*/ pNode->Add( pFrm ); +/*?*/ if( pFrm->IsTxtFrm() && !pFrm->IsFollow() && +/*?*/ ((SwTxtFrm*)pFrm)->GetOfst() ) +/*?*/ ((SwTxtFrm*)pFrm)->SetOfst( 0 ); +/*?*/ } +/*?*/ } while( 0 != ( pLast = aIter++ )); +/*?*/ +/*?*/ if ( IsInCache() ) +/*?*/ { +/*?*/ SwFrm::GetCache().Delete( this ); +/*?*/ SetInCache( FALSE ); +/*?*/ } +/*?*/ +/*?*/ UnlockModify(); // Benachrichtigungen wieder freischalten +/*?*/ +/*?*/ const SwRootFrm *pRootFrm; +/*?*/ // If there is an accessible layout we must call modify even +/*?*/ // with length zero, because we have to notify about the changed +/*?*/ // text node. +/*?*/ if( nTxtLen != nSplitPos +/*?*/ #ifdef ACCESSIBLE_LAYOUT +/*?*/ || +/*?*/ ( (pRootFrm = pNode->GetDoc()->GetRootFrm()) != 0 && +/*?*/ pRootFrm->IsAnyShellAccessible() ) +/*?*/ #endif +/*?*/ ) +/*?*/ +/*?*/ { +/*?*/ // dann sage den Frames noch, das am Ende etwas "geloescht" wurde +/*?*/ if( 1 == nTxtLen - nSplitPos ) +/*?*/ { +/*?*/ SwDelChr aHint( nSplitPos ); +/*?*/ pNode->SwModify::Modify( 0, &aHint ); +/*?*/ } +/*?*/ else +/*?*/ { +/*?*/ SwDelTxt aHint( nSplitPos, nTxtLen - nSplitPos ); +/*?*/ pNode->SwModify::Modify( 0, &aHint ); +/*?*/ } +/*?*/ } +/*?*/ if( pSwpHints ) + {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 /*?*/ MoveTxtAttr_To_AttrSet(); +/*?*/ pNode->MakeFrms( *this ); // neue Frames anlegen. +/*?*/ lcl_ChangeFtnRef( *this ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ SwWrongList *pList = GetWrong(); +/*N*/ pWrong = NULL; +/*N*/ +/*N*/ SetWrongDirty( TRUE ); +/*N*/ +/*N*/ SwIndex aIdx( this ); +/*N*/ Cut( pNode, aIdx, rPos.nContent.GetIndex() ); +/*N*/ +/*N*/ // JP 01.10.96: alle leeren und nicht zu expandierenden +/*N*/ // Attribute loeschen +/*N*/ if( pSwpHints ) +/*N*/ { + DBG_BF_ASSERT(0, "STRIP"); //STRIP001 /*?*/ SwTxtAttr* pHt; +/*N*/ } +/*N*/ +/*N*/ if( pList ) +/*N*/ { + DBG_BF_ASSERT(0, "STRIP"); //STRIP001 /*?*/ pNode->SetWrong( pList->SplitList( nSplitPos ) ); +/*N*/ } +/*N*/ +/*N*/ if ( GetDepends() ) +/*N*/ MakeFrms( *pNode ); // neue Frames anlegen. +/*N*/ lcl_ChangeFtnRef( *pNode ); +/*N*/ } +/*N*/ +/*N*/ { +/*N*/ //Hint fuer Pagedesc versenden. Das mueste eigntlich das Layout im +/*N*/ //Paste der Frames selbst erledigen, aber das fuehrt dann wiederum +/*N*/ //zu weiteren Folgefehlern, die mit Laufzeitkosten geloest werden +/*N*/ //muesten. #56977# #55001# #56135# +/*N*/ const SfxPoolItem *pItem; +/*N*/ if( GetDepends() && SFX_ITEM_SET == pNode->GetSwAttrSet(). +/*N*/ GetItemState( RES_PAGEDESC, TRUE, &pItem ) ) +/*?*/ pNode->Modify( (SfxPoolItem*)pItem, (SfxPoolItem*)pItem ); +/*N*/ } +/*N*/ return pNode; +/*N*/ } + + +/*N*/ SwCntntNode *SwTxtNode::JoinNext() +/*N*/ { +/*N*/ SwNodes& rNds = GetNodes(); +/*N*/ SwNodeIndex aIdx( *this ); +/*N*/ if( SwCntntNode::CanJoinNext( &aIdx ) ) +/*N*/ { +/*N*/ SwDoc* pDoc = rNds.GetDoc(); +/*N*/ SvULongs aBkmkArr( 15, 15 ); +/*N*/ _SaveCntntIdx( pDoc, aIdx.GetIndex(), USHRT_MAX, aBkmkArr, SAVEFLY ); +/*N*/ SwTxtNode *pTxtNode = aIdx.GetNode().GetTxtNode(); +/*N*/ xub_StrLen nOldLen = aText.Len(); +/*N*/ SwWrongList *pList = GetWrong(); +/*N*/ if( pList ) +/*N*/ { + DBG_BF_ASSERT(0, "STRIP"); //STRIP001 /*?*/ pList->JoinList( pTxtNode->GetWrong(), nOldLen ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ pList = pTxtNode->GetWrong(); +/*N*/ if( pList ) +/*N*/ { + DBG_BF_ASSERT(0, "STRIP");//STRIP001 /*?*/ pList->Move( 0, nOldLen ); +/*N*/ } +/*N*/ } +/*N*/ { // wg. SwIndex +/*N*/ pTxtNode->Cut( this, SwIndex(pTxtNode), pTxtNode->Len() ); +/*N*/ } +/*N*/ // verschiebe noch alle Bookmarks/TOXMarks +/*N*/ if( aBkmkArr.Count() ) +/*N*/ _RestoreCntntIdx( pDoc, aBkmkArr, GetIndex(), nOldLen ); +/*N*/ +/*N*/ if( pTxtNode->HasAnyIndex() ) +/*N*/ { +/*N*/ // alle Crsr/StkCrsr/UnoCrsr aus dem Loeschbereich verschieben +/*?*/ pDoc->CorrAbs( aIdx, SwPosition( *this ), nOldLen, TRUE ); +/*N*/ } +/*N*/ rNds.Delete(aIdx); +/*N*/ pWrong = pList; +/*N*/ InvalidateNumRule(); +/*N*/ } +/*N*/ else +/*N*/ ASSERT( FALSE, "kein TxtNode." ); +/*N*/ +/*N*/ return this; +/*N*/ } + +/*N*/ SwCntntNode *SwTxtNode::JoinPrev() +/*N*/ { +/*N*/ SwNodes& rNds = GetNodes(); +/*N*/ SwNodeIndex aIdx( *this ); +/*N*/ if( SwCntntNode::CanJoinPrev( &aIdx ) ) +/*N*/ { +/*N*/ SwDoc* pDoc = rNds.GetDoc(); +/*N*/ SvULongs aBkmkArr( 15, 15 ); +/*N*/ _SaveCntntIdx( pDoc, aIdx.GetIndex(), USHRT_MAX, aBkmkArr, SAVEFLY ); +/*N*/ SwTxtNode *pTxtNode = aIdx.GetNode().GetTxtNode(); +/*N*/ xub_StrLen nLen = pTxtNode->Len(); +/*N*/ SwWrongList *pList = pTxtNode->GetWrong(); +/*N*/ if( pList ) +/*N*/ { + DBG_BF_ASSERT(0, "STRIP"); //STRIP001 /*?*/ pList->JoinList( GetWrong(), Len() ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ pList = GetWrong(); +/*N*/ if( pList ) +/*N*/ { + DBG_BF_ASSERT(0, "STRIP"); //STRIP001 /*?*/ pList->Move( 0, nLen ); +/*N*/ } +/*N*/ } +/*N*/ { // wg. SwIndex +/*N*/ pTxtNode->Cut( this, SwIndex( this ), SwIndex(pTxtNode), nLen ); +/*N*/ } +/*N*/ // verschiebe noch alle Bookmarks/TOXMarks +/*N*/ if( aBkmkArr.Count() ) +/*N*/ _RestoreCntntIdx( pDoc, aBkmkArr, GetIndex() ); +/*N*/ +/*N*/ if( pTxtNode->HasAnyIndex() ) +/*N*/ { +/*N*/ // alle Crsr/StkCrsr/UnoCrsr aus dem Loeschbereich verschieben +/*?*/ pDoc->CorrAbs( aIdx, SwPosition( *this ), nLen, TRUE ); +/*N*/ } +/*N*/ rNds.Delete(aIdx); +/*N*/ pWrong = pList; +/*N*/ InvalidateNumRule(); +/*N*/ } +/*N*/ else +/*N*/ ASSERT( FALSE, "kein TxtNode." ); +/*N*/ +/*N*/ return this; +/*N*/ } + +// erzeugt einen AttrSet mit Bereichen fuer Frame-/Para/Char-Attributen +/*N*/ void SwTxtNode::NewAttrSet( SwAttrPool& rPool ) +/*N*/ { +/*N*/ ASSERT( !pAttrSet, "AttrSet ist doch gesetzt" ); +/*N*/ pAttrSet = new SwAttrSet( rPool, aTxtNodeSetRange ); +/*N*/ //FEATURE::CONDCOLL +/*N*/ // pAttrSet->SetParent( &GetFmtColl()->GetAttrSet() ); +/*N*/ pAttrSet->SetParent( &GetAnyFmtColl().GetAttrSet() ); +/*N*/ //FEATURE::CONDCOLL +/*N*/ } + + +// change the URL in the attribut - if it is a valid URL! +/*N*/ void lcl_CheckURLChanged( const SwFmtINetFmt& rURLAttr, const String& rText, +/*N*/ xub_StrLen nStt, xub_StrLen nEnd ) +/*N*/ { +/*N*/ if( nStt < nEnd ) +/*N*/ { +/*N*/ xub_StrLen nS = nStt, nE = nEnd; +/*N*/ String sNew( FindFirstURLInText( rText, nS, nE, +/*N*/ GetAppCharClass() )); +/*N*/ if( sNew.Len() && nS == nStt && nE == nEnd ) +/*N*/ { +/*N*/ // it is an valid URL, so set it to the URL Object +/*N*/ ((SwFmtINetFmt&)rURLAttr).SetValue( rText.Copy( nS, nE - nS )); +/*N*/ } +/*N*/ } +/*N*/ } + +// Ueberladen der virtuellen Update-Methode von SwIndexReg. Dadurch +// benoetigen die Text-Attribute nur xub_StrLen statt SwIndizies! +/*N*/ void SwTxtNode::Update( const SwIndex & aPos, xub_StrLen nLen, +/*N*/ BOOL bNegativ ) +/*N*/ { +/*N*/ SetAutoCompleteWordDirty( TRUE ); +/*N*/ +/*N*/ TmpHints* pCollector = NULL; +/*N*/ if( pSwpHints ) +/*N*/ { +/*N*/ xub_StrLen nPos = aPos.GetIndex(); +/*N*/ xub_StrLen* pIdx; +/*N*/ SwTxtAttr* pHt; +/*N*/ if( bNegativ ) +/*N*/ { +/*N*/ xub_StrLen nMax = nPos + nLen; +/*N*/ for( USHORT n = 0; n < pSwpHints->Count(); ++n ) +/*N*/ { +/*N*/ BOOL bCheckURL = FALSE, bSttBefore = FALSE; +/*N*/ pHt = pSwpHints->GetHt(n); +/*N*/ pIdx = pHt->GetStart(); +/*N*/ if( *pIdx >= nPos ) +/*N*/ { +/*N*/ if( *pIdx > nMax ) +/*N*/ *pIdx -= nLen; +/*N*/ else +/*N*/ { +/*N*/ if( *pIdx < nMax ) +/*N*/ bCheckURL = TRUE; +/*N*/ *pIdx = nPos; +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ bSttBefore = TRUE; +/*N*/ +/*N*/ if( 0 == (pIdx = pHt->GetEnd()) ) +/*N*/ continue; +/*N*/ +/*N*/ if( *pIdx >= nPos ) +/*N*/ { +/*N*/ if( *pIdx > nMax ) +/*N*/ { +/*N*/ *pIdx -= nLen; +/*N*/ if( bSttBefore ) +/*N*/ bCheckURL = TRUE; +/*N*/ } +/*N*/ else if( *pIdx != nPos ) +/*N*/ { +/*N*/ *pIdx = nPos; +/*N*/ if( bSttBefore ) +/*N*/ bCheckURL = TRUE; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if( bCheckURL && RES_TXTATR_INETFMT == pHt->Which() ) +/*N*/ { +/*N*/ // reset the URL in the attribut - if it is a valid URL! +/*N*/ lcl_CheckURLChanged( pHt->GetINetFmt(), aText, +/*N*/ *pHt->GetStart(), *pHt->GetEnd() ); +/*N*/ } +/*N*/ +/*N*/ //JP 01.10.96: fuers SplitNode sollte das Flag nicht geloescht werden! +/*N*/ // pHt->SetDontExpand( FALSE ); +/*N*/ } +/*N*/ // AMA: Durch das Loeschen koennen Attribute gleiche Start- +/*N*/ // und/oder Endwerte erhalten, die vorher echt ungleich +/*N*/ // waren. Dadurch kann die Sortierung durcheinander geraten, +/*N*/ // die bei gleichen Start/Endwerten den Pointer selbst +/*N*/ // vergleicht, also ClearDummies ... +/*N*/ pSwpHints->ClearDummies( *this ); +/*N*/ if ( !pSwpHints->Merge( *this ) ) +/*N*/ ((SwpHintsArr*)pSwpHints)->Resort(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ xub_StrLen* pEnd; +/*N*/ BOOL bNoExp = FALSE; +/*N*/ BOOL bResort = FALSE; +/*N*/ const USHORT coArrSz = RES_TXTATR_WITHEND_END - RES_CHRATR_BEGIN + +/*N*/ ( RES_UNKNOWNATR_END - RES_UNKNOWNATR_BEGIN ); +/*N*/ +/*N*/ BOOL aDontExp[ coArrSz ]; +/*N*/ memset( &aDontExp, 0, coArrSz * sizeof(BOOL) ); +/*N*/ +/*N*/ for( USHORT n = 0; n < pSwpHints->Count(); ++n ) +/*N*/ { +/*N*/ BOOL bCheckURL = FALSE; +/*N*/ pHt = pSwpHints->GetHt(n); +/*N*/ pIdx = pHt->GetStart(); +/*N*/ if( *pIdx >= nPos ) +/*N*/ { +/*N*/ *pIdx += nLen; +/*N*/ if( 0 != ( pEnd = pHt->GetEnd() ) ) +/*N*/ *pEnd += nLen; +/*N*/ } +/*N*/ else if( 0 != ( pEnd = pHt->GetEnd() ) && *pEnd >= nPos ) +/*N*/ { +/*N*/ if( *pEnd > nPos || IsIgnoreDontExpand() ) +/*N*/ { +/*N*/ bCheckURL = TRUE; +/*N*/ *pEnd += nLen; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ USHORT nWhPos, nWhich = pHt->Which(); +/*N*/ +/*N*/ if( RES_CHRATR_BEGIN <= nWhich && +/*N*/ nWhich < RES_TXTATR_WITHEND_END ) +/*N*/ nWhPos = nWhich - RES_CHRATR_BEGIN; +/*N*/ else if( RES_UNKNOWNATR_BEGIN <= nWhich && +/*N*/ nWhich < RES_UNKNOWNATR_END ) +/*?*/ nWhPos = nWhich - RES_UNKNOWNATR_BEGIN + +/*?*/ ( RES_TXTATR_WITHEND_END - RES_CHRATR_BEGIN ); +/*N*/ else +/*N*/ continue; +/*N*/ +/*N*/ if( aDontExp[ nWhPos ] ) +/*N*/ continue; +/*N*/ +/*N*/ if( pHt->DontExpand() ) +/*N*/ { +/*?*/ pHt->SetDontExpand( FALSE ); +/*?*/ bResort = TRUE; +/*?*/ if( pHt->IsCharFmtAttr() ) +/*?*/ { +/*?*/ bNoExp = TRUE; +/*?*/ aDontExp[ RES_TXTATR_CHARFMT -RES_CHRATR_BEGIN ] +/*?*/ = TRUE; +/*?*/ aDontExp[ RES_TXTATR_INETFMT -RES_CHRATR_BEGIN ] +/*?*/ = TRUE; +/*?*/ } +/*?*/ else +/*?*/ aDontExp[ nWhPos ] = TRUE; +/*N*/ } +/*N*/ else if( bNoExp ) +/*N*/ { +/*?*/ if( !pCollector ) +/*?*/ pCollector = new TmpHints; +/*?*/ USHORT nCollCnt = pCollector->Count(); +/*?*/ for( USHORT i = 0; i < nCollCnt; ++i ) +/*?*/ { +/*?*/ SwTxtAttr *pTmp = (*pCollector)[ i ]; +/*?*/ if( nWhich == pTmp->Which() ) +/*?*/ { +/*?*/ pCollector->Remove( i ); +/*?*/ delete pTmp; +/*?*/ break; +/*?*/ } +/*?*/ } +/*?*/ SwTxtAttr *pTmp = MakeTxtAttr( pHt->GetAttr(), +/*?*/ nPos, nPos + nLen ); +/*?*/ pCollector->C40_INSERT( SwTxtAttr, pTmp, pCollector->Count() ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ *pEnd += nLen; +/*N*/ bCheckURL = TRUE; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if( bCheckURL && RES_TXTATR_INETFMT == pHt->Which() ) +/*N*/ { +/*N*/ // reset the URL in the attribut - if it is a valid URL! +/*N*/ lcl_CheckURLChanged( pHt->GetINetFmt(), aText, +/*N*/ *pHt->GetStart(), *pHt->GetEnd() ); +/*N*/ } +/*N*/ } +/*N*/ if( bResort ) +/*?*/ ((SwpHintsArr*)pSwpHints)->Resort(); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ SwIndexReg aTmpIdxReg; +/*N*/ if( !bNegativ ) +/*N*/ { +/*N*/ SwIndex* pIdx; +/*N*/ const SwRedlineTbl& rTbl = GetDoc()->GetRedlineTbl(); +/*N*/ if( rTbl.Count() ) +/*?*/ for( USHORT i = 0; i < rTbl.Count(); ++i ) +/*?*/ { +/*?*/ SwRedline* pRedl = rTbl[ i ]; +/*?*/ if( pRedl->HasMark() ) +/*?*/ { +/*?*/ SwPosition* pEnd = pRedl->End(); +/*?*/ if( this == &pEnd->nNode.GetNode() && +/*?*/ *pRedl->GetPoint() != *pRedl->GetMark() && +/*?*/ aPos.GetIndex() == +/*?*/ (pIdx = &pEnd->nContent)->GetIndex() ) +/*?*/ pIdx->Assign( &aTmpIdxReg, pIdx->GetIndex() ); +/*?*/ } +/*?*/ else if( this == &pRedl->GetPoint()->nNode.GetNode() && +/*?*/ aPos.GetIndex() == (pIdx = &pRedl->GetPoint()-> +/*?*/ nContent)->GetIndex() ) +/*?*/ { +/*?*/ pIdx->Assign( &aTmpIdxReg, pIdx->GetIndex() ); +/*?*/ if( &pRedl->GetBound( TRUE ) == pRedl->GetPoint() ) +/*?*/ { +/*?*/ pRedl->GetBound( FALSE ) = pRedl->GetBound( TRUE ); +/*?*/ pIdx = &pRedl->GetBound( FALSE ).nContent; +/*?*/ } +/*?*/ else +/*?*/ { +/*?*/ pRedl->GetBound( TRUE ) = pRedl->GetBound( FALSE ); +/*?*/ pIdx = &pRedl->GetBound( TRUE ).nContent; +/*?*/ } +/*?*/ pIdx->Assign( &aTmpIdxReg, pIdx->GetIndex() ); +/*?*/ } +/*N*/ } +/*N*/ +/*N*/ const SwBookmarks& rBkmk = GetDoc()->GetBookmarks(); +/*N*/ if( rBkmk.Count() ) +/*N*/ for( USHORT i = 0; i < rBkmk.Count(); ++i ) +/*N*/ { +/*N*/ SwBookmark* pBkmk = rBkmk[ i ]; +/*N*/ if( (this == &pBkmk->GetPos().nNode.GetNode() && +/*N*/ aPos.GetIndex() == (pIdx = (SwIndex*)&pBkmk->GetPos(). +/*N*/ nContent)->GetIndex() ) || +/*N*/ ( pBkmk->GetOtherPos() && +/*N*/ this == &pBkmk->GetOtherPos()->nNode.GetNode() && +/*N*/ aPos.GetIndex() == (pIdx = (SwIndex*)&pBkmk-> +/*N*/ GetOtherPos()->nContent)->GetIndex() ) ) +/*N*/ pIdx->Assign( &aTmpIdxReg, pIdx->GetIndex() ); +/*N*/ } +/*N*/ } +/*N*/ SwIndexReg::Update( aPos, nLen, bNegativ ); +/*N*/ if( pCollector ) +/*N*/ { +/*?*/ USHORT nCount = pCollector->Count(); +/*?*/ for( USHORT i = 0; i < nCount; ++i ) +/*?*/ pSwpHints->Insert( (*pCollector)[ i ], *this, FALSE ); +/*?*/ delete pCollector; +/*N*/ } +/*N*/ +/*N*/ aTmpIdxReg.MoveTo( *this ); +/*N*/ } + +/*N*/ SwFmtColl* SwTxtNode::ChgFmtColl( SwFmtColl *pNewColl ) +/*N*/ { +/*N*/ ASSERT( pNewColl,"ChgFmtColl: Collectionpointer ist 0." ); +/*N*/ ASSERT( HAS_BASE( SwTxtFmtColl, pNewColl ), +/*N*/ "ChgFmtColl: ist kein Text-Collectionpointer." ); +/*N*/ +/*N*/ SwTxtFmtColl *pOldColl = GetTxtColl(); +/*N*/ if( pNewColl != pOldColl ) +/*N*/ SwCntntNode::ChgFmtColl( pNewColl ); +/*N*/ // nur wenn im normalen Nodes-Array +/*N*/ if( GetNodes().IsDocNodes() ) +/*N*/ _ChgTxtCollUpdateNum( pOldColl, (SwTxtFmtColl*)pNewColl ); +/*N*/ return pOldColl; +/*N*/ } + +/*N*/ void SwTxtNode::_ChgTxtCollUpdateNum( const SwTxtFmtColl *pOldColl, +/*N*/ const SwTxtFmtColl *pNewColl) +/*N*/ { +/*N*/ SwDoc* pDoc = GetDoc(); +/*N*/ ASSERT( pDoc, "Kein Doc?" ); +/*N*/ // erfrage die OutlineLevel und update gegebenenfalls das Nodes-Array, +/*N*/ // falls sich die Level geaendert haben ! +/*N*/ const BYTE nOldLevel = pOldColl ? pOldColl->GetOutlineLevel():NO_NUMBERING; +/*N*/ const BYTE nNewLevel = pNewColl ? pNewColl->GetOutlineLevel():NO_NUMBERING; +/*N*/ +/*N*/ SwNodes& rNds = GetNodes(); +/*N*/ if( nOldLevel != nNewLevel ) +/*N*/ { +/*N*/ delete pNdOutl, pNdOutl = 0; +/*N*/ // Numerierung aufheben, falls sie aus der Vorlage kommt +/*N*/ // und nicht nicht aus der neuen +/*N*/ if( NO_NUMBERING != nNewLevel && pNdNum && ( !GetpSwAttrSet() || +/*N*/ SFX_ITEM_SET != GetpSwAttrSet()->GetItemState( +/*N*/ RES_PARATR_NUMRULE, FALSE )) && +/*N*/ (!pNewColl || SFX_ITEM_SET != pNewColl->GetItemState( +/*N*/ RES_PARATR_NUMRULE )) ) +/*N*/ delete pNdNum, pNdNum = 0; +/*N*/ if( rNds.IsDocNodes() ) +/*N*/ rNds.UpdateOutlineNode( *this, nOldLevel, nNewLevel ); +/*N*/ } +/*N*/ +/*N*/ // Update beim Level 0 noch die Fussnoten !! +/*N*/ if( (!nNewLevel || !nOldLevel) && pDoc->GetFtnIdxs().Count() && +/*N*/ FTNNUM_CHAPTER == pDoc->GetFtnInfo().eNum && +/*N*/ rNds.IsDocNodes() ) +/*N*/ { +/*?*/ SwNodeIndex aTmpIndex( rNds, GetIndex()); +/*?*/ +/*?*/ pDoc->GetFtnIdxs().UpdateFtn( aTmpIndex); +/*N*/ } +/*N*/ +/*N*/ //FEATURE::CONDCOLL +/*N*/ if( /*pOldColl != pNewColl && pNewColl && */ +/*N*/ RES_CONDTXTFMTCOLL == pNewColl->Which() ) +/*N*/ { +/*N*/ // Erfrage die akt. Condition des TextNodes: +/*N*/ ChkCondColl(); +/*N*/ } +/*N*/ //FEATURE::CONDCOLL +/*N*/ } + +// Wenn man sich genau am Ende einer Text- bzw. INetvorlage befindet, +// bekommt diese das DontExpand-Flag verpasst + + + +// gebe das vorgegebene Attribut, welches an der TextPosition (rIdx) +// gesetzt ist, zurueck. Gibt es keines, returne 0-Pointer. +// (gesetzt heisst, je nach bExpand ? +// Start < rIdx <= End +// : Start <= rIdx < End ) + +/*N*/ SwTxtAttr* SwTxtNode::GetTxtAttr( const SwIndex& rIdx, USHORT nWhichHt, +/*N*/ BOOL bExpand ) const +/*N*/ { +/*N*/ const SwTxtAttr* pRet = 0; +/*N*/ const SwTxtAttr* pHt = 0; +/*N*/ const xub_StrLen *pEndIdx = 0; +/*N*/ const xub_StrLen nIdx = rIdx.GetIndex(); +/*N*/ const USHORT nSize = pSwpHints ? pSwpHints->Count() : 0; +/*N*/ +/*N*/ for( USHORT i = 0; i < nSize; ++i ) +/*N*/ { +/*N*/ // ist der Attribut-Anfang schon groesser als der Idx ? +/*N*/ if( nIdx < *((pHt = (*pSwpHints)[i])->GetStart()) ) +/*N*/ break; // beenden, kein gueltiges Attribut +/*N*/ +/*N*/ // ist es das gewuenschte Attribut ? +/*N*/ if( pHt->Which() != nWhichHt ) +/*N*/ continue; // nein, weiter +/*N*/ +/*N*/ pEndIdx = pHt->GetEnd(); +/*N*/ // liegt innerhalb des Bereiches ?? +/*N*/ if( !pEndIdx ) +/*N*/ { +/*N*/ if( *pHt->GetStart() == nIdx ) +/*N*/ { +/*N*/ pRet = pHt; +/*N*/ break; +/*N*/ } +/*N*/ } +/*N*/ else if( *pHt->GetStart() <= nIdx && nIdx <= *pEndIdx ) +/*N*/ { +/*N*/ // Wenn bExpand gesetzt ist, wird das Verhalten bei Eingabe +/*N*/ // simuliert, d.h. der Start wuede verschoben, das Ende expandiert, +/*N*/ if( bExpand ) +/*N*/ { +/*?*/ if( *pHt->GetStart() < nIdx ) +/*?*/ pRet = pHt; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if( nIdx < *pEndIdx ) +/*N*/ pRet = pHt; // den am dichtesten liegenden +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ return (SwTxtAttr*)pRet; // kein gueltiges Attribut gefunden !! +/*N*/ } + +/************************************************************************* + * CopyHint() + *************************************************************************/ + + +/*N*/ void lcl_CopyHint( const USHORT nWhich, const SwTxtAttr *pHt, +/*N*/ SwTxtAttr *pNewHt, SwDoc* pOtherDoc, SwTxtNode *pDest ) +/*N*/ { +/*N*/ ASSERT( nWhich == pHt->Which(), "Falsche Hint-Id" ); +/*N*/ switch( nWhich ) +/*N*/ { +/*N*/ // Wenn wir es mit einem Fussnoten-Attribut zu tun haben, +/*N*/ // muessen wir natuerlich auch den Fussnotenbereich kopieren. +/*N*/ case RES_TXTATR_FTN : + {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 /*?*/ ((SwTxtFtn*)pHt)->CopyFtn( (SwTxtFtn*)pNewHt ); +/*?*/ break; +/*N*/ +/*N*/ // Beim Kopieren von Feldern in andere Dokumente +/*N*/ // muessen die Felder bei ihren neuen Feldtypen angemeldet werden. +/*N*/ +/*N*/ // TabellenFormel muessen relativ kopiert werden. +/*N*/ case RES_TXTATR_FIELD : +/*N*/ { +/*N*/ const SwFmtFld& rFld = pHt->GetFld(); +/*N*/ if( pOtherDoc ) + {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 /*?*/ ((SwTxtFld*)pHt)->CopyFld( (SwTxtFld*)pNewHt ); +/*N*/ +/*N*/ // Tabellenformel ?? +/*N*/ if( RES_TABLEFLD == rFld.GetFld()->GetTyp()->Which() +/*N*/ && ((SwTblField*)rFld.GetFld())->IsIntrnlName() ) +/*N*/ { +/*N*/ // wandel die interne in eine externe Formel um +/*?*/ const SwTableNode* pDstTblNd = ((SwTxtFld*)pHt)-> +/*?*/ GetTxtNode().FindTableNode(); +/*?*/ if( pDstTblNd ) +/*?*/ { +/*?*/ SwTblField* pTblFld = (SwTblField*) +/*?*/ pNewHt->GetFld().GetFld(); +/*?*/ pTblFld->PtrToBoxNm( &pDstTblNd->GetTable() ); +/*?*/ } +/*N*/ } +/*N*/ } +/*N*/ break; +/*N*/ +/*N*/ case RES_TXTATR_TOXMARK : +/*N*/ if( pOtherDoc && pDest && pDest->GetpSwpHints() +/*N*/ && USHRT_MAX != pDest->GetpSwpHints()->GetPos( pNewHt ) ) +/*N*/ // Beim Kopieren von TOXMarks(Client) in andere Dokumente +/*N*/ // muss der Verzeichnis (Modify) ausgetauscht werden +/*N*/ ((SwTxtTOXMark*)pNewHt)->CopyTOXMark( pOtherDoc ); +/*N*/ break; +/*N*/ +/*N*/ case RES_TXTATR_CHARFMT : +/*N*/ // Wenn wir es mit einer Zeichenvorlage zu tun haben, +/*N*/ // muessen wir natuerlich auch die Formate kopieren. +/*N*/ if( pDest && pDest->GetpSwpHints() +/*N*/ && USHRT_MAX != pDest->GetpSwpHints()->GetPos( pNewHt ) ) +/*N*/ { +/*N*/ SwCharFmt* pFmt = (SwCharFmt*)pHt->GetCharFmt().GetCharFmt(); +/*N*/ +/*N*/ if( pFmt && pOtherDoc ) +/*?*/ pFmt = pOtherDoc->CopyCharFmt( *pFmt ); +/*N*/ ((SwFmtCharFmt&)pNewHt->GetCharFmt()).SetCharFmt( pFmt ); +/*N*/ } +/*N*/ break; +/*?*/ case RES_TXTATR_INETFMT : +/*?*/ // Wenn wir es mit benutzerdefinierten INet-Zeichenvorlagen +/*?*/ // zu tun haben, muessen wir natuerlich auch die Formate kopieren. +/*?*/ if( pOtherDoc && pDest && pDest->GetpSwpHints() +/*?*/ && USHRT_MAX != pDest->GetpSwpHints()->GetPos( pNewHt ) ) +/*?*/ { +/*?*/ const SwDoc* pDoc; +/*?*/ if( 0!=( pDoc = ((SwTxtINetFmt*)pHt)->GetTxtNode().GetDoc() ) ) +/*?*/ { + DBG_BF_ASSERT(0, "STRIP"); //STRIP001 /*?*/ const SwCharFmts* pCharFmts = pDoc->GetCharFmts(); +/*?*/ } +/*?*/ } +/*?*/ //JP 24.04.98: Bug 49753 - ein TextNode muss am Attribut +/*?*/ // gesetzt sein, damit die Vorlagen erzeugt +/*?*/ // werden koenne +/*?*/ if( !((SwTxtINetFmt*)pNewHt)->GetpTxtNode() ) +/*?*/ ((SwTxtINetFmt*)pNewHt)->ChgTxtNode( pDest ); +/*?*/ +/*?*/ //JP 22.10.97: Bug 44875 - Verbindung zum Format herstellen +/*?*/ ((SwTxtINetFmt*)pNewHt)->GetCharFmt(); +/*?*/ break; +/*N*/ } +/*N*/ } + +/************************************************************************* +|* SwTxtNode::CopyAttr() +|* Beschreibung kopiert Attribute an der Position nStart in pDest. +|* BP 7.6.93: Es werden mit Absicht nur die Attribute _mit_ EndIdx +|* kopiert! CopyAttr wird vornehmlich dann gerufen, +|* wenn Attribute fuer einen Node mit leerem String +|* gesetzt werden sollen. +*************************************************************************/ + +/*N*/ void SwTxtNode::CopyAttr( SwTxtNode *pDest, const xub_StrLen nTxtStartIdx, +/*N*/ const xub_StrLen nOldPos ) +/*N*/ { +/*N*/ if( pSwpHints ) // keine Attribute, keine Kekse +/*N*/ { +/*N*/ const xub_StrLen *pEndIdx = 0; +/*N*/ const SwTxtAttr *pHt = 0; +/*N*/ SwTxtAttr *pNewHt = 0; +/*N*/ xub_StrLen nAttrStartIdx = 0; +/*N*/ USHORT nWhich; +/*N*/ +/*N*/ SwDoc* pOtherDoc = pDest->GetDoc(); +/*N*/ if( pOtherDoc == GetDoc() ) +/*N*/ pOtherDoc = 0; +/*N*/ +/*N*/ for( USHORT i = 0; i < pSwpHints->Count(); i++ ) +/*N*/ { +/*?*/ pHt = (*pSwpHints)[i]; +/*?*/ if( nTxtStartIdx < ( nAttrStartIdx = *pHt->GetStart() ) ) +/*?*/ break; // ueber das Textende, da nLen == 0 +/*?*/ +/*?*/ pEndIdx = pHt->GetEnd(); +/*?*/ if( pEndIdx ) +/*?*/ { +/*?*/ if( ( *pEndIdx > nTxtStartIdx || +/*?*/ ( *pEndIdx == nTxtStartIdx && +/*?*/ nAttrStartIdx == nTxtStartIdx ) ) ) +/*?*/ { +/*?*/ if( RES_TXTATR_REFMARK != ( nWhich = pHt->Which()) ) +/*?*/ { +/*?*/ // Attribut liegt im Bereich, also kopieren +/*?*/ if( 0 != ( pNewHt = pDest->Insert( pHt->GetAttr(), +/*?*/ nOldPos, nOldPos ) ) ) +/*?*/ lcl_CopyHint( nWhich, pHt, pNewHt, pOtherDoc, pDest ); +/*?*/ } +/*?*/ else if( !pOtherDoc ? GetDoc()->IsCopyIsMove() +/*?*/ : 0 == pOtherDoc->GetRefMark( +/*?*/ pHt->GetRefMark().GetRefName() ) ) +/*?*/ pDest->Insert( pHt->GetAttr(), nOldPos, nOldPos ); +/*?*/ } +/*?*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if( this != pDest ) +/*N*/ { +/*N*/ // Frames benachrichtigen, sonst verschwinden die Ftn-Nummern +/*N*/ SwUpdateAttr aHint( nOldPos, nOldPos, 0 ); +/*N*/ pDest->Modify( 0, &aHint ); +/*N*/ } +/*N*/ } + +/************************************************************************* +|* SwTxtNode::Copy() +|* Beschreibung kopiert Zeichen und Attibute in pDest, +|* wird angehaengt +*************************************************************************/ + +/*N*/ void SwTxtNode::Copy( SwTxtNode *pDest, const SwIndex &rStart, xub_StrLen nLen ) +/*N*/ { +/*N*/ SwIndex aIdx( pDest, pDest->aText.Len() ); +/*N*/ Copy( pDest, aIdx, rStart, nLen ); +/*N*/ } + +/*N*/ void SwTxtNode::Copy( SwTxtNode *pDest, const SwIndex &rDestStart, +/*N*/ const SwIndex &rStart, xub_StrLen nLen) +/*N*/ { +/*N*/ xub_StrLen nTxtStartIdx = rStart.GetIndex(); +/*N*/ xub_StrLen nDestStart = rDestStart.GetIndex(); // alte Pos merken +/*N*/ +/*N*/ if( !nLen ) +/*N*/ { +/*N*/ // wurde keine Laenge angegeben, dann Kopiere die Attribute +/*N*/ // an der Position rStart. +/*N*/ CopyAttr( pDest, nTxtStartIdx, nDestStart ); +/*N*/ +/*N*/ // harte Absatz umspannende Attribute kopieren +/*N*/ if( GetpSwAttrSet() ) +/*N*/ { +/*N*/ // alle, oder nur die CharAttribute ? +/*N*/ if( nDestStart || pDest->GetpSwAttrSet() || +/*N*/ nLen != pDest->GetTxt().Len() ) +/*N*/ { +/*?*/ SfxItemSet aCharSet( pDest->GetDoc()->GetAttrPool(), +/*?*/ RES_CHRATR_BEGIN, RES_CHRATR_END-1, +/*?*/ RES_TXTATR_CHARFMT, RES_TXTATR_CHARFMT, +/*?*/ RES_TXTATR_INETFMT, RES_TXTATR_INETFMT, +/*?*/ RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END-1, +/*?*/ 0 ); +/*?*/ aCharSet.Put( *GetpSwAttrSet() ); +/*N*/ if( aCharSet.Count() ) +/*N*/ pDest->SetAttr( aCharSet, nDestStart, nDestStart ); +/*N*/ } +/*N*/ else +/*N*/ GetpSwAttrSet()->CopyToModify( *pDest ); +/*N*/ } +/*N*/ +/*N*/ return; +/*N*/ } +/*N*/ +/*N*/ // 1. Text kopieren +/*N*/ xub_StrLen i = pDest->aText.Len() - nDestStart; +/*N*/ //JP 15.02.96: Bug 25537 - Attributbehandlung am Ende fehlt! Darum +/*N*/ // ueber die InsertMethode den Text einfuegen und nicht +/*N*/ // selbst direkt +/*N*/ pDest->Insert( aText.Copy( nTxtStartIdx, nLen ), rDestStart, +/*N*/ INS_EMPTYEXPAND ); +/*N*/ +/*N*/ // um reale Groesse Updaten ! +/*N*/ nLen = pDest->aText.Len() - nDestStart - i; +/*N*/ if( !nLen ) // String nicht gewachsen ?? +/*N*/ return; +/*N*/ +/*N*/ i = 0; +/*N*/ const xub_StrLen *pEndIdx = 0; +/*N*/ xub_StrLen nAttrStartIdx = 0; +/*N*/ const SwTxtAttr *pHt = 0; +/*N*/ SwTxtAttr *pNewHt = 0; +/*N*/ +/*N*/ SwDoc* pOtherDoc = pDest->GetDoc(); +/*N*/ if( pOtherDoc == GetDoc() ) +/*N*/ pOtherDoc = 0; +/*N*/ +/*N*/ // harte Absatz umspannende Attribute kopieren +/*N*/ if( GetpSwAttrSet() ) +/*N*/ { +/*N*/ // alle, oder nur die CharAttribute ? +/*N*/ if( nDestStart || pDest->GetpSwAttrSet() || +/*N*/ nLen != pDest->GetTxt().Len() ) +/*N*/ { +/*N*/ SfxItemSet aCharSet( pDest->GetDoc()->GetAttrPool(), +/*N*/ RES_CHRATR_BEGIN, RES_CHRATR_END-1, +/*N*/ RES_TXTATR_CHARFMT, RES_TXTATR_CHARFMT, +/*N*/ RES_TXTATR_INETFMT, RES_TXTATR_INETFMT, +/*N*/ RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END-1, +/*N*/ 0 ); +/*N*/ aCharSet.Put( *GetpSwAttrSet() ); +/*N*/ if( aCharSet.Count() ) +/*N*/ pDest->SetAttr( aCharSet, nDestStart, nDestStart + nLen ); +/*N*/ } +/*N*/ else +/*N*/ GetpSwAttrSet()->CopyToModify( *pDest ); +/*N*/ } +/*N*/ +/*N*/ +/*N*/ const BOOL bUndoNodes = FALSE; // !pOtherDoc && GetDoc()->GetUndoNds() == &GetNodes(); +/*N*/ +/*N*/ // Ende erst jetzt holen, weil beim Kopieren in sich selbst der +/*N*/ // Start-Index und alle Attribute vorher aktualisiert werden. +/*N*/ nTxtStartIdx = rStart.GetIndex(); +/*N*/ xub_StrLen nEnd = nTxtStartIdx + nLen; +/*N*/ +/*N*/ // 2. Attribute kopieren +/*N*/ // durch das Attribute-Array, bis der Anfang des Geltungsbereiches +/*N*/ // des Attributs hinter dem zu kopierenden Bereich liegt +/*N*/ USHORT nWhich, nSize = pSwpHints ? pSwpHints->Count() : 0; +/*N*/ xub_StrLen nAttrStt, nAttrEnd; +/*N*/ +/*N*/ // wird in sich selbst kopiert, dann kann beim Einfuegen ein +/*N*/ // Attribut geloescht werden. Darum erst ins Tmp-Array kopieren und +/*N*/ // dann erst ins eigene uebertragen. +/*N*/ SwpHts aArr( 5 ); +/*N*/ +/*N*/ // Del-Array fuer alle RefMarks ohne Ausdehnung +/*N*/ SwpHts aRefMrkArr; +/*N*/ +/*N*/ //Achtung: kann ungueltig sein!! +/*N*/ while( ( i < nSize ) && +/*N*/ ((nAttrStartIdx = *(*pSwpHints)[i]->GetStart()) < nEnd) ) +/*N*/ { +/*N*/ pHt = (*pSwpHints)[i]; +/*N*/ pNewHt = 0; +/*N*/ pEndIdx = pHt->GetEnd(); +/*N*/ nWhich = pHt->Which(); +/*N*/ +/*N*/ // JP 26.04.94: REFMARK's werden nie kopiert. Hat das Refmark aber +/*N*/ // keinen Bereich umspannt, so steht im Text ein 255 +/*N*/ // dieses muss entfernt werden. Trick: erst kopieren, +/*N*/ // erkennen und sammeln, nach dem kopieren Loeschen. +/*N*/ // Nimmt sein Zeichen mit ins Grab !! +/*N*/ // JP 14.08.95: Duerfen RefMarks gemovt werden? +/*N*/ int bCopyRefMark = RES_TXTATR_REFMARK == nWhich && ( bUndoNodes || +/*N*/ (!pOtherDoc ? GetDoc()->IsCopyIsMove() +/*N*/ : 0 == pOtherDoc->GetRefMark( +/*N*/ pHt->GetRefMark().GetRefName() ))); +/*N*/ +/*N*/ if( pEndIdx && RES_TXTATR_REFMARK == nWhich && !bCopyRefMark ) +/*N*/ { +/*N*/ ++i; +/*N*/ continue; +/*N*/ } +/*N*/ +/*N*/ if( nAttrStartIdx < nTxtStartIdx ) +/*N*/ { +/*N*/ // Anfang liegt vor dem Bereich +/*?*/ if( pEndIdx && ( nAttrEnd = *pEndIdx ) > nTxtStartIdx ) +/*?*/ { +/*?*/ // Attribut mit einem Bereich +/*?*/ // und das Ende des Attribut liegt im Bereich +/*?*/ nAttrStt = nDestStart; +/*?*/ nAttrEnd = nAttrEnd > nEnd +/*?*/ ? rDestStart.GetIndex() +/*?*/ : nDestStart + nAttrEnd - nTxtStartIdx; +/*?*/ } +/*?*/ else +/*?*/ { +/*?*/ ++i; +/*?*/ continue; +/*?*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ // der Anfang liegt innerhalb des Bereiches +/*N*/ nAttrStt = nDestStart + ( nAttrStartIdx - nTxtStartIdx ); +/*N*/ if( pEndIdx ) +/*N*/ nAttrEnd = *pEndIdx > nEnd +/*N*/ ? rDestStart.GetIndex() +/*N*/ : nDestStart + ( *pEndIdx - nTxtStartIdx ); +/*N*/ else +/*N*/ nAttrEnd = nAttrStt; +/*N*/ } +/*N*/ +/*N*/ if( pDest == this ) +/*N*/ { +/*N*/ // die Daten kopieren +/*?*/ pNewHt = MakeTxtAttr( pHt->GetAttr(), nAttrStt, nAttrEnd ); +/*?*/ +/*?*/ //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +/*?*/ //JP 23.04.95: erstmal so gesondert hier behandeln. Am Besten ist es +/*?*/ // aber im CopyFtn wenn die pDestFtn keinen StartNode hat, +/*?*/ // sich diesen dann anlegt. +/*?*/ // Aber so kurz vor der BETA besser nicht anfassen. +/*?*/ if( RES_TXTATR_FTN == nWhich ) +/*?*/ { +/*?*/ SwTxtFtn* pFtn = (SwTxtFtn*)pNewHt; +/*?*/ pFtn->ChgTxtNode( this ); +/*?*/ pFtn->MakeNewTextSection( GetNodes() ); +/*?*/ lcl_CopyHint( nWhich, pHt, pFtn, 0, 0 ); +/*?*/ pFtn->ChgTxtNode( 0 ); +/*?*/ } +/*?*/ else +/*?*/ //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +/*?*/ { +/*?*/ lcl_CopyHint( nWhich, pHt, pNewHt, 0, pDest ); +/*?*/ } +/*?*/ aArr.C40_INSERT( SwTxtAttr, pNewHt, aArr.Count() ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ pNewHt = pDest->Insert( pHt->GetAttr(), nAttrStt, +/*N*/ nAttrEnd, SETATTR_NOTXTATRCHR ); +/*N*/ if( pNewHt ) +/*N*/ lcl_CopyHint( nWhich, pHt, pNewHt, pOtherDoc, pDest ); +/*N*/ else if( !pEndIdx ) +/*N*/ { +/*N*/ // Attribut wurde nicht kopiert, hat seinen Inhalt mitgenommen! +/*N*/ // Damit der rest aber korrekt kopiert werden kann, muss das +/*N*/ // Zeichen wieder an der Position stehen. Darum hier ein +/*N*/ // "Dummy-TextAttribut" einfuegen, wird am Ende wieder entfernt! +/*?*/ pNewHt = pDest->Insert( SwFmtHardBlank( 0xB7 ), nAttrStt, 0 +/*?*/ /*???, INS_NOHINTEXPAND*/ ); +/*?*/ aRefMrkArr.C40_INSERT( SwTxtAttr, pNewHt, aRefMrkArr.Count() ); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if( RES_TXTATR_REFMARK == nWhich && !pEndIdx && !bCopyRefMark ) +/*N*/ { +/*?*/ aRefMrkArr.C40_INSERT( SwTxtAttr, pNewHt, aRefMrkArr.Count() ); +/*N*/ } +/*N*/ +/*N*/ ++i; +/*N*/ } +/*N*/ +/*N*/ // nur falls im Array Attribute stehen (kann nur beim Kopieren +/*N*/ // sich selbst passieren!!) +/*N*/ for( i = 0; i < aArr.Count(); ++i ) +/*?*/ Insert( aArr[ i ], SETATTR_NOTXTATRCHR ); +/*N*/ +/*N*/ if( pDest->GetpSwpHints() ) +/*N*/ for( i = 0; i < aRefMrkArr.Count(); ++i ) +/*N*/ { +/*?*/ pNewHt = aRefMrkArr[i]; +/*?*/ if( pNewHt->GetEnd() ) +/*?*/ { +/*?*/ pDest->GetpSwpHints()->Delete( pNewHt ); +/*?*/ pDest->DestroyAttr( pNewHt ); +/*?*/ } +/*?*/ else +/*?*/ { +/*?*/ const SwIndex aIdx( pDest, *pNewHt->GetStart() ); +/*?*/ pDest->Erase( aIdx, 1 ); +/*?*/ } +/*N*/ } +/*N*/ +/*N*/ CHECK_SWPHINTS(this); +/*N*/ } + + +/* + * Rudimentaeres Editieren, damit die SwDoc-Insert-Methoden + * funktionieren. + */ + +/*M*/ SwTxtNode& SwTxtNode::Insert( const XubString &rStr, +/*M*/ const SwIndex &rIdx, const USHORT nMode ) +/*M*/ { +/*M*/ ASSERT( rIdx <= aText.Len(), "Array ueberindiziert." ); +/*M*/ ASSERT( (ULONG)aText.Len() + (ULONG)rStr.Len() <= STRING_LEN, +/*M*/ "STRING_LEN ueberschritten." ); +/*M*/ +/*M*/ xub_StrLen aPos = rIdx.GetIndex(); +/*M*/ xub_StrLen nLen = aText.Len() - aPos; +/*M*/ +/*M*/ // sequence input checking +/*M*/ sal_Bool bInputChecked = sal_False; +/*M*/ +/*M*/ // We check only buffers which contain less than MAX_SEQUENCE_CHECK_LEN +/*M*/ // characters. This is for performance reasons, because a "copy and paste" +/*M*/ // can give us a really big input string. +/*N*/ SvtCTLOptions& rCTLOptions = SW_MOD()->GetCTLOptions(); +/*N*/ if ( rCTLOptions.IsCTLFontEnabled() && +/*N*/ rCTLOptions.IsCTLSequenceChecking() && aPos && +/*M*/ rStr.Len() < MAX_SEQUENCE_CHECK_LEN && pBreakIt->xBreak.is() && +/*M*/ ::com::sun::star::i18n::ScriptType::COMPLEX == +/*M*/ pBreakIt->xBreak->getScriptType( rStr, 0 ) ) +/*M*/ { +/*M*/ // generate new sequence input checker if not already done +/*M*/ if ( ! pCheckIt ) +/*M*/ pCheckIt = new SwCheckIt; +/*M*/ +/*M*/ if ( pCheckIt->xCheck.is() ) +/*M*/ { +/*M*/ xub_StrLen nI = 0; +/*M*/ xub_StrLen nTmpPos = aPos; +/*M*/ xub_Unicode cChar; +/*M*/ +/*M*/ while ( nI < rStr.Len() ) +/*M*/ { +/*M*/ cChar = rStr.GetChar( nI++ ); +/*M*/ if ( pCheckIt->xCheck->checkInputSequence( +/*M*/ aText, nTmpPos - 1, cChar, +/*N*/ ::com::sun::star::i18n::InputSequenceCheckMode::BASIC ) ) +/*M*/ { +/*M*/ // character can be inserted +/*M*/ aText.Insert( cChar, nTmpPos++ ); +/*M*/ } +/*M*/ } +/*M*/ bInputChecked = sal_True; +/*M*/ } +/*M*/ } +/*M*/ +/*M*/ if ( ! bInputChecked ) +/*M*/ aText.Insert( rStr, aPos ); +/*M*/ +/*M*/ nLen = aText.Len() - aPos - nLen; +/*M*/ if( !nLen ) // String nicht gewachsen ?? +/*M*/ return *this; +/*M*/ Update( rIdx, nLen ); // um reale Groesse Updaten ! +/*M*/ +/*M*/ // analog zu Insert(char) in txtedt.cxx: +/*M*/ // 1) bei bHintExp leere Hints an rIdx.GetIndex suchen und aufspannen +/*M*/ // 2) bei bHintExp == FALSE mitgezogene Feldattribute zuruecksetzen +/*M*/ +/*M*/ register USHORT i; +/*M*/ +/*M*/ if( pSwpHints ) +/*M*/ { +/*M*/ for( i = 0; i < pSwpHints->Count() && +/*M*/ rIdx >= *(*pSwpHints)[i]->GetStart(); ++i ) +/*M*/ { +/*M*/ SwTxtAttr *pHt = pSwpHints->GetHt( i ); +/*M*/ xub_StrLen* pEndIdx = pHt->GetEnd(); +/*M*/ if( !pEndIdx ) +/*M*/ continue; +/*M*/ +/*M*/ if( rIdx == *pEndIdx ) +/*M*/ { +/*M*/ if( nMode & INS_NOHINTEXPAND || pHt->DontExpand() ) +/*M*/ { +/*M*/ // bei leeren Attributen auch Start veraendern +/*M*/ if( rIdx == *pHt->GetStart() ) +/*M*/ *pHt->GetStart() -= nLen; +/*M*/ *pEndIdx -= nLen; +/*M*/ } +/*M*/ // leere Hints an rIdx.GetIndex ? +/*M*/ else if( nMode & INS_EMPTYEXPAND && +/*M*/ *pEndIdx == *pHt->GetStart() ) +/*M*/ { +/*M*/ *pHt->GetStart() -= nLen; +/*M*/ +/*M*/ // 8484: Symbol von 0-4, Roman von 4-6, +/*M*/ // neuer Hint: Roman 4-4 +/*M*/ +/*M*/ // - while ... die Vorgaenger ueberpruefen: +/*M*/ // wenn gleiches Ende und gleicher Which +/*M*/ // => das Ende des gefundenen zuruecksetzen +/*M*/ const USHORT nWhich = pHt->Which(); +/*M*/ SwTxtAttr *pFound; +/*M*/ xub_StrLen *pFoundEnd; +/*M*/ for( USHORT j = 0; j < i; ++j ) +/*M*/ if( 0 != (pFound = pSwpHints->GetHt( j )) && +/*M*/ nWhich == pFound->Which() && +/*M*/ 0 != ( pFoundEnd = pFound->GetEnd() ) && +/*M*/ rIdx == *pFoundEnd ) +/*M*/ { +/*M*/ *pFoundEnd -= nLen; +/*M*/ const USHORT nAktHtLen = pSwpHints->Count(); +/*M*/ pSwpHints->DeleteAtPos(j); +/*M*/ Insert( pFound, SETATTR_NOHINTADJUST ); +/*M*/ // AMA: Sicher ist sicher, falls pFound weiter hinten +/*M*/ // einsortiert wurde, koennte sonst die neue Position +/*M*/ // j vergessen werden! +/*M*/ if ( j ) --j; +/*M*/ // falls Attribute zusammengefasst werden, steht +/*M*/ // der "Index" ins Array falsch ! +/*M*/ i -= nAktHtLen - pSwpHints->Count(); +/*M*/ // Insert und Delete ? +/*M*/ } +/*M*/ +/*M*/ // ist unser Attribut ueberhaupt noch vorhanden ? +/*M*/ if( pHt == pSwpHints->GetHt( i ) ) +/*M*/ { +/*M*/ const USHORT nAktLen = pSwpHints->Count(); +/*M*/ pSwpHints->DeleteAtPos(i); +/*M*/ Insert( pHt, SETATTR_NOHINTADJUST ); +/*M*/ if( nAktLen > pSwpHints->Count() && i ) +/*M*/ --i; +/*M*/ } +/*M*/ continue; +/*M*/ } +/*M*/ else +/*M*/ continue; +/*M*/ pSwpHints->DeleteAtPos(i); +/*M*/ Insert( pHt, SETATTR_NOHINTADJUST ); +/*M*/ } +/*M*/ if ( !(nMode & INS_NOHINTEXPAND) && +/*M*/ rIdx == nLen && *pHt->GetStart() == rIdx.GetIndex() && +/*M*/ !pHt->IsDontExpandStartAttr() ) +/*M*/ { +/*M*/ // Kein Feld, am Absatzanfang, HintExpand +/*M*/ pSwpHints->DeleteAtPos(i); +/*M*/ *pHt->GetStart() -= nLen; +/*M*/ Insert( pHt, SETATTR_NOHINTADJUST ); +/*M*/ } +/*M*/ } +/*M*/ if ( pSwpHints->CanBeDeleted() ) +/*M*/ DELETEZ( pSwpHints ); +/*M*/ } +/*M*/ +/*M*/ if ( GetDepends() ) +/*M*/ { +/*M*/ SwInsTxt aHint( aPos, nLen ); +/*M*/ SwModify::Modify( 0, &aHint ); +/*M*/ } +/*M*/ +/*M*/ CHECK_SWPHINTS(this); +/*M*/ return *this; +/*M*/ } + +/************************************************************************* +|* +|* SwTxtNode::Cut() +|* +|* Beschreibung text.doc +|* Ersterstellung VB 20.03.91 +|* Letzte Aenderung JP 11.08.94 +|* +*************************************************************************/ + +/*N*/ void SwTxtNode::Cut( SwTxtNode *pDest, const SwIndex &rStart, xub_StrLen nLen ) +/*N*/ { +/*N*/ if(pDest) +/*N*/ { +/*N*/ SwIndex aDestStt( pDest, pDest->GetTxt().Len() ); +/*N*/ _Cut( pDest, aDestStt, rStart, nLen, FALSE ); +/*N*/ } +/*N*/ else +/*N*/ Erase( rStart, nLen ); +/*N*/ } + + +/*N*/ void SwTxtNode::_Cut( SwTxtNode *pDest, const SwIndex& rDestStart, +/*N*/ const SwIndex &rStart, xub_StrLen nLen, BOOL bUpdate ) +/*N*/ { +/*N*/ if(!pDest) +/*N*/ { +/*?*/ Erase( rStart, nLen ); +/*?*/ return; +/*N*/ } +/*N*/ +/*N*/ // nicht im Dokument verschieben ? +/*N*/ if( GetDoc() != pDest->GetDoc() ) +/*N*/ { +/*?*/ Copy( pDest, rDestStart, rStart, nLen); +/*?*/ Erase(rStart,nLen); +/*?*/ return; +/*N*/ } +/*N*/ +/*N*/ if( !nLen ) +/*N*/ { +/*N*/ // wurde keine Laenge angegeben, dann Kopiere die Attribute +/*N*/ // an der Position rStart. +/*N*/ CopyAttr( pDest, rStart.GetIndex(), rDestStart.GetIndex() ); +/*N*/ return; +/*N*/ } +/*N*/ +/*N*/ xub_StrLen nTxtStartIdx = rStart.GetIndex(); +/*N*/ xub_StrLen nDestStart = rDestStart.GetIndex(); // alte Pos merken +/*N*/ xub_StrLen nInitSize = pDest->aText.Len(); +/*N*/ +/*N*/ xub_StrLen *pEndIdx = 0; +/*N*/ xub_StrLen nAttrStartIdx = 0; +/*N*/ SwTxtAttr *pHt = 0; +/*N*/ SwTxtAttr *pNewHt = 0; +/*N*/ +/*N*/ // wird in sich selbst verschoben, muss es gesondert behandelt werden !! +/*N*/ if( pDest == this ) +/*N*/ { +/*?*/ aText.Insert( aText, nTxtStartIdx, nLen, nDestStart ); +/*?*/ aText.Erase( nTxtStartIdx + (nDestStart<nTxtStartIdx ? nLen : 0), nLen ); +/*?*/ +/*?*/ xub_StrLen nEnd = rStart.GetIndex() + nLen; +/*?*/ USHORT n; +/*?*/ +/*?*/ // dann suche mal alle Attribute zusammen, die im verschobenen +/*?*/ // Bereich liegen. Diese werden in das extra Array verschoben, +/*?*/ // damit sich die Indizies beim Updaten nicht veraendern !!! +/*?*/ SwIndexReg aTmpRegArr; +/*?*/ SwpHts aArr( 5 ); +/*?*/ +/*?*/ // 2. Attribute verschieben +/*?*/ // durch das Attribute-Array, bis der Anfang des Geltungsbereiches +/*?*/ // des Attributs hinter dem zu verschiebenden Bereich liegt +/*?*/ USHORT nAttrCnt = 0, nWhich; +/*?*/ while( pSwpHints && nAttrCnt < pSwpHints->Count() && +/*?*/ (nAttrStartIdx = *(pHt = pSwpHints->GetHt(nAttrCnt))-> +/*?*/ GetStart()) < nEnd ) +/*?*/ { +/*?*/ pNewHt = 0; +/*?*/ pEndIdx = pHt->GetEnd(); +/*?*/ +/*?*/ if(nAttrStartIdx < nTxtStartIdx) +/*?*/ { +/*?*/ // Anfang liegt vor dem Bereich +/*?*/ if( RES_TXTATR_REFMARK != ( nWhich = pHt->Which() ) && +/*?*/ pEndIdx && *pEndIdx > nTxtStartIdx ) +/*?*/ { +/*?*/ // Attribut mit einem Bereich +/*?*/ // und das Ende des Attribut liegt im Bereich +/*?*/ pNewHt = MakeTxtAttr( pHt->GetAttr(), 0, +/*?*/ *pEndIdx > nEnd +/*?*/ ? nLen +/*?*/ : *pEndIdx - nTxtStartIdx ); +/*?*/ } +/*?*/ } +/*?*/ else +/*?*/ { +/*?*/ // der Anfang liegt vollstaendig im Bereich +/*?*/ if( !pEndIdx || *pEndIdx < nEnd ) +/*?*/ { +/*?*/ // Attribut verschieben +/*?*/ pSwpHints->Delete( pHt ); +/*?*/ // die Start/End Indicies neu setzen +/*?*/ *pHt->GetStart() = nAttrStartIdx - nTxtStartIdx; +/*?*/ if( pEndIdx ) +/*?*/ *pHt->GetEnd() = *pEndIdx - nTxtStartIdx; +/*?*/ aArr.C40_INSERT( SwTxtAttr, pHt, aArr.Count() ); +/*?*/ continue; // while-Schleife weiter, ohne ++ ! +/*?*/ } +/*?*/ // das Ende liegt dahinter +/*?*/ else if( RES_TXTATR_REFMARK != ( nWhich = pHt->Which() )) +/*?*/ { +/*?*/ pNewHt = MakeTxtAttr( pHt->GetAttr(), +/*?*/ nAttrStartIdx - nTxtStartIdx, +/*?*/ !pEndIdx ? 0 +/*?*/ : ( *pEndIdx > nEnd +/*?*/ ? nLen +/*?*/ : *pEndIdx - nTxtStartIdx )); +/*?*/ } +/*?*/ } +/*?*/ if( pNewHt ) +/*?*/ { +/*?*/ // die Daten kopieren +/*?*/ lcl_CopyHint( nWhich, pHt, pNewHt, 0, this ); +/*?*/ aArr.C40_INSERT( SwTxtAttr, pNewHt, aArr.Count() ); +/*?*/ } +/*?*/ ++nAttrCnt; +/*?*/ } +/*?*/ +/*?*/ if( bUpdate ) +/*?*/ // Update aller Indizies +/*?*/ Update( rDestStart, nLen ); +/*?*/ #ifdef CUTNOEXPAND +/*?*/ else +/*?*/ // wird am Ende eingefuegt, nur die Attribut-Indizies verschieben +/*?*/ if( 0 < nLen && 0 < nInitSize && pSwpHints ) +/*?*/ { +/*?*/ // siehe nach, ob an der Einfuegeposition das Ende eines +/*?*/ // Attributes stand. Ist es kein Feld, muss es expandiert werden !!! +/*?*/ for( n = 0; n < pSwpHints->Count(); n++ ) +/*?*/ { +/*?*/ pHt = pSwpHints->GetHt(n); +/*?*/ if( 0 != ( pEndIdx = pHt->GetEnd() ) && +/*?*/ *pEndIdx == nInitSize ) +/*?*/ *pEndIdx += nLen; +/*?*/ } +/*?*/ } +/*?*/ #endif +/*?*/ CHECK_SWPHINTS(this); +/*?*/ +/*?*/ Update( rStart, nLen, TRUE ); +/*?*/ +/*?*/ CHECK_SWPHINTS(this); +/*?*/ +/*?*/ // dann setze die kopierten/geloeschten Attribute in den Node +/*?*/ if( nDestStart <= nTxtStartIdx ) +/*?*/ nTxtStartIdx += nLen; +/*?*/ else +/*?*/ nDestStart -= nLen; +/*?*/ +/*?*/ for( n = 0; n < aArr.Count(); ++n ) +/*?*/ { +/*?*/ pNewHt = aArr[n]; +/*?*/ *pNewHt->GetStart() = nDestStart + *pNewHt->GetStart(); +/*?*/ if( 0 != ( pEndIdx = pNewHt->GetEnd() )) +/*?*/ *pEndIdx = nDestStart + *pEndIdx; +/*?*/ Insert( pNewHt, SETATTR_NOTXTATRCHR ); +/*?*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ xub_StrLen i = nInitSize - nDestStart; +/*N*/ pDest->aText.Insert( aText, nTxtStartIdx, nLen, nDestStart ); +/*N*/ aText.Erase( nTxtStartIdx, nLen ); +/*N*/ nLen = pDest->aText.Len() - nDestStart - i; // um reale Groesse Updaten ! +/*N*/ if( !nLen ) // String nicht gewachsen ?? +/*N*/ return; +/*N*/ +/*N*/ i = 0; +/*N*/ +/*N*/ if( bUpdate ) +/*N*/ // Update aller Indizies +/*N*/ pDest->Update( rDestStart, nLen); +/*N*/ #ifdef CUTNOEXPAND +/*N*/ else +/*N*/ // wird am Ende eingefuegt, nur die Attribut-Indizies verschieben +/*N*/ if( 0 < nLen && 0 < nInitSize && pDest->pSwpHints ) +/*N*/ { +/*N*/ // siehe nach, ob an der Einfuegeposition das Ende eines +/*N*/ // Attributes stand. Ist es kein Feld, muss es expandiert werden !!! +/*N*/ for( USHORT n = 0; n < pDest->pSwpHints->Count(); n++ ) +/*N*/ { +/*N*/ pHt = pDest->pSwpHints->GetHt(n); +/*N*/ if( 0 != ( pEndIdx = pHt->GetEnd() ) && +/*N*/ *pEndIdx == nInitSize ) +/*N*/ *pEndIdx += nLen; +/*N*/ } +/*N*/ } +/*N*/ #endif +/*N*/ CHECK_SWPHINTS(pDest); +/*N*/ +/*N*/ USHORT nEnd = rStart.GetIndex() + nLen; +/*N*/ SwDoc* pOtherDoc = pDest->GetDoc(); +/*N*/ if( pOtherDoc == GetDoc() ) +/*N*/ pOtherDoc = 0; +/*N*/ const BOOL bUndoNodes = FALSE; // !pOtherDoc && GetDoc()->GetUndoNds() == &GetNodes(); +/*N*/ +/*N*/ // harte Absatz umspannende Attribute kopieren +/*N*/ if( GetpSwAttrSet() ) +/*N*/ { +/*N*/ // alle, oder nur die CharAttribute ? +/*N*/ if( nInitSize || pDest->GetpSwAttrSet() || +/*N*/ nLen != pDest->GetTxt().Len() ) +/*N*/ { +/*?*/ SfxItemSet aCharSet( pDest->GetDoc()->GetAttrPool(), +/*?*/ RES_CHRATR_BEGIN, RES_CHRATR_END-1, +/*?*/ RES_TXTATR_CHARFMT, RES_TXTATR_CHARFMT, +/*?*/ RES_TXTATR_INETFMT, RES_TXTATR_INETFMT, +/*?*/ RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END-1, +/*?*/ 0 ); +/*?*/ aCharSet.Put( *GetpSwAttrSet() ); +/*?*/ if( aCharSet.Count() ) +/*?*/ pDest->SetAttr( aCharSet, nDestStart, nDestStart + nLen ); +/*N*/ } +/*N*/ else +/*N*/ GetpSwAttrSet()->CopyToModify( *pDest ); +/*N*/ } +/*N*/ +/*N*/ // 2. Attribute verschieben +/*N*/ // durch das Attribute-Array, bis der Anfang des Geltungsbereiches +/*N*/ // des Attributs hinter dem zu verschiebenden Bereich liegt +/*N*/ USHORT nAttrCnt = 0, nWhich; +/*N*/ while( pSwpHints && nAttrCnt < pSwpHints->Count() && +/*N*/ ( (nAttrStartIdx = *(pHt = pSwpHints->GetHt(nAttrCnt))-> +/*N*/ GetStart()) < nEnd ) ) +/*N*/ { +/*N*/ pNewHt = 0; +/*N*/ pEndIdx = pHt->GetEnd(); +/*N*/ +/*N*/ if(nAttrStartIdx < nTxtStartIdx) +/*N*/ { +/*N*/ // Anfang liegt vor dem Bereich +/*?*/ if( ( RES_TXTATR_REFMARK != ( nWhich = pHt->Which() ) +/*?*/ || bUndoNodes ) && pEndIdx && *pEndIdx > nTxtStartIdx ) +/*?*/ { +/*?*/ // Attribut mit einem Bereich +/*?*/ // und das Ende des Attribut liegt im Bereich +/*?*/ pNewHt = pDest->MakeTxtAttr( pHt->GetAttr(), nDestStart, +/*?*/ nDestStart + ( +/*?*/ *pEndIdx > nEnd +/*?*/ ? nLen +/*?*/ : *pEndIdx - nTxtStartIdx ) ); +/*?*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ // der Anfang liegt vollstaendig im Bereich +/*N*/ nWhich = pHt->Which(); +/*N*/ if( !pEndIdx || *pEndIdx < nEnd || +/*N*/ ( !pOtherDoc && !bUndoNodes && RES_TXTATR_REFMARK +/*N*/ == nWhich ) ) +/*N*/ { +/*N*/ // Attribut verschieben +/*N*/ pSwpHints->Delete( pHt ); +/*N*/ // die Start/End Indicies neu setzen +/*N*/ *pHt->GetStart() = +/*N*/ nDestStart + (nAttrStartIdx - nTxtStartIdx); +/*N*/ if( pEndIdx ) +/*N*/ *pHt->GetEnd() = nDestStart + ( +/*N*/ *pEndIdx > nEnd +/*N*/ ? nLen +/*N*/ : *pEndIdx - nTxtStartIdx ); +/*N*/ pDest->Insert( pHt, SETATTR_NOTXTATRCHR | SETATTR_DONTREPLACE ); +/*N*/ continue; // while-Schleife weiter, ohne ++ ! +/*N*/ } +/*N*/ // das Ende liegt dahinter +/*N*/ else if( RES_TXTATR_REFMARK != nWhich || bUndoNodes ) +/*N*/ { +/*N*/ pNewHt = MakeTxtAttr( pHt->GetAttr(), +/*N*/ nDestStart + (nAttrStartIdx - nTxtStartIdx), +/*N*/ !pEndIdx ? 0 +/*N*/ : nDestStart + ( *pEndIdx > nEnd +/*N*/ ? nLen +/*N*/ : *pEndIdx - nTxtStartIdx )); +/*N*/ } +/*N*/ } +/*N*/ if ( pNewHt ) +/*N*/ { +/*N*/ if( pDest->Insert( pNewHt, SETATTR_NOTXTATRCHR | SETATTR_DONTREPLACE )) +/*N*/ lcl_CopyHint( nWhich, pHt, pNewHt, pOtherDoc, pDest ); +/*N*/ } +/*N*/ ++nAttrCnt; +/*N*/ } +/*N*/ // sollten jetzt noch leere Attribute rumstehen, dann haben diese +/*N*/ // eine hoehere Praezedenz. Also herausholen und das Array updaten. +/*N*/ // Die dabei entstehenden leeren Hints werden von den gesicherten +/*N*/ // "uebergeplaettet". (Bug: 6977) +/*N*/ if( pSwpHints && nAttrCnt < pSwpHints->Count() ) +/*N*/ { +/*?*/ SwpHts aArr( 5 ); +/*?*/ for( ; nAttrCnt < pSwpHints->Count() && +/*?*/ nEnd == *(pHt = pSwpHints->GetHt(nAttrCnt))->GetStart(); +/*?*/ ++nAttrCnt ) +/*?*/ { +/*?*/ if( 0 != ( pEndIdx = pHt->GetEnd() ) && *pEndIdx == nEnd ) +/*?*/ { +/*?*/ aArr.C40_INSERT( SwTxtAttr, pHt, aArr.Count() ); +/*?*/ pSwpHints->Delete( pHt ); +/*?*/ --nAttrCnt; +/*?*/ } +/*?*/ } +/*?*/ Update( rStart, nLen, TRUE ); +/*?*/ +/*?*/ for( nAttrCnt = 0; nAttrCnt < aArr.Count(); ++nAttrCnt ) +/*?*/ { +/*?*/ pHt = aArr[ nAttrCnt ]; +/*?*/ *pHt->GetStart() = *pHt->GetEnd() = rStart.GetIndex(); +/*?*/ Insert( pHt ); +/*?*/ } +/*N*/ } +/*N*/ else +/*N*/ Update( rStart, nLen, TRUE ); +/*N*/ +/*N*/ CHECK_SWPHINTS(this); +/*N*/ } +/*N*/ +/*N*/ if( pSwpHints && pSwpHints->CanBeDeleted() ) +/*N*/ DELETEZ( pSwpHints ); +/*N*/ +/*N*/ // Frames benachrichtigen; +/*N*/ SwInsTxt aInsHint( nDestStart, nLen ); +/*N*/ pDest->SwCntntNode::Modify( 0, &aInsHint ); +/*N*/ SwDelTxt aDelHint( nTxtStartIdx, nLen ); +/*N*/ SwCntntNode::Modify( 0, &aDelHint ); +/*N*/ } + + +/*N*/ SwTxtNode& SwTxtNode::Erase(const SwIndex &rIdx, xub_StrLen nCount, +/*N*/ const USHORT nMode ) +/*N*/ { +/*N*/ ASSERT( rIdx <= aText.Len(), "Array ueberindiziert." ); +/*N*/ +/*N*/ const xub_StrLen nCnt = STRING_LEN == nCount +/*N*/ ? aText.Len() - rIdx.GetIndex() : nCount; +/*N*/ aText.Erase( rIdx.GetIndex(), nCnt ); +/*N*/ + /* GCAttr(); alle leeren weggwerfen ist zu brutal. + * Es duerfen nur die wegggeworfen werden, + * die im Bereich liegen und nicht am Ende des Bereiches liegen + */ +/*N*/ +/*N*/ // Abfrage auf pSwpHints weil TextFelder und FlyFrames Text loeschen +/*N*/ // (Rekursion)!! +/*N*/ for( USHORT i = 0; pSwpHints && i < pSwpHints->Count(); ++i ) +/*N*/ { +/*N*/ SwTxtAttr *pHt = pSwpHints->GetHt(i); +/*N*/ +/*N*/ const xub_StrLen nHtStt = *pHt->GetStart(); +/*N*/ +/*N*/ if( nHtStt < rIdx.GetIndex() ) +/*N*/ continue; +/*N*/ +/*N*/ // TextFelder und FlyFrames loeschen Text (Rekursion)!! +/*N*/ const xub_StrLen nEndIdx = rIdx.GetIndex() + nCnt; +/*N*/ if( nHtStt > nEndIdx ) +/*N*/ // die Hints sind nach Ende sortiert, also ist Start +/*N*/ // vom Hint groesser als EndIdx dann Abbrechen +/*N*/ break; +/*N*/ +/*N*/ const xub_StrLen* pHtEndIdx = pHt->GetEnd(); +/*N*/ const USHORT nWhich = pHt->Which(); +/*N*/ +/*N*/ if( !pHtEndIdx ) +/*N*/ { +/*N*/ // TxtHints ohne EndIndex werden natuerlich auch geloescht: +/*N*/ if( RES_TXTATR_BEGIN <= nWhich && RES_TXTATR_END > nWhich && +/*N*/ nHtStt >= rIdx.GetIndex() && nHtStt < nEndIdx ) +/*N*/ { +/*N*/ pSwpHints->DeleteAtPos(i); +/*N*/ // Damit im Dtor der TxtAttr ohne End die CH_TXTATR nicht +/*N*/ // geloescht werden... +/*N*/ *(pHt->GetStart()) = USHRT_MAX; +/*N*/ DestroyAttr( pHt ); +/*N*/ --i; +/*N*/ } +/*N*/ continue; +/*N*/ } +/*N*/ +/*N*/ if( *pHtEndIdx >= nEndIdx && !( +/*N*/ !(INS_EMPTYEXPAND & nMode) && *pHtEndIdx == nEndIdx && +/*N*/ (nWhich == RES_TXTATR_TOXMARK || nWhich == RES_TXTATR_REFMARK)) ) +/*N*/ continue; +/*N*/ +/*N*/ pSwpHints->DeleteAtPos(i); +/*N*/ DestroyAttr( pHt ); +/*N*/ --i; +/*N*/ } +/*N*/ +/*N*/ if ( pSwpHints && pSwpHints->CanBeDeleted() ) +/*?*/ DELETEZ( pSwpHints ); +/*N*/ +/*N*/ Update( rIdx, nCnt, TRUE ); +/*N*/ +/*N*/ if( 1 == nCnt ) +/*N*/ { +/*N*/ SwDelChr aHint( rIdx.GetIndex() ); +/*N*/ SwModify::Modify( 0, &aHint ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ SwDelTxt aHint( rIdx.GetIndex(), nCnt ); +/*N*/ SwModify::Modify( 0, &aHint ); +/*N*/ } +/*N*/ +/*N*/ CHECK_SWPHINTS(this); +/*N*/ return *this; +/*N*/ } + +/*********************************************************************** +#* Class : SwTxtNode +#* Methode : GCAttr +#* +#* Beschreibung +#* text.doc +#* +#* Datum : MS 28.11.90 +#* Update : VB 24.07.91 +#***********************************************************************/ + + +/*N*/ const SwNodeNum* SwTxtNode::UpdateNum( const SwNodeNum& rNum ) +/*N*/ { +/*N*/ if( NO_NUMBERING == rNum.GetLevel() ) // kein Nummerierung mehr ? +/*N*/ { +/*N*/ if( !pNdNum ) +/*N*/ return 0; +/*N*/ delete pNdNum, pNdNum = 0; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if( !pNdNum ) +/*N*/ pNdNum = new SwNodeNum( rNum ); +/*N*/ else if( !( *pNdNum == rNum )) +/*N*/ *pNdNum = rNum; +/*N*/ } +/*N*/ NumRuleChgd(); +/*N*/ return pNdNum; +/*N*/ } + +/*N*/ const SwNumRule* SwTxtNode::GetNumRule() const +/*N*/ { +/*N*/ const SwNumRule* pRet = 0; +/*N*/ const SfxPoolItem* pItem = GetNoCondAttr( RES_PARATR_NUMRULE, TRUE ); +/*N*/ if( pItem && ((SwNumRuleItem*)pItem)->GetValue().Len() ) +/*N*/ pRet = GetDoc()->FindNumRulePtr( ((SwNumRuleItem*)pItem)->GetValue() ); +/*N*/ return pRet; +/*N*/ } + +/*N*/ void SwTxtNode::NumRuleChgd() +/*N*/ { +/*N*/ #ifndef NUM_RELSPACE +/*N*/ +/*N*/ // 6969: Aktualisierung der NumPortions auch bei leeren Zeilen! +/*N*/ SwInsTxt aHint( 0, 0 ); +/*N*/ SwModify::Modify( 0, &aHint ); +/*N*/ +/*N*/ #else +/*N*/ +/*N*/ if( IsInCache() ) +/*N*/ { +/*N*/ SwFrm::GetCache().Delete( this ); +/*N*/ SetInCache( FALSE ); +/*N*/ } +/*N*/ SetInSwFntCache( FALSE ); +/*N*/ +/*N*/ SvxLRSpaceItem& rLR = (SvxLRSpaceItem&)GetSwAttrSet().GetLRSpace(); +/*N*/ SwModify::Modify( &rLR, &rLR ); +/*N*/ +/*N*/ #endif +/*N*/ } + +/*N*/ const SwNodeNum* SwTxtNode::UpdateOutlineNum( const SwNodeNum& rNum ) +/*N*/ { +/*N*/ if( NO_NUMBERING == rNum.GetLevel() ) // kein Nummerierung mehr ? +/*N*/ { +/*N*/ if( !pNdOutl ) +/*N*/ return 0; +/*N*/ delete pNdOutl, pNdOutl = 0; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if( !pNdOutl ) +/*N*/ pNdOutl = new SwNodeNum( rNum ); +/*N*/ else if( !( *pNdOutl == rNum )) +/*N*/ *pNdOutl = rNum; +/*N*/ } +/*N*/ +/*N*/ // 6969: Aktualisierung der NumPortions auch bei leeren Zeilen! +/*N*/ NumRuleChgd(); +/*N*/ return pNdOutl; +/*N*/ } + +/*N*/ SwTxtNode* SwTxtNode::_MakeNewTxtNode( const SwNodeIndex& rPos, BOOL bNext, +/*N*/ BOOL bChgFollow ) +/*N*/ { +/*N*/ /* hartes PageBreak/PageDesc/ColumnBreak aus AUTO-Set ignorieren */ +/*N*/ SwAttrSet* pNewAttrSet = 0; +/*N*/ if( GetpSwAttrSet() ) +/*N*/ { +/*N*/ pNewAttrSet = new SwAttrSet( *GetpSwAttrSet() ); +/*N*/ SwAttrSet* pTmpSet = GetpSwAttrSet(); +/*N*/ +/*N*/ if( bNext ) // der naechste erbt keine Breaks! +/*N*/ pTmpSet = pNewAttrSet; +/*N*/ +/*N*/ // PageBreaks/PageDesc/ColBreak rausschmeissen. +/*N*/ BOOL bRemoveFromCache = 0 != pTmpSet->ClearItem( RES_PAGEDESC ); +/*N*/ if( SFX_ITEM_SET == pTmpSet->GetItemState( RES_BREAK, FALSE ) ) +/*N*/ { +/*N*/ pTmpSet->ClearItem( RES_BREAK ); +/*N*/ bRemoveFromCache = TRUE; +/*N*/ } +/*N*/ if( !bNext && bRemoveFromCache && IsInCache() ) +/*N*/ { +/*N*/ SwFrm::GetCache().Delete( this ); +/*N*/ SetInCache( FALSE ); +/*N*/ } +/*N*/ } +/*N*/ SwNodes& rNds = GetNodes(); +/*N*/ +/*N*/ SwTxtFmtColl* pColl = GetTxtColl(); +/*N*/ +/*N*/ SwTxtNode *pNode = new SwTxtNode( rPos, pColl, pNewAttrSet ); +/*N*/ +/*N*/ if( pNewAttrSet ) +/*N*/ delete pNewAttrSet; +/*N*/ +/*N*/ const SwNumRule* pRule = GetNumRule(); +/*N*/ if( pRule && rNds.IsDocNodes() ) +/*N*/ { +/*N*/ // ist am Node eine Nummerierung gesetzt und wird dieser vor dem +/*N*/ // alten eingefuegt, so kopiere die Nummer +/*N*/ if( !bNext && pNdNum && NO_NUMBERING != pNdNum->GetLevel() ) +/*N*/ { +/*N*/ if( pNode->pNdNum ) +/*N*/ *pNode->pNdNum = *pNdNum; +/*N*/ else +/*N*/ pNode->pNdNum = new SwNodeNum( *pNdNum ); +/*N*/ +/*N*/ // SetValue immer auf default zurueck setzem +/*N*/ pNdNum->SetSetValue( USHRT_MAX ); +/*N*/ if( pNdNum->IsStart() ) +/*N*/ { +/*N*/ pNdNum->SetStart( FALSE ); +/*N*/ pNode->pNdNum->SetStart( TRUE ); +/*N*/ } +/*N*/ +/*N*/ // Ein SplitNode erzeugt !!immer!! einen neuen Level, NO_NUM +/*N*/ // kann nur ueber eine entsprechende Methode erzeugt werden !! +/*N*/ if( NO_NUMLEVEL & pNdNum->GetLevel() ) +/*N*/ { +/*N*/ pNdNum->SetLevel( pNdNum->GetLevel() & ~NO_NUMLEVEL ); +/*N*/ #ifndef NUM_RELSPACE +/*N*/ SetNumLSpace( TRUE ); +/*N*/ #endif +/*N*/ } +/*N*/ } +/*N*/ rNds.GetDoc()->UpdateNumRule( pRule->GetName(), pNode->GetIndex() ); +/*N*/ } +/*N*/ +/*N*/ // jetzt kann es sein, das durch die Nummerierung dem neuen Node eine +/*N*/ // Vorlage aus dem Pool zugewiesen wurde. Dann darf diese nicht +/*N*/ // nochmal uebergeplaettet werden !! +/*N*/ if( pColl != pNode->GetTxtColl() || +/*N*/ ( bChgFollow && pColl != GetTxtColl() )) +/*N*/ return pNode; // mehr duerfte nicht gemacht werden oder ???? +/*N*/ +/*N*/ pNode->_ChgTxtCollUpdateNum( 0, pColl ); // fuer Nummerierung/Gliederung +/*N*/ if( bNext || !bChgFollow ) +/*N*/ return pNode; +/*N*/ +/*N*/ SwTxtFmtColl *pNextColl = &pColl->GetNextTxtFmtColl(); +/*N*/ ChgFmtColl( pNextColl ); +/*N*/ +/*N*/ return pNode; +/*N*/ } + +/*N*/ SwCntntNode* SwTxtNode::AppendNode( const SwPosition & rPos ) +/*N*/ { +/*N*/ // Position hinter dem eingefuegt wird +/*N*/ SwNodeIndex aIdx( rPos.nNode, 1 ); +/*N*/ SwTxtNode* pNew = _MakeNewTxtNode( aIdx, TRUE ); +/*N*/ if( GetDepends() ) +/*N*/ MakeFrms( *pNew ); +/*N*/ return pNew; +/*N*/ } + +/************************************************************************* + * SwTxtNode::GetTxtAttr + * + * Diese Methode liefert nur Textattribute auf der Position nIdx + * zurueck, die kein EndIdx besitzen und denselben Which besitzen. + * Ueblicherweise steht an dieser Position ein CH_TXTATR. + * Bei RES_TXTATR_END entfaellt die Pruefung auf den Which-Wert. + *************************************************************************/ + +/*N*/ SwTxtAttr *SwTxtNode::GetTxtAttr( const xub_StrLen nIdx, +/*N*/ const USHORT nWhichHt ) const +/*N*/ { +/*N*/ if( pSwpHints ) +/*N*/ { +/*N*/ for( USHORT i = 0; i < pSwpHints->Count(); ++i ) +/*N*/ { +/*N*/ SwTxtAttr *pPos = pSwpHints->GetHt(i); +/*N*/ const xub_StrLen nStart = *pPos->GetStart(); +/*N*/ if( nIdx < nStart ) +/*N*/ return 0; +/*N*/ if( nIdx == nStart && !pPos->GetEnd() ) +/*N*/ { +/*N*/ if( RES_TXTATR_END == nWhichHt || nWhichHt == pPos->Which() ) +/*N*/ return pPos; +/*N*/ else +/*N*/ return 0; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ return 0; +/*N*/ } + +/************************************************************************* + * SwTxtNode::GetExpandTxt + *************************************************************************/ +// Felder werden expandiert: + +/*N*/ XubString SwTxtNode::GetNumString() const +/*N*/ { +/*N*/ const SwNodeNum* pNum; +/*N*/ const SwNumRule* pRule; +/*N*/ if( (( 0 != ( pNum = GetNum() ) && +/*N*/ 0 != ( pRule = GetNumRule() )) || +/*N*/ ( 0 != ( pNum = GetOutlineNum() ) && +/*N*/ 0 != ( pRule = GetDoc()->GetOutlineNumRule() ) ) ) && +/*N*/ pNum->GetLevel() < MAXLEVEL && +/*N*/ pRule->Get( pNum->GetLevel() ).IsTxtFmt() ) +/*?*/ return pRule->MakeNumString( *pNum ); +/*N*/ return aEmptyStr; +/*N*/ } + +/*N*/ long SwTxtNode::GetLeftMarginWithNum( BOOL bTxtLeft ) const +/*N*/ { +/*N*/ long nOffset; +/*N*/ const SwNodeNum* pNum; +/*N*/ const SwNumRule* pRule; +/*N*/ if( (( 0 != ( pNum = GetNum() ) && +/*N*/ 0 != ( pRule = GetNumRule() )) || +/*N*/ ( 0 != ( pNum = GetOutlineNum() ) && +/*N*/ 0 != ( pRule = GetDoc()->GetOutlineNumRule() ) ) ) && +/*N*/ pNum->GetLevel() < NO_NUM ) +/*N*/ { +/*N*/ const SwNumFmt& rFmt = pRule->Get( GetRealLevel( pNum->GetLevel() ) ); +/*N*/ nOffset = rFmt.GetAbsLSpace(); +/*N*/ +/*N*/ if( !bTxtLeft ) +/*N*/ { +/*N*/ if( 0 > rFmt.GetFirstLineOffset() && +/*N*/ nOffset > -rFmt.GetFirstLineOffset() ) +/*N*/ nOffset += rFmt.GetFirstLineOffset(); +/*N*/ else +/*N*/ nOffset = 0; +/*N*/ } +/*N*/ +/*N*/ if( pRule->IsAbsSpaces() ) +/*N*/ nOffset -= GetSwAttrSet().GetLRSpace().GetLeft(); +/*N*/ } +/*N*/ else +/*N*/ nOffset = 0; +/*N*/ return nOffset; +/*N*/ } + +/*N*/ BOOL SwTxtNode::GetFirstLineOfsWithNum( short& rFLOffset ) const +/*N*/ { +/*N*/ const SwNodeNum* pNum; +/*N*/ const SwNumRule* pRule; +/*N*/ if( (( 0 != ( pNum = GetNum() ) && +/*N*/ 0 != ( pRule = GetNumRule() )) || +/*N*/ ( 0 != ( pNum = GetOutlineNum() ) && +/*N*/ 0 != ( pRule = GetDoc()->GetOutlineNumRule() ) ) ) && +/*N*/ pNum->GetLevel() < NO_NUM ) +/*N*/ { +/*N*/ if( NO_NUMLEVEL & pNum->GetLevel() ) +/*N*/ rFLOffset = 0; +/*N*/ else +/*N*/ rFLOffset = pRule->Get( pNum->GetLevel() ).GetFirstLineOffset(); +/*N*/ return TRUE; +/*N*/ } +/*N*/ rFLOffset = GetSwAttrSet().GetLRSpace().GetTxtFirstLineOfst(); +/*N*/ return FALSE; +/*N*/ } + +/*N*/ void SwTxtNode::Replace0xFF( XubString& rTxt, xub_StrLen& rTxtStt, +/*N*/ xub_StrLen nEndPos, BOOL bExpandFlds ) const +/*N*/ { +/*N*/ if( GetpSwpHints() ) +/*N*/ { +/*N*/ sal_Unicode cSrchChr = CH_TXTATR_BREAKWORD; +/*N*/ for( int nSrchIter = 0; 2 > nSrchIter; ++nSrchIter, +/*N*/ cSrchChr = CH_TXTATR_INWORD ) +/*N*/ { +/*N*/ xub_StrLen nPos = rTxt.Search( cSrchChr ); +/*N*/ while( STRING_NOTFOUND != nPos && nPos < nEndPos ) +/*N*/ { +/*N*/ const SwTxtAttr* pAttr = GetTxtAttr( rTxtStt + nPos ); +/*N*/ if( pAttr ) +/*N*/ { +/*N*/ switch( pAttr->Which() ) +/*N*/ { +/*N*/ case RES_TXTATR_FIELD: +/*N*/ rTxt.Erase( nPos, 1 ); +/*N*/ if( bExpandFlds ) +/*N*/ { +/*N*/ const XubString aExpand( ((SwTxtFld*)pAttr)->GetFld(). +/*N*/ GetFld()->Expand() ); +/*N*/ rTxt.Insert( aExpand, nPos ); +/*N*/ nPos += aExpand.Len(); +/*N*/ nEndPos += aExpand.Len(); +/*N*/ rTxtStt -= aExpand.Len(); +/*N*/ } +/*N*/ ++rTxtStt; +/*N*/ break; +/*N*/ case RES_TXTATR_HARDBLANK: + {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 /*?*/ rTxt.SetChar( nPos, ((SwTxtHardBlank*)pAttr)->GetChar() ); +/*?*/ break; +/*N*/ case RES_TXTATR_FTN: +/*N*/ rTxt.Erase( nPos, 1 ); +/*N*/ if( bExpandFlds ) +/*N*/ { +/*N*/ const SwFmtFtn& rFtn = pAttr->GetFtn(); +/*N*/ XubString sExpand; +/*N*/ if( rFtn.GetNumStr().Len() ) +/*N*/ sExpand = rFtn.GetNumStr(); +/*N*/ else if( rFtn.IsEndNote() ) +/*?*/ sExpand = GetDoc()->GetEndNoteInfo().aFmt. +/*?*/ GetNumStr( rFtn.GetNumber() ); +/*N*/ else +/*N*/ sExpand = GetDoc()->GetFtnInfo().aFmt. +/*N*/ GetNumStr( rFtn.GetNumber() ); +/*N*/ rTxt.Insert( sExpand, nPos ); +/*N*/ nPos += sExpand.Len(); +/*N*/ nEndPos += sExpand.Len(); +/*N*/ rTxtStt -= sExpand.Len(); +/*N*/ } +/*N*/ ++rTxtStt; +/*N*/ break; +/*N*/ default: +/*N*/ rTxt.Erase( nPos, 1 ); +/*N*/ ++rTxtStt; +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ ++nPos, ++nEndPos; +/*N*/ nPos = rTxt.Search( cSrchChr, nPos ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } + +/*N*/ XubString SwTxtNode::GetExpandTxt( const xub_StrLen nIdx, const xub_StrLen nLen, +/*N*/ const BOOL bWithNum ) const +/*N*/ { +/*N*/ XubString aTxt( GetTxt().Copy( nIdx, nLen ) ); +/*N*/ xub_StrLen nTxtStt = nIdx; +/*N*/ Replace0xFF( aTxt, nTxtStt, aTxt.Len(), TRUE ); +/*N*/ +/*N*/ if( bWithNum ) +/*?*/ aTxt.Insert( GetNumString(), 0 ); +/*N*/ +/*N*/ return aTxt; +/*N*/ } + + + + +/************************************************************************* + * SwTxtNode::GetExpandTxt + *************************************************************************/ +// Felder werden expandiert: + +/*N*/ void SwTxtNode::Replace( const SwIndex& rStart, xub_Unicode cCh ) +/*N*/ { +/*N*/ +/*N*/ ASSERT( rStart.GetIndex() < aText.Len(), "ausserhalb des Strings" ); +/*N*/ SwTxtAttr* pHt; +/*N*/ if( ( CH_TXTATR_BREAKWORD == aText.GetChar( rStart.GetIndex() ) || +/*N*/ CH_TXTATR_INWORD == aText.GetChar( rStart.GetIndex() )) && +/*N*/ 0 != ( pHt = GetTxtAttr( rStart.GetIndex() ) )) +/*N*/ { +/*?*/ Delete( pHt ); +/*?*/ aText.Insert( cCh, rStart.GetIndex() ); +/*N*/ } +/*N*/ else +/*N*/ aText.SetChar( rStart.GetIndex(), cCh ); +/*N*/ +/*N*/ SwDelTxt aDelHint( rStart.GetIndex(), 1 ); +/*N*/ SwModify::Modify( 0, &aDelHint ); +/*N*/ +/*N*/ SwInsTxt aHint( rStart.GetIndex(), 1 ); +/*N*/ SwModify::Modify( 0, &aHint ); +/*N*/ } + + + +/*N*/ void SwTxtNode::Modify( SfxPoolItem* pOldValue, SfxPoolItem* pNewValue ) +/*N*/ { +/*N*/ // Bug 24616/24617: +/*N*/ // Modify ueberladen, damit beim Loeschen von Vorlagen diese +/*N*/ // wieder richtig verwaltet werden (Outline-Numerierung!!) +/*N*/ // Bug25481: +/*N*/ // bei Nodes im Undo nie _ChgTxtCollUpdateNum rufen. +/*N*/ if( pOldValue && pNewValue && RES_FMT_CHG == pOldValue->Which() && +/*N*/ pRegisteredIn == ((SwFmtChg*)pNewValue)->pChangedFmt && +/*N*/ GetNodes().IsDocNodes() ) +/*N*/ _ChgTxtCollUpdateNum( +/*N*/ (SwTxtFmtColl*)((SwFmtChg*)pOldValue)->pChangedFmt, +/*N*/ (SwTxtFmtColl*)((SwFmtChg*)pNewValue)->pChangedFmt ); +/*N*/ +/*N*/ SwCntntNode::Modify( pOldValue, pNewValue ); +/*N*/ } + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/txtnode/sw_swfntcch.cxx b/binfilter/bf_sw/source/core/txtnode/sw_swfntcch.cxx new file mode 100644 index 000000000000..2a6a214e5c04 --- /dev/null +++ b/binfilter/bf_sw/source/core/txtnode/sw_swfntcch.cxx @@ -0,0 +1,99 @@ +/* -*- 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. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include <viewsh.hxx> +#include "swfntcch.hxx" +#include "fmtcol.hxx" +namespace binfilter { + +// aus atrstck.cxx +extern const BYTE StackPos[]; + +// globale Variablen, werden in SwFntCch.Hxx bekanntgegeben +// Der FontCache wird in TxtInit.Cxx _TXTINIT erzeugt und in _TXTEXIT geloescht +SwFontCache *pSwFontCache = NULL; + +/************************************************************************* +|* +|* SwFontObj::SwFontObj(), ~SwFontObj() +|* +|* Ersterstellung AMA 25. Jun. 95 +|* Letzte Aenderung AMA 25. Jun. 95 +|* +|*************************************************************************/ + +/*N*/ SwFontObj::SwFontObj( const void *pOwner, ViewShell *pSh ) : +/*N*/ SwCacheObj( (void*)pOwner ), +/*N*/ aSwFont( &((SwTxtFmtColl *)pOwner)->GetAttrSet(), pSh ? pSh->GetDoc() : 0 ) +/*N*/ { +/*N*/ aSwFont.GoMagic( pSh, aSwFont.GetActual() ); +/*N*/ const SwAttrSet& rAttrSet = ((SwTxtFmtColl *)pOwner)->GetAttrSet(); +/*N*/ for (USHORT i = RES_CHRATR_BEGIN; i < RES_CHRATR_END; i++) +/*N*/ pDefaultArray[ StackPos[ i ] ] = &rAttrSet.Get( i, TRUE ); +/*N*/ } + +/*N*/ SwFontObj::~SwFontObj() +/*N*/ { +/*N*/ } + +/************************************************************************* +|* +|* SwFontAccess::SwFontAccess() +|* +|* Ersterstellung AMA 25. Jun. 95 +|* Letzte Aenderung AMA 25. Jun. 95 +|* +|*************************************************************************/ + +/*N*/ SwFontAccess::SwFontAccess( const void *pOwner, ViewShell *pSh ) : +/*N*/ SwCacheAccess( *pSwFontCache, pOwner, +/*N*/ (BOOL) ((SwTxtFmtColl*)pOwner)->IsInSwFntCache() ), +/*N*/ pShell( pSh ) +/*N*/ { +/*N*/ } + +/*N*/ SwFontObj *SwFontAccess::Get( ) +/*N*/ { +/*N*/ return (SwFontObj *) SwCacheAccess::Get( ); +/*N*/ } + +/*N*/ SwCacheObj *SwFontAccess::NewObj( ) +/*N*/ { +/*N*/ ((SwTxtFmtColl*)pOwner)->SetInSwFntCache( TRUE ); +/*N*/ return new SwFontObj( pOwner, pShell ); +/*N*/ } + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/txtnode/sw_swfont.cxx b/binfilter/bf_sw/source/core/txtnode/sw_swfont.cxx new file mode 100644 index 000000000000..04df7333e3a6 --- /dev/null +++ b/binfilter/bf_sw/source/core/txtnode/sw_swfont.cxx @@ -0,0 +1,856 @@ +/* -*- 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. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include <hintids.hxx> + +#include <com/sun/star/i18n/ScriptType.hdl> +#include <bf_svx/brshitem.hxx> +#include <bf_svx/wrlmitem.hxx> +#include <bf_svx/blnkitem.hxx> +#include <bf_svx/nhypitem.hxx> +#include <bf_svx/kernitem.hxx> +#include <bf_svx/cmapitem.hxx> +#include <bf_svx/langitem.hxx> +#include <bf_svx/escpitem.hxx> +#include <bf_svx/akrnitem.hxx> +#include <bf_svx/shdditem.hxx> +#include <bf_svx/charreliefitem.hxx> +#include <bf_svx/cntritem.hxx> +#include <bf_svx/cscoitem.hxx> +#include <bf_svx/crsditem.hxx> +#include <bf_svx/udlnitem.hxx> +#include <bf_svx/wghtitem.hxx> +#include <bf_svx/postitem.hxx> +#include <bf_svx/fhgtitem.hxx> +#include <bf_svx/fontitem.hxx> +#include <bf_svx/emphitem.hxx> +#include <bf_svx/charscaleitem.hxx> +#include <bf_svx/charrotateitem.hxx> +#include <bf_svx/twolinesitem.hxx> + +#include <horiornt.hxx> + +#include <doc.hxx> +#include <vcl/window.hxx> + +#include <charatr.hxx> +#include <viewsh.hxx> // Bildschirmabgleich +#include <swfont.hxx> +#include <fntcache.hxx> // FontCache +namespace binfilter { + +#if defined(WIN) || defined(WNT) || defined(PM2) +#define FNT_LEADING_HACK +#endif + +#if defined(WIN) || defined(WNT) +#define FNT_ATM_HACK +#endif + +#ifdef DBG_UTIL +// globale Variable +SvStatistics aSvStat; +#endif + +using namespace ::com::sun::star::i18n::ScriptType; + +/************************************************************************ + * Hintergrundbrush setzen, z.B. bei Zeichenvorlagen + ***********************************************************************/ + +/*N*/ void SwFont::SetBackColor( Color* pNewColor ) +/*N*/ { +/*N*/ delete pBackColor; +/*N*/ pBackColor = pNewColor; +/*N*/ bFntChg = TRUE; +/*N*/ aSub[SW_LATIN].pMagic = aSub[SW_CJK].pMagic = aSub[SW_CTL].pMagic = 0; +/*N*/ } + +/************************************************************************ + * Hintergrundbrush setzen, + * die alte Brush wird _nicht_ destruiert, sondern ist der Rueckgabewert. + ***********************************************************************/ + + + +// maps directions for vertical layout +/*N*/ USHORT MapDirection( USHORT nDir, const BOOL bVertFormat ) +/*N*/ { +/*N*/ if ( bVertFormat ) +/*N*/ { +/*N*/ switch ( nDir ) +/*N*/ { +/*N*/ case 0 : +/*N*/ nDir = 2700; +/*N*/ break; +/*N*/ case 900 : +/*N*/ nDir = 0; +/*N*/ break; +/*N*/ case 2700 : +/*N*/ nDir = 1800; +/*N*/ break; +/*N*/ #if OSL_DEBUG_LEVEL > 1 +/*N*/ default : +/*N*/ ASSERT( sal_False, "Unsupported direction" ); +/*N*/ break; +/*N*/ #endif +/*N*/ } +/*N*/ } +/*N*/ return nDir; +/*N*/ } + +// maps the absolute direction set at the font to its logical conterpart +// in the rotated environment +/*N*/ USHORT UnMapDirection( USHORT nDir, const BOOL bVertFormat ) +/*N*/ { +/*N*/ if ( bVertFormat ) +/*N*/ { +/*?*/ switch ( nDir ) +/*?*/ { +/*?*/ case 0 : +/*?*/ nDir = 900; +/*?*/ break; +/*?*/ case 1800 : +/*?*/ nDir = 2700; +/*?*/ break; +/*?*/ case 2700 : +/*?*/ nDir = 0; +/*?*/ break; +/*?*/ #if OSL_DEBUG_LEVEL > 1 +/*?*/ default : +/*?*/ ASSERT( sal_False, "Unsupported direction" ); +/*?*/ break; +/*?*/ #endif +/*?*/ } +/*N*/ } +/*N*/ return nDir; +/*N*/ } + +/*N*/ USHORT SwFont::GetOrientation( const BOOL bVertFormat ) const +/*N*/ { +/*N*/ return UnMapDirection( aSub[nActual].GetOrientation(), bVertFormat ); +/*N*/ } + +/*N*/ void SwFont::SetVertical( USHORT nDir, const BOOL bVertFormat ) +/*N*/ { +/*N*/ // map direction if frame has vertical layout +/*N*/ nDir = MapDirection( nDir, bVertFormat ); +/*N*/ +/*N*/ if( nDir != aSub[0].GetOrientation() ) +/*N*/ { +/*N*/ bFntChg = TRUE; +/*N*/ aSub[0].SetVertical( nDir, bVertFormat ); +/*N*/ aSub[1].SetVertical( nDir, bVertFormat || nDir > 1000 ); +/*N*/ aSub[2].SetVertical( nDir, bVertFormat ); +/*N*/ } +/*N*/ } + +/************************************************************************* + Escapement: + frEsc: Fraction, Grad des Escapements + Esc = resultierendes Escapement + A1 = Original-Ascent (nOrgAscent) + A2 = verkleinerter Ascent (nEscAscent) + Ax = resultierender Ascent (GetAscent()) + H1 = Original-Hoehe (nOrgHeight) + H2 = verkleinerter Hoehe (nEscHeight) + Hx = resultierender Hoehe (GetHeight()) + Bx = resultierende Baseline fuer die Textausgabe (CalcPos()) + (Vorsicht: Y - A1!) + + Escapement: + Esc = H1 * frEsc; + + Hochstellung: + Ax = A2 + Esc; + Hx = H2 + Esc; + Bx = A1 - Esc; + + Tiefstellung: + Ax = A1; + Hx = A1 + Esc + (H2 - A2); + Bx = A1 + Esc; + +*************************************************************************/ + +/************************************************************************* + * SwSubFont::CalcEscAscent( const USHORT nOldAscent ) + *************************************************************************/ + +// nEsc ist der Prozentwert +/*N*/ USHORT SwSubFont::CalcEscAscent( const USHORT nOldAscent ) const +/*N*/ { +/*N*/ if( DFLT_ESC_AUTO_SUPER != GetEscapement() && +/*N*/ DFLT_ESC_AUTO_SUB != GetEscapement() ) +/*N*/ { +/*N*/ const long nAscent = nOldAscent + +/*N*/ ( (long) nOrgHeight * GetEscapement() ) / 100L; +/*N*/ if ( nAscent>0 ) +/*N*/ return ( Max( USHORT (nAscent), nOrgAscent )); +/*N*/ } +/*N*/ return nOrgAscent; +/*N*/ } + +/************************************************************************* + * SwFont::SetDiffFnt() + *************************************************************************/ + +/*N*/ void SwFont::SetDiffFnt( const SfxItemSet *pAttrSet, const SwDoc *pDoc ) +/*N*/ { +/*N*/ delete pBackColor; +/*N*/ pBackColor = NULL; +/*N*/ +/*N*/ +/*N*/ if( pAttrSet ) +/*N*/ { +/*N*/ const SfxPoolItem* pItem; +/*N*/ if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_FONT, +/*N*/ TRUE, &pItem )) +/*N*/ { +/*N*/ const SvxFontItem *pFont = (const SvxFontItem *)pItem; +/*N*/ aSub[SW_LATIN].SetFamily( pFont->GetFamily() ); +/*N*/ aSub[SW_LATIN].Font::SetName( pFont->GetFamilyName() ); +/*N*/ aSub[SW_LATIN].Font::SetStyleName( pFont->GetStyleName() ); +/*N*/ aSub[SW_LATIN].Font::SetPitch( pFont->GetPitch() ); +/*N*/ aSub[SW_LATIN].Font::SetCharSet( pFont->GetCharSet() ); +/*N*/ } +/*N*/ if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_FONTSIZE, +/*N*/ TRUE, &pItem )) +/*N*/ { +/*N*/ const SvxFontHeightItem *pHeight = (const SvxFontHeightItem *)pItem; +/*N*/ aSub[SW_LATIN].SvxFont::SetPropr( 100 ); +/*N*/ aSub[SW_LATIN].aSize = aSub[SW_LATIN].Font::GetSize(); +/*N*/ Size aTmpSize = aSub[SW_LATIN].aSize; +/*N*/ aTmpSize.Height() = pHeight->GetHeight(); +/*N*/ aSub[SW_LATIN].SetSize( aTmpSize ); +/*N*/ } +/*N*/ if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_POSTURE, +/*N*/ TRUE, &pItem )) +/*?*/ aSub[SW_LATIN].Font::SetItalic( ((SvxPostureItem*)pItem)->GetPosture() ); +/*N*/ if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_WEIGHT, +/*N*/ TRUE, &pItem )) +/*?*/ aSub[SW_LATIN].Font::SetWeight( ((SvxWeightItem*)pItem)->GetWeight() ); +/*N*/ if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_LANGUAGE, +/*N*/ TRUE, &pItem )) +/*?*/ aSub[SW_LATIN].SetLanguage( ((SvxLanguageItem*)pItem)->GetLanguage() ); +/*N*/ +/*N*/ if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_CJK_FONT, +/*N*/ TRUE, &pItem )) +/*N*/ { +/*?*/ const SvxFontItem *pFont = (const SvxFontItem *)pItem; +/*?*/ aSub[SW_CJK].SetFamily( pFont->GetFamily() ); +/*?*/ aSub[SW_CJK].Font::SetName( pFont->GetFamilyName() ); +/*?*/ aSub[SW_CJK].Font::SetStyleName( pFont->GetStyleName() ); +/*?*/ aSub[SW_CJK].Font::SetPitch( pFont->GetPitch() ); +/*?*/ aSub[SW_CJK].Font::SetCharSet( pFont->GetCharSet() ); +/*N*/ } +/*N*/ if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_CJK_FONTSIZE, +/*N*/ TRUE, &pItem )) +/*N*/ { +/*?*/ const SvxFontHeightItem *pHeight = (const SvxFontHeightItem *)pItem; +/*?*/ aSub[SW_CJK].SvxFont::SetPropr( 100 ); +/*?*/ aSub[SW_CJK].aSize = aSub[SW_CJK].Font::GetSize(); +/*?*/ Size aTmpSize = aSub[SW_CJK].aSize; +/*?*/ aTmpSize.Height() = pHeight->GetHeight(); +/*?*/ aSub[SW_CJK].SetSize( aTmpSize ); +/*N*/ } +/*N*/ if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_CJK_POSTURE, +/*N*/ TRUE, &pItem )) +/*?*/ aSub[SW_CJK].Font::SetItalic( ((SvxPostureItem*)pItem)->GetPosture() ); +/*N*/ if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_CJK_WEIGHT, +/*N*/ TRUE, &pItem )) +/*?*/ aSub[SW_CJK].Font::SetWeight( ((SvxWeightItem*)pItem)->GetWeight() ); +/*N*/ if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_CJK_LANGUAGE, +/*N*/ TRUE, &pItem )) +/*N*/ { +/*?*/ LanguageType eNewLang = ((SvxLanguageItem*)pItem)->GetLanguage(); +/*?*/ aSub[SW_CJK].SetLanguage( eNewLang ); +/*?*/ aSub[SW_LATIN].SetCJKContextLanguage( eNewLang ); +/*?*/ aSub[SW_CJK].SetCJKContextLanguage( eNewLang ); +/*?*/ aSub[SW_CTL].SetCJKContextLanguage( eNewLang ); +/*N*/ } +/*N*/ +/*N*/ if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_CTL_FONT, +/*N*/ TRUE, &pItem )) +/*N*/ { +/*?*/ const SvxFontItem *pFont = (const SvxFontItem *)pItem; +/*?*/ aSub[SW_CTL].SetFamily( pFont->GetFamily() ); +/*?*/ aSub[SW_CTL].Font::SetName( pFont->GetFamilyName() ); +/*?*/ aSub[SW_CTL].Font::SetStyleName( pFont->GetStyleName() ); +/*?*/ aSub[SW_CTL].Font::SetPitch( pFont->GetPitch() ); +/*?*/ aSub[SW_CTL].Font::SetCharSet( pFont->GetCharSet() ); +/*N*/ } +/*N*/ if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_CTL_FONTSIZE, +/*N*/ TRUE, &pItem )) +/*N*/ { +/*?*/ const SvxFontHeightItem *pHeight = (const SvxFontHeightItem *)pItem; +/*?*/ aSub[SW_CTL].SvxFont::SetPropr( 100 ); +/*?*/ aSub[SW_CTL].aSize = aSub[SW_CTL].Font::GetSize(); +/*?*/ Size aTmpSize = aSub[SW_CTL].aSize; +/*?*/ aTmpSize.Height() = pHeight->GetHeight(); +/*?*/ aSub[SW_CTL].SetSize( aTmpSize ); +/*N*/ } +/*N*/ if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_CTL_POSTURE, +/*N*/ TRUE, &pItem )) +/*?*/ aSub[SW_CTL].Font::SetItalic( ((SvxPostureItem*)pItem)->GetPosture() ); +/*N*/ if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_CTL_WEIGHT, +/*N*/ TRUE, &pItem )) +/*?*/ aSub[SW_CTL].Font::SetWeight( ((SvxWeightItem*)pItem)->GetWeight() ); +/*N*/ if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_CTL_LANGUAGE, +/*N*/ TRUE, &pItem )) +/*?*/ aSub[SW_CTL].SetLanguage( ((SvxLanguageItem*)pItem)->GetLanguage() ); +/*N*/ +/*N*/ if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_UNDERLINE, +/*N*/ TRUE, &pItem )) +/*N*/ { +/*N*/ SetUnderline( ((SvxUnderlineItem*)pItem)->GetUnderline() ); +/*N*/ SetUnderColor( ((SvxUnderlineItem*)pItem)->GetColor() ); +/*N*/ } +/*N*/ if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_CROSSEDOUT, +/*N*/ TRUE, &pItem )) +/*?*/ SetStrikeout( ((SvxCrossedOutItem*)pItem)->GetStrikeout() ); +/*N*/ if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_COLOR, +/*N*/ TRUE, &pItem )) +/*N*/ SetColor( ((SvxColorItem*)pItem)->GetValue() ); +/*N*/ if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_EMPHASIS_MARK, +/*N*/ TRUE, &pItem )) +/*?*/ SetEmphasisMark( ((SvxEmphasisMarkItem*)pItem)->GetEmphasisMark() ); +/*N*/ +/*N*/ SetTransparent( TRUE ); +/*N*/ SetAlign( ALIGN_BASELINE ); +/*N*/ if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_CONTOUR, +/*N*/ TRUE, &pItem )) +/*?*/ SetOutline( ((SvxContourItem*)pItem)->GetValue() ); +/*N*/ if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_SHADOWED, +/*N*/ TRUE, &pItem )) +/*?*/ SetShadow( ((SvxShadowedItem*)pItem)->GetValue() ); +/*N*/ if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_RELIEF, +/*N*/ TRUE, &pItem )) +/*?*/ SetRelief( (FontRelief)((SvxCharReliefItem*)pItem)->GetValue() ); +/*N*/ if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_SHADOWED, +/*N*/ TRUE, &pItem )) +/*N*/ SetPropWidth(((SvxShadowedItem*)pItem)->GetValue() ? 50 : 100 ); +/*N*/ if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_AUTOKERN, +/*N*/ TRUE, &pItem )) +/*N*/ { +/*?*/ if( ((SvxAutoKernItem*)pItem)->GetValue() ) +/*?*/ SetAutoKern( ( !pDoc || !pDoc->IsKernAsianPunctuation() ) ? +/*?*/ KERNING_FONTSPECIFIC : KERNING_ASIAN ); +/*?*/ else +/*?*/ SetAutoKern( 0 ); +/*N*/ } +/*N*/ if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_WORDLINEMODE, +/*N*/ TRUE, &pItem )) +/*?*/ SetWordLineMode( ((SvxWordLineModeItem*)pItem)->GetValue() ); +/*N*/ +/*N*/ if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_ESCAPEMENT, +/*N*/ TRUE, &pItem )) +/*N*/ { +/*N*/ const SvxEscapementItem *pEsc = (const SvxEscapementItem *)pItem; +/*N*/ SetEscapement( pEsc->GetEsc() ); +/*N*/ if( aSub[SW_LATIN].IsEsc() ) +/*N*/ SetProportion( pEsc->GetProp() ); +/*N*/ } +/*N*/ if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_CASEMAP, +/*N*/ TRUE, &pItem )) +/*N*/ SetCaseMap( ((SvxCaseMapItem*)pItem)->GetCaseMap() ); +/*N*/ if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_KERNING, +/*N*/ TRUE, &pItem )) +/*?*/ SetFixKerning( ((SvxKerningItem*)pItem)->GetValue() ); +/*N*/ if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_NOHYPHEN, +/*N*/ TRUE, &pItem )) +/*?*/ SetNoHyph( ((SvxNoHyphenItem*)pItem)->GetValue() ); +/*N*/ if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_BLINK, +/*N*/ TRUE, &pItem )) +/*?*/ SetBlink( ((SvxBlinkItem*)pItem)->GetValue() ); +/*N*/ if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_ROTATE, +/*N*/ TRUE, &pItem )) +/*?*/ SetVertical( ((SvxCharRotateItem*)pItem)->GetValue() ); +/*N*/ if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_BACKGROUND, +/*N*/ TRUE, &pItem )) +/*N*/ pBackColor = new Color( ((SvxBrushItem*)pItem)->GetColor() ); +/*N*/ else +/*N*/ pBackColor = NULL; +/*N*/ const SfxPoolItem* pTwoLinesItem = 0; +/*N*/ if( SFX_ITEM_SET == +/*N*/ pAttrSet->GetItemState( RES_CHRATR_TWO_LINES, TRUE, &pTwoLinesItem )) +/*?*/ if ( ((SvxTwoLinesItem*)pTwoLinesItem)->GetValue() ) +/*?*/ SetVertical( 0 ); +/*N*/ } +/*N*/ else +/*N*/ { +/*?*/ Invalidate(); +/*?*/ bNoHyph = FALSE; +/*?*/ bBlink = FALSE; +/*N*/ } +/*N*/ bPaintBlank = FALSE; +/*N*/ bPaintWrong = FALSE; +/*N*/ ASSERT( aSub[SW_LATIN].IsTransparent(), "SwFont: Transparent revolution" ); +/*N*/ } + +/************************************************************************* + * class SwFont + *************************************************************************/ + +/*N*/ SwFont::SwFont( const SwFont &rFont ) +/*N*/ { +/*N*/ aSub[SW_LATIN] = rFont.aSub[SW_LATIN]; +/*N*/ aSub[SW_CJK] = rFont.aSub[SW_CJK]; +/*N*/ aSub[SW_CTL] = rFont.aSub[SW_CTL]; +/*N*/ nActual = rFont.nActual; +/*N*/ pBackColor = rFont.pBackColor ? new Color( *rFont.pBackColor ) : NULL; +/*N*/ aUnderColor = rFont.GetUnderColor(); +/*N*/ nToxCnt = nRefCnt = 0; +/*N*/ bFntChg = rFont.bFntChg; +/*N*/ bOrgChg = rFont.bOrgChg; +/*N*/ bPaintBlank = rFont.bPaintBlank; +/*N*/ bPaintWrong = FALSE; +/*N*/ bURL = rFont.bURL; +/*N*/ bGreyWave = rFont.bGreyWave; +/*N*/ bNoColReplace = rFont.bNoColReplace; +/*N*/ bNoHyph = rFont.bNoHyph; +/*N*/ bBlink = rFont.bBlink; +/*N*/ } + +/*N*/ SwFont::SwFont( const SwAttrSet* pAttrSet, const SwDoc *pDoc ) +/*N*/ { +/*N*/ nActual = SW_LATIN; +/*N*/ nToxCnt = nRefCnt = 0; +/*N*/ bPaintBlank = FALSE; +/*N*/ bPaintWrong = FALSE; +/*N*/ bURL = FALSE; +/*N*/ bGreyWave = FALSE; +/*N*/ bNoColReplace = FALSE; +/*N*/ bNoHyph = pAttrSet->GetNoHyphenHere().GetValue(); +/*N*/ bBlink = pAttrSet->GetBlink().GetValue(); +/*N*/ { +/*N*/ const SvxFontItem& rFont = pAttrSet->GetFont(); +/*N*/ aSub[SW_LATIN].SetFamily( rFont.GetFamily() ); +/*N*/ aSub[SW_LATIN].SetName( rFont.GetFamilyName() ); +/*N*/ aSub[SW_LATIN].SetStyleName( rFont.GetStyleName() ); +/*N*/ aSub[SW_LATIN].SetPitch( rFont.GetPitch() ); +/*N*/ aSub[SW_LATIN].SetCharSet( rFont.GetCharSet() ); +/*N*/ aSub[SW_LATIN].SvxFont::SetPropr( 100 ); // 100% der FontSize +/*N*/ Size aTmpSize = aSub[SW_LATIN].aSize; +/*N*/ aTmpSize.Height() = pAttrSet->GetSize().GetHeight(); +/*N*/ aSub[SW_LATIN].SetSize( aTmpSize ); +/*N*/ aSub[SW_LATIN].SetItalic( pAttrSet->GetPosture().GetPosture() ); +/*N*/ aSub[SW_LATIN].SetWeight( pAttrSet->GetWeight().GetWeight() ); +/*N*/ aSub[SW_LATIN].SetLanguage( pAttrSet->GetLanguage().GetLanguage() ); +/*N*/ } +/*N*/ +/*N*/ { +/*N*/ const SvxFontItem& rFont = pAttrSet->GetCJKFont(); +/*N*/ aSub[SW_CJK].SetFamily( rFont.GetFamily() ); +/*N*/ aSub[SW_CJK].SetName( rFont.GetFamilyName() ); +/*N*/ aSub[SW_CJK].SetStyleName( rFont.GetStyleName() ); +/*N*/ aSub[SW_CJK].SetPitch( rFont.GetPitch() ); +/*N*/ aSub[SW_CJK].SetCharSet( rFont.GetCharSet() ); +/*N*/ aSub[SW_CJK].SvxFont::SetPropr( 100 ); // 100% der FontSize +/*N*/ Size aTmpSize = aSub[SW_CJK].aSize; +/*N*/ aTmpSize.Height() = pAttrSet->GetCJKSize().GetHeight(); +/*N*/ aSub[SW_CJK].SetSize( aTmpSize ); +/*N*/ aSub[SW_CJK].SetItalic( pAttrSet->GetCJKPosture().GetPosture() ); +/*N*/ aSub[SW_CJK].SetWeight( pAttrSet->GetCJKWeight().GetWeight() ); +/*N*/ LanguageType eNewLang = pAttrSet->GetCJKLanguage().GetLanguage(); +/*N*/ aSub[SW_CJK].SetLanguage( eNewLang ); +/*N*/ aSub[SW_LATIN].SetCJKContextLanguage( eNewLang ); +/*N*/ aSub[SW_CJK].SetCJKContextLanguage( eNewLang ); +/*N*/ aSub[SW_CTL].SetCJKContextLanguage( eNewLang ); +/*N*/ } +/*N*/ +/*N*/ { +/*N*/ const SvxFontItem& rFont = pAttrSet->GetCTLFont(); +/*N*/ aSub[SW_CTL].SetFamily( rFont.GetFamily() ); +/*N*/ aSub[SW_CTL].SetName( rFont.GetFamilyName() ); +/*N*/ aSub[SW_CTL].SetStyleName( rFont.GetStyleName() ); +/*N*/ aSub[SW_CTL].SetPitch( rFont.GetPitch() ); +/*N*/ aSub[SW_CTL].SetCharSet( rFont.GetCharSet() ); +/*N*/ aSub[SW_CTL].SvxFont::SetPropr( 100 ); // 100% der FontSize +/*N*/ Size aTmpSize = aSub[SW_CTL].aSize; +/*N*/ aTmpSize.Height() = pAttrSet->GetCTLSize().GetHeight(); +/*N*/ aSub[SW_CTL].SetSize( aTmpSize ); +/*N*/ aSub[SW_CTL].SetItalic( pAttrSet->GetCTLPosture().GetPosture() ); +/*N*/ aSub[SW_CTL].SetWeight( pAttrSet->GetCTLWeight().GetWeight() ); +/*N*/ aSub[SW_CTL].SetLanguage( pAttrSet->GetCTLLanguage().GetLanguage() ); +/*N*/ } +/*N*/ +/*N*/ SetUnderline( pAttrSet->GetUnderline().GetUnderline() ); +/*N*/ SetUnderColor( pAttrSet->GetUnderline().GetColor() ); +/*N*/ SetEmphasisMark( pAttrSet->GetEmphasisMark().GetEmphasisMark() ); +/*N*/ SetStrikeout( pAttrSet->GetCrossedOut().GetStrikeout() ); +/*N*/ SetColor( pAttrSet->GetColor().GetValue() ); +/*N*/ SetTransparent( TRUE ); +/*N*/ SetAlign( ALIGN_BASELINE ); +/*N*/ SetOutline( pAttrSet->GetContour().GetValue() ); +/*N*/ SetShadow( pAttrSet->GetShadowed().GetValue() ); +/*M*/ SetPropWidth( pAttrSet->GetCharScaleW().GetValue() ); +/*N*/ SetRelief( (FontRelief)pAttrSet->GetCharRelief().GetValue() ); +/*N*/ if( pAttrSet->GetAutoKern().GetValue() ) +/*?*/ SetAutoKern( ( !pDoc || !pDoc->IsKernAsianPunctuation() ) ? +/*?*/ KERNING_FONTSPECIFIC : KERNING_ASIAN ); +/*N*/ else +/*N*/ SetAutoKern( 0 ); +/*N*/ SetWordLineMode( pAttrSet->GetWordLineMode().GetValue() ); +/*N*/ const SvxEscapementItem &rEsc = pAttrSet->GetEscapement(); +/*N*/ SetEscapement( rEsc.GetEsc() ); +/*N*/ if( aSub[SW_LATIN].IsEsc() ) +/*?*/ SetProportion( rEsc.GetProp() ); +/*N*/ SetCaseMap( pAttrSet->GetCaseMap().GetCaseMap() ); +/*N*/ SetFixKerning( pAttrSet->GetKerning().GetValue() ); +/*N*/ const SfxPoolItem* pItem; +/*N*/ if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_BACKGROUND, +/*N*/ TRUE, &pItem )) +/*N*/ pBackColor = new Color( ((SvxBrushItem*)pItem)->GetColor() ); +/*N*/ else +/*N*/ pBackColor = NULL; +/*N*/ const SvxTwoLinesItem& rTwoLinesItem = pAttrSet->Get2Lines(); +/*N*/ if ( ! rTwoLinesItem.GetValue() ) +/*N*/ SetVertical( pAttrSet->GetCharRotate().GetValue() ); +/*N*/ else +/*?*/ SetVertical( 0 ); +/*N*/ } + +/*N*/ SwSubFont& SwSubFont::operator=( const SwSubFont &rFont ) +/*N*/ { +/*N*/ SvxFont::operator=( rFont ); +/*N*/ pMagic = rFont.pMagic; +/*N*/ nFntIndex = rFont.nFntIndex; +/*N*/ nOrgHeight = rFont.nOrgHeight; +/*N*/ nOrgAscent = rFont.nOrgAscent; +/*N*/ nPropWidth = rFont.nPropWidth; +/*N*/ aSize = rFont.aSize; +/*N*/ return *this; +/*N*/ } + +/*N*/ SwFont& SwFont::operator=( const SwFont &rFont ) +/*N*/ { +/*N*/ aSub[SW_LATIN] = rFont.aSub[SW_LATIN]; +/*N*/ aSub[SW_CJK] = rFont.aSub[SW_CJK]; +/*N*/ aSub[SW_CTL] = rFont.aSub[SW_CTL]; +/*N*/ nActual = rFont.nActual; +/*N*/ delete pBackColor; +/*N*/ pBackColor = rFont.pBackColor ? new Color( *rFont.pBackColor ) : NULL; +/*N*/ aUnderColor = rFont.GetUnderColor(); +/*N*/ nToxCnt = nRefCnt = 0; +/*N*/ bFntChg = rFont.bFntChg; +/*N*/ bOrgChg = rFont.bOrgChg; +/*N*/ bPaintBlank = rFont.bPaintBlank; +/*N*/ bPaintWrong = FALSE; +/*N*/ bURL = rFont.bURL; +/*N*/ bGreyWave = rFont.bGreyWave; +/*N*/ bNoColReplace = rFont.bNoColReplace; +/*N*/ bNoHyph = rFont.bNoHyph; +/*N*/ bBlink = rFont.bBlink; +/*N*/ return *this; +/*N*/ } + +/************************************************************************* + * SwFont::GoMagic() + *************************************************************************/ + +/*N*/ void SwFont::GoMagic( ViewShell *pSh, BYTE nWhich ) +/*N*/ { +/*N*/ SwFntAccess aFntAccess( aSub[nWhich].pMagic, aSub[nWhich].nFntIndex, +/*N*/ &aSub[nWhich], pSh, TRUE ); +/*N*/ } + +/************************************************************************* + * SwSubFont::IsSymbol() + *************************************************************************/ + +/*N*/ BOOL SwSubFont::IsSymbol( ViewShell *pSh ) +/*N*/ { +/*N*/ SwFntAccess aFntAccess( pMagic, nFntIndex, this, pSh, FALSE ); +/*N*/ return aFntAccess.Get()->IsSymbol(); +/*N*/ } + +/************************************************************************* + * SwSubFont::ChgFnt() + *************************************************************************/ + +/*N*/ BOOL SwSubFont::ChgFnt( ViewShell *pSh, OutputDevice *pOut ) +/*N*/ { +/*N*/ if ( pLastFont ) +/*N*/ pLastFont->Unlock(); +/*N*/ SwFntAccess aFntAccess( pMagic, nFntIndex, this, pSh, TRUE ); +/*N*/ SV_STAT( nChangeFont ); +/*N*/ +/*N*/ pLastFont = aFntAccess.Get(); +/*N*/ +/*N*/ pLastFont->SetDevFont( pSh, pOut ); +/*N*/ +/*N*/ pLastFont->Lock(); +/*N*/ return UNDERLINE_NONE != GetUnderline() || STRIKEOUT_NONE != GetStrikeout(); +/*N*/ } + +/************************************************************************* + * SwFont::ChgPhysFnt() + *************************************************************************/ + +/*N*/ void SwFont::ChgPhysFnt( ViewShell *pSh, OutputDevice *pOut ) +/*N*/ { +/*N*/ ASSERT( pOut, "SwFont:;ChgPhysFnt, not OutDev." ); +/*N*/ +/*N*/ if( bOrgChg && aSub[nActual].IsEsc() ) +/*N*/ { +/*N*/ const BYTE nOldProp = aSub[nActual].GetPropr(); +/*N*/ SetProportion( 100 ); +/*N*/ ChgFnt( pSh, pOut ); +/*N*/ SwFntAccess aFntAccess( aSub[nActual].pMagic, aSub[nActual].nFntIndex, +/*N*/ &aSub[nActual], pSh ); +/*N*/ aSub[nActual].nOrgHeight = aFntAccess.Get()->GetHeight( pSh, pOut ); +/*N*/ aSub[nActual].nOrgAscent = aFntAccess.Get()->GetAscent( pSh, pOut ); +/*N*/ SetProportion( nOldProp ); +/*N*/ bOrgChg = FALSE; +/*N*/ } +/*N*/ +/*N*/ if( bFntChg ) +/*N*/ { +/*N*/ ChgFnt( pSh, pOut ); +/*N*/ bFntChg = bOrgChg; +/*N*/ } +/*N*/ if( pOut->GetTextLineColor() != aUnderColor ) +/*?*/ pOut->SetTextLineColor( aUnderColor ); +/*N*/ } + +/************************************************************************* + * SwFont::CalcEscHeight() + * Height = MaxAscent + MaxDescent + * MaxAscent = Max (T1_ascent, T2_ascent + (Esc * T1_height) ); + * MaxDescent = Max (T1_height-T1_ascent, + * T2_height-T2_ascent - (Esc * T1_height) + *************************************************************************/ + +/*N*/ USHORT SwSubFont::CalcEscHeight( const USHORT nOldHeight, +/*N*/ const USHORT nOldAscent ) const +/*N*/ { +/*N*/ if( DFLT_ESC_AUTO_SUPER != GetEscapement() && +/*N*/ DFLT_ESC_AUTO_SUB != GetEscapement() ) +/*N*/ { +/*N*/ long nDescent = nOldHeight - nOldAscent - +/*N*/ ( (long) nOrgHeight * GetEscapement() ) / 100L; +/*N*/ const USHORT nDesc = ( nDescent>0 ) ? Max ( USHORT(nDescent), +/*N*/ USHORT(nOrgHeight - nOrgAscent) ) : nOrgHeight - nOrgAscent; +/*N*/ return ( nDesc + CalcEscAscent( nOldAscent ) ); +/*N*/ } +/*N*/ return nOrgHeight; +/*N*/ } + +/*N*/ short SwSubFont::_CheckKerning( ) +/*N*/ { +/*N*/ #if OSL_DEBUG_LEVEL > 1 +/*N*/ static short nTst = 6; +/*N*/ short nKernx = - short( Font::GetSize().Height() / nTst ); +/*N*/ #else +/*N*/ short nKernx = - short( Font::GetSize().Height() / 6 ); +/*N*/ #endif +/*N*/ if ( nKernx < GetFixKerning() ) +/*N*/ return GetFixKerning(); +/*N*/ return nKernx; +/*N*/ } + +/************************************************************************* + * SwSubFont::GetAscent() + *************************************************************************/ + +/*N*/ USHORT SwSubFont::GetAscent( ViewShell *pSh, const OutputDevice *pOut ) +/*N*/ { +/*N*/ register USHORT nAscent; +/*N*/ SwFntAccess aFntAccess( pMagic, nFntIndex, this, pSh ); +/*N*/ nAscent = aFntAccess.Get()->GetAscent( pSh, pOut ); +/*N*/ if( GetEscapement() ) +/*N*/ nAscent = CalcEscAscent( nAscent ); +/*N*/ return nAscent; +/*N*/ } + +/************************************************************************* + * SwSubFont::GetHeight() + *************************************************************************/ + +/*N*/ USHORT SwSubFont::GetHeight( ViewShell *pSh, const OutputDevice *pOut ) +/*N*/ { +/*N*/ SV_STAT( nGetTextSize ); +/*N*/ SwFntAccess aFntAccess( pMagic, nFntIndex, this, pSh ); +/*N*/ const USHORT nHeight = aFntAccess.Get()->GetHeight( pSh, pOut ); +/*N*/ if ( GetEscapement() ) +/*N*/ { +/*N*/ const USHORT nAscent = aFntAccess.Get()->GetAscent( pSh, pOut ); +/*N*/ return CalcEscHeight( nHeight, nAscent ); // + nLeading; +/*N*/ } +/*N*/ return nHeight; // + nLeading; +/*N*/ } + +/************************************************************************* + * SwSubFont::_GetTxtSize() + *************************************************************************/ +/*N*/ Size SwSubFont::_GetTxtSize( SwDrawTextInfo& rInf ) +/*N*/ { +/*N*/ // Robust: Eigentlich sollte der Font bereits eingestellt sein, aber +/*N*/ // sicher ist sicher ... +/*N*/ if ( !pLastFont || pLastFont->GetOwner()!=pMagic || +/*N*/ !IsSameInstance( rInf.GetpOut()->GetFont() ) ) +/*N*/ ChgFnt( rInf.GetShell(), rInf.GetpOut() ); +/*N*/ +/*N*/ Size aTxtSize; +/*N*/ xub_StrLen nLn = ( rInf.GetLen() == STRING_LEN ? rInf.GetText().Len() +/*N*/ : rInf.GetLen() ); +/*N*/ rInf.SetLen( nLn ); +/*N*/ if( IsCapital() && nLn ) +/*N*/ aTxtSize = GetCapitalSize( rInf ); +/*N*/ else +/*N*/ { +/*N*/ SV_STAT( nGetTextSize ); +/*N*/ short nOldKern = rInf.GetKern(); +/*N*/ const XubString &rOldTxt = rInf.GetText(); +/*N*/ rInf.SetKern( CheckKerning() ); +/*N*/ if ( !IsCaseMap() ) +/*N*/ aTxtSize = pLastFont->GetTextSize( rInf ); +/*N*/ else +/*N*/ { +/*N*/ String aTmp = CalcCaseMap( rInf.GetText() ); +/*N*/ const XubString &rOldStr = rInf.GetText(); +/*N*/ sal_Bool bCaseMapLengthDiffers(aTmp.Len() != rOldStr.Len()); +/*N*/ +/*N*/ if(bCaseMapLengthDiffers && rInf.GetLen()) +/*N*/ { +/*N*/ // #108203# +/*N*/ // If the length of the original string and the CaseMapped one +/*N*/ // are different, it is necessary to handle the given text part as +/*N*/ // a single snippet since itÄs size may differ, too. +/*N*/ xub_StrLen nOldIdx(rInf.GetIdx()); +/*N*/ xub_StrLen nOldLen(rInf.GetLen()); +/*N*/ const XubString aSnippet(rOldStr, nOldIdx, nOldLen); +/*N*/ XubString aNewText(CalcCaseMap(aSnippet)); +/*N*/ +/*N*/ rInf.SetText( aNewText ); +/*N*/ rInf.SetIdx( 0 ); +/*N*/ rInf.SetLen( aNewText.Len() ); +/*N*/ +/*N*/ aTxtSize = pLastFont->GetTextSize( rInf ); +/*N*/ +/*N*/ rInf.SetIdx( nOldIdx ); +/*N*/ rInf.SetLen( nOldLen ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ rInf.SetText( aTmp ); +/*N*/ aTxtSize = pLastFont->GetTextSize( rInf ); +/*N*/ } +/*N*/ +/*N*/ rInf.SetText( rOldStr ); +/*N*/ } +/*N*/ rInf.SetKern( nOldKern ); +/*N*/ rInf.SetText( rOldTxt ); +/*N*/ // 15142: Ein Wort laenger als eine Zeile, beim Zeilenumbruch +/*N*/ // hochgestellt, muss seine effektive Hoehe melden. +/*N*/ if( GetEscapement() ) +/*N*/ { +/*N*/ const USHORT nAscent = pLastFont->GetAscent( rInf.GetShell(), +/*N*/ rInf.GetpOut() ); +/*N*/ aTxtSize.Height() = +/*N*/ (long)CalcEscHeight( (USHORT)aTxtSize.Height(), nAscent); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ return aTxtSize; +/*N*/ } + +/************************************************************************* + * SwFont::GetTxtBreak() + *************************************************************************/ + + +/************************************************************************* + * SwFont::GetTxtBreak() + *************************************************************************/ + + +/************************************************************************* + * SwSubFont::_DrawText() + *************************************************************************/ + + + +/************************************************************************* + * SwSubFont::_GetCrsrOfst() + *************************************************************************/ + +/*N*/ xub_StrLen SwSubFont::_GetCrsrOfst( SwDrawTextInfo& rInf ) +/*N*/ { +/*N*/ if ( !pLastFont || pLastFont->GetOwner()!=pMagic ) +/*?*/ ChgFnt( rInf.GetShell(), rInf.GetpOut() ); +/*N*/ +/*N*/ xub_StrLen nLn = rInf.GetLen() == STRING_LEN ? rInf.GetText().Len() +/*N*/ : rInf.GetLen(); +/*N*/ rInf.SetLen( nLn ); +/*N*/ xub_StrLen nCrsr = 0; +/*N*/ if( IsCapital() && nLn ) + {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 /*?*/ nCrsr = GetCapitalCrsrOfst( rInf ); +/*N*/ else +/*N*/ { +/*N*/ const XubString &rOldTxt = rInf.GetText(); +/*N*/ short nOldKern = rInf.GetKern(); +/*N*/ rInf.SetKern( CheckKerning() ); +/*N*/ SV_STAT( nGetTextSize ); +/*N*/ if ( !IsCaseMap() ) +/*?*/ {DBG_BF_ASSERT(0, "STRIP"); }//STRIP001 nCrsr = pLastFont->GetCrsrOfst( rInf ); +/*N*/ else +/*N*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 +/*N*/ } +/*N*/ rInf.SetKern( nOldKern ); +/*N*/ rInf.SetText( rOldTxt ); +/*N*/ } +/*N*/ return nCrsr; +/*N*/ } + +/************************************************************************* + * SwSubFont::CalcEsc() + *************************************************************************/ + + +// used during painting of small capitals + +/************************************************************************* + * SwUnderlineFont::~SwUnderlineFont + * + * Used for the "continuous underline" feature. + *************************************************************************/ + + + +//Helper for filters to find true lineheight of a font + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/txtnode/sw_thints.cxx b/binfilter/bf_sw/source/core/txtnode/sw_thints.cxx new file mode 100644 index 000000000000..c2d2c1b78f52 --- /dev/null +++ b/binfilter/bf_sw/source/core/txtnode/sw_thints.cxx @@ -0,0 +1,2006 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include <hintids.hxx> + +#include <bf_svtools/whiter.hxx> +#include <bf_svtools/itemiter.hxx> +#include <bf_svx/langitem.hxx> +#include <bf_svx/emphitem.hxx> + +#include <txtinet.hxx> +#include <txtflcnt.hxx> +#include <fmtanchr.hxx> +#include <fmtfld.hxx> +#include <fmtinfmt.hxx> +#include <txtatr.hxx> +#include <fchrfmt.hxx> +#include <fmtflcnt.hxx> +#include <fmtftn.hxx> +#include <txttxmrk.hxx> +#include <txtrfmrk.hxx> +#include <txtftn.hxx> +#include <txtfld.hxx> +#include <charfmt.hxx> +#include <frmfmt.hxx> +#include <ftnidx.hxx> +#include <breakit.hxx> + +#include <horiornt.hxx> + +#include <doc.hxx> +#include <pam.hxx> +#include <ndtxt.hxx> +#include <hints.hxx> // fuer SwFmtChg +#include <ddefld.hxx> +#include <docufld.hxx> +#include <expfld.hxx> +#include <usrfld.hxx> +#include <poolfmt.hxx> +// OD 26.06.2003 #108784# +#include <dcontact.hxx> + +#include <algorithm> +namespace binfilter { + +#ifdef DBG_UTIL +#define CHECK Check(); +#else +#define CHECK +#endif + +using namespace ::com::sun::star::i18n; + +/************************************************************************* + * SwTxtNode::MakeTxtAttr() + *************************************************************************/ + + // lege ein neues TextAttribut an und fuege es SwpHints-Array ein +/*N*/ SwTxtAttr* SwTxtNode::MakeTxtAttr( const SfxPoolItem& rAttr, +/*N*/ xub_StrLen nStt, xub_StrLen nEnd, BOOL bPool ) +/*N*/ { +/*N*/ // das neue Attribut im Pool anlegen +/*N*/ const SfxPoolItem& rNew = bPool ? GetDoc()->GetAttrPool().Put( rAttr ) : +/*N*/ rAttr; +/*N*/ +/*N*/ SwTxtAttr* pNew = 0; +/*N*/ switch( rNew.Which() ) +/*N*/ { +/*N*/ case RES_CHRATR_CASEMAP: +/*N*/ case RES_CHRATR_COLOR: +/*N*/ case RES_CHRATR_CHARSETCOLOR: +/*N*/ case RES_CHRATR_CONTOUR: +/*N*/ case RES_CHRATR_CROSSEDOUT: +/*N*/ case RES_CHRATR_ESCAPEMENT: +/*N*/ case RES_CHRATR_KERNING: +/*N*/ case RES_CHRATR_SHADOWED: +/*N*/ case RES_CHRATR_AUTOKERN: +/*N*/ case RES_CHRATR_WORDLINEMODE: +/*N*/ case RES_CHRATR_UNDERLINE: +/*N*/ case RES_CHRATR_FONT: +/*N*/ case RES_CHRATR_CTL_FONT: +/*N*/ case RES_CHRATR_CJK_FONT: +/*N*/ case RES_CHRATR_FONTSIZE: +/*N*/ case RES_CHRATR_CTL_FONTSIZE: +/*N*/ case RES_CHRATR_CJK_FONTSIZE: +/*N*/ case RES_CHRATR_LANGUAGE: +/*N*/ case RES_CHRATR_CTL_LANGUAGE: +/*N*/ case RES_CHRATR_CJK_LANGUAGE: +/*N*/ case RES_CHRATR_POSTURE: +/*N*/ case RES_CHRATR_CTL_POSTURE: +/*N*/ case RES_CHRATR_CJK_POSTURE: +/*N*/ case RES_CHRATR_WEIGHT: +/*N*/ case RES_CHRATR_CTL_WEIGHT: +/*N*/ case RES_CHRATR_CJK_WEIGHT: +/*N*/ case RES_CHRATR_EMPHASIS_MARK: +/*N*/ case RES_CHRATR_NOHYPHEN: +/*N*/ case RES_CHRATR_BLINK: +/*N*/ case RES_CHRATR_BACKGROUND: +/*N*/ case RES_CHRATR_ROTATE: +/*N*/ case RES_CHRATR_SCALEW: +/*N*/ case RES_CHRATR_RELIEF: +/*N*/ pNew = new SwTxtAttrEnd( rNew, nStt, nEnd ); +/*N*/ break; +/*N*/ case RES_TXTATR_CHARFMT: +/*N*/ { +/*N*/ SwFmtCharFmt &rFmtCharFmt = (SwFmtCharFmt&) rNew; +/*N*/ if( !rFmtCharFmt.GetCharFmt() ) +/*?*/ rFmtCharFmt.SetCharFmt( GetDoc()->GetDfltCharFmt() ); +/*N*/ +/*N*/ pNew = new SwTxtCharFmt( rFmtCharFmt, nStt, nEnd ); +/*N*/ } +/*N*/ break; +/*N*/ case RES_TXTATR_INETFMT: +/*N*/ pNew = new SwTxtINetFmt( (SwFmtINetFmt&)rNew, nStt, nEnd ); +/*N*/ break; +/*N*/ case RES_TXTATR_FIELD: +/*N*/ pNew = new SwTxtFld( (SwFmtFld&)rNew, nStt ); +/*N*/ break; +/*N*/ case RES_TXTATR_FLYCNT: +/*N*/ { +/*N*/ // erst hier wird das Frame-Format kopiert (mit Inhalt) !! +/*N*/ pNew = new SwTxtFlyCnt( (SwFmtFlyCnt&)rNew, nStt ); +/*N*/ // Kopie von einem Text-Attribut +/*N*/ if( ((SwFmtFlyCnt&)rAttr).GetTxtFlyCnt() ) +/*N*/ // dann muss das Format Kopiert werden +/*N*/ ((SwTxtFlyCnt*)pNew)->CopyFlyFmt( GetDoc() ); +/*N*/ } +/*N*/ break; +/*N*/ case RES_TXTATR_FTN: +/*N*/ pNew = new SwTxtFtn( (SwFmtFtn&)rNew, nStt ); +/*N*/ // ggfs. SeqNo kopieren +/*N*/ if( ((SwFmtFtn&)rAttr).GetTxtFtn() ) +/*?*/ ((SwTxtFtn*)pNew)->SetSeqNo( ((SwFmtFtn&)rAttr).GetTxtFtn()->GetSeqRefNo() ); +/*N*/ break; +/*?*/ case RES_TXTATR_HARDBLANK: + {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 /*?*/ pNew = new SwTxtHardBlank( (SwFmtHardBlank&)rNew, nStt ); +/*?*/ break; +/*?*/ case RES_CHRATR_TWO_LINES: + {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 /*?*/ pNew = new SwTxt2Lines( (SvxTwoLinesItem&)rNew, nStt, nEnd ); +/*?*/ break; +/*N*/ case RES_TXTATR_REFMARK: +/*N*/ pNew = nStt == nEnd +/*N*/ ? new SwTxtRefMark( (SwFmtRefMark&)rNew, nStt ) +/*N*/ : new SwTxtRefMark( (SwFmtRefMark&)rNew, nStt, &nEnd ); +/*N*/ break; +/*N*/ case RES_TXTATR_TOXMARK: +/*N*/ pNew = new SwTxtTOXMark( (SwTOXMark&)rNew, nStt, &nEnd ); +/*N*/ break; +/*N*/ case RES_UNKNOWNATR_CONTAINER: +/*?*/ case RES_TXTATR_UNKNOWN_CONTAINER: + {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 /*?*/ pNew = new SwTxtXMLAttrContainer( (SvXMLAttrContainerItem&)rNew, +/*?*/ break; +/*N*/ case RES_TXTATR_CJK_RUBY: +/*N*/ pNew = new SwTxtRuby( (SwFmtRuby&)rNew, nStt, nEnd ); +/*N*/ break; +/*N*/ } +/*N*/ ASSERT( pNew, "was fuer ein TextAttribut soll hier angelegt werden?" ); +/*N*/ return pNew; +/*N*/ } + +// loesche das Text-Attribut (muss beim Pool abgemeldet werden!) +/*N*/ void SwTxtNode::DestroyAttr( SwTxtAttr* pAttr ) +/*N*/ { +/*N*/ if( pAttr ) +/*N*/ { +/*N*/ // einige Sachen muessen vorm Loeschen der "Format-Attribute" erfolgen +/*N*/ SwDoc* pDoc = GetDoc(); +/*N*/ USHORT nDelMsg = 0; +/*N*/ switch( pAttr->Which() ) +/*N*/ { +/*N*/ case RES_TXTATR_FLYCNT: +/*N*/ { +/*N*/ // siehe auch die Anmerkung "Loeschen von Formaten +/*N*/ // zeichengebundener Frames" in fesh.cxx, SwFEShell::DelFmt() +/*N*/ SwFrmFmt* pFmt = pAttr->GetFlyCnt().GetFrmFmt(); +/*N*/ if( pFmt ) // vom Undo auf 0 gesetzt ?? +/*N*/ pDoc->DelLayoutFmt( (SwFlyFrmFmt*)pFmt ); +/*N*/ } +/*N*/ break; +/*N*/ +/*N*/ case RES_TXTATR_FTN: +/*N*/ ((SwTxtFtn*)pAttr)->SetStartNode( 0 ); +/*N*/ nDelMsg = RES_FOOTNOTE_DELETED; +/*N*/ break; +/*N*/ +/*N*/ case RES_TXTATR_FIELD: +/*N*/ if( !pDoc->IsInDtor() ) +/*N*/ { +/*N*/ // Wenn wir ein HiddenParaField sind, dann muessen wir +/*N*/ // ggf. fuer eine Neuberechnung des Visible-Flags sorgen. +/*N*/ const SwField* pFld = pAttr->GetFld().GetFld(); +/*N*/ +/*N*/ //JP 06-08-95: DDE-Felder bilden eine Ausnahme +/*N*/ ASSERT( RES_DDEFLD == pFld->GetTyp()->Which() || +/*N*/ this == ((SwTxtFld*)pAttr)->GetpTxtNode(), +/*N*/ "Wo steht denn dieses Feld?" ) +/*N*/ +/*N*/ // bestimmte Felder mussen am Doc das Calculations-Flag updaten +/*N*/ switch( pFld->GetTyp()->Which() ) +/*N*/ { +/*?*/ case RES_HIDDENPARAFLD: +/*?*/ SetCalcVisible(); +/*?*/ // kein break ! +/*?*/ case RES_DBSETNUMBERFLD: +/*?*/ case RES_GETEXPFLD: +/*?*/ case RES_DBFLD: +/*?*/ case RES_SETEXPFLD: +/*?*/ case RES_HIDDENTXTFLD: +/*?*/ case RES_DBNUMSETFLD: +/*?*/ case RES_DBNEXTSETFLD: +/*?*/ if( !pDoc->IsNewFldLst() && GetNodes().IsDocNodes() ) +/*?*/ pDoc->InsDelFldInFldLst( FALSE, *(SwTxtFld*)pAttr ); +/*?*/ break; +/*?*/ case RES_DDEFLD: +/*?*/ if( GetNodes().IsDocNodes() && +/*?*/ ((SwTxtFld*)pAttr)->GetpTxtNode() ) +/*?*/ ((SwDDEFieldType*)pFld->GetTyp())->DecRefCnt(); +/*?*/ break; +/*N*/ } +/*N*/ } +/*N*/ nDelMsg = RES_FIELD_DELETED; +/*N*/ break; +/*N*/ +/*N*/ case RES_TXTATR_TOXMARK: +/*N*/ nDelMsg = RES_TOXMARK_DELETED; +/*N*/ break; +/*N*/ +/*N*/ case RES_TXTATR_REFMARK: +/*N*/ nDelMsg = RES_REFMARK_DELETED; +/*N*/ break; +/*N*/ } +/*N*/ +/*N*/ if( nDelMsg && !pDoc->IsInDtor() && GetNodes().IsDocNodes() ) +/*N*/ { +/*N*/ SwPtrMsgPoolItem aMsgHint( nDelMsg, (void*)&pAttr->GetAttr() ); +/*N*/ pDoc->GetUnoCallBack()->Modify( &aMsgHint, &aMsgHint ); +/*N*/ } +/*N*/ +/*N*/ pAttr->RemoveFromPool( pDoc->GetAttrPool() ); +/*N*/ delete pAttr; +/*N*/ } +/*N*/ } + +/************************************************************************* + * SwTxtNode::Insert() + *************************************************************************/ + +// lege ein neues TextAttribut an und fuege es ins SwpHints-Array ein +/*N*/ SwTxtAttr* SwTxtNode::Insert( const SfxPoolItem& rAttr, +/*N*/ xub_StrLen nStt, xub_StrLen nEnd, USHORT nMode ) +/*N*/ { +/*N*/ SwTxtAttr* pNew = MakeTxtAttr( rAttr, nStt, nEnd ); +/*N*/ return (pNew && Insert( pNew, nMode )) ? pNew : 0; +/*N*/ } + +// uebernehme den Pointer auf das Text-Attribut + +/*N*/ BOOL SwTxtNode::Insert( SwTxtAttr *pAttr, USHORT nMode ) +/*N*/ { +/*N*/ BOOL bHiddenPara = FALSE; +/*N*/ +/*N*/ ASSERT( *pAttr->GetStart() <= Len(), "StartIdx hinter Len!" ); +/*N*/ +/*N*/ if( !pAttr->GetEnd() ) +/*N*/ { +/*N*/ USHORT nInsMode = nMode; +/*N*/ switch( pAttr->Which() ) +/*N*/ { +/*N*/ case RES_TXTATR_FLYCNT: +/*N*/ { +/*N*/ SwTxtFlyCnt *pFly = (SwTxtFlyCnt *)pAttr; +/*N*/ SwFrmFmt* pFmt = pAttr->GetFlyCnt().GetFrmFmt(); +/*N*/ if( !(SETATTR_NOTXTATRCHR & nInsMode) ) +/*N*/ { +/*N*/ // Wir muessen zuerst einfuegen, da in SetAnchor() +/*N*/ // dem FlyFrm GetStart() uebermittelt wird. +/*N*/ //JP 11.05.98: falls das Anker-Attribut schon richtig +/*N*/ // gesetzt ist, dann korrigiere dieses nach dem Einfuegen +/*N*/ // des Zeichens. Sonst muesste das immer ausserhalb +/*N*/ // erfolgen (Fehleranfaellig !) +/*N*/ const SwFmtAnchor* pAnchor = 0; +/*N*/ pFmt->GetItemState( RES_ANCHOR, FALSE, +/*N*/ (const SfxPoolItem**)&pAnchor ); +/*N*/ +/*N*/ SwIndex aIdx( this, *pAttr->GetStart() ); +/*N*/ Insert( GetCharOfTxtAttr(*pAttr), aIdx ); +/*N*/ nInsMode |= SETATTR_NOTXTATRCHR; +/*N*/ +/*N*/ if( pAnchor && FLY_IN_CNTNT == pAnchor->GetAnchorId() && +/*N*/ pAnchor->GetCntntAnchor() && +/*N*/ pAnchor->GetCntntAnchor()->nNode == *this && +/*N*/ pAnchor->GetCntntAnchor()->nContent == aIdx ) +/*N*/ ((SwIndex&)pAnchor->GetCntntAnchor()->nContent)--; +/*N*/ } +/*N*/ pFly->SetAnchor( this ); +/*N*/ +/*N*/ // Format-Pointer kann sich im SetAnchor geaendert haben! +/*N*/ // (Kopieren in andere Docs!) +/*N*/ pFmt = pAttr->GetFlyCnt().GetFrmFmt(); +/*N*/ SwDoc *pDoc = pFmt->GetDoc(); +/*N*/ +/*N*/ // OD 26.06.2003 #108784# - allow drawing objects in header/footer. +/*N*/ // But don't allow control objects in header/footer +/*N*/ if( RES_DRAWFRMFMT == pFmt->Which() && +/*N*/ pDoc->IsInHeaderFooter( pFmt->GetAnchor().GetCntntAnchor()->nNode ) ) +/*N*/ { +/*N*/ SwDrawContact* pDrawContact = +/*N*/ static_cast<SwDrawContact*>(pFmt->FindContactObj()); +/*N*/ if ( pDrawContact && +/*N*/ pDrawContact->GetMaster() && +/*N*/ ::binfilter::CheckControlLayer( pDrawContact->GetMaster() ) ) +/*N*/ { +/*N*/ // das soll nicht meoglich sein; hier verhindern +/*N*/ // Der Dtor des TxtHints loescht nicht das Zeichen. +/*N*/ // Wenn ein CH_TXTATR_.. vorliegt, dann muss man +/*N*/ // dieses explizit loeschen +/*?*/ if( SETATTR_NOTXTATRCHR & nInsMode ) +/*?*/ { +/*?*/ // loesche das Zeichen aus dem String ! +/*?*/ ASSERT( ( CH_TXTATR_BREAKWORD == +/*?*/ aText.GetChar(*pAttr->GetStart() ) || +/*?*/ CH_TXTATR_INWORD == +/*?*/ aText.GetChar(*pAttr->GetStart())), +/*?*/ "where is my attribu character" ); +/*?*/ aText.Erase( *pAttr->GetStart(), 1 ); +/*?*/ // Indizies Updaten +/*?*/ SwIndex aTmpIdx( this, *pAttr->GetStart() ); +/*?*/ Update( aTmpIdx, 1, TRUE ); +/*?*/ } +/*?*/ DestroyAttr( pAttr ); +/*?*/ return FALSE; +/*N*/ } +/*N*/ } +/*N*/ break; +/*N*/ } +/*N*/ case RES_TXTATR_FTN : +/*N*/ { +/*N*/ // Fussnoten, man kommt an alles irgendwie heran. +/*N*/ // CntntNode erzeugen und in die Inserts-Section stellen +/*N*/ SwDoc *pDoc = GetDoc(); +/*N*/ SwNodes &rNodes = pDoc->GetNodes(); +/*N*/ +/*N*/ // FussNote in nicht Content-/Redline-Bereich einfuegen ?? +/*N*/ if( StartOfSectionIndex() < rNodes.GetEndOfAutotext().GetIndex() ) +/*N*/ { +/*N*/ // das soll nicht meoglich sein; hier verhindern +/*N*/ // Der Dtor des TxtHints loescht nicht das Zeichen. +/*N*/ // Wenn ein CH_TXTATR_.. vorliegt, dann muss man +/*N*/ // dieses explizit loeschen +/*?*/ if( SETATTR_NOTXTATRCHR & nInsMode ) +/*?*/ { +/*?*/ // loesche das Zeichen aus dem String ! +/*?*/ ASSERT( ( CH_TXTATR_BREAKWORD == +/*?*/ aText.GetChar(*pAttr->GetStart() ) || +/*?*/ CH_TXTATR_INWORD == +/*?*/ aText.GetChar(*pAttr->GetStart())), +/*?*/ "where is my attribu character" ); +/*?*/ aText.Erase( *pAttr->GetStart(), 1 ); +/*?*/ // Indizies Updaten +/*?*/ SwIndex aTmpIdx( this, *pAttr->GetStart() ); +/*?*/ Update( aTmpIdx, 1, TRUE ); +/*?*/ } +/*?*/ DestroyAttr( pAttr ); +/*?*/ return FALSE; +/*N*/ } +/*N*/ +/*N*/ // wird eine neue Fussnote eingefuegt ?? +/*N*/ BOOL bNewFtn = 0 == ((SwTxtFtn*)pAttr)->GetStartNode(); +/*N*/ if( bNewFtn ) +/*N*/ ((SwTxtFtn*)pAttr)->MakeNewTextSection( GetNodes() ); +/*N*/ else if ( !GetpSwpHints() || !GetpSwpHints()->IsInSplitNode() ) +/*N*/ { +/*N*/ // loesche alle Frames der Section, auf die der StartNode zeigt +/*N*/ ULONG nSttIdx = +/*N*/ ((SwTxtFtn*)pAttr)->GetStartNode()->GetIndex(); +/*N*/ ULONG nEndIdx = rNodes[ nSttIdx++ ]->EndOfSectionIndex(); +/*N*/ SwCntntNode* pCNd; +/*N*/ for( ; nSttIdx < nEndIdx; ++nSttIdx ) +/*N*/ if( 0 != ( pCNd = rNodes[ nSttIdx ]->GetCntntNode() )) +/*N*/ pCNd->DelFrms(); +/*N*/ } +/*N*/ +/*N*/ if( !(SETATTR_NOTXTATRCHR & nInsMode) ) +/*N*/ { +/*N*/ // Wir muessen zuerst einfuegen, da sonst gleiche Indizes +/*N*/ // entstehen koennen und das Attribut im _SortArr_ am +/*N*/ // Dokument nicht eingetrage wird. +/*N*/ SwIndex aNdIdx( this, *pAttr->GetStart() ); +/*N*/ Insert( GetCharOfTxtAttr(*pAttr), aNdIdx ); +/*N*/ nInsMode |= SETATTR_NOTXTATRCHR; +/*N*/ } +/*N*/ +/*N*/ // Wir tragen uns am FtnIdx-Array des Docs ein ... +/*N*/ SwTxtFtn* pTxtFtn = 0; +/*N*/ if( !bNewFtn ) +/*N*/ { +/*N*/ // eine alte Ftn wird umgehaengt (z.B. SplitNode) +/*N*/ for( USHORT n = 0; n < pDoc->GetFtnIdxs().Count(); ++n ) +/*?*/ if( pAttr == pDoc->GetFtnIdxs()[n] ) +/*?*/ { +/*?*/ // neuen Index zuweisen, dafuer aus dem SortArray +/*?*/ // loeschen und neu eintragen +/*?*/ pTxtFtn = pDoc->GetFtnIdxs()[n]; +/*?*/ pDoc->GetFtnIdxs().Remove( n ); +/*?*/ break; +/*?*/ } +/*N*/ // wenn ueber Undo der StartNode gesetzt wurde, kann +/*N*/ // der Index noch gar nicht in der Verwaltung stehen !! +/*N*/ } +/*N*/ if( !pTxtFtn ) +/*N*/ pTxtFtn = (SwTxtFtn*)pAttr; +/*N*/ +/*N*/ // fuers Update der Nummern und zum Sortieren +/*N*/ // muss der Node gesetzt sein. +/*N*/ ((SwTxtFtn*)pAttr)->ChgTxtNode( this ); +/*N*/ +/*N*/ // FussNote im Redline-Bereich NICHT ins FtnArray einfuegen! +/*N*/ if( StartOfSectionIndex() > rNodes.GetEndOfRedlines().GetIndex() ) +/*N*/ { +/*N*/ #ifdef DBG_UTIL +/*N*/ const BOOL bSuccess = +/*N*/ #endif +/*N*/ pDoc->GetFtnIdxs().Insert( pTxtFtn ); +/*N*/ #ifdef DBG_UTIL +/*N*/ ASSERT( bSuccess, "FtnIdx nicht eingetragen." ); +/*N*/ #endif +/*N*/ } +/*N*/ SwNodeIndex aTmpIndex( *this ); +/*N*/ pDoc->GetFtnIdxs().UpdateFtn( aTmpIndex); +/*N*/ ((SwTxtFtn*)pAttr)->SetSeqRefNo(); +/*N*/ } +/*N*/ break; +/*N*/ +/*N*/ case RES_TXTATR_FIELD: +/*N*/ { +/*N*/ // fuer HiddenParaFields Benachrichtigungsmechanismus +/*N*/ // anwerfen +/*N*/ if( RES_HIDDENPARAFLD == +/*N*/ pAttr->GetFld().GetFld()->GetTyp()->Which() ) +/*N*/ bHiddenPara = TRUE; +/*N*/ } +/*N*/ break; +/*N*/ +/*N*/ } +/*N*/ // Fuer SwTxtHints ohne Endindex werden CH_TXTATR_.. +/*N*/ // eingefuegt, aStart muss danach um einen zurueckgesetzt werden. +/*N*/ // Wenn wir im SwTxtNode::Copy stehen, so wurde das Zeichen bereits +/*N*/ // mitkopiert. In solchem Fall ist SETATTR_NOTXTATRCHR angegeben worden. +/*N*/ if( !(SETATTR_NOTXTATRCHR & nInsMode) ) +/*N*/ { +/*N*/ SwIndex aIdx( this, *pAttr->GetStart() ); +/*N*/ Insert( GetCharOfTxtAttr(*pAttr), aIdx ); +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ ASSERT( *pAttr->GetEnd() <= Len(), "EndIdx hinter Len!" ); +/*N*/ } +/*N*/ +/*N*/ if ( !pSwpHints ) +/*N*/ pSwpHints = new SwpHints(); +/*N*/ +/*N*/ // 4263: AttrInsert durch TextInsert => kein Adjust +/*N*/ pSwpHints->Insert( pAttr, *this, nMode ); +/*N*/ +/*N*/ // 47375: In pSwpHints->Insert wird u.a. Merge gerufen und das Hints-Array +/*N*/ // von ueberfluessigen Hints befreit, dies kann u.U. sogar der frisch +/*N*/ // eingefuegte Hint pAttr sein, der dann zerstoert wird!! +/*N*/ if( USHRT_MAX == pSwpHints->GetPos( pAttr ) ) +/*N*/ return FALSE; +/*N*/ +/*N*/ if(bHiddenPara) +/*N*/ SetCalcVisible(); +/*N*/ return TRUE; +/*N*/ } + +/************************************************************************* + * SwTxtNode::Delete() + *************************************************************************/ + +/*N*/ void SwTxtNode::Delete( SwTxtAttr *pAttr, BOOL bThisOnly ) +/*N*/ { +/*N*/ if ( !pSwpHints ) +/*N*/ return; +/*N*/ if( bThisOnly ) +/*N*/ { +/*?*/ xub_StrLen* pEndIdx = pAttr->GetEnd(); +/*?*/ if( !pEndIdx ) +/*?*/ { +/*?*/ // hat es kein Ende kann es nur das sein, was hier steht! +/*?*/ // Unbedingt Copy-konstruieren! +/*?*/ const SwIndex aIdx( this, *pAttr->GetStart() ); +/*?*/ Erase( aIdx, 1 ); +/*?*/ } +/*?*/ else +/*?*/ { +/*?*/ // den MsgHint jetzt fuettern, weil gleich sind +/*?*/ // Start und End weg. +/*?*/ SwUpdateAttr aHint( *pAttr->GetStart(), *pEndIdx, pAttr->Which() ); +/*?*/ pSwpHints->Delete( pAttr ); +/*?*/ pAttr->RemoveFromPool( GetDoc()->GetAttrPool() ); +/*?*/ delete pAttr; +/*?*/ SwModify::Modify( 0, &aHint ); // die Frames benachrichtigen +/*?*/ +/*?*/ if( pSwpHints && pSwpHints->CanBeDeleted() ) +/*?*/ DELETEZ( pSwpHints ); +/*?*/ } +/*?*/ +/*?*/ return; +/*N*/ } +/*N*/ Delete( pAttr->Which(), *pAttr->GetStart(), *pAttr->GetAnyEnd() ); +/*N*/ } + +/************************************************************************* + * SwTxtNode::Delete() + *************************************************************************/ + +/*N*/ void SwTxtNode::Delete( USHORT nTxtWhich, xub_StrLen nStart, xub_StrLen nEnd ) +/*N*/ { +/*N*/ if ( !pSwpHints ) +/*N*/ return; +/*N*/ +/*N*/ const xub_StrLen *pEndIdx; +/*N*/ const xub_StrLen *pSttIdx; +/*N*/ SwTxtAttr* pTxtHt; +/*N*/ +/*N*/ for( USHORT nPos = 0; pSwpHints && nPos < pSwpHints->Count(); nPos++ ) +/*N*/ { +/*N*/ pTxtHt = pSwpHints->GetHt( nPos ); +/*N*/ const USHORT nWhich = pTxtHt->Which(); +/*N*/ if( nWhich == nTxtWhich && +/*N*/ *( pSttIdx = pTxtHt->GetStart()) == nStart ) +/*N*/ { +/*N*/ pEndIdx = pTxtHt->GetEnd(); +/*N*/ +/*N*/ // Text-Attribute sind voellig dynamisch, so dass diese nur +/*N*/ // mit ihrer Start-Position verglichen werden. +/*N*/ if( !pEndIdx ) +/*N*/ { +/*N*/ // Unbedingt Copy-konstruieren! +/*?*/ const SwIndex aIdx( this, *pSttIdx ); +/*?*/ Erase( aIdx, 1 ); +/*?*/ break; +/*N*/ } +/*N*/ else if( *pEndIdx == nEnd ) +/*N*/ { +/*N*/ // den MsgHint jetzt fuettern, weil gleich sind +/*N*/ // Start und End weg. +/*N*/ // Das CalcVisibleFlag bei HiddenParaFields entfaellt, +/*N*/ // da dies das Feld im Dtor selbst erledigt. +/*N*/ SwUpdateAttr aHint( *pSttIdx, *pEndIdx, nTxtWhich ); +/*N*/ pSwpHints->DeleteAtPos( nPos ); // gefunden, loeschen, +/*N*/ pTxtHt->RemoveFromPool( GetDoc()->GetAttrPool() ); +/*N*/ delete pTxtHt; +/*N*/ SwModify::Modify( 0, &aHint ); // die Frames benachrichtigen +/*N*/ break; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ if( pSwpHints && pSwpHints->CanBeDeleted() ) +/*N*/ DELETEZ( pSwpHints ); +/*N*/ } + +/************************************************************************* + * SwTxtNode::DelSoftHyph() + *************************************************************************/ + +// setze diese Attribute am TextNode. Wird der gesamte Bereich umspannt, +// dann setze sie nur im AutoAttrSet (SwCntntNode:: SetAttr) +/*N*/ BOOL SwTxtNode::SetAttr( const SfxItemSet& rSet, xub_StrLen nStt, +/*N*/ xub_StrLen nEnd, USHORT nMode ) +/*N*/ { +/*N*/ if( !rSet.Count() ) +/*N*/ return FALSE; +/*N*/ +/*N*/ // teil die Sets auf (fuer Selektion in Nodes) +/*N*/ const SfxItemSet* pSet = &rSet; +/*N*/ SfxItemSet aTxtSet( *rSet.GetPool(), RES_TXTATR_BEGIN, RES_TXTATR_END-1 ); +/*N*/ +/*N*/ // gesamter Bereich +/*N*/ if( !nStt && nEnd == aText.Len() && !(nMode & SETATTR_NOFORMATATTR ) ) +/*N*/ { +/*N*/ // sind am Node schon Zeichenvorlagen gesetzt, muss man diese Attribute +/*N*/ // (rSet) immer als TextAttribute setzen, damit sie angezeigt werden. +/*N*/ int bHasCharFmts = FALSE; +/*N*/ if( pSwpHints ) +/*N*/ for( USHORT n = 0; n < pSwpHints->Count(); ++n ) +/*N*/ if( (*pSwpHints)[ n ]->IsCharFmtAttr() ) +/*N*/ { +/*N*/ bHasCharFmts = TRUE; +/*N*/ break; +/*N*/ } +/*N*/ +/*N*/ if( !bHasCharFmts ) +/*N*/ { +/*N*/ aTxtSet.Put( rSet ); +/*N*/ if( aTxtSet.Count() != rSet.Count() ) +/*N*/ { +/*N*/ BOOL bRet = SwCntntNode::SetAttr( rSet ); +/*N*/ if( !aTxtSet.Count() ) +/*N*/ return bRet; +/*N*/ } +/*N*/ pSet = &aTxtSet; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if ( !pSwpHints ) +/*N*/ pSwpHints = new SwpHints(); +/*N*/ +/*N*/ USHORT nWhich, nCount = 0; +/*N*/ SwTxtAttr* pNew; +/*N*/ SfxItemIter aIter( *pSet ); +/*N*/ const SfxPoolItem* pItem = aIter.GetCurItem(); +/*N*/ do { +/*N*/ if( pItem && (SfxPoolItem*)-1 != pItem && +/*N*/ (( RES_CHRATR_BEGIN <= ( nWhich = pItem->Which()) && +/*N*/ RES_CHRATR_END > nWhich ) || +/*N*/ ( RES_TXTATR_BEGIN <= nWhich && RES_TXTATR_END > nWhich ) || +/*N*/ ( RES_UNKNOWNATR_BEGIN <= nWhich && RES_UNKNOWNATR_END > nWhich )) ) +/*N*/ { +/*N*/ if( RES_TXTATR_CHARFMT == pItem->Which() && +/*N*/ GetDoc()->GetDfltCharFmt()==((SwFmtCharFmt*)pItem)->GetCharFmt()) +/*N*/ { + DBG_BF_ASSERT(0, "STRIP"); //STRIP001 /*?*/ SwIndex aIndex( this, nStt ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ pNew = MakeTxtAttr( *pItem, nStt, nEnd ); +/*N*/ if( pNew ) +/*N*/ { +/*N*/ // Attribut ohne Ende, aber Bereich markiert ? +/*N*/ if( nEnd != nStt && !pNew->GetEnd() ) +/*N*/ { +/*?*/ ASSERT( !this, "Attribut ohne Ende aber Bereich vorgegeben" ); +/*?*/ DestroyAttr( pNew ); // nicht einfuegen +/*N*/ } +/*N*/ else if( Insert( pNew, nMode )) +/*N*/ ++nCount; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ if( aIter.IsAtEnd() ) +/*N*/ break; +/*?*/ pItem = aIter.NextItem(); +/*N*/ } while( TRUE ); +/*N*/ +/*N*/ if( pSwpHints && pSwpHints->CanBeDeleted() ) +/*?*/ DELETEZ( pSwpHints ); +/*N*/ +/*N*/ return nCount ? TRUE : FALSE; +/*N*/ } + +/*N*/ BOOL lcl_Included( const USHORT nWhich, const SwTxtAttr *pAttr ) +/*N*/ { +/*N*/ #if OSL_DEBUG_LEVEL > 1 +/*N*/ static long nTest = 0; +/*N*/ ++nTest; +/*N*/ #endif +/*N*/ BOOL bRet; +/*N*/ SwCharFmt* pFmt = RES_TXTATR_INETFMT == pAttr->Which() ? +/*N*/ ((SwTxtINetFmt*)pAttr)->GetCharFmt() : +/*N*/ pAttr->GetCharFmt().GetCharFmt(); +/*N*/ if( pFmt ) +/*N*/ bRet = SFX_ITEM_SET == pFmt->GetAttrSet().GetItemState( nWhich, TRUE ); +/*N*/ else +/*N*/ bRet = FALSE; +/*N*/ return bRet; +/*N*/ } + +/*N*/ void lcl_MergeAttr( SfxItemSet& rSet, const SfxPoolItem& rAttr ) +/*N*/ { +/*N*/ rSet.Put( rAttr ); +/*N*/ } + +/*N*/ void lcl_MergeAttr_ExpandChrFmt( SfxItemSet& rSet, const SfxPoolItem& rAttr ) +/*N*/ { +/*N*/ if( RES_TXTATR_CHARFMT == rAttr.Which() || +/*N*/ RES_TXTATR_INETFMT == rAttr.Which() ) +/*N*/ { +/*N*/ // aus der Vorlage die Attribute holen: +/*N*/ SwCharFmt* pFmt = RES_TXTATR_INETFMT == rAttr.Which() ? +/*N*/ ((SwFmtINetFmt&)rAttr).GetTxtINetFmt()->GetCharFmt() : +/*N*/ ((SwFmtCharFmt&)rAttr).GetCharFmt(); +/*N*/ if( pFmt ) +/*N*/ { +/*N*/ const SfxItemSet& rCFSet = pFmt->GetAttrSet(); +/*N*/ SfxWhichIter aIter( rCFSet ); +/*N*/ register USHORT nWhich = aIter.FirstWhich(); +/*N*/ while( nWhich ) +/*N*/ { +/*N*/ if( ( nWhich < RES_CHRATR_END ) && +/*N*/ ( SFX_ITEM_SET == rCFSet.GetItemState( nWhich, TRUE ) ) ) +/*N*/ rSet.Put( rCFSet.Get( nWhich ) ); +/*N*/ nWhich = aIter.NextWhich(); +/*N*/ } +/*N*/ #if 0 +/*N*/ SfxItemSet aTmpSet( *rSet.GetPool(), rSet.GetRanges() ); +/*N*/ aTmpSet.Set( pFmt->GetAttrSet(), TRUE ); + /* + ????? JP 31.01.95 ???? wie jetzt ??? + rSet.MergeValues( aTmpSet ); + + // jetzt alle zusammen "mergen" + rSet.Differentiate( aTmpSet ); + */ +/*N*/ rSet.Put( aTmpSet ); +/*N*/ #endif +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ // aufnehmen als MergeWert (falls noch nicht gesetzt neu setzen!) +/*N*/ #if 0 + /* wenn mehrere Attribute ueberlappen werden diese gemergt !! + z.B + 1234567890123456789 + |------------| Font1 + |------| Font2 + ^ ^ + |--| Abfragebereich: -> uneindeutig + */ +/*N*/ else if( SFX_ITEM_DEFAULT == rSet.GetItemState( rAttr.Which(), FALSE )) +/*N*/ rSet.Put( rAttr ); +/*N*/ else +/*N*/ rSet.MergeValue( rAttr ); +/*N*/ #else + /* wenn mehrere Attribute ueberlappen gewinnt der letze !! + z.B + 1234567890123456789 + |------------| Font1 + |------| Font2 + ^ ^ + |--| Abfragebereich: -> Gueltig ist Font2 + */ +/*N*/ rSet.Put( rAttr ); +/*N*/ #endif +/*N*/ } + +// erfrage die Attribute vom TextNode ueber den Bereich +/*N*/ BOOL SwTxtNode::GetAttr( SfxItemSet& rSet, xub_StrLen nStart, xub_StrLen nEnd, +/*N*/ BOOL bOnlyTxtAttr, BOOL bGetFromChrFmt ) const +/*N*/ { +/*N*/ if( pSwpHints ) +/*N*/ { + /* stelle erstmal fest, welche Text-Attribut in dem Bereich gueltig + * sind. Dabei gibt es folgende Faelle: + * UnEindeutig wenn: (wenn != Format-Attribut) + * - das Attribut liegt vollstaendig im Bereich + * - das Attributende liegt im Bereich + * - der Attributanfang liegt im Bereich: + * Eindeutig (im Set mergen): + * - das Attrib umfasst den Bereich + * nichts tun: + * das Attribut liegt ausserhalb des Bereiches + */ +/*N*/ +/*N*/ void (*fnMergeAttr)( SfxItemSet&, const SfxPoolItem& ) +/*N*/ = bGetFromChrFmt ? &lcl_MergeAttr_ExpandChrFmt +/*N*/ : &lcl_MergeAttr; +/*N*/ +/*N*/ // dann besorge mal die Auto-(Fmt)Attribute +/*N*/ SfxItemSet aFmtSet( *rSet.GetPool(), rSet.GetRanges() ); +/*N*/ if( !bOnlyTxtAttr ) +/*N*/ SwCntntNode::GetAttr( aFmtSet ); +/*N*/ +/*N*/ const USHORT nSize = pSwpHints->Count(); +/*N*/ register USHORT n; +/*N*/ register xub_StrLen nAttrStart; +/*N*/ register const xub_StrLen* pAttrEnd; +/*N*/ +/*N*/ if( nStart == nEnd ) // kein Bereich: +/*N*/ { +/*N*/ for( n = 0; n < nSize; ++n ) // +/*N*/ { +/*N*/ const SwTxtAttr* pHt = (*pSwpHints)[n]; +/*N*/ nAttrStart = *pHt->GetStart(); +/*N*/ if( nAttrStart > nEnd ) // ueber den Bereich hinaus +/*N*/ break; +/*N*/ +/*N*/ if( 0 == ( pAttrEnd = pHt->GetEnd() )) // nie Attribute ohne Ende +/*N*/ continue; +/*N*/ +/*N*/ if( ( nAttrStart < nStart && +/*N*/ ( pHt->DontExpand() ? nStart < *pAttrEnd +/*N*/ : nStart <= *pAttrEnd )) || +/*N*/ ( nStart == nAttrStart && +/*N*/ ( nAttrStart == *pAttrEnd || !nStart ))) +/*N*/ (*fnMergeAttr)( rSet, pHt->GetAttr() ); +/*N*/ } +/*N*/ } +/*N*/ else // es ist ein Bereich definiert +/*N*/ { +/*N*/ SwTxtAttr** aAttrArr = 0; +/*N*/ const USHORT coArrSz = RES_TXTATR_WITHEND_END - RES_CHRATR_BEGIN + +/*N*/ ( RES_UNKNOWNATR_END - +/*N*/ RES_UNKNOWNATR_BEGIN ); +/*N*/ +/*N*/ for( n = 0; n < nSize; ++n ) +/*N*/ { +/*N*/ const SwTxtAttr* pHt = (*pSwpHints)[n]; +/*N*/ nAttrStart = *pHt->GetStart(); +/*N*/ if( nAttrStart > nEnd ) // ueber den Bereich hinaus +/*N*/ break; +/*N*/ +/*N*/ if( 0 == ( pAttrEnd = pHt->GetEnd() )) // nie Attribute ohne Ende +/*N*/ continue; +/*N*/ +/*N*/ BOOL bChkInvalid = FALSE; +/*N*/ if( nAttrStart <= nStart ) // vor oder genau Start +/*N*/ { +/*N*/ if( *pAttrEnd <= nStart ) // liegt davor +/*N*/ continue; +/*N*/ +/*N*/ if( nEnd <= *pAttrEnd ) // hinter oder genau Ende +/*N*/ (*fnMergeAttr)( aFmtSet, pHt->GetAttr() ); +/*N*/ else +/*N*/ // else if( pHt->GetAttr() != aFmtSet.Get( pHt->Which() ) ) +/*N*/ // uneindeutig +/*N*/ bChkInvalid = TRUE; +/*N*/ } +/*N*/ else if( nAttrStart < nEnd // reicht in den Bereich +/*N*/ )// && pHt->GetAttr() != aFmtSet.Get( pHt->Which() ) ) +/*N*/ bChkInvalid = TRUE; +/*N*/ +/*N*/ if( bChkInvalid ) +/*N*/ { +/*?*/ // uneindeutig ? +/*?*/ if( !aAttrArr ) +/*?*/ { +/*?*/ aAttrArr = new SwTxtAttr* [ coArrSz ]; +/*?*/ memset( aAttrArr, 0, sizeof( SwTxtAttr* ) * coArrSz ); +/*?*/ } +/*?*/ +/*?*/ const SwTxtAttr** ppPrev; +/*?*/ if( RES_CHRATR_BEGIN <= pHt->Which() && +/*?*/ pHt->Which() < RES_TXTATR_WITHEND_END ) +/*?*/ ppPrev = (const SwTxtAttr**)&aAttrArr[ +/*?*/ pHt->Which() - RES_CHRATR_BEGIN ]; +/*?*/ else if( RES_UNKNOWNATR_BEGIN <= pHt->Which() && +/*?*/ pHt->Which() < RES_UNKNOWNATR_END ) +/*?*/ ppPrev = (const SwTxtAttr**)&aAttrArr[ +/*?*/ pHt->Which() - RES_UNKNOWNATR_BEGIN +/*?*/ + ( RES_TXTATR_WITHEND_END - +/*?*/ RES_CHRATR_BEGIN ) ]; +/*?*/ else +/*?*/ ppPrev = 0; +/*?*/ +/*?*/ if( !*ppPrev ) +/*?*/ { +/*?*/ if( nAttrStart > nStart ) +/*?*/ { +/*?*/ rSet.InvalidateItem( pHt->Which() ); +/*?*/ *ppPrev = (SwTxtAttr*)-1; +/*?*/ } +/*?*/ else +/*?*/ *ppPrev = pHt; +/*?*/ } +/*?*/ else if( (SwTxtAttr*)-1 != *ppPrev ) +/*?*/ { +/*?*/ if( *(*ppPrev)->GetEnd() == nAttrStart && +/*?*/ (*ppPrev)->GetAttr() == pHt->GetAttr() ) +/*?*/ *ppPrev = pHt; +/*?*/ else +/*?*/ { +/*?*/ rSet.InvalidateItem( pHt->Which() ); +/*?*/ *ppPrev = (SwTxtAttr*)-1; +/*?*/ } +/*?*/ } +/*N*/ } +/*N*/ } +/*N*/ if( aAttrArr ) +/*N*/ { +/*?*/ const SwTxtAttr* pAttr; +/*?*/ for( n = 0; n < coArrSz; ++n ) +/*?*/ if( 0 != ( pAttr = aAttrArr[ n ] ) && +/*?*/ (SwTxtAttr*)-1 != pAttr ) +/*?*/ { +/*?*/ USHORT nWh; +/*?*/ if( n < (RES_TXTATR_WITHEND_END - +/*?*/ RES_CHRATR_BEGIN )) +/*?*/ nWh = n + RES_CHRATR_BEGIN; +/*?*/ else +/*?*/ nWh = n - ( RES_TXTATR_WITHEND_END - +/*?*/ RES_CHRATR_BEGIN ) + +/*?*/ RES_UNKNOWNATR_BEGIN; +/*?*/ +/*?*/ if( nEnd <= *pAttr->GetEnd() ) // hinter oder genau Ende +/*?*/ { +/*?*/ if( pAttr->GetAttr() != aFmtSet.Get( nWh ) ) +/*?*/ (*fnMergeAttr)( rSet, pAttr->GetAttr() ); +/*?*/ } +/*?*/ else +/*?*/ // uneindeutig +/*?*/ rSet.InvalidateItem( nWh ); +/*?*/ } +/*?*/ delete [] aAttrArr; +/*N*/ } +/*N*/ } +/*N*/ if( aFmtSet.Count() ) +/*N*/ { +/*N*/ // aus dem Format-Set alle entfernen, die im TextSet auch gesetzt sind +/*N*/ aFmtSet.Differentiate( rSet ); +/*N*/ // jetzt alle zusammen "mergen" +/*N*/ rSet.Put( aFmtSet ); +/*N*/ } +/*N*/ } +/*N*/ else if( !bOnlyTxtAttr ) +/*N*/ // dann besorge mal die Auto-(Fmt)Attribute +/*N*/ SwCntntNode::GetAttr( rSet ); +/*N*/ +/*N*/ return rSet.Count() ? TRUE : FALSE; +/*N*/ } + +/*N*/ void SwTxtNode::FmtToTxtAttr( SwTxtNode* pNd ) +/*N*/ { +/*N*/ SfxItemSet aThisSet( GetDoc()->GetAttrPool(), aCharFmtSetRange ); +/*N*/ if( GetpSwAttrSet() && GetpSwAttrSet()->Count() ) +/*?*/ aThisSet.Put( *GetpSwAttrSet() ); +/*N*/ +/*N*/ if ( !pSwpHints ) +/*N*/ pSwpHints = new SwpHints(); +/*N*/ +/*N*/ if( pNd == this ) +/*N*/ { +/*?*/ if( aThisSet.Count() ) +/*?*/ { +/*?*/ SfxItemIter aIter( aThisSet ); +/*?*/ const SfxPoolItem* pItem = aIter.GetCurItem(); +/*?*/ while( TRUE ) +/*?*/ { + DBG_BF_ASSERT(0, "STRIP"); //STRIP001 /*?*/ if( lcl_IsNewAttrInSet( *pSwpHints, *pItem, GetTxt().Len() ) ) +/*?*/ } +/*?*/ } +/*N*/ +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ SfxItemSet aNdSet( pNd->GetDoc()->GetAttrPool(), aCharFmtSetRange ); +/*N*/ if( pNd->GetpSwAttrSet() && pNd->GetpSwAttrSet()->Count() ) +/*?*/ aNdSet.Put( *pNd->GetpSwAttrSet() ); +/*N*/ +/*N*/ if ( !pNd->pSwpHints ) +/*N*/ pNd->pSwpHints = new SwpHints(); +/*N*/ +/*N*/ if( aThisSet.Count() ) +/*N*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 SfxItemIter aIter( aThisSet ); +/*N*/ } +/*N*/ +/*N*/ if( aNdSet.Count() ) +/*N*/ { +/*?*/ SfxItemIter aIter( aNdSet ); +/*?*/ const SfxPoolItem* pItem = aIter.GetCurItem(); +/*?*/ while( TRUE ) +/*?*/ { + DBG_BF_ASSERT(0, "STRIP"); //STRIP001 /*?*/ if( lcl_IsNewAttrInSet( *pNd->pSwpHints, *pItem, pNd->GetTxt().Len() ) ) +/*?*/ } +/*?*/ +/*?*/ SwFmtChg aTmp1( pNd->GetFmtColl() ); +/*?*/ pNd->SwModify::Modify( &aTmp1, &aTmp1 ); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if( pNd->pSwpHints->CanBeDeleted() ) +/*N*/ DELETEZ( pNd->pSwpHints ); +/*N*/ } + +/************************************************************************* + * SwpHints::CalcFlags() + *************************************************************************/ + +/*N*/ void SwpHints::CalcFlags() +/*N*/ { +/*N*/ bDDEFlds = bFtn = FALSE; +/*N*/ const USHORT nSize = Count(); +/*N*/ const SwTxtAttr* pAttr; +/*N*/ for( USHORT nPos = 0; nPos < nSize; ++nPos ) +/*N*/ switch( ( pAttr = (*this)[ nPos ])->Which() ) +/*N*/ { +/*N*/ case RES_TXTATR_FTN: +/*N*/ bFtn = TRUE; +/*N*/ if( bDDEFlds ) +/*N*/ return; +/*N*/ break; +/*N*/ case RES_TXTATR_FIELD: +/*N*/ { +/*N*/ const SwField* pFld = pAttr->GetFld().GetFld(); +/*N*/ if( RES_DDEFLD == pFld->GetTyp()->Which() ) +/*N*/ { +/*N*/ bDDEFlds = TRUE; +/*N*/ if( bFtn ) +/*N*/ return; +/*N*/ } +/*N*/ } +/*N*/ break; +/*N*/ } +/*N*/ } + +/************************************************************************* + * SwpHints::CalcVisibleFlag() + *************************************************************************/ + +/*N*/ BOOL SwpHints::CalcVisibleFlag() +/*N*/ { +/*N*/ BOOL bOldVis = bVis; +/*N*/ bCalcVis = FALSE; +/*N*/ BOOL bNewVis = TRUE; +/*N*/ const USHORT nSize = Count(); +/*N*/ const SwTxtAttr *pTxtHt; +/*N*/ +/*N*/ for( USHORT nPos = 0; nPos < nSize; ++nPos ) +/*N*/ { +/*N*/ pTxtHt = (*this)[ nPos ]; +/*N*/ const USHORT nWhich = pTxtHt->Which(); +/*N*/ +/*N*/ if( RES_TXTATR_FIELD == nWhich ) +/*N*/ { +/*N*/ const SwFmtFld& rFld = pTxtHt->GetFld(); +/*N*/ if( RES_HIDDENPARAFLD == rFld.GetFld()->GetTyp()->Which()) +/*N*/ { +/*N*/ if( !((SwHiddenParaField*)rFld.GetFld())->IsHidden() ) +/*N*/ { +/*N*/ SetVisible(TRUE); +/*N*/ return !bOldVis; +/*N*/ } +/*N*/ else +/*N*/ bNewVis = FALSE; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ SetVisible( bNewVis ); +/*N*/ return bOldVis != bNewVis; +/*N*/ } + +/************************************************************************* + * SwpHints::Resort() + *************************************************************************/ + +// Ein Hint hat seinen Anfangswert geaendert. +// Hat sich dadurch die Sortierreihenfolge +// geaendert, so wird solange umsortiert, bis +// sie wieder stimmt. + +/*N*/ BOOL SwpHints::Resort( const USHORT nPos ) +/*N*/ { +/*N*/ const SwTxtAttr *pTmp; +/*N*/ +/*N*/ if ( ( nPos+1 < Count() && +/*N*/ *(*this)[nPos]->GetStart() > *(*this)[nPos+1]->GetStart() ) || +/*N*/ ( nPos > 0 && +/*N*/ *(*this)[nPos]->GetStart() < *(*this)[nPos-1]->GetStart() ) ) +/*N*/ { +/*?*/ pTmp = (*this)[nPos]; +/*?*/ DeleteAtPos( nPos ); +/*?*/ SwpHintsArr::Insert( pTmp ); +/*?*/ // Wenn tatsaechlich umsortiert wurde, muss die +/*?*/ // Position i nochmal bearbeitet werden. +/*?*/ return TRUE; +/*N*/ } +/*N*/ return FALSE; +/*N*/ } + +/************************************************************************* + * SwpHints::ClearDummies() + *************************************************************************/ + +/* + * ClearDummies: Hints, die genau den gleichen Bereich umfassen wie + * ein nachfolgender mit gleichem Attribut oder eine nachfolgende Zeichen- + * vorlage, muessen entfernt werden. + * Solche Hints entstehen, wenn sie urspruenglich einen groesseren, den + * Nachfolger umfassenden Bereich hatten, die Aussenanteile aber durch + * SwTxtNode::RstAttr oder SwTxtNode::Update geloescht wurden. + */ + +/*N*/ void SwpHints::ClearDummies( SwTxtNode &rNode ) +/*N*/ { +/*N*/ USHORT i = 0; +/*N*/ while ( i < Count() ) +/*N*/ { +/*N*/ SwTxtAttr *pHt = GetHt( i++ ); +/*N*/ const USHORT nWhich = pHt->Which(); +/*N*/ const xub_StrLen *pEnd = pHt->GetEnd(); +/*N*/ if ( pEnd && !pHt->IsOverlapAllowedAttr() && !pHt->IsCharFmtAttr() ) +/*N*/ for( USHORT j = i; j < Count(); ++j ) +/*N*/ { +/*N*/ SwTxtAttr *pOther = GetHt(j); +/*N*/ if ( *pOther->GetStart() > *pHt->GetStart() ) +/*N*/ break; +/*N*/ +/*N*/ if( pOther->Which() == nWhich || pOther->IsCharFmtAttr() ) +/*N*/ { +/*N*/ //JP 03.10.95: nicht zusammenfassen, zu kompliziert +/*N*/ // fuer WIN95-Compiler!! +/*?*/ if( *pEnd == *pOther->GetEnd() && +/*?*/ ( pOther->Which() == nWhich || +/*?*/ lcl_Included( nWhich, pOther ) ) ) +/*?*/ { +/*?*/ rNode.DestroyAttr( Cut( --i ) ); +/*?*/ break; +/*?*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } + +/************************************************************************* + * SwpHints::Merge( ) + *************************************************************************/ + +/* + * Merge: Gleichartigen, gleichwertige Hints, die aneinandergrenzen, + * koennen verschmolzen werden, wenn an ihrer gemeinsamen Kante nicht ein + * gleichartiges Attribut endet oder beginnt, welches einen von der beiden + * Kandidaten umfasst, auch Zeichenvorlage duerfen nicht ueberlappt werden. + */ +/*-----------------5.9.2001 09:26------------------- + * And here a smarter version of good old Merge(..) + * If a SwTxtAttr is given, only the merging between this attribute and the + * neighbours are checked. This saves time, if no attribute is given (in more + * complex situations), the whole attribute array is checked as before. + * --------------------------------------------------*/ + +/*N*/ BOOL SwpHints::Merge( SwTxtNode &rNode, SwTxtAttr* pAttr ) +/*N*/ { +/*N*/ USHORT i; +/*N*/ BOOL bMerged = FALSE; +/*N*/ if( pAttr && USHRT_MAX != ( i = GetPos( pAttr ) ) ) +/*N*/ { +/*N*/ const xub_StrLen *pEnd = pAttr->GetEnd(); +/*N*/ if ( pEnd && !pAttr->IsDontMergeAttr() ) +/*N*/ { +/*N*/ USHORT j = i; +/*N*/ const USHORT nWhich = pAttr->Which(); +/*N*/ const USHORT nStart = *pAttr->GetStart(); +/*N*/ const USHORT nEnd = *pEnd; +/*N*/ SwTxtAttr *pPrev; +/*N*/ SwTxtAttr *pNext; +/*N*/ USHORT nEndIdx = aHtEnd.C40_GETPOS( SwTxtAttr, pAttr ); +/*N*/ ASSERT( USHRT_MAX != nEndIdx, "Missing end index" ); +/*N*/ if( nEndIdx ) +/*N*/ { +/*N*/ // If there's a attribute with same start and which-id, +/*N*/ // it's not possible to merge with a previous attribute. +/*N*/ pPrev = pAttr; +/*N*/ while( j ) +/*N*/ { +/*N*/ SwTxtAttr *pOther = GetHt(--j); +/*N*/ if ( *pOther->GetStart() < nStart ) +/*N*/ break; +/*N*/ if( pOther->Which() == nWhich || pOther->IsCharFmtAttr() +/*N*/ || pAttr->IsCharFmtAttr() ) +/*N*/ { +/*N*/ pPrev = NULL; +/*N*/ break; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ pPrev = NULL; +/*N*/ if( i + 1 < Count() ) +/*N*/ { +/*N*/ // If there's a attribute with same end and which-id, +/*N*/ // it's not possible to merge with a following attribute. +/*N*/ j = nEndIdx + 1; +/*N*/ pNext = pAttr; +/*N*/ while( j < Count() ) +/*N*/ { +/*N*/ SwTxtAttr *pOther = GetEnd( j++ ); +/*N*/ if( !pOther->GetEnd() ) +/*N*/ continue; +/*N*/ if( *pOther->GetEnd() > nEnd ) +/*N*/ break; +/*N*/ if( pOther->Which() == nWhich || pOther->IsCharFmtAttr() +/*N*/ || pAttr->IsCharFmtAttr() ) +/*N*/ { +/*N*/ pNext = NULL; +/*N*/ break; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ pNext = NULL; +/*N*/ if( pPrev ) +/*N*/ { +/*N*/ pPrev = NULL; +/*N*/ j = nEndIdx; +/*N*/ do +/*N*/ { +/*N*/ // Looking for a previous attribute with the same which-id +/*N*/ // which ends exact at the start of the given attribute +/*N*/ SwTxtAttr *pOther = GetEnd( --j ); +/*N*/ pEnd = pOther->GetEnd(); +/*N*/ if( !pEnd || *pEnd > nStart ) +/*N*/ continue; +/*N*/ if( *pEnd < nStart ) +/*N*/ break; +/*N*/ if( pOther->Which() == nWhich ) +/*N*/ { +/*N*/ if( pOther->GetAttr() == pAttr->GetAttr() ) +/*N*/ { +/*N*/ bMerged = TRUE; +/*N*/ pPrev = pOther; +/*N*/ } +/*N*/ else +/*N*/ pPrev = NULL; +/*N*/ break; +/*N*/ } +/*N*/ if( pOther->IsCharFmtAttr() || pAttr->IsCharFmtAttr() ) +/*N*/ { +/*N*/ pPrev = NULL; +/*N*/ break; +/*N*/ } +/*N*/ } while ( j ); +/*N*/ } +/*N*/ if( pNext ) +/*N*/ { +/*N*/ j = i + 1; +/*N*/ pNext = NULL; +/*N*/ while( j < Count() ) +/*N*/ { +/*N*/ // Looking for a following attribute with the same which-id +/*N*/ // which starts at the end of the given attribute +/*N*/ SwTxtAttr *pOther = GetStart( j++ ); +/*N*/ pEnd = pOther->GetEnd(); +/*N*/ if( !pEnd || *pOther->GetStart() < nEnd ) +/*N*/ continue; +/*N*/ if( *pOther->GetStart() > nEnd ) +/*N*/ break; +/*N*/ if( pOther->Which() == nWhich ) +/*N*/ { +/*N*/ if( pOther->GetAttr() == pAttr->GetAttr() ) +/*N*/ { +/*N*/ bMerged = TRUE; +/*N*/ pNext = pOther; +/*N*/ } +/*N*/ else +/*N*/ pNext = NULL; +/*N*/ break; +/*N*/ } +/*?*/ if( pOther->IsCharFmtAttr() || pAttr->IsCharFmtAttr() ) +/*?*/ { +/*?*/ pNext = NULL; +/*?*/ break; +/*?*/ } +/*N*/ } +/*N*/ } +/*N*/ if( bMerged ) +/*N*/ { +/*N*/ if( pNext ) +/*N*/ { +/*N*/ if ( pPrev == pNext ) +/*N*/ pPrev = NULL; +/*N*/ +/*?*/ *pAttr->GetEnd() = *pNext->GetEnd(); +/*?*/ pAttr->SetDontExpand( FALSE ); +/*?*/ rNode.DestroyAttr( Cut( j - 1 ) ); +/*N*/ } +/*N*/ if( pPrev ) +/*N*/ { +/*N*/ *pPrev->GetEnd() = *pAttr->GetEnd(); +/*N*/ pPrev->SetDontExpand( FALSE ); +/*N*/ rNode.DestroyAttr( Cut( i ) ); +/*N*/ } +/*N*/ return TRUE; +/*N*/ } +/*N*/ return FALSE; +/*N*/ } +/*N*/ } +/*N*/ i = 0; +/*N*/ while ( i < Count() ) +/*N*/ { +/*N*/ SwTxtAttr *pHt = GetHt( i++ ); +/*N*/ const xub_StrLen *pEnd = pHt->GetEnd(); +/*N*/ if ( pEnd && !pHt->IsDontMergeAttr() ) +/*N*/ { +/*N*/ const USHORT nWhich = pHt->Which(); +/*N*/ for ( USHORT j = i; j < Count(); j++ ) +/*N*/ { +/*N*/ SwTxtAttr *pOther = GetHt(j); +/*N*/ if ( *pOther->GetStart() > *pEnd ) +/*N*/ break; // keine beruehrenden Attribute mehr vorhanden +/*N*/ +/*N*/ if( *pOther->GetStart() == *pEnd && +/*N*/ ( pOther->Which() == nWhich || +/*N*/ pOther->IsCharFmtAttr() || +/*N*/ ( pHt->IsCharFmtAttr() && !pHt->IsDontMergeAttr() ))) +/*N*/ { +/*?*/ // Beruehrendes Attribut gefunden mit gleichem Typ bzw. +/*?*/ // Zeichenvorlage. +/*?*/ // Bei Attribut mit anderem Wert bzw. Zeichenvorlage +/*?*/ // ist keine Verschmelzung mehr moeglich +/*?*/ if( pOther->Which() == nWhich && +/*?*/ pOther->GetAttr() == pHt->GetAttr() ) +/*?*/ { +/*?*/ // Unser Partner pOther erfuellt alle Voraussetzungen, +/*?*/ // jetzt muessen wir uns selbst noch ueberpruefen, ob wir +/*?*/ // nicht von einem gleichartigen Attribut oder einer +/*?*/ // Zeichenvorlage umfasst werden, die das gleiche Ende +/*?*/ // wie wir selbst haben. +/*?*/ BOOL bMerge = TRUE; +/*?*/ for ( USHORT k = 0; k+1 < i; k++ ) +/*?*/ { +/*?*/ SwTxtAttr *pAnOther = GetHt(k); +/*?*/ if( ( pAnOther->Which() == nWhich || +/*?*/ pAnOther->IsCharFmtAttr() || +/*?*/ pHt->IsCharFmtAttr() ) +/*?*/ && pAnOther->GetEnd() +/*?*/ && *pAnOther->GetEnd() == *pEnd ) +/*?*/ { +/*?*/ bMerge = FALSE; // kein Verschmelzen von i+j +/*?*/ break; +/*?*/ } +/*?*/ } +/*?*/ if ( bMerge ) +/*?*/ { +/*?*/ *pHt->GetEnd() = *pOther->GetEnd(); +/*?*/ pHt->SetDontExpand( FALSE ); +/*?*/ rNode.DestroyAttr( Cut( j ) ); +/*?*/ --i; +/*?*/ bMerged = TRUE; +/*?*/ } +/*?*/ } +/*?*/ break; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ if ( bMerged ) +/*?*/ ClearDummies( rNode ); +/*N*/ return bMerged; +/*N*/ } + +/************************************************************************* + * SwpHints::Forget( ... ) + *************************************************************************/ + +/* + * Forget: Hints, die genau den gleichen Bereich umfassen wie + * ein nachfolgender mit gleichem Attribut oder eine nachfolgende Zeichen- + * vorlage, duerfen nicht eingefuegt werden. + * Solche Hints koennen entstehen, wenn durch SwTxtNode::RstAttr + * ein Attribut in zwei Teile zerlegt wird und der zweite Teil einen + * identischen Bereich mit einem inneren Attribut bekaeme. + */ + +/************************************************************************* + * SwpHints::Insert() + *************************************************************************/ + +/* + * Insert: Der neue Hint wird immer eingefuegt. Wenn dabei ein + * ueberlappender oder gleicher Hintbereich mit gleichem Attribut + * und Wert gefunden, wird der neue Hint entsprechend veraendert + * und der alte herausgenommen (und zerstoert: + * SwpHints::Destroy()). + */ + +/*N*/ void SwpHints::Insert( SwTxtAttr *pHint, SwTxtNode &rNode, USHORT nMode ) +/*N*/ { +/*N*/ // Irgendwann ist immer Schluss +/*N*/ if( USHRT_MAX == Count() ) +/*N*/ return; +/*N*/ +/*N*/ // Felder bilden eine Ausnahme: +/*N*/ // 1) Sie koennen nie ueberlappen +/*N*/ // 2) Wenn zwei Felder genau aneinander liegen, +/*N*/ // sollen sie nicht zu einem verschmolzen werden. +/*N*/ // Wir koennen also auf die while-Schleife verzichten +/*N*/ +/*N*/ xub_StrLen *pHtEnd = pHint->GetEnd(); +/*N*/ USHORT nWhich = pHint->Which(); +/*N*/ +/*N*/ switch( nWhich ) +/*N*/ { +/*N*/ case RES_TXTATR_CHARFMT: +/*N*/ ((SwTxtCharFmt*)pHint)->ChgTxtNode( &rNode ); +/*N*/ break; +/*N*/ case RES_TXTATR_INETFMT: +/*N*/ { +/*N*/ ((SwTxtINetFmt*)pHint)->ChgTxtNode( &rNode ); +/*N*/ SwCharFmt* pFmt = rNode.GetDoc()->GetCharFmtFromPool( RES_POOLCHR_INET_NORMAL ); +/*N*/ pFmt->Add( (SwTxtINetFmt*)pHint ); +/*N*/ } +/*N*/ break; +/*N*/ case RES_TXTATR_FIELD: +/*N*/ { +/*N*/ BOOL bDelFirst = 0 != ((SwTxtFld*)pHint)->GetpTxtNode(); +/*N*/ ((SwTxtFld*)pHint)->ChgTxtNode( &rNode ); +/*N*/ SwDoc* pDoc = rNode.GetDoc(); +/*N*/ const SwField* pFld = ((SwTxtFld*)pHint)->GetFld().GetFld(); +/*N*/ +/*N*/ if( !pDoc->IsNewFldLst() ) +/*N*/ { +/*N*/ // was fuer ein Feld ist es denn ?? +/*N*/ // bestimmte Felder mussen am Doc das Calculations-Flag updaten +/*N*/ switch( pFld->GetTyp()->Which() ) +/*N*/ { +/*N*/ case RES_DBFLD: +/*N*/ case RES_SETEXPFLD: +/*N*/ case RES_HIDDENPARAFLD: +/*N*/ case RES_HIDDENTXTFLD: +/*N*/ case RES_DBNUMSETFLD: +/*N*/ case RES_DBNEXTSETFLD: +/*N*/ { +/*N*/ if( bDelFirst ) +/*?*/ pDoc->InsDelFldInFldLst( FALSE, *(SwTxtFld*)pHint ); +/*N*/ if( rNode.GetNodes().IsDocNodes() ) +/*N*/ pDoc->InsDelFldInFldLst( TRUE, *(SwTxtFld*)pHint ); +/*N*/ } +/*N*/ break; +/*?*/ case RES_DDEFLD: +/*?*/ if( rNode.GetNodes().IsDocNodes() ) +/*?*/ ((SwDDEFieldType*)pFld->GetTyp())->IncRefCnt(); +/*?*/ break; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ // gehts ins normale Nodes-Array? +/*N*/ if( rNode.GetNodes().IsDocNodes() ) +/*N*/ { +/*N*/ BOOL bInsFldType = FALSE; +/*N*/ switch( pFld->GetTyp()->Which() ) +/*N*/ { +/*N*/ case RES_SETEXPFLD: +/*N*/ bInsFldType = ((SwSetExpFieldType*)pFld->GetTyp())->IsDeleted(); +/*N*/ if( GSE_SEQ & ((SwSetExpFieldType*)pFld->GetTyp())->GetType() ) +/*N*/ { +/*N*/ // bevor die ReferenzNummer gesetzt wird, sollte +/*N*/ // das Feld am richtigen FeldTypen haengen! +/*N*/ SwSetExpFieldType* pFldType = (SwSetExpFieldType*) +/*N*/ pDoc->InsertFldType( *pFld->GetTyp() ); +/*N*/ if( pFldType != pFld->GetTyp() ) +/*N*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 SwFmtFld* pFmtFld = (SwFmtFld*)&((SwTxtFld*)pHint) +/*N*/ } +/*N*/ pFldType->SetSeqRefNo( *(SwSetExpField*)pFld ); +/*N*/ } +/*N*/ break; +/*N*/ case RES_USERFLD: +/*N*/ bInsFldType = ((SwUserFieldType*)pFld->GetTyp())->IsDeleted(); +/*N*/ break; +/*N*/ +/*N*/ case RES_DDEFLD: +/*N*/ if( pDoc->IsNewFldLst() ) +/*N*/ ((SwDDEFieldType*)pFld->GetTyp())->IncRefCnt(); +/*N*/ bInsFldType = ((SwDDEFieldType*)pFld->GetTyp())->IsDeleted(); +/*N*/ break; +/*N*/ } +/*N*/ if( bInsFldType ) +/*?*/ {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 pDoc->InsDeletedFldType( *pFld->GetTyp() ); +/*N*/ } +/*N*/ } +/*N*/ break; +/*N*/ case RES_TXTATR_FTN : +/*N*/ ((SwTxtFtn*)pHint)->ChgTxtNode( &rNode ); +/*N*/ break; +/*N*/ case RES_TXTATR_REFMARK: +/*N*/ ((SwTxtRefMark*)pHint)->ChgTxtNode( &rNode ); +/*N*/ if( rNode.GetNodes().IsDocNodes() ) +/*N*/ { +/*N*/ //search for a refernce with the same name +/*N*/ SwTxtAttr* pHt; + // redefinition of *pHtEnd shadows declaration at top of method + // usage within if stmt does NOT match usage above, also used again below switch/case... +/*N*/ xub_StrLen *pHtEnd, *pHintEnd; +/*N*/ for( USHORT n = 0, nEnd = Count(); n < nEnd; ++n ) +/*N*/ if( RES_TXTATR_REFMARK == (pHt = GetHt( n ))->Which() && +/*N*/ pHint->GetAttr() == pHt->GetAttr() && +/*N*/ 0 != ( pHtEnd = pHt->GetEnd() ) && +/*N*/ 0 != ( pHintEnd = pHint->GetEnd() ) ) +/*N*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 SwComparePosition eCmp = ::ComparePosition( +/*N*/ } +/*N*/ } +/*N*/ break; +/*N*/ case RES_TXTATR_TOXMARK: +/*N*/ ((SwTxtTOXMark*)pHint)->ChgTxtNode( &rNode ); +/*N*/ break; +/*N*/ +/*N*/ case RES_TXTATR_CJK_RUBY: +/*N*/ { + DBG_BF_ASSERT(0, "STRIP"); //STRIP001 /*?*/ ((SwTxtRuby*)pHint)->ChgTxtNode( &rNode ); +/*N*/ } +/*N*/ break; +/*N*/ } +/*N*/ +/*N*/ if( SETATTR_DONTEXPAND & nMode ) +/*N*/ pHint->SetDontExpand( TRUE ); +/*N*/ +/*N*/ // SwTxtAttrs ohne Ende werden sonderbehandelt: +/*N*/ // Sie werden natuerlich in das Array insertet, aber sie werden nicht +/*N*/ // in die pPrev/Next/On/Off-Verkettung aufgenommen. +/*N*/ // Der Formatierer erkennt diese TxtHints an dem CH_TXTATR_.. im Text ! +/*N*/ xub_StrLen nHtStart = *pHint->GetStart(); +/*N*/ if( !pHtEnd ) +/*N*/ { +/*N*/ SwpHintsArr::Insert( pHint ); +/*N*/ CalcFlags(); +/*N*/ #ifdef DBG_UTIL +/*N*/ if( !rNode.GetDoc()->IsInReading() ) +/*N*/ CHECK; +/*N*/ #endif +/*N*/ // ... und die Abhaengigen benachrichtigen +/*N*/ if ( rNode.GetDepends() ) +/*N*/ { +/*N*/ SwUpdateAttr aHint( nHtStart, nHtStart, nWhich ); +/*N*/ rNode.Modify( 0, &aHint ); +/*N*/ } +/*N*/ return; +/*N*/ } +/*N*/ +/*N*/ // ---------------------------------------------------------------- +/*N*/ // Ab hier gibt es nur noch pHint mit einem EndIdx !!! +/*N*/ +/*N*/ SwTxtAttr *pMerge = pHint; // For a smarter Merge-function +/*N*/ +/*N*/ BOOL bResort = FALSE; +/*N*/ +/*N*/ if( *pHtEnd < nHtStart ) +/*N*/ { +/*?*/ ASSERT( *pHtEnd >= nHtStart, +/*?*/ "+SwpHints::Insert: invalid hint, end < start" ); +/*?*/ +/*?*/ // Wir drehen den Quatsch einfach um: +/*?*/ *pHint->GetStart() = *pHtEnd; +/*?*/ *pHtEnd = nHtStart; +/*?*/ nHtStart = *pHint->GetStart(); +/*N*/ } +/*N*/ +/*N*/ // AMA: Damit wir endlich mit ueberlappenden Hints fertig werden ... +/*N*/ // das neue Verfahren: +/*N*/ +/*N*/ if( !(SETATTR_NOHINTADJUST & nMode) && !pHint->IsOverlapAllowedAttr() ) +/*N*/ { +/*N*/ const SfxPoolItem* pParaItem; +/*N*/ xub_StrLen nMaxEnd = *pHtEnd; +/*N*/ xub_StrLen nHtEnd = *pHtEnd; +/*N*/ BOOL bParaAttr = rNode.GetpSwAttrSet() && +/*N*/ ( SFX_ITEM_SET == rNode.GetpSwAttrSet()->GetItemState( nWhich, +/*N*/ FALSE, &pParaItem ) ) && ( pParaItem == &pHint->GetAttr() ); +/*N*/ BOOL bReplace = !( SETATTR_DONTREPLACE & nMode ); +/*N*/ ::binfilter::SwpHtStart_SAR *pTmpHints = 0; +/*N*/ +/*N*/ USHORT i; +/*N*/ // Wir wollen zwar von nHtStart bis nMaxEnd, muessen aber ggf. +/*N*/ // stueckeln (Attribute duerfen keine Zeichenvorlagen ueberlappen). +/*N*/ // Das erste Stueck wird also von nHtStart bis zum ersten Start/Ende +/*N*/ // einer Zeichenvorlage gehen usw. bis nHtEnd = nMaxEnd erreicht ist. +/*N*/ do { +/*N*/ BOOL bINet = nWhich == RES_TXTATR_INETFMT; +/*N*/ BOOL bForgetAttr = bParaAttr; +/*N*/ // Muessen wir uns aufspalten? +/*N*/ if ( !bINet && !pHint->IsDontMergeAttr() ) +/*N*/ { +/*N*/ // Ab der zweiten Runde muessen wir zunaechst einen neuen +/*N*/ // Hint erzeugen. +/*N*/ if ( nHtEnd != nMaxEnd ) +/*N*/ { +/*?*/ pMerge = NULL; // No way to use the smarter Merge() +/*?*/ pHint = rNode.MakeTxtAttr( bParaAttr ? *pParaItem : +/*?*/ pHint->GetAttr(), +/*?*/ nHtStart, nMaxEnd ); +/*?*/ nHtEnd = *pHint->GetEnd(); +/*N*/ } +/*N*/ +/*N*/ for ( i = 0; i < Count(); i++) +/*N*/ { +/*N*/ SwTxtAttr *pOther = GetHt(i); +/*N*/ // Wir suchen nach Zeichenvorlagen, die uns schneiden +/*N*/ // oder in uns liegen +/*N*/ BOOL bOtherFmt = pOther->IsCharFmtAttr(); +/*N*/ if( bOtherFmt || +/*N*/ ( RES_TXTATR_CHARFMT == nWhich && pOther->GetEnd() ) ) +/*N*/ { +/*N*/ if( bForgetAttr && bOtherFmt && +/*N*/ *pOther->GetStart() <= nHtStart && +/*N*/ *pOther->GetEnd() >= nHtStart ) +/*N*/ bForgetAttr = FALSE; + /* Die Flags bCheckInclude und bOtherFmt sollen die + * Anzahl der Aufrufe von lcl_Include minimieren, da + * dieses wg. IsVisitedURL() teuer ist. */ +/*N*/ BOOL bCheckInclude = FALSE; +/*N*/ if( *pOther->GetStart() > nHtStart +/*N*/ && *pOther->GetStart() < nHtEnd +/*N*/ && ( bReplace || *pOther->GetEnd() > nHtEnd ) ) +/*N*/ { +/*?*/ if( !bOtherFmt ) +/*?*/ { + DBG_BF_ASSERT(0, "STRIP"); //STRIP001 /*?*/ bOtherFmt = !lcl_Included( pOther->Which(), +/*?*/ } +/*?*/ if( bOtherFmt ) +/*?*/ nHtEnd = *pOther->GetStart(); +/*N*/ } +/*N*/ if( *pOther->GetEnd() > nHtStart +/*N*/ && *pOther->GetEnd() < nHtEnd +/*N*/ && ( bReplace || *pOther->GetStart() < nHtStart ) ) +/*N*/ { +/*?*/ if( bOtherFmt || ( !bCheckInclude && +/*?*/ !lcl_Included( pOther->Which(), pHint ) ) ) +/*?*/ nHtEnd = *pOther->GetEnd(); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ *pHint->GetEnd() = nHtEnd; +/*N*/ } +/*N*/ +/*N*/ i = 0; +/*N*/ while(i < Count()) +/*N*/ { +/*N*/ SwTxtAttr *pOther = GetHt(i); +/*N*/ const USHORT nOtherWhich = pOther->Which(); +/*N*/ BOOL bCheckInclude = pHint->IsCharFmtAttr() && +/*N*/ pOther->IsCharFmtAttr() && +/*N*/ nWhich != nOtherWhich; +/*N*/ +/*N*/ BOOL bOtherCharFmt = RES_TXTATR_CHARFMT == nOtherWhich; +/*N*/ if( nOtherWhich == nWhich || bCheckInclude ) +/*N*/ { +/*N*/ if(0 == pOther->GetEnd()) +/*N*/ { +/*?*/ if( *pOther->GetStart() == nHtStart && +/*?*/ nOtherWhich == nWhich && +/*?*/ pOther->GetAttr() == pHint->GetAttr() ) +/*?*/ { +/*?*/ // Gibts schon, alten raus. +/*?*/ rNode.DestroyAttr( Cut(i) ); +/*?*/ } +/*?*/ else +/*?*/ ++i; +/*?*/ continue; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ // Attribute mit Anfang und Ende. +/*N*/ const Range aHintRg( nHtStart, nHtEnd ); +/*N*/ const Range aOtherRg( *pOther->GetStart(), +/*N*/ *pOther->GetEnd() ); +/*N*/ +/*N*/ if( aOtherRg.IsInside( aHintRg.Min() ) || +/*N*/ aHintRg.IsInside( aOtherRg.Min() ) ) +/*N*/ { +/*N*/ // aBig umspannt beide Ranges +/*N*/ const Range aBig( +/*N*/ Min( aHintRg.Min(), aOtherRg.Min()), +/*N*/ Max( aHintRg.Max(), aOtherRg.Max())); +/*N*/ +/*N*/ // Gleiches Attribut +/*N*/ // oder Zeichenvorlage: +/*N*/ // Bereiche duerfen nicht ueberlappen. +/*N*/ +/*N*/ // Zuerst wurde geprueft, ob sich der neue mit dem +/*N*/ // alten ueberschneidet, danach gibt es nur noch +/*N*/ // drei Faelle zu beachten: +/*N*/ // 1) der neue umschliesst den alten +/*N*/ // 2) der neue ueberlappt den alten hinten +/*N*/ // 3) der neue ueberlappt den alten vorne +/*N*/ +/*N*/ BOOL bNoINet = RES_TXTATR_INETFMT != nOtherWhich || +/*N*/ nWhich == nOtherWhich; +/*N*/ +/*N*/ // 1) der neue umschliesst den alten +/*N*/ if( aBig == aHintRg ) +/*N*/ { +/*N*/ BOOL bTmpReplace = bReplace || +/*N*/ ( aHintRg == aOtherRg && +/*N*/ nWhich == nOtherWhich && +/*N*/ !pHint->IsCharFmtAttr() ); +/*N*/ if( bNoINet && bTmpReplace && +/*N*/ ( !bOtherCharFmt || nWhich == nOtherWhich ) ) +/*N*/ { +/*N*/ if( !bCheckInclude || +/*N*/ lcl_Included( nOtherWhich, pHint ) ) +/*N*/ { +/*N*/ rNode.DestroyAttr( Cut(i) ); +/*N*/ } +/*N*/ else +/*N*/ ++i; +/*N*/ continue; +/*N*/ } +/*N*/ } +/*N*/ else if( !bReplace && aBig == aOtherRg ) +/*?*/ bForgetAttr = FALSE; +/*N*/ // 2) der neue ueberlappt hinten +/*N*/ else if( aBig.Max() == aHintRg.Max() ) +/*N*/ { +/*N*/ if( bNoINet && +/*N*/ ( !bOtherCharFmt || RES_TXTATR_CHARFMT != nWhich ) && +/*N*/ ( bReplace || aHintRg.Max() != aOtherRg.Max() ) ) +/*N*/ { +/*N*/ if( ( bCheckInclude && +/*N*/ lcl_Included( nOtherWhich, pHint ) ) || +/*N*/ ( !bCheckInclude && !bOtherCharFmt ) ) +/*N*/ { +/*N*/ if( nMaxEnd == nHtStart ) +/*N*/ bForgetAttr = FALSE; +/*N*/ *pOther->GetEnd() = nHtStart; +/*N*/ bResort = TRUE; +/*N*/ // ChainDelEnd( pOther ); +/*N*/ // ChainEnds( pOther ); +/*N*/ } +/*N*/ else if( bINet && +/*N*/ aHintRg.Max() != aOtherRg.Max() && +/*N*/ aHintRg.Min() < aOtherRg.Max() ) +/*N*/ { +/*N*/ // Wenn ein INetFmt eingefuegt wird, muss +/*N*/ // sich ein anderes Attribut ggf. aufspal- +/*N*/ // ten. Es wird beiseite gestellt und in +/*N*/ // einem spaeteren Durchgang eingefuegt. +/*N*/ // Beim Einfuegen spaltet es sich selbst. +/*?*/ if( !pTmpHints ) +/*?*/ pTmpHints = new ::binfilter::SwpHtStart_SAR(); +/*?*/ pTmpHints->C40_INSERT( SwTxtAttr, pOther, +/*?*/ pTmpHints->Count() ); +/*?*/ Cut( i ); +/*?*/ continue; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ // 3) der neue ueberlappt vorne +/*N*/ else if( aBig.Min() == aHintRg.Min() ) +/*N*/ { +/*N*/ if( bNoINet && +/*N*/ ( RES_TXTATR_CHARFMT != nOtherWhich || +/*N*/ RES_TXTATR_CHARFMT != nWhich ) && +/*N*/ ( bReplace || aHintRg.Min() != aOtherRg.Min() ) ) +/*N*/ { +/*N*/ if( ( bCheckInclude && +/*N*/ lcl_Included( nOtherWhich, pHint ) ) || +/*N*/ ( !bCheckInclude && !bOtherCharFmt ) ) +/*N*/ { +/*N*/ +/*N*/ *pOther->GetStart() = nHtEnd; +/*N*/ +/*N*/ // ChainDelStart( pOther ); +/*N*/ // ChainStarts( pOther ); +/*N*/ +/*N*/ const BOOL bOk = Resort(i); +/*N*/ if( bOk ) +/*N*/ continue; +/*N*/ } +/*N*/ else if( bINet && +/*N*/ aHintRg.Min() != aOtherRg.Min() && +/*N*/ aHintRg.Max() > aOtherRg.Min() ) +/*N*/ { +/*?*/ // Wenn ein INetFmt eingefuegt wird, muss +/*?*/ // sich ein anderes Attribut ggf. aufspal- +/*?*/ // ten. Es wird beiseite gestellt und in +/*?*/ // einem spaeteren Durchgang eingefuegt. +/*?*/ // Beim Einfuegen spaltet es sich selbst. +/*?*/ if( !pTmpHints ) +/*?*/ pTmpHints = new ::binfilter::SwpHtStart_SAR(); +/*?*/ pTmpHints->C40_INSERT( SwTxtAttr, pOther, +/*?*/ pTmpHints->Count() ); +/*?*/ Cut( i ); +/*?*/ continue; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ bForgetAttr = FALSE; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ ++i; +/*N*/ } +/*N*/ +/*N*/ ClearDummies( rNode ); +/*N*/ // Nur wenn wir nicht sowieso schon durch die Absatzattribute +/*N*/ // gueltig sind, werden wir eingefuegt ... +/*N*/ if( bForgetAttr ) +/*N*/ { +/*?*/ rNode.DestroyAttr( pHint ); +/*?*/ pMerge = NULL; // No smart Merge() +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ SwpHintsArr::Insert( pHint ); +/*N*/ bResort = FALSE; +/*N*/ } +/*N*/ // InsertChain( pHint ); +/*N*/ +/*N*/ // ... und die Abhaengigen benachrichtigen +/*N*/ if ( rNode.GetDepends() ) +/*N*/ { +/*N*/ SwUpdateAttr aHint( nHtStart, nHtEnd, nWhich ); +/*N*/ rNode.Modify( 0, &aHint ); +/*N*/ } +/*N*/ // Falls es noch 'ne Runde gibt: +/*N*/ nHtStart = nHtEnd; +/*N*/ if( nMaxEnd > nHtEnd ) +/*N*/ continue; +/*N*/ if( !pTmpHints ) +/*N*/ break; +/*?*/ pMerge = NULL; // No smart Merge() +/*?*/ pHint = pTmpHints->GetObject(0); +/*?*/ nWhich = pHint->Which(); +/*?*/ nHtStart = *pHint->GetStart(); +/*?*/ nHtEnd = *pHint->GetEnd(); +/*?*/ nMaxEnd = nHtEnd; +/*?*/ bParaAttr = FALSE; +/*?*/ pTmpHints->Remove(0); +/*?*/ if( !pTmpHints->Count() ) +/*?*/ { +/*?*/ delete pTmpHints; +/*?*/ pTmpHints = NULL; +/*?*/ } +/*N*/ } while ( TRUE ); +/*N*/ +/*N*/ if( bResort ) +/*?*/ SwpHintsArr::Resort(); +/*N*/ +/*N*/ // Jetzt wollen wir mal gucken, ob wir das SwpHintsArray nicht +/*N*/ // etwas vereinfachen koennen ... +/*N*/ Merge( rNode, pMerge ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ SwpHintsArr::Insert( pHint ); +/*N*/ // InsertChain( pHint ); +/*N*/ +/*N*/ // ... und die Abhaengigen benachrichtigen +/*N*/ if ( rNode.GetDepends() ) +/*N*/ { +/*N*/ SwUpdateAttr aHint( nHtStart, +/*N*/ nHtStart == *pHtEnd ? *pHtEnd + 1 : *pHtEnd, nWhich ); +/*N*/ rNode.Modify( 0, &aHint ); +/*N*/ } +/*N*/ } +/*N*/ #ifdef DBG_UTIL +/*N*/ if( !rNode.GetDoc()->IsInReading() ) +/*N*/ CHECK; +/*N*/ #endif +/*N*/ } + +/************************************************************************* + * SwpHints::DeleteAtPos() + *************************************************************************/ + +/*N*/ void SwpHints::DeleteAtPos( const USHORT nPos ) +/*N*/ { +/*N*/ SwTxtAttr *pHint = GetHt(nPos); +/*N*/ // ChainDelete( pHint ); +/*N*/ SwpHintsArr::DeleteAtPos( nPos ); +/*N*/ +/*N*/ if( RES_TXTATR_FIELD == pHint->Which() ) +/*N*/ { +/*N*/ SwFieldType* pFldTyp = ((SwTxtFld*)pHint)->GetFld().GetFld()->GetTyp(); +/*N*/ if( RES_DDEFLD == pFldTyp->Which() ) +/*N*/ { +/*?*/ const SwTxtNode* pNd = ((SwTxtFld*)pHint)->GetpTxtNode(); +/*?*/ if( pNd && pNd->GetNodes().IsDocNodes() ) +/*?*/ ((SwDDEFieldType*)pFldTyp)->DecRefCnt(); +/*?*/ ((SwTxtFld*)pHint)->ChgTxtNode( 0 ); +/*N*/ } +/*N*/ else if( !bVis && RES_HIDDENPARAFLD == pFldTyp->Which() ) +/*N*/ bCalcVis = TRUE; +/*N*/ } +/*N*/ CalcFlags(); +/*N*/ CHECK; +/*N*/ } + +// Ist der Hint schon bekannt, dann suche die Position und loesche ihn. +// Ist er nicht im Array, so gibt es ein ASSERT !! + +/*N*/ void SwpHints::Delete( SwTxtAttr* pTxtHt ) +/*N*/ { +/*N*/ // Attr 2.0: SwpHintsArr::Delete( pTxtHt ); +/*N*/ const USHORT nPos = GetStartOf( pTxtHt ); +/*N*/ ASSERT( USHRT_MAX != nPos, "Attribut nicht im Attribut-Array!" ); +/*N*/ if( USHRT_MAX != nPos ) +/*N*/ DeleteAtPos( nPos ); +/*N*/ } + +/*N*/ #ifdef VERTICAL_LAYOUT +/*N*/ USHORT SwTxtNode::GetLang( const xub_StrLen nBegin, const xub_StrLen nLen, +/*N*/ USHORT nScript ) const +/*N*/ #else +/*N*/ USHORT SwTxtNode::GetLang( const xub_StrLen nBegin, const xub_StrLen nLen) const +/*N*/ #endif +/*N*/ { +/*N*/ USHORT nWhichId = RES_CHRATR_LANGUAGE; +/*N*/ USHORT nRet = LANGUAGE_DONTKNOW; +/*N*/ if( pSwpHints ) +/*N*/ { +/*N*/ #ifdef VERTICAL_LAYOUT +/*N*/ if ( ! nScript ) +/*N*/ nScript = pBreakIt->GetRealScriptOfText( aText, nBegin ); +/*N*/ +/*N*/ nWhichId = GetWhichOfScript( nWhichId, nScript ); +/*N*/ #else +/*N*/ nWhichId = GetWhichOfScript( nWhichId, +/*N*/ pBreakIt->GetRealScriptOfText( aText, nBegin )); +/*N*/ #endif +/*N*/ +/*N*/ xub_StrLen nEnd = nBegin + nLen; +/*N*/ for( USHORT i = 0, nSize = pSwpHints->Count(); i < nSize; ++i ) +/*N*/ { +/*N*/ // ist der Attribut-Anfang schon groesser als der Idx ? +/*N*/ const SwTxtAttr *pHt = pSwpHints->operator[](i); +/*N*/ xub_StrLen nAttrStart = *pHt->GetStart(); +/*N*/ if( nEnd < nAttrStart ) +/*N*/ break; +/*N*/ +/*N*/ const USHORT nWhich = pHt->Which(); +/*N*/ +/*N*/ if( ( pHt->IsCharFmtAttr() && lcl_Included( nWhichId, pHt ) ) +/*N*/ || nWhichId == nWhich ) +/*N*/ { +/*N*/ const xub_StrLen *pEndIdx = pHt->GetEnd(); +/*N*/ // Ueberlappt das Attribut den Bereich? +/*N*/ +/*N*/ if( pEndIdx && +/*N*/ nLen ? ( nAttrStart < nEnd && nBegin < *pEndIdx ) +/*N*/ : (( nAttrStart < nBegin && +/*N*/ ( pHt->DontExpand() ? nBegin < *pEndIdx +/*N*/ : nBegin <= *pEndIdx )) || +/*N*/ ( nBegin == nAttrStart && +/*N*/ ( nAttrStart == *pEndIdx || !nBegin ))) ) +/*N*/ { +/*N*/ const SfxPoolItem* pItem; +/*N*/ if( RES_TXTATR_CHARFMT == nWhich ) +/*N*/ pItem = &pHt->GetCharFmt().GetCharFmt()->GetAttr( nWhichId ); +/*N*/ else if( RES_TXTATR_INETFMT == nWhich ) +/*?*/ pItem = &((SwTxtINetFmt*)pHt)->GetCharFmt()->GetAttr( nWhichId ); +/*N*/ else +/*N*/ pItem = &pHt->GetAttr(); +/*N*/ +/*N*/ USHORT nLng = ((SvxLanguageItem*)pItem)->GetLanguage(); +/*N*/ +/*N*/ // Umfasst das Attribut den Bereich komplett? +/*N*/ if( nAttrStart <= nBegin && nEnd <= *pEndIdx ) +/*N*/ nRet = nLng; +/*N*/ else if( LANGUAGE_DONTKNOW == nRet ) +/*N*/ nRet = nLng; // partielle Ueberlappung, der 1. gewinnt +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ if( LANGUAGE_DONTKNOW == nRet ) +/*N*/ { +/*N*/ if( !pSwpHints ) +/*N*/ nWhichId = GetWhichOfScript( RES_CHRATR_LANGUAGE, +/*N*/ pBreakIt->GetRealScriptOfText( aText, nBegin )); +/*N*/ +/*N*/ nRet = ((SvxLanguageItem&)GetSwAttrSet().Get( nWhichId )).GetLanguage(); +/*N*/ if( LANGUAGE_DONTKNOW == nRet ) +/*N*/ nRet = GetAppLanguage(); +/*N*/ } +/*N*/ return nRet; +/*N*/ } + +/*N*/ sal_Unicode GetCharOfTxtAttr( const SwTxtAttr& rAttr ) +/*N*/ { +/*N*/ sal_Unicode cRet = CH_TXTATR_BREAKWORD; +/*N*/ switch ( rAttr.Which() ) +/*N*/ { +/*N*/ case RES_TXTATR_REFMARK: +/*N*/ case RES_TXTATR_TOXMARK: +/*N*/ +/*N*/ // case RES_TXTATR_FIELD: ?????? +/*N*/ // case RES_TXTATR_FLYCNT, // 29 +/*N*/ +/*N*/ case RES_TXTATR_FTN: +/*N*/ cRet = CH_TXTATR_INWORD; +/*N*/ break; +/*N*/ +/*N*/ // depends on the character ?? +/*N*/ // case RES_TXTATR_HARDBLANK: +/*N*/ // cRet = CH_TXTATR_INWORD; +/*N*/ // break; +/*N*/ } +/*N*/ return cRet; +/*N*/ } + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/txtnode/sw_txatbase.cxx b/binfilter/bf_sw/source/core/txtnode/sw_txatbase.cxx new file mode 100644 index 000000000000..04477fa64732 --- /dev/null +++ b/binfilter/bf_sw/source/core/txtnode/sw_txatbase.cxx @@ -0,0 +1,76 @@ +/* -*- 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. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include <bf_svtools/itempool.hxx> +#include <txatbase.hxx> +namespace binfilter { + +/*N*/ SwTxtAttr::SwTxtAttr( const SfxPoolItem& rAttr, xub_StrLen nStt ) +/*N*/ : pAttr( &rAttr ), nStart( nStt ) +/*N*/ { +/*N*/ bDontExpand = bLockExpandFlag = bDontMergeAttr = bDontMoveAttr = +/*N*/ bCharFmtAttr = bOverlapAllowedAttr = bPriorityAttr = +/*N*/ bDontExpandStart = FALSE; +/*N*/ } + +/*N*/ SwTxtAttr::~SwTxtAttr( ) +/*N*/ { +/*N*/ } + +/*N*/ xub_StrLen* SwTxtAttr::GetEnd() +/*N*/ { +/*N*/ return 0; +/*N*/ } + + // RemoveFromPool muss immer vorm DTOR Aufruf erfolgen!! + // Meldet sein Attribut beim Pool ab +/*N*/ void SwTxtAttr::RemoveFromPool( SfxItemPool& rPool ) +/*N*/ { +/*N*/ rPool.Remove( GetAttr() ); +/*N*/ pAttr = 0; +/*N*/ } + + +/*N*/ SwTxtAttrEnd::SwTxtAttrEnd( const SfxPoolItem& rAttr, xub_StrLen nS, +/*N*/ xub_StrLen nE ) +/*N*/ : SwTxtAttr( rAttr, nS ), nEnd( nE ) +/*N*/ { +/*N*/ } + +/*N*/ xub_StrLen* SwTxtAttrEnd::GetEnd() +/*N*/ { +/*N*/ return &nEnd; +/*N*/ } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/txtnode/sw_txtatr2.cxx b/binfilter/bf_sw/source/core/txtnode/sw_txtatr2.cxx new file mode 100644 index 000000000000..89f5f1abfc7a --- /dev/null +++ b/binfilter/bf_sw/source/core/txtnode/sw_txtatr2.cxx @@ -0,0 +1,218 @@ +/* -*- 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. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include <hintids.hxx> +#include <txtinet.hxx> +#include <txtatr.hxx> +#include <fchrfmt.hxx> +#include <fmtinfmt.hxx> +#include <charfmt.hxx> +#include <ndtxt.hxx> // SwCharFmt, SwTxtNode +#include <hints.hxx> // SwCharFmt, SwUpdateAttr +#include <poolfmt.hxx> // RES_POOLCHR_INET_... + +#include <horiornt.hxx> + +#include <doc.hxx> // SwDoc +namespace binfilter { + + +/************************************************************************* + * class SwTxtHardBlank + *************************************************************************/ + + + +/************************************************************************* + * class SwTxtCharFmt + *************************************************************************/ + +/*N*/ SwTxtCharFmt::SwTxtCharFmt( const SwFmtCharFmt& rAttr, +/*N*/ xub_StrLen nStartIn, xub_StrLen nEndIn ) +/*N*/ : SwTxtAttrEnd( rAttr, nStartIn, nEndIn ), +/*N*/ pMyTxtNd( 0 ) +/*N*/ { +/*N*/ ((SwFmtCharFmt&)rAttr).pTxtAttr = this; +/*N*/ SetCharFmtAttr( TRUE ); +/*N*/ } + +/*N*/ SwTxtCharFmt::~SwTxtCharFmt( ) +/*N*/ { +/*N*/ } + +/*N*/ void SwTxtCharFmt::Modify( SfxPoolItem* pOld, SfxPoolItem* pNew ) +/*N*/ { +/*N*/ USHORT nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0; +/*N*/ #ifdef DBG_UTIL +/*N*/ if ( (nWhich<RES_CHRATR_BEGIN || nWhich>RES_CHRATR_END) +/*N*/ && (nWhich!=RES_OBJECTDYING) +/*N*/ && (nWhich!=RES_ATTRSET_CHG) +/*N*/ && (nWhich!=RES_FMT_CHG) ) +/*N*/ ASSERT(!this, "SwTxtCharFmt::Modify(): unbekanntes Modify!"); +/*N*/ #endif +/*N*/ +/*N*/ if( pMyTxtNd ) +/*N*/ { +/*N*/ SwUpdateAttr aUpdateAttr( *GetStart(), *GetEnd(), nWhich ); +/*N*/ pMyTxtNd->SwCntntNode::Modify( &aUpdateAttr, &aUpdateAttr ); +/*N*/ } +/*N*/ } + + // erfrage vom Modify Informationen +/*N*/ BOOL SwTxtCharFmt::GetInfo( SfxPoolItem& rInfo ) const +/*N*/ { +/*N*/ if( RES_AUTOFMT_DOCNODE != rInfo.Which() || !pMyTxtNd || +/*N*/ &pMyTxtNd->GetNodes() != ((SwAutoFmtGetDocNode&)rInfo).pNodes ) +/*N*/ return TRUE; +/*N*/ +/*N*/ ((SwAutoFmtGetDocNode&)rInfo).pCntntNode = pMyTxtNd; +/*N*/ return FALSE; +/*N*/ } + +/************************************************************************* + * class SwTxtINetFmt + *************************************************************************/ + +/*N*/ SwTxtINetFmt::SwTxtINetFmt( const SwFmtINetFmt& rAttr, +/*N*/ xub_StrLen nStartIn, xub_StrLen nEndIn ) +/*N*/ : SwTxtAttrEnd( rAttr, nStartIn, nEndIn ), +/*N*/ SwClient( 0 ), +/*N*/ pMyTxtNd( 0 ) +/*N*/ { +/*N*/ bValidVis = FALSE; +/*N*/ ((SwFmtINetFmt&)rAttr).pTxtAttr = this; +/*N*/ SetCharFmtAttr( TRUE ); +/*N*/ } + +/*N*/ SwTxtINetFmt::~SwTxtINetFmt( ) +/*N*/ { +/*N*/ } + +/*N*/ SwCharFmt* SwTxtINetFmt::GetCharFmt() +/*N*/ { +/*N*/ const SwFmtINetFmt& rFmt = SwTxtAttrEnd::GetINetFmt(); +/*N*/ SwCharFmt* pRet = NULL; +/*N*/ +/*N*/ if( rFmt.GetValue().Len() ) +/*N*/ { +/*N*/ const SwDoc* pDoc = GetTxtNode().GetDoc(); +/*N*/ if( !IsValidVis() ) +/*N*/ { +/*N*/ SetVisited( pDoc->IsVisitedURL( rFmt.GetValue() ) ); +/*N*/ SetValidVis( TRUE ); +/*N*/ } +/*N*/ USHORT nId; +/*N*/ const String& rStr = IsVisited() ? rFmt.GetVisitedFmt() +/*N*/ : rFmt.GetINetFmt(); +/*N*/ if( rStr.Len() ) +/*N*/ nId = IsVisited() ? rFmt.GetVisitedFmtId() : rFmt.GetINetFmtId(); +/*N*/ else +/*N*/ nId = IsVisited() ? RES_POOLCHR_INET_VISIT : RES_POOLCHR_INET_NORMAL; +/*N*/ +/*N*/ // JP 10.02.2000, Bug 72806: dont modify the doc for getting the +/*N*/ // correct charstyle. +/*N*/ BOOL bResetMod = !pDoc->IsModified(); +/*N*/ Link aOle2Lnk; +/*N*/ if( bResetMod ) +/*N*/ { +/*N*/ aOle2Lnk = pDoc->GetOle2Link(); +/*N*/ ((SwDoc*)pDoc)->SetOle2Link( Link() ); +/*N*/ } +/*N*/ +/*N*/ pRet = IsPoolUserFmt( nId ) +/*N*/ ? ((SwDoc*)pDoc)->FindCharFmtByName( rStr ) +/*N*/ : ((SwDoc*)pDoc)->GetCharFmtFromPool( nId ); +/*N*/ +/*N*/ if( bResetMod ) +/*N*/ { +/*N*/ ((SwDoc*)pDoc)->ResetModified(); +/*N*/ ((SwDoc*)pDoc)->SetOle2Link( aOle2Lnk ); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if( pRet ) +/*N*/ pRet->Add( this ); +/*N*/ else if( GetRegisteredIn() ) +/*N*/ pRegisteredIn->Remove( this ); +/*N*/ +/*N*/ return pRet; +/*N*/ } + +/*N*/ void SwTxtINetFmt::Modify( SfxPoolItem* pOld, SfxPoolItem* pNew ) +/*N*/ { +/*N*/ USHORT nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0; +/*N*/ #ifdef DBG_UTIL +/*N*/ if ( (nWhich<RES_CHRATR_BEGIN || nWhich>RES_CHRATR_END) +/*N*/ && (nWhich!=RES_OBJECTDYING) +/*N*/ && (nWhich!=RES_ATTRSET_CHG) +/*N*/ && (nWhich!=RES_FMT_CHG) ) +/*N*/ ASSERT(!this, "SwTxtCharFmt::Modify(): unbekanntes Modify!"); +/*N*/ #endif +/*N*/ +/*N*/ if( pMyTxtNd ) +/*N*/ { +/*N*/ SwUpdateAttr aUpdateAttr( *GetStart(), *GetEnd(), nWhich ); +/*N*/ pMyTxtNd->SwCntntNode::Modify( &aUpdateAttr, &aUpdateAttr ); +/*N*/ } +/*N*/ } + + // erfrage vom Modify Informationen +/*N*/ BOOL SwTxtINetFmt::GetInfo( SfxPoolItem& rInfo ) const +/*N*/ { +/*N*/ if( RES_AUTOFMT_DOCNODE != rInfo.Which() || !pMyTxtNd || +/*N*/ &pMyTxtNd->GetNodes() != ((SwAutoFmtGetDocNode&)rInfo).pNodes ) +/*N*/ return TRUE; +/*N*/ +/*N*/ ((SwAutoFmtGetDocNode&)rInfo).pCntntNode = pMyTxtNd; +/*N*/ return FALSE; +/*N*/ } + + +// ATT_XNLCONTAINERITEM ****************************** + + + + +// ****************************** + + + + + + +// ****************************** + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/txtnode/sw_txtedt.cxx b/binfilter/bf_sw/source/core/txtnode/sw_txtedt.cxx new file mode 100644 index 000000000000..cf73888ca8ba --- /dev/null +++ b/binfilter/bf_sw/source/core/txtnode/sw_txtedt.cxx @@ -0,0 +1,396 @@ +/* -*- 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. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + + +// So kann man die Linguistik-Statistik ( (Tmp-Path)\swlingu.stk ) aktivieren: +//#define LINGU_STATISTIK +#ifdef LINGU_STATISTIK + #include <stdio.h> // in SwLinguStatistik::DTOR + #include <stdlib.h> // getenv() + #include <time.h> // clock() +#endif + +#include <hintids.hxx> + +#include <vcl/svapp.hxx> +#include <bf_svx/langitem.hxx> +#include <bf_svx/scripttypeitem.hxx> +#include <com/sun/star/i18n/WordType.hdl> +#include <com/sun/star/i18n/ScriptType.hdl> + +#include <acmplwrd.hxx> + +#include <horiornt.hxx> + +#include <doc.hxx> // GetDoc() +#include <txatbase.hxx> +#include <hints.hxx> +#include <ndtxt.hxx> +#include <txtfrm.hxx> +#include <wrong.hxx> +#include <breakit.hxx> +#include <drawfont.hxx> // SwDrawTextInfo +namespace binfilter { + +using namespace ::com::sun::star; +using namespace ::com::sun::star::i18n; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::linguistic2; + +#define C2U(cChar) ::rtl::OUString::createFromAscii(cChar) + +// Wir ersparen uns in Hyphenate ein GetFrm() +// Achtung: in edlingu.cxx stehen die Variablen! +extern const SwTxtNode *pLinguNode; +extern SwTxtFrm *pLinguFrm; + +bool lcl_IsSkippableWhiteSpace( xub_Unicode cCh ) +{ + return 0x3000 == cCh || + ' ' == cCh || + '\t' == cCh || + 0x0a == cCh; +} + +/* + * Ein Zeichen wurde eingefuegt. + */ + +/*N*/ SwTxtNode& SwTxtNode::Insert( xub_Unicode c, const SwIndex &rIdx ) +/*N*/ { +/*N*/ xub_StrLen nOrigLen = aText.Len(); +/*N*/ +/*N*/ ASSERT( rIdx <= nOrigLen, "Array ueberindiziert." ); +/*N*/ ASSERT( nOrigLen < STRING_LEN, "USHRT_MAX ueberschritten." ); +/*N*/ +/*N*/ if( nOrigLen == aText.Insert( c, rIdx.GetIndex() ).Len() ) +/*N*/ return *this; +/*N*/ +/*N*/ Update(rIdx,1); +/*N*/ +/*N*/ // leere Hints und Feldattribute an rIdx.GetIndex suchen +/*N*/ if( pSwpHints ) +/*N*/ { +/*N*/ USHORT* pEndIdx; +/*N*/ for( USHORT i=0; i < pSwpHints->Count() && +/*N*/ rIdx >= *(*pSwpHints)[i]->GetStart(); ++i) +/*N*/ { +/*N*/ SwTxtAttr *pHt = pSwpHints->GetHt(i); +/*N*/ if( 0 != ( pEndIdx = pHt->GetEnd()) ) +/*N*/ { +/*N*/ // leere Hints an rIdx.GetIndex ? +/*N*/ BOOL bEmpty = *pEndIdx == *pHt->GetStart() +/*N*/ && rIdx == *pHt->GetStart(); +/*N*/ +/*N*/ if( bEmpty ) +/*N*/ { +/*N*/ pSwpHints->DeleteAtPos(i); +/*N*/ if( bEmpty ) +/*N*/ *pHt->GetStart() -= 1; +/*N*/ else +/*N*/ *pEndIdx -= 1; +/*N*/ Insert(pHt); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ if ( pSwpHints->CanBeDeleted() ) +/*N*/ DELETEZ( pSwpHints ); +/*N*/ } +/*N*/ // den Frames Bescheid sagen +/*N*/ SwInsChr aHint( rIdx.GetIndex()-1 ); +/*N*/ SwModify::Modify( 0, &aHint ); +/*N*/ return *this; +/*N*/ } + + +/* + * void SwTxtNode::RstAttr(const SwIndex &rIdx, USHORT nLen) + * + * loescht alle Attribute ab der Position rIdx ueber eine Laenge + * von nLen. + */ + +/* 5 Faelle: + * 1) Das Attribut liegt vollstaendig im Bereich: + * -> loeschen + * 2) Das Attributende liegt im Bereich: + * -> Loeschen, mit neuem Ende einfuegen + * 3) Der Attributanfang liegt im Bereich: + * -> Loeschen, mit neuem Anfang einfuegen + * 4) Das Attrib umfasst den Bereich: + * Aufsplitten, d.h. + * -> Loeschen, mit alten Anfang und Anfang des Bereiches einfuegen + * -> Neues Attribut mit Ende des Bereiches und altem Ende einfuegen + * 5) Das Attribut liegt ausserhalb des Bereiches + * -> nichts tun. + */ + + + +/*M*/ void SwTxtNode::RstAttr(const SwIndex &rIdx, xub_StrLen nLen, USHORT nWhich, +/*M*/ const SfxItemSet* pSet, BOOL bInclRefToxMark ) +/*M*/ { +/*M*/ // Attribute? +/*M*/ if ( !GetpSwpHints() ) +/*M*/ return; +/*M*/ +/*M*/ USHORT i = 0; +/*M*/ xub_StrLen nStart = rIdx.GetIndex(); +/*M*/ xub_StrLen nEnd = nStart + nLen; +/*M*/ xub_StrLen *pAttrEnd; +/*M*/ xub_StrLen nAttrStart; +/*M*/ SwTxtAttr *pHt; +/*M*/ +/*M*/ BOOL bChanged = FALSE; +/*M*/ +/*M*/ // nMin und nMax werden invers auf das Maximum bzw. Minimum gesetzt. +/*M*/ xub_StrLen nMin = aText.Len(); +/*M*/ xub_StrLen nMax = nStart; +/*M*/ +/*M*/ const BOOL bNoLen = !nMin; +/*M*/ +/*M*/ // We have to remember the "new" attributes, which have +/*M*/ // been introduced by splitting surrounding attributes (case 4). +/*M*/ // They may not be forgotten inside the "Forget" function +/*M*/ std::vector< const SwTxtAttr* > aNewAttributes; +/*M*/ +/*M*/ // durch das Attribute-Array, bis der Anfang des Geltungsbereiches +/*M*/ // des Attributs hinter dem Bereich liegt +/*M*/ while( (i < pSwpHints->Count()) && +/*M*/ ((( nAttrStart = *(*pSwpHints)[i]->GetStart()) < nEnd ) +/*M*/ || nLen==0) ) +/*M*/ { +/*M*/ pHt = pSwpHints->GetHt(i); +/*M*/ +/*M*/ // Attribute ohne Ende bleiben drin! +/*M*/ if ( 0 == (pAttrEnd=pHt->GetEnd()) ) +/*M*/ { +/*M*/ i++; +/*M*/ continue; +/*M*/ } +/*M*/ +/*M*/ // loesche alle TextAttribute die als Attribut im Set vorhanden sind +/*M*/ if( pSet ? SFX_ITEM_SET != pSet->GetItemState( pHt->Which(), FALSE ) +/*M*/ : ( nWhich ? nWhich != pHt->Which() +/*M*/ : (!bInclRefToxMark && +/*M*/ ( RES_TXTATR_REFMARK == pHt->Which() || +/*M*/ RES_TXTATR_TOXMARK == pHt->Which() )))) +/*M*/ { +/*M*/ // Es sollen nur Attribute mit nWhich beachtet werden +/*M*/ i++; +/*M*/ continue; +/*M*/ } +/*M*/ +/*M*/ +/*M*/ if( nStart <= nAttrStart ) // Faelle: 1,3,5 +/*M*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 +/*M*/ } +/*M*/ else // Faelle: 2,4,5 +/*M*/ if( *pAttrEnd > nStart ) // Faelle: 2,4 +/*M*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 +/*M*/ } +/*M*/ ++i; +/*M*/ } +/*M*/ +/*M*/ if ( pSwpHints && pSwpHints->CanBeDeleted() ) +/*M*/ DELETEZ( pSwpHints ); +/*M*/ if(bChanged) +/*M*/ { +/*M*/ if ( pSwpHints ) +/*M*/ { +/*M*/ pSwpHints->ClearDummies( *this ); +/*M*/ ((SwpHintsArr*)pSwpHints)->Resort(); +/*M*/ pSwpHints->Merge( *this ); +/*M*/ } +/*M*/ //TxtFrm's reagieren auf aHint, andere auf aNew +/*M*/ SwUpdateAttr aHint( nMin, nMax, 0 ); +/*M*/ SwModify::Modify( 0, &aHint ); +/*M*/ SwFmtChg aNew( GetFmtColl() ); +/*M*/ SwModify::Modify( 0, &aNew ); +/*M*/ } +/*M*/ } + + + +/************************************************************************* + * SwTxtNode::GetCurWord() + * + * Aktuelles Wort zurueckliefern: + * Wir suchen immer von links nach rechts, es wird also das Wort + * vor nPos gesucht. Es sei denn, wir befinden uns am Anfang des + * Absatzes, dann wird das erste Wort zurueckgeliefert. + * Wenn dieses erste Wort nur aus Whitespaces besteht, returnen wir + * einen leeren String. + *************************************************************************/ + + + + + +/*M*/ void SwTxtNode::SetWrong( SwWrongList *pNew ) +/*M*/ { +/*M*/ delete pWrong; +/*M*/ pWrong = pNew; +/*M*/ } + +/*M*/ SwScanner::SwScanner( const SwTxtNode& rNd, const SwWrongList* pWrng, +/*M*/ USHORT nType, xub_StrLen nStart, xub_StrLen nEnde, +/*M*/ BOOL bRev, BOOL bOS ) +/*M*/ : rNode( rNd ), pWrong( pWrng ), nWordType( nType ), nLen( 0 ), +/*M*/ bReverse( bRev ), bStart( TRUE ), bIsOnlineSpell( bOS ) +/*M*/ { +/*M*/ ASSERT( rNd.GetTxt().Len(), "SwScanner: EmptyString" ); +/*M*/ if( bReverse ) +/*M*/ { +/*M*/ nBegin = nEnde; +/*M*/ nEndPos = nStart; +/*M*/ } +/*M*/ else +/*M*/ { +/*M*/ nBegin = nStart; +/*M*/ nEndPos = nEnde; +/*M*/ } +/*M*/ +/*M*/ aCurrLang = rNd.GetLang( nBegin ); +/*M*/ } + + +/*N*/ BOOL SwScanner::NextWord() +/*N*/ { +/*N*/ ASSERT( ! bReverse, +/*N*/ "SwScanner::NextWord() currently not implemented for reverse mode" ) +/*N*/ +/*N*/ nBegin += nLen; +/*N*/ +/*N*/ // first we have to skip some whitespace characters +/*N*/ const XubString& rText = rNode.GetTxt(); +/*N*/ Boundary aBound; +/*N*/ +/*N*/ while ( true ) +/*N*/ { +/*N*/ +/*N*/ while ( nBegin < rText.Len() && +/*N*/ lcl_IsSkippableWhiteSpace( rText.GetChar( nBegin ) ) ) +/*N*/ ++nBegin; +/*N*/ +/*N*/ if ( nBegin >= rText.Len() || nBegin >= nEndPos ) +/*N*/ return FALSE; +/*N*/ +/*N*/ // get next language in order to find next or previous word +/*N*/ const USHORT nNextScript = +/*N*/ pBreakIt->xBreak->getScriptType( rText, nBegin ); +/*N*/ if ( nNextScript != GetI18NScriptTypeOfLanguage( aCurrLang ) ) +/*N*/ { +/*N*/ LanguageType aNextLang = rNode.GetLang( nBegin, nNextScript ); +/*N*/ aCurrLang = aNextLang; +/*N*/ } +/*N*/ +/*N*/ // get the word boundaries +/*N*/ aBound = pBreakIt->xBreak->getWordBoundary( rText, nBegin, +/*N*/ pBreakIt->GetLocale( aCurrLang ), nWordType, sal_True ); +/*N*/ +/*N*/ //no word boundaries could be found +/*N*/ if(aBound.endPos == aBound.startPos) +/*N*/ return FALSE; +/*N*/ +/*N*/ if( nBegin == aBound.endPos ) +/*N*/ ++nBegin; +/*N*/ else +/*N*/ break; +/*N*/ +/*N*/ } // end while( true ) + +/*N*/ +/*N*/ // we have to differenciate between these cases: +/*N*/ if ( aBound.startPos <= nBegin ) +/*N*/ { +/*N*/ ASSERT( aBound.endPos >= nBegin, "Unexpected aBound result" ) +/*N*/ +/*N*/ // restrict boundaries to script boundaries and nEndPos +/*N*/ const USHORT nCurrScript = +/*N*/ pBreakIt->xBreak->getScriptType( rText, nBegin ); +/*N*/ +/*N*/ XubString aTmpWord = rText.Copy( nBegin, aBound.endPos - nBegin ); +/*N*/ const sal_Int32 nScriptEnd = nBegin + +/*N*/ pBreakIt->xBreak->endOfScript( aTmpWord, 0, nCurrScript ); +/*N*/ const sal_Int32 nEnd = Min( aBound.endPos, nScriptEnd ); +/*N*/ +/*N*/ // restrict word start to last script change position +/*N*/ sal_Int32 nScriptBegin = 0; +/*N*/ if ( aBound.startPos < nBegin ) +/*N*/ { +/*N*/ // search from nBegin backwards until the next script change +/*N*/ aTmpWord = rText.Copy( aBound.startPos, nBegin - aBound.startPos + 1 ); +/*N*/ nScriptBegin = aBound.startPos + +/*N*/ pBreakIt->xBreak->beginOfScript( aTmpWord, nBegin - aBound.startPos, +/*N*/ nCurrScript ); +/*N*/ } +/*N*/ +/*N*/ nBegin = (xub_StrLen)Max( aBound.startPos, nScriptBegin ); +/*N*/ nLen = (xub_StrLen)(nEnd - nBegin); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ const USHORT nCurrScript = +/*N*/ pBreakIt->xBreak->getScriptType( rText, aBound.startPos ); +/*N*/ XubString aTmpWord = rText.Copy( aBound.startPos, aBound.endPos - aBound.startPos ); +/*N*/ const sal_Int32 nScriptEnd = aBound.startPos + +/*N*/ pBreakIt->xBreak->endOfScript( aTmpWord, 0, nCurrScript ); +/*N*/ const sal_Int32 nEnd = Min( aBound.endPos, nScriptEnd ); +/*N*/ nBegin = (xub_StrLen)aBound.startPos; +/*N*/ nLen = (xub_StrLen)(nEnd - nBegin); +/*N*/ } +/*N*/ +/*N*/ if( ! nLen ) +/*N*/ return FALSE; +/*N*/ +/*N*/ aWord = rText.Copy( nBegin, nLen ); +/*N*/ +/*N*/ return TRUE; +/*N*/ } + +#ifdef LINGU_STATISTIK + +// globale Variable +SwLinguStatistik aSwLinguStat; + + + +#endif + +// change text to Upper/Lower/Hiragana/Katagana/... + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |