summaryrefslogtreecommitdiff
path: root/binfilter/bf_sw/source/core/sw3io/sw_sw3nodes.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'binfilter/bf_sw/source/core/sw3io/sw_sw3nodes.cxx')
-rw-r--r--binfilter/bf_sw/source/core/sw3io/sw_sw3nodes.cxx2794
1 files changed, 2794 insertions, 0 deletions
diff --git a/binfilter/bf_sw/source/core/sw3io/sw_sw3nodes.cxx b/binfilter/bf_sw/source/core/sw3io/sw_sw3nodes.cxx
new file mode 100644
index 000000000000..896f4dfa290e
--- /dev/null
+++ b/binfilter/bf_sw/source/core/sw3io/sw_sw3nodes.cxx
@@ -0,0 +1,2794 @@
+/* -*- 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>
+
+#if !(defined _SVSTDARR_STRINGS_DECL && defined _SVSTDARR_BYTESTRINGS_DECL && \
+ defined _SVSTDARR_USHORTS_DECL && defined _SVSTDARR_XUB_STRLEN_DECL && \
+ defined _SVSTDARR_BOOLS_DECL)
+#define _SVSTDARR_STRINGS
+#define _SVSTDARR_BYTESTRINGS
+#define _SVSTDARR_USHORTS
+#define _SVSTDARR_XUB_STRLEN
+#define _SVSTDARR_BOOLS
+#endif
+
+#include <bf_svtools/imap.hxx>
+#include <bf_svtools/urihelper.hxx>
+#include <bf_svx/fontitem.hxx>
+#include <bf_svx/cscoitem.hxx>
+#include <bf_svx/lrspitem.hxx>
+#include <bf_svx/tstpitem.hxx>
+
+#include <horiornt.hxx>
+
+#include <doc.hxx>
+
+#include <errhdl.hxx>
+
+#include <pam.hxx>
+#include <fmtanchr.hxx>
+#include <txtftn.hxx>
+#include <fmturl.hxx>
+#include <fchrfmt.hxx>
+#include <fmtftn.hxx>
+#include <fmtflcnt.hxx>
+#include <fmtfld.hxx>
+#include <fmtinfmt.hxx>
+#include <txtflcnt.hxx>
+#include <charatr.hxx>
+#include <frmfmt.hxx>
+#include <charfmt.hxx>
+#include <paratr.hxx>
+#include <poolfmt.hxx>
+#include <sw3io.hxx>
+#include <sw3imp.hxx>
+#include <ndtxt.hxx>
+#include <ndgrf.hxx>
+#include <ndole.hxx>
+#include <crypter.hxx>
+#include <wrong.hxx>
+#include <tox.hxx>
+#include <fmthbsh.hxx>
+// OD 27.06.2003 #108784#
+
+// Export
+#include <fldbas.hxx>
+#include <frmatr.hxx>
+
+#include <swerror.h>
+#include <SwStyleNameMapper.hxx>
+#include "bf_so3/staticbaseurl.hxx"
+namespace binfilter {
+
+#define URL_DECODE \
+ , INetURLObject::WAS_ENCODED, INetURLObject::DECODE_UNAMBIGUOUS
+
+/*N*/ SV_IMPL_PTRARR_SORT(Sw3SortFmts,SwFmtPtr)
+
+////////////////////////////////////////////////////////////////////////////
+
+// Vorbereitung des Exports eines Text-Nodes in das Sw31 File-Format
+// (dazu muessen SwFmtInetFmt-Hints in Felder umgewandelt werden)
+// Idee:
+// Die Start- und End-Positionen aller Hints werden in zwei USHORT-Arrays
+// gespeichert, die SfxPoolItems der Hints in einem dritten. Diese
+// "Hint"-Arrays werden entsprechend aufbereitet und dann statt der
+// Original-Hints ausgegeben.
+//
+// Wie wird aufbereitet?
+// Die "Hints" werden zunaechst in die Arrays kopiert. dabei werden
+// - Schachtelungen von SwFmtINetFmt-Hints aufgeloest.
+// - leere SwFmtINetFmt-Hints "entfernt"
+// - Hints innerhalb von SwFmtINetFmt-Hints "entfernt"
+//
+// Danach werden die Texte der SwFmtINetFmt-Hints extrahiert und der
+// Text des Nodes sowie die Htnt-Psotionen an die Verwendung von Feldern
+// angepasst.
+
+SV_DECL_PTRARR(SfxPoolItems,SfxPoolItem * ,16,16)
+struct Sw3ExportTxtAttrs
+{
+ SvXub_StrLens aItemStarts; // Start-Pos der Hints
+ SvXub_StrLens aItemEnds; // End-Pos der Hints
+ SfxPoolItems aItems; // Items der Hints
+ SvByteStrings aINetFmtTexts; // Texte der SwFmtINetFmt-Hints
+
+ ByteString aText; // Node-Text
+
+ USHORT nDrawFrmFmts; // Anzahl zeichengeb. Zeichen-Objekte
+
+ Sw3ExportTxtAttrs() : nDrawFrmFmts( 0 ) {}
+};
+
+class SwInsHardBlankSoftHyph
+{
+ SvXub_StrLens aItemStarts; // Start-Pos der Hints
+ SfxPoolItems aItems; // Items der Hints
+public:
+ SwInsHardBlankSoftHyph() {}
+ ~SwInsHardBlankSoftHyph();
+ void AddItem( xub_StrLen nPos, sal_Unicode c );
+ void ChangePos( xub_StrLen nHtEnd, xub_StrLen nOffs );
+ void OutAttr( Sw3IoImp& rIo, xub_StrLen nStt, xub_StrLen nEnd );
+};
+
+
+////////////////////////////////////////////////////////////////////////////
+
+// Ausgabe von FlyFrames, die an einem Node kleben
+
+/*N*/ void Sw3IoImp::OutNodeFlyFrames( ULONG nNodeId )
+/*N*/ {
+/*N*/ // FlyFrames duerfen Tabellen enthalten, koennen also Tabelle in Tabelle
+/*N*/ // simulieren
+/*N*/ SwTable* pSave = pCurTbl; pCurTbl = NULL;
+/*N*/ SwFmt* pFly;
+/*N*/ while( ( pFly = FindFlyFrm( nNodeId ) ) != NULL )
+/*N*/ {
+/*N*/ if( !pFly->IsDefault() )
+/*N*/ {
+/*N*/ BYTE cType = SWG_FLYFMT;
+/*N*/ // OD 27.06.2003 #108784# - do *not* export drawing objects in header/footer
+/*N*/ bool bExport = true;
+/*N*/ if( RES_DRAWFRMFMT == pFly->Which() )
+/*N*/ {
+/*N*/ cType = SWG_SDRFMT;
+/*N*/ SwFrmFmt* pDrawFrmFmt = static_cast<SwFrmFmt*>(pFly);
+/*N*/ const SwFmtAnchor& rFmtAnchor = pDrawFrmFmt->GetAnchor();
+/*N*/ if ( rFmtAnchor.GetAnchorId() != FLY_PAGE &&
+/*N*/ pDrawFrmFmt->GetDoc()->IsInHeaderFooter( rFmtAnchor.GetCntntAnchor()->nNode ) )
+/*N*/ {
+/*N*/ bExport = false;
+/*N*/ }
+/*N*/ }
+/*N*/ if ( bExport )
+/*N*/ {
+/*N*/ OutFormat( cType, *pFly );
+/*N*/ }
+/*N*/ }
+/*N*/ }
+/*N*/ pCurTbl = pSave;
+/*N*/ }
+
+// zeichengebundene Zeichen-Objekte absatzgebunden exportieren
+void Sw3IoImp::ExportNodeDrawFrmFmts( const SwTxtNode& rNd, xub_StrLen nStart,
+ xub_StrLen nEnd, USHORT nCount )
+{
+ ASSERT( pExportInfo, "Wo sind die Export-Informationen???" );
+ if( !pExportInfo || !nCount )
+ return;
+
+ pExportInfo->bDrwFrmFmt31 = TRUE;
+
+ USHORT nCntAttr = rNd.HasHints() ? rNd.GetSwpHints().Count() : 0;
+ USHORT nExported = 0;
+ for( USHORT n = 0; n < nCntAttr && nExported < nCount; n++ )
+ {
+ const SwTxtAttr* pHt = rNd.GetSwpHints()[ n ];
+ BOOL bHtEnd = BOOL( pHt->GetEnd() != NULL );
+ xub_StrLen nHtStart = *pHt->GetStart();
+
+ if( !bHtEnd && nHtStart >= nStart && nHtStart < nEnd &&
+ RES_TXTATR_FLYCNT==pHt->GetAttr().Which() )
+ {
+ const SwFmtFlyCnt& rFlyCnt = (const SwFmtFlyCnt&)pHt->GetAttr();
+ const SwFmt *pFmt = rFlyCnt.GetFrmFmt();
+ if( RES_DRAWFRMFMT == pFmt->Which() )
+ {
+ OutFormat( SWG_SDRFMT, *pFmt );
+ nExported++;
+ }
+ }
+ }
+
+ pExportInfo->bDrwFrmFmt31 = FALSE;
+}
+
+/*N*/ sal_Char Sw3IoImp::ConvStarSymbolCharToStarBats( sal_Unicode c )
+/*N*/ {
+/*N*/ if( !hBatsFontConv )
+/*N*/ {
+/*N*/ hBatsFontConv = CreateFontToSubsFontConverter( sStarSymbol,
+/*N*/ FONTTOSUBSFONT_EXPORT|FONTTOSUBSFONT_ONLYOLDSOSYMBOLFONTS );
+/*N*/ ASSERT( hBatsFontConv, "Got no symbol font converter" );
+/*N*/ }
+/*N*/ if( hBatsFontConv )
+/*N*/ {
+/*N*/ c = ConvertFontToSubsFontChar( hBatsFontConv, c );
+/*N*/ }
+/*N*/
+/*N*/ return (sal_Char)c;
+/*N*/ }
+
+/*N*/ sal_Unicode Sw3IoImp::ConvStarBatsCharToStarSymbol( sal_Char c )
+/*N*/ {
+/*N*/ sal_Unicode cNew = (sal_Unicode)(sal_uChar)c;
+/*N*/ if( !hBatsFontConv )
+/*N*/ {
+/*N*/ hBatsFontConv = CreateFontToSubsFontConverter( sStarBats,
+/*N*/ FONTTOSUBSFONT_IMPORT|FONTTOSUBSFONT_ONLYOLDSOSYMBOLFONTS );
+/*N*/ ASSERT( hBatsFontConv, "Got no symbol font converter" );
+/*N*/ }
+/*N*/ if( hBatsFontConv )
+/*N*/ {
+/*N*/ cNew = ConvertFontToSubsFontChar( hBatsFontConv, (sal_Unicode)(sal_uChar)c + 0xf000 );
+/*N*/ }
+/*N*/
+/*N*/ return cNew;
+/*N*/ }
+
+sal_Unicode Sw3IoImp::ConvStarMathCharToStarSymbol( sal_Char c )
+{
+ sal_Unicode cNew = c;
+ if( !hMathFontConv )
+ {
+ hMathFontConv = CreateFontToSubsFontConverter( sStarMath,
+ FONTTOSUBSFONT_IMPORT|FONTTOSUBSFONT_ONLYOLDSOSYMBOLFONTS );
+ ASSERT( hMathFontConv, "Got no symbol font converter" );
+ }
+ if( hMathFontConv )
+ {
+ cNew = ConvertFontToSubsFontChar( hMathFontConv, (sal_Unicode)(sal_uChar)c + 0xf000 );
+ }
+
+ return cNew;
+}
+
+/*N*/ sal_Bool lcl_sw3io_isStarSymbolFontItem( const SvxFontItem& rFontItem )
+/*N*/ {
+/*N*/ return ( rFontItem.GetFamilyName().EqualsAscii( "StarSymbol", 0, sizeof("StarSymbol")-1 ) ||
+/*N*/ rFontItem.GetFamilyName().EqualsAscii( "OpenSymbol", 0, sizeof("OpenSymbol")-1 ) );
+/*N*/ }
+
+// Hilfsroutine fuer ConvertText: Suche nach dem naechsten Hint,
+// der eine Konversion verbietet. Zur Zeit sind dies Hints, die entweder
+// direkt oder indirekt auf einen Font mit CHARSET_SYMBOL hinweisen.
+/*N*/ const SvxFontItem *lcl_sw3io_getNextFontHint( const SwpHints* pHints, USHORT& rHint,
+/*N*/ xub_StrLen& rStart, xub_StrLen& rEnd,
+/*N*/ sal_Bool& rIsMathOrBatsFontItem,
+/*N*/ Sw3Fmts *pConvToSymbolFmts,
+/*N*/ const SvxFontItem& rStarBatsItem,
+/*N*/ const SvxFontItem& rStarMathItem )
+/*N*/ {
+/*N*/ rStart = rEnd = (xub_StrLen)-1;
+/*N*/ rIsMathOrBatsFontItem = sal_False;
+/*N*/
+/*N*/ if( !pHints )
+/*N*/ return 0;
+/*N*/
+/*N*/ const SvxFontItem *pFontItem = 0;
+/*N*/ while( rHint < pHints->Count() )
+/*N*/ {
+/*N*/ const SwTxtAttr* pHnt = (*pHints) [rHint++];
+/*N*/ if( pHnt->Which() == RES_CHRATR_FONT )
+/*N*/ {
+/*N*/ rStart = *pHnt->GetStart();
+/*N*/ rEnd = *pHnt->GetEnd();
+/*N*/ pFontItem = &pHnt->GetFont();
+/*N*/ rIsMathOrBatsFontItem =
+/*N*/ RTL_TEXTENCODING_SYMBOL == pFontItem->GetCharSet() &&
+/*N*/ ( pFontItem->GetFamilyName().EqualsIgnoreCaseAscii( "StarBats", 0, sizeof("StarBats")-1 ) ||
+/*N*/ pFontItem->GetFamilyName().EqualsIgnoreCaseAscii( "StarMath", 0, sizeof("StarMath")-1 ) );
+/*N*/ break;
+/*N*/ }
+/*N*/ // Gibt es einen CharFormat-Hint mit einem Symbol-Font?
+/*N*/ else if( pHnt->Which() == RES_TXTATR_CHARFMT )
+/*N*/ {
+/*N*/ SwCharFmt* pFmt = pHnt->GetCharFmt().GetCharFmt();
+/*N*/ if( pFmt->GetAttrSet().GetItemState( RES_CHRATR_FONT, FALSE )
+/*N*/ == SFX_ITEM_SET )
+/*N*/ {
+/*N*/ rStart = *pHnt->GetStart();
+/*N*/ rEnd = *pHnt->GetEnd();
+/*N*/ pFontItem = &pFmt->GetFont();
+/*N*/ if( pConvToSymbolFmts &&
+/*N*/ lcl_sw3io_isStarSymbolFontItem( *pFontItem ) )
+/*N*/ {
+/*?*/ BYTE nFlags = pConvToSymbolFmts->GetFlags( pFmt );
+/*?*/ if( (SW3IO_CONV_FROM_BATS & nFlags) != 0 )
+/*?*/ pFontItem = &rStarBatsItem;
+/*?*/ else if( (SW3IO_CONV_FROM_MATH & nFlags) != 0 )
+/*?*/ pFontItem = &rStarMathItem;
+/*N*/ }
+/*N*/ break;
+/*N*/ }
+/*N*/ }
+/*N*/ }
+/*N*/
+/*N*/ return pFontItem;
+/*N*/ }
+
+// Text Node konvertieren
+// Wird aufgerufen, wenn sich die Systeme unterscheiden. Der Text wird
+// vom einen in den anderen Zeichensatz konvertiert. Nicht konvertierbare
+// Zeichen werden farblich unterlegt; Hints mit CHARSET_SYMBOL-Zeichensaetzen
+// werden uebersprungen
+
+/*N*/ const SwTxtAttr* lcl_sw3io_hasTxtAttr( const SwpHints *pHints, xub_StrLen nIdx )
+/*N*/ {
+/*N*/ const SwTxtAttr* pRet = 0;
+/*N*/ if( pHints )
+/*N*/ {
+/*N*/ USHORT nHints = pHints->Count();
+/*N*/ for( USHORT i = 0; i < nHints; i++ )
+/*N*/ {
+/*N*/ const SwTxtAttr *pPos = (*pHints)[i];
+/*N*/ const xub_StrLen nStart = *pPos->GetStart();
+/*N*/ if( nIdx == nStart && !pPos->GetEnd() )
+/*N*/ {
+/*N*/ pRet = pPos;
+/*N*/ break;
+/*N*/ }
+/*N*/ if( nStart > nIdx )
+/*N*/ break;
+/*N*/ }
+/*N*/ }
+/*N*/
+/*N*/ return pRet;
+/*N*/ }
+
+/*N*/ sal_Bool Sw3IoImp::ConvertText( ByteString& rText8, String& rText,
+/*N*/ xub_StrLen nStart, xub_StrLen nEnd,
+/*N*/ xub_StrLen nOffset, const SwTxtNode& rNd,
+/*N*/ rtl_TextEncoding eEnc,
+/*N*/ const SvxFontItem& rFontItem,
+/*N*/ SwInsHardBlankSoftHyph* pHBSH, BOOL bTo8 )
+/*N*/ {
+/*N*/ sal_Bool bRet = sal_False;
+/*N*/ const SwpHints *pHints = rNd.GetpSwpHints();
+/*N*/ if( bTo8 )
+/*N*/ {
+/*N*/ sal_Bool bToBats = lcl_sw3io_isStarSymbolFontItem( rFontItem );
+/*N*/ bRet = bToBats;
+/*N*/ if( bToBats || RTL_TEXTENCODING_SYMBOL == rFontItem.GetCharSet() )
+/*N*/ {
+/*N*/ for( xub_StrLen nPos = nStart; nPos < nEnd; nPos++ )
+/*N*/ {
+/*N*/ sal_Unicode c = rText.GetChar( nPos );
+/*N*/ switch ( c )
+/*N*/ {
+/*N*/ case CHAR_HARDBLANK:
+/*N*/ case CHAR_HARDHYPHEN:
+/*?*/ case CHAR_SOFTHYPHEN:
+/*?*/ if( pHBSH )
+/*?*/ {
+/*?*/ pHBSH->AddItem( nPos, c );
+/*?*/ c = '\xff';
+/*?*/ }
+/*?*/ break;
+/*N*/
+/*N*/ case CH_TXTATR_BREAKWORD:
+/*N*/ case CH_TXTATR_INWORD:
+/*N*/ if( lcl_sw3io_hasTxtAttr( pHints, nPos+nOffset ) )
+/*N*/ c = '\xff';
+/*N*/ break;
+/*N*/ }
+/*N*/ if( bToBats )
+/*N*/ rText8 += ConvStarSymbolCharToStarBats( c );
+/*N*/ else
+/*N*/ rText8 += (sal_Char)c;
+/*N*/ }
+/*N*/ }
+/*N*/ else
+/*N*/ {
+/*N*/ xub_StrLen nCopy = nStart;
+/*N*/ for( xub_StrLen nPos = nStart; nPos < nEnd; nPos++ )
+/*N*/ {
+/*N*/ sal_Unicode c = rText.GetChar( nPos );
+/*N*/ BOOL bToFF = FALSE;
+/*N*/ switch ( c )
+/*N*/ {
+/*N*/ case CHAR_HARDBLANK:
+/*N*/ case CHAR_HARDHYPHEN:
+/*N*/ case CHAR_SOFTHYPHEN:
+/*N*/ if( pHBSH )
+/*N*/ {
+/*N*/ pHBSH->AddItem( nPos, c );
+/*N*/ bToFF = TRUE;
+/*N*/ }
+/*N*/ break;
+/*N*/
+/*N*/ case CH_TXTATR_BREAKWORD:
+/*N*/ case CH_TXTATR_INWORD:
+/*N*/ bToFF = 0 != lcl_sw3io_hasTxtAttr( pHints, nPos+nOffset );
+/*N*/ break;
+/*N*/ }
+/*N*/ if( bToFF )
+/*N*/ {
+/*N*/ if( nCopy < nPos )
+/*N*/ rText8 += ByteString( rText.Copy(nCopy,nPos-nCopy),
+/*N*/ eEnc );
+/*N*/ rText8 += '\xff';
+/*N*/ nCopy = nPos + 1;
+/*N*/ }
+/*N*/ }
+/*N*/ if( nCopy < nEnd )
+/*N*/ rText8 += ByteString( rText.Copy(nCopy,nEnd-nCopy), eEnc );
+/*N*/ }
+/*N*/ }
+/*N*/ else
+/*N*/ {
+/*N*/ const SwTxtAttr* pTAttr;
+/*N*/ if( RTL_TEXTENCODING_SYMBOL == rFontItem.GetCharSet() )
+/*N*/ {
+/*N*/ sal_Bool bBatsToSymbol =
+/*N*/ rFontItem.GetFamilyName().EqualsIgnoreCaseAscii( sStarBats );
+/*N*/ sal_Bool bMathToSymbol =
+/*N*/ rFontItem.GetFamilyName().EqualsIgnoreCaseAscii( sStarMath );
+/*N*/ bRet = bBatsToSymbol || bMathToSymbol;
+/*N*/ for( xub_StrLen nPos = nStart; nPos < nEnd; nPos++ )
+/*N*/ {
+/*N*/ sal_Char c = rText8.GetChar( nPos );
+/*N*/ if( '\xff' == c && 0 != (pTAttr =
+/*N*/ lcl_sw3io_hasTxtAttr( pHints, nPos+nOffset )) )
+/*N*/ rText += GetCharOfTxtAttr( *pTAttr );
+/*N*/ else if( bBatsToSymbol )
+/*N*/ rText += ConvStarBatsCharToStarSymbol( c );
+/*N*/ else if( bMathToSymbol )
+ rText += ConvStarMathCharToStarSymbol( c );
+/*N*/ else
+/*N*/ rText += ByteString::ConvertToUnicode( c,
+/*N*/ RTL_TEXTENCODING_SYMBOL );
+/*N*/ }
+/*N*/ }
+/*N*/ else
+/*N*/ {
+/*N*/ xub_StrLen nCopy = nStart;
+/*N*/ for( xub_StrLen nPos = nStart; nPos < nEnd; nPos++ )
+/*N*/ {
+/*N*/ sal_Char c = rText8.GetChar( nPos );
+/*N*/ sal_Unicode cNew;
+/*N*/ if( '\xff' == c )
+/*N*/ {
+/*N*/ if( 0 != ( pTAttr = lcl_sw3io_hasTxtAttr(
+/*N*/ pHints, nPos+nOffset )) ||
+/*N*/ CHAR_HARDBLANK ==
+/*N*/ ( cNew = rNd.GetTxt().GetChar( nPos+nOffset )) ||
+/*N*/ CHAR_HARDHYPHEN == cNew || CHAR_SOFTHYPHEN == cNew )
+/*N*/ {
+/*N*/ if( nCopy < nPos )
+/*N*/ rText += String( rText8.Copy(nCopy,nPos-nCopy), eEnc );
+/*N*/ if( pTAttr )
+/*N*/ rText += GetCharOfTxtAttr( *pTAttr );
+/*N*/ else
+/*N*/ rText += cNew;
+/*N*/ nCopy = nPos + 1;
+/*N*/ }
+/*N*/ }
+/*N*/ else if( CHAR_SOFTHYPHEN ==rNd.GetTxt().GetChar( nPos+nOffset ) )
+/*N*/ {
+/*N*/ // The original charcter has been converted into a soft
+/*N*/ // hyphen, but there was no text attribute at this position.
+/*N*/ // We then have to replace the soft hyphen with a hard one.
+/*N*/ // The check is based on the source char set and not on
+/*N*/ // the actual one. The assumption is here that there is
+/*N*/ // no difference in the position of the soft hyphen.
+/*N*/ // However, to not accidentially do a wrong conversion
+/*N*/ // we check this again. The only mistake we might make
+/*N*/ // if the assumption is wrong is to not convert a soft
+/*N*/ // hyphen.
+/*N*/ if( eEnc == eSrcSet ||
+/*N*/ CHAR_SOFTHYPHEN == ByteString::ConvertToUnicode( c, eEnc ) )
+/*N*/ {
+/*N*/ if( nCopy < nPos )
+/*N*/ rText += String( rText8.Copy(nCopy,nPos-nCopy), eEnc );
+/*N*/ rText += '-';
+/*N*/ nCopy = nPos + 1;
+/*N*/ }
+/*N*/ }
+/*N*/ }
+/*N*/ if( nCopy < nEnd )
+/*N*/ rText += String( rText8.Copy( nCopy, nEnd-nCopy ), eEnc );
+/*N*/ }
+/*N*/ }
+/*N*/ return bRet;
+/*N*/ }
+
+typedef const SvxFontItem *SvxFontItemPtr;
+SV_DECL_PTRARR( SvxFontItems, SvxFontItemPtr, 5, 5 )//STRIP008 ;
+
+typedef SwTxtAttr *SwTxtAttrPtr;
+SV_DECL_PTRARR( SwTxtAttrs, SwTxtAttrPtr, 5, 5 )//STRIP008 ;
+
+/*N*/ void Sw3IoImp::ConvertText( ByteString& rText8, String& rText,
+/*N*/ xub_StrLen nOffset, SwTxtNode& rNd,
+/*N*/ rtl_TextEncoding eEnc, const SvxFontItem& rFontItem,
+/*N*/ SwInsHardBlankSoftHyph* pHBSH, BOOL bTo8 )
+/*N*/
+/*N*/ {
+/*N*/ SvxFontItems aFontItemStack;
+/*N*/ SvXub_StrLens aEndPosStack;
+/*N*/ SwTxtAttrs aDeleteFontTxtAttrs;
+/*N*/ SvXub_StrLens aInsertSymbolFontStartPoss;
+/*N*/ SvXub_StrLens aInsertSymbolFontEndPoss;
+/*N*/
+/*N*/ SvxFontItem aStarBatsItem( FAMILY_DONTKNOW, sStarBats, aEmptyStr,
+/*N*/ PITCH_DONTKNOW, RTL_TEXTENCODING_SYMBOL );
+/*N*/ SvxFontItem aStarMathItem( FAMILY_DONTKNOW, sStarMath, aEmptyStr,
+/*N*/ PITCH_DONTKNOW, RTL_TEXTENCODING_SYMBOL );
+/*N*/
+/*N*/ SwpHints *pHints = rNd.GetpSwpHints();
+/*N*/ // find next
+/*N*/ xub_StrLen nFntStart = (xub_StrLen)-1, nFntEnd = 0;
+/*N*/ USHORT nHint = 0;
+/*N*/ const SvxFontItem *pFontItem = &rFontItem;
+/*N*/ sal_Bool bIsBatsOrMathFontItem;
+/*N*/ const SvxFontItem *pNewFontItem =
+/*N*/ lcl_sw3io_getNextFontHint( pHints, nHint, nFntStart,
+/*N*/ nFntEnd, bIsBatsOrMathFontItem,
+/*N*/ pConvToSymbolFmts, aStarBatsItem,
+/*N*/ aStarMathItem );
+/*N*/ if( !bTo8 && pNewFontItem && bIsBatsOrMathFontItem )
+/*N*/ aDeleteFontTxtAttrs.Insert( pHints->GetHt( nHint-1), aDeleteFontTxtAttrs.Count() );
+/*N*/ xub_StrLen nLen = nOffset + (bTo8 ? rText.Len() : rText8.Len() );
+/*N*/ xub_StrLen nCopy = nOffset;
+ xub_StrLen nPos=0;
+/*N*/ for( nPos = 0; nPos < nLen; nPos++ )
+/*N*/ {
+/*N*/ if( aEndPosStack.Count() &&
+/*N*/ nPos == aEndPosStack[aEndPosStack.Count()-1] )
+/*N*/ {
+/*N*/ if( nPos > nCopy )
+/*N*/ {
+/*N*/ sal_Bool bSymConv = ConvertText( rText8, rText, nCopy, nPos,
+/*N*/ nOffset, rNd, eEnc,
+/*N*/ *pFontItem, pHBSH, bTo8 );
+/*N*/ if( bSymConv && !bTo8 )
+/*N*/ {
+/*N*/ aInsertSymbolFontStartPoss.Insert( nCopy,
+/*N*/ aInsertSymbolFontStartPoss.Count() );
+/*N*/ aInsertSymbolFontEndPoss.Insert( nPos,
+/*N*/ aInsertSymbolFontEndPoss.Count() );
+/*N*/ }
+/*N*/ nCopy = nPos;
+/*N*/ }
+/*N*/ pFontItem = aFontItemStack[ aFontItemStack.Count()-1 ];
+/*N*/ aFontItemStack.Remove( aFontItemStack.Count()-1 );
+/*N*/ aEndPosStack.Remove( aEndPosStack.Count()-1 );
+/*N*/ }
+/*N*/ while( (xub_StrLen)-1 != nFntStart && nPos == nFntStart )
+/*N*/ {
+/*N*/ if( nPos > nCopy )
+/*N*/ {
+/*N*/ sal_Bool bSymConv = ConvertText( rText8, rText, nCopy, nPos,
+/*N*/ nOffset, rNd,eEnc, *pFontItem,
+/*N*/ pHBSH, bTo8 );
+/*N*/ if( bSymConv && !bTo8 )
+/*N*/ {
+/*?*/ aInsertSymbolFontStartPoss.Insert( nCopy,
+/*?*/ aInsertSymbolFontStartPoss.Count() );
+/*?*/ aInsertSymbolFontEndPoss.Insert( nPos,
+/*?*/ aInsertSymbolFontEndPoss.Count() );
+/*N*/ }
+/*N*/ nCopy = nPos;
+/*N*/ }
+/*N*/ aEndPosStack.Insert( nFntEnd, aEndPosStack.Count() );
+/*N*/ aFontItemStack.Insert( pFontItem, aFontItemStack.Count() );
+/*N*/ pFontItem = pNewFontItem;
+/*N*/ pNewFontItem = lcl_sw3io_getNextFontHint( pHints, nHint, nFntStart,
+/*N*/ nFntEnd, bIsBatsOrMathFontItem,
+/*N*/ pConvToSymbolFmts, aStarBatsItem,
+/*N*/ aStarMathItem);
+/*N*/ if( !bTo8 && pNewFontItem && bIsBatsOrMathFontItem )
+/*N*/ aDeleteFontTxtAttrs.Insert( pHints->GetHt( nHint-1 ), aDeleteFontTxtAttrs.Count() );
+/*N*/ }
+/*N*/ }
+/*N*/ if( nLen > nCopy )
+/*N*/ {
+/*N*/ sal_Bool bSymConv = ConvertText( rText8, rText, nCopy, nLen, nOffset,
+/*N*/ rNd, eEnc, *pFontItem, pHBSH, bTo8 );
+/*N*/ if( bSymConv && !bTo8 )
+/*N*/ {
+/*N*/ aInsertSymbolFontStartPoss.Insert( nCopy,
+/*N*/ aInsertSymbolFontStartPoss.Count() );
+/*N*/ aInsertSymbolFontEndPoss.Insert( nPos,
+/*N*/ aInsertSymbolFontEndPoss.Count() );
+/*N*/ }
+/*N*/ }
+/*N*/ while( aDeleteFontTxtAttrs.Count() )
+/*N*/ {
+/*N*/ SwTxtAttr *pAttr = aDeleteFontTxtAttrs[0];
+/*N*/ aDeleteFontTxtAttrs.Remove( 0 );
+/*N*/ rNd.Delete( pAttr );
+/*N*/ }
+/*N*/ if( aInsertSymbolFontStartPoss.Count() )
+/*N*/ {
+/*N*/ const Font& rSymbolFont = SwNumRule::GetDefBulletFont();
+/*N*/ SvxFontItem aFontItem( rSymbolFont.GetFamily(), rSymbolFont.GetName(),
+/*N*/ rSymbolFont.GetStyleName(),
+/*N*/ rSymbolFont.GetPitch(),
+/*N*/ rSymbolFont.GetCharSet() );
+/*N*/ for( USHORT i=0; i < aInsertSymbolFontStartPoss.Count(); i++ )
+/*N*/ {
+/*N*/ rNd.Insert( aFontItem, aInsertSymbolFontStartPoss[i],
+/*N*/ aInsertSymbolFontEndPoss[i] );
+/*N*/ }
+/*N*/ }
+/*N*/ }
+
+/*N*/ void Sw3IoImp::ConvertText( SwTxtNode& rNd, const ByteString& rText8,
+/*N*/ xub_StrLen nOffset,
+/*N*/ SvUShorts *pEncs, SvXub_StrLens *pPoss )
+/*N*/ {
+/*N*/ if( !rText8.Len() )
+/*N*/ return;
+/*N*/
+/*N*/ const SvxFontItem& rFont = rNd.GetSwAttrSet().GetFont();
+/*N*/ BOOL bNdSym = rFont.GetCharSet() == RTL_TEXTENCODING_SYMBOL;
+/*N*/
+/*N*/ String& rNdText = (String &)rNd.GetTxt();
+/*N*/ String aText;
+/*N*/ ByteString aText8( rText8 );
+/*N*/ SvxFontItem aFontItem( rFont );
+/*N*/ if( pConvToSymbolFmts &&
+/*N*/ lcl_sw3io_isStarSymbolFontItem( aFontItem ) )
+/*N*/ {
+/*?*/ BYTE nFlags = pConvToSymbolFmts->GetFlags( rNd.GetFmtColl() );
+/*?*/ if( (SW3IO_CONV_FROM_BATS & nFlags) != 0 )
+/*?*/ {
+/*?*/ aFontItem.GetFamilyName() = sStarBats;
+/*?*/ aFontItem.GetCharSet() = RTL_TEXTENCODING_SYMBOL;
+/*?*/ }
+/*?*/ else if( (SW3IO_CONV_FROM_MATH & nFlags) != 0 )
+/*?*/ {
+/*?*/ aFontItem.GetFamilyName() = sStarMath;
+/*?*/ aFontItem.GetCharSet() = RTL_TEXTENCODING_SYMBOL;
+/*?*/ }
+/*N*/ }
+/*N*/ ConvertText( aText8, aText, nOffset, rNd,
+/*N*/ eSrcSet, aFontItem, 0, FALSE );
+/*N*/ rNdText.Replace( nOffset, aText.Len(), aText );
+/*N*/ if( bNdSym &&
+/*N*/ SFX_ITEM_SET == rNd.GetSwAttrSet().GetItemState( RES_CHRATR_FONT,
+/*N*/ sal_False ) &&
+/*N*/ ( rFont.GetFamilyName().EqualsIgnoreCaseAscii( sStarBats ) ||
+/*N*/ rFont.GetFamilyName().EqualsIgnoreCaseAscii( sStarMath ) ) )
+/*N*/ {
+/*?*/ const Font& rSymbolFont = SwNumRule::GetDefBulletFont();
+/*?*/ SvxFontItem aFontItem( rSymbolFont.GetFamily(),
+/*?*/ rSymbolFont.GetName(),
+/*?*/ rSymbolFont.GetStyleName(),
+/*?*/ rSymbolFont.GetPitch(),
+/*?*/ rSymbolFont.GetCharSet() );
+/*?*/ ((SwCntntNode&)rNd).SetAttr( aFontItem );
+/*N*/ }
+/*N*/
+/*N*/ if( pEncs )
+/*N*/ {
+/*?*/ for( USHORT i=0; i < pEncs->Count(); i++ )
+/*?*/ {
+/*?*/ xub_StrLen nStart = (*pPoss)[2*i];
+/*?*/ String aTmp( rText8.Copy( nStart - nOffset,
+/*?*/ (*pPoss)[2*i+1] - nStart ),
+/*?*/ (rtl_TextEncoding)(*pEncs)[i] );
+/*?*/ rNdText.Replace( nStart, aTmp.Len(), aTmp );
+/*?*/ }
+/*N*/ }
+/*N*/ }
+
+// Text Node einlesen
+// Falls kein Node angegeben ist, wird ein neuer Node an der angegebenen
+// Position erzeugt.
+// nInsFirstPara - beim Document einfuegen, muss der erste Absatz
+// sonderbehandelt werden (Absatz Attribute!)
+
+/*N*/ void Sw3IoImp::InTxtNode( SwTxtNode* pNd, SwNodeIndex& rPos, xub_StrLen nOffset,
+/*N*/ BYTE nInsFirstPara )
+/*N*/ {
+/*N*/ SwTxtNode *pOldNd = pNd && pNd->GetDepends() ? pNd : 0;
+/*N*/
+/*N*/ SvStringsDtor *pINetFldTexts = 0; // Texte aus Internet-Feldern
+/*N*/ SvXub_StrLens *pINetFldPoss = 0; // Positionen der Internet-Felder
+/*N*/
+/*N*/ SvXub_StrLens *pErasePoss = 0; // Positionen der Draw-Formate
+/*N*/
+/*N*/ SvUShorts *pCharSetColorEncs = 0;
+/*N*/ SvXub_StrLens *pCharSetColorPoss = 0; //
+/*N*/
+/*N*/ OpenRec( SWG_TEXTNODE );
+/*N*/ BYTE cNumLevel = NO_NUMBERING;
+/*N*/ USHORT nColl = IDX_DFLT_VALUE, nCondColl = IDX_DFLT_VALUE;
+/*N*/ SwWrongList *pWrong = 0;
+/*N*/ // 0x0L: Laenge der Daten
+/*N*/ // 0x10: Numerierung folgt
+/*N*/ // 0x20: Wrong-Liste ist nicht dirty
+/*N*/ BYTE cFlags = OpenFlagRec();
+/*N*/ *pStrm >> nColl;
+/*N*/ if( !IsVersion(SWG_LONGIDX) && (cFlags & 0x10) )
+/*N*/ {
+/*N*/ *pStrm >> cNumLevel;
+/*N*/ // Im SW31-format wurde fuer nicht numerierte
+/*N*/ // Absaetzte noch ein NO_NUMLEVEL mit rausgeschrieben.
+/*N*/ if( NO_NUM == cNumLevel &&
+/*N*/ IsVersion( SWG_NONUMLEVEL, SWG_DESKTOP40 ) &&
+/*N*/ pStrm->Tell() != nFlagRecEnd ) // wenn noch Daten da sind
+/*?*/ *pStrm >> cNumLevel; // NO_NUM -> NO_NUMLEVEL
+/*N*/
+/*N*/ // Wenn ein NO_NUM gelesen wurde muss es noch in ein NO_NUMLEVEL
+/*N*/ // umgewandelt werden.
+/*N*/ bConvertNoNum |= (NO_NUM == cNumLevel);
+/*N*/ }
+/*N*/
+/*N*/ if( IsVersion( SWG_CONDCOLLS, SWG_EXPORT31, SWG_DESKTOP40 ) )
+/*N*/ {
+/*N*/ // bedingte Vorlagen gibt es nicht im 31-Export-Format
+/*N*/ *pStrm >> nCondColl;
+/*N*/ if( IDX_DFLT_VALUE != nCondColl )
+/*N*/ {
+/*N*/ // es ist eine gesetzt, dieses ist die bedingte Vorlage
+/*N*/ USHORT nTmp = nCondColl;
+/*N*/ nCondColl = nColl;
+/*N*/ nColl = nTmp;
+/*N*/ }
+/*N*/ }
+/*N*/
+/*N*/ CloseFlagRec();
+/*N*/ SwTxtFmtColl* pColl = FindTxtColl( nColl );
+/*N*/
+/*N*/ // JP 07.08.00: set never the default text format collection on a node
+/*N*/ if( pColl == pDoc->GetDfltTxtFmtColl() )
+/*?*/ pColl = pDoc->GetTxtCollFromPool( RES_POOLCOLL_STANDARD );
+/*N*/
+/*N*/ // Der Text des Nodes darf nicht einfach so konvertiert werden!
+/*N*/ ByteString aText8;
+/*N*/ pStrm->ReadByteString( aText8 );
+/*N*/ if( pCrypter )
+ pCrypter->Decrypt( aText8 );
+/*N*/ String aText( aText8, eSrcSet );
+/*N*/ if( !pNd )
+/*N*/ {
+/*N*/ pNd = pDoc->GetNodes().MakeTxtNode( rPos, pColl );
+/*N*/ rPos--;
+/*N*/ (String&) pNd->GetTxt() = aText;
+/*N*/ }
+/*N*/ else
+/*N*/ {
+/*N*/ if( !nInsFirstPara )
+/*N*/ pNd->ChgFmtColl( pColl );
+/*N*/ SwIndex aOff( pNd, nOffset );
+/*N*/ pNd->Insert( aText, aOff );
+/*N*/ }
+/*N*/
+/*N*/ // Der Offset kann wegen Einf. von nicht sichtbaren Redlines auch
+/*N*/ // negativ werden. Das darf aber auch ausser weiteren Redlines nichts
+/*N*/ // mehr kommen.
+/*N*/ INT32 nOffsetL = nOffset;
+/*N*/
+/*N*/ BOOL bConverted = FALSE;
+/*N*/
+/*N*/ while( BytesLeft() )
+/*N*/ {
+/*N*/ BYTE cType = Peek();
+/*N*/ switch( cType )
+/*N*/ {
+/*N*/ case SWG_ATTRSET:
+/*N*/ if( nInsFirstPara )
+/*N*/ {
+/*?*/ SwAttrSet aTmpSet( pDoc->GetAttrPool(),
+/*?*/ RES_CHRATR_BEGIN, RES_CHRATR_END - 1 );
+/*?*/ InAttrSet( aTmpSet );
+/*?*/ if( aTmpSet.Count() )
+/*?*/ {
+/*?*/ ASSERT( nOffsetL>=0,
+/*?*/ "Offset darf hier nicht negativ sein" );
+/*?*/ if( 2 == nInsFirstPara )
+/*?*/ pNd->SetAttr( aTmpSet, 0, aText.Len() );
+/*?*/ else
+/*?*/ pNd->SetAttr( aTmpSet, (xub_StrLen)nOffsetL,
+/*?*/ pNd->GetTxt().Len() );
+/*?*/
+/*?*/ if( pNd->GetpSwAttrSet() )
+/*?*/ pNd->GetpSwAttrSet()->SetModifyAtAttr( pNd );
+/*N*/ }
+/*N*/ }
+/*N*/ else if( pOldNd )
+/*N*/ {
+/*?*/ SwAttrSet aTmpSet( pDoc->GetAttrPool(), aTxtNodeSetRange );
+/*?*/ InAttrSet( aTmpSet );
+/*?*/ if( aTmpSet.Count() )
+/*?*/ {
+/*?*/ pNd->SwCntntNode::SetAttr( aTmpSet );
+/*?*/
+/*?*/ if( pNd->GetpSwAttrSet() )
+/*?*/ pNd->GetpSwAttrSet()->SetModifyAtAttr( pNd );
+/*?*/ }
+/*N*/ }
+/*N*/ else
+/*N*/ {
+/*N*/ if( !pNd->GetpSwAttrSet() )
+/*N*/ ((SwCntntNode*) pNd)->NewAttrSet( pDoc->GetAttrPool() );
+/*N*/ InAttrSet( *pNd->GetpSwAttrSet() );
+/*N*/ pNd->GetpSwAttrSet()->SetModifyAtAttr( pNd );
+/*N*/ }
+/*N*/ break;
+/*N*/ case SWG_SDRFMT:
+/*N*/ // Keine Draw-Formate in Kopf oder Fusszeilen einfuegen oder
+/*N*/ // wenn kein Drawing-Layer da ist!
+/*N*/ if( (nGblFlags & SW3F_NODRAWING) || bInsIntoHdrFtr )
+/*N*/ {
+/*?*/ SkipRec(); break;
+/*N*/ } // sonst weiter:
+/*N*/ case SWG_FLYFMT:
+/*N*/ {
+/*N*/ // Absatzgebundener oder Rahmengebundener FlyFrame
+/*N*/ USHORT eSave_StartNodeType = eStartNodeType;
+/*N*/ eStartNodeType = SwFlyStartNode;
+/*N*/ SwFrmFmt* pFmt = (SwFrmFmt*) InFormat( cType, NULL );
+/*N*/ eStartNodeType = eSave_StartNodeType;
+/*N*/
+/*N*/ if( !pFmt )
+/*N*/ break;
+/*N*/
+/*N*/ // Anker darin versenken
+/*N*/ SwFmtAnchor aAnchor( pFmt->GetAnchor() );
+/*N*/ if( FLY_AT_CNTNT==aAnchor.GetAnchorId() ||
+/*N*/ FLY_IN_CNTNT==aAnchor.GetAnchorId() )
+/*N*/ {
+/*N*/ // Absatzgebunende Rahmen: Die Abfrage auf FLY_IN_CNTNT
+/*N*/ // ist drinne, weil der SW31-Export sowas dummerweise
+/*N*/ // mal exportiert hat...
+/*N*/ aAnchor.SetType( FLY_AT_CNTNT );
+/*N*/ SwPosition aPos( rPos );
+/*N*/ aAnchor.SetAnchor( &aPos );
+/*N*/ }
+/*N*/ else
+/*N*/ {
+/*N*/ // Dies sollte bisher nur ein rahmengebundener Rahmen
+/*N*/ // sein, koennte aber auch mal was anderes werden. Es
+/*N*/ // bleibt dann auf jeden Fall auch di Cntnt-Position
+/*N*/ // erhalten.
+/*?*/ SwPosition aPos( rPos, SwIndex(pNd,aAnchor.GetPageNum()) );
+/*?*/ aAnchor.SetAnchor( &aPos );
+/*N*/ }
+/*N*/ aAnchor.SetPageNum( 0 );
+/*N*/ pFmt->SetAttr( aAnchor );
+/*N*/ // Layout-Frames im Insert Mode fuer absatzgebundene
+/*N*/ // Flys erzeugen
+/*N*/ if( bInsert && !nRes ) pFmt->MakeFrms();
+/*N*/ break;
+/*N*/ }
+/*N*/ case SWG_ATTRIBUTE:
+/*N*/ ASSERT( nOffsetL>=0, "Offset darf hier nicht negativ sein" );
+/*N*/ InTxtAttr( *pNd, aText8, (xub_StrLen)nOffsetL, &pINetFldTexts,
+/*N*/ &pINetFldPoss, &pErasePoss,
+/*N*/ &pCharSetColorEncs, &pCharSetColorPoss );
+/*N*/ break;
+/*N*/ case SWG_NUMRULE:
+/*N*/ // NumRules gibt es an dieser Stelle nur im 3.1 und 4.0
+/*N*/ // Fileformat. Seit dem 5.0-Filformat werden sie in einem
+/*N*/ // eigenen Stream bzw. am Dok-Anfang gespeichert.
+/*N*/ OpenNumRange40( rPos );
+/*N*/ break;
+/*N*/ case SWG_NODENUM:
+/*N*/ // Den NodeNum-Record gibt es seit der 5.0
+/*N*/ {
+/*N*/ SwNodeNum aNodeNum;
+/*N*/ InNodeNum( aNodeNum );
+/*N*/ pNd->UpdateNum( aNodeNum );
+/*N*/ }
+/*N*/ break;
+/*N*/ case SWG_MARK:
+/*N*/ ASSERT( nOffsetL>=0, "Offset darf hier nicht negativ sein" );
+/*N*/ InNodeMark( rPos, (xub_StrLen)nOffsetL );
+/*N*/ break;
+/*N*/
+/*N*/ case SWG_NODEREDLINE:
+/*N*/ // nOffsetL ist Referenz-Parameter.
+/*N*/ // nOffsetL kann jetzt negativ werden!
+/*N*/ // The text has to be converted before any redlines are
+/*N*/ // inserted. Otherwise, the content positions will not match
+/*N*/ // the indices within the 8-Bit-Text.
+/*N*/ /*?*/ if( !bConverted ) // SW50.SDW
+/*N*/ /*?*/ {
+/*N*/ /*?*/ ConvertText( *pNd, aText8, (xub_StrLen)nOffsetL,
+/*N*/ /*?*/ pCharSetColorEncs, pCharSetColorPoss );
+/*N*/ /*?*/ bConverted = TRUE;
+/*N*/ /*?*/ }
+/*N*/ /*?*/ InNodeRedline( rPos, nOffsetL );
+/*?*/ break;
+/*N*/
+/*N*/ case SWG_WRONGLIST:
+/*N*/ {
+/*N*/ if( IsVersion( SWG_DESKTOP40 ) )
+/*N*/ {
+/*N*/ OpenRec( SWG_WRONGLIST );
+/*N*/ pWrong = new SwWrongList;
+/*N*/ UINT16 nBeginInv, nEndInv, nCount;
+/*N*/ OpenFlagRec();
+/*N*/ *pStrm >> nBeginInv >> nEndInv;
+/*N*/ CloseFlagRec();
+/*N*/ pWrong->SetInvalid( (xub_StrLen)nBeginInv,
+/*N*/ (xub_StrLen)nEndInv );
+/*N*/ *pStrm >> nCount;
+/*N*/ for( USHORT i=0; Good() && i<nCount; i++ )
+/*N*/ {
+/*N*/ UINT32 nWrong;
+/*N*/ *pStrm >> nWrong;
+/*N*/ xub_StrLen nPos = (xub_StrLen)nWrong;
+/*N*/ xub_StrLen nLen = (xub_StrLen)(0xFFFF & (nWrong >> 16));
+/*N*/ pWrong->Insert( nPos, nLen, pWrong->Count() );
+/*N*/ }
+/*N*/ if( bSpellAllAgain )
+/*N*/ pWrong->SetInvalid( 0, STRING_MAXLEN );
+/*N*/ if( bSpellWrongAgain )
+/*N*/ pWrong->InvalidateWrong();
+/*N*/ CloseRec( SWG_WRONGLIST );
+/*N*/ }
+/*N*/ else
+/*N*/ SkipRec();
+/*N*/ }
+/*N*/ break;
+/*N*/ default:
+/*?*/ SkipRec();
+/*N*/ }
+/*N*/ }
+/*N*/ CloseRec( SWG_TEXTNODE );
+/*N*/
+/*N*/ // Eventuell den Text konvertieren
+/*N*/ if( !bConverted )
+/*N*/ ConvertText( *pNd, aText8, (xub_StrLen)nOffsetL,
+/*N*/ pCharSetColorEncs, pCharSetColorPoss );
+/*N*/
+/*N*/ // Numerierung uebernehmen
+/*N*/ if( !IsVersion(SWG_LONGIDX) )
+/*N*/ {
+/*N*/ if( cNumLevel != NO_NUMBERING )
+/*N*/ {
+/*N*/ // MAXLEVEL war im 3.1/4.0-SW 5 und kann sich nichr mehr aendern,
+/*N*/ // deshalb baruchen wir es nicht zu beachten.
+/*N*/ #if 0
+/*N*/ if( cNumLevel != NO_NUM && GetRealLevel(cNumLevel) >= MAXLEVEL )
+/*N*/ {
+/*N*/ // die Numerierungs-Ebene ist zu hoch => die hoecht moegliche
+/*N*/ // setzen
+/*N*/ BYTE cTmp = MAXLEVEL-1;
+/*N*/ if( cNumLevel & NO_NUMLEVEL )
+/*N*/ cTmp |= NO_NUMLEVEL;
+/*N*/ cNumLevel = cTmp;
+/*N*/ }
+/*N*/ #endif
+/*N*/ pNd->UpdateNum( SwNodeNum( cNumLevel ) );
+/*N*/ }
+/*N*/ else
+/*N*/ CloseNumRange40( rPos );
+/*N*/ }
+/*N*/
+/*N*/ const SwNodeNum *pNdNum = pNd->GetNum();
+/*N*/ const SwAttrSet *pAttrSet = pNd->GetpSwAttrSet();
+/*N*/ if( pNdNum && IsVersion(SWG_LONGIDX) )
+/*N*/ {
+/*N*/ if( pAttrSet )
+/*N*/ {
+/*N*/ // Wenn der Absatz numeriert ist, muss die zugehoerige Numerierung
+/*N*/ // noch als benutzt markiert werden bzw. eine automatische
+/*N*/ // Numerierung beim Einfuegen umbenannt werden. Da automatische
+/*N*/ // Numerierungen nicht in Vorlagen vorkommen koennen, gehen
+/*N*/ // wir hier ueber das Attribut im Node-AttrSet und damit direkt
+/*N*/ // an unser Namens-Array.
+/*N*/ const SfxPoolItem *pItem;
+/*N*/ if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_PARATR_NUMRULE,
+/*N*/ FALSE, &pItem ) )
+/*N*/ {
+/*N*/ const String& rName = ((const SwNumRuleItem*)pItem)->GetValue();
+/*N*/ if( rName.Len() )
+/*N*/ {
+/*N*/ Sw3NumRuleInfo aTmp( rName );
+/*N*/ USHORT nPos;
+/*N*/ if( aNumRuleInfos.Seek_Entry( &aTmp, &nPos ) )
+/*N*/ {
+/*N*/ Sw3NumRuleInfo *pInfo = aNumRuleInfos[nPos];
+/*N*/ if( !bNormal || bInsert )
+/*N*/ {
+/*N*/ // Beim Einfuegen oder Laden von Seitenvorlagen
+/*N*/ // muss das Item evtl. noch an den geaenderten Namen
+/*N*/ // der Seiten-Vorlage angepasst werden.
+/*?*/ pInfo->SetUsed();
+/*?*/ if( rName != pInfo->GetNewName() )
+/*?*/ {
+/*?*/ ((SwCntntNode *)pNd)
+/*?*/ ->SetAttr( SwNumRuleItem(pInfo->GetNewName()) );
+/*?*/ }
+/*N*/ }
+/*N*/ else
+/*N*/ {
+/*N*/ // Die entsprechende NumRule wird benutzt und braucht
+/*N*/ // nicht mehr geloescht zu werden. Also raus aus
+/*N*/ // dem Array damit.
+/*N*/ aNumRuleInfos.Remove( nPos, 1 );
+/*N*/ delete pInfo;
+/*N*/ }
+/*N*/ }
+/*N*/ }
+/*N*/ else
+/*N*/ {
+/*?*/ SwNodeNum aNodeNum( NO_NUMBERING );
+/*?*/ pNd->UpdateNum( aNodeNum );
+/*?*/ pNdNum = 0;
+/*N*/ }
+/*N*/ }
+/*N*/ }
+/*N*/
+/*N*/ if( bPageDescs && !bNumRules )
+/*N*/ {
+/*N*/ // Wenn Seiten-Vorlagen aber keine Numerierungs-Vorlagen
+/*N*/ // geladen werden, dann muessen wir sicherstellen, dass
+/*N*/ // die Numerierungs-Vorlage auch existiert.
+/*?*/ const SfxPoolItem* pItem =
+/*?*/ pNd->GetNoCondAttr( RES_PARATR_NUMRULE, TRUE );
+/*?*/ if( pItem && ((SwNumRuleItem*)pItem)->GetValue().Len() &&
+/*?*/ !pDoc->FindNumRulePtr( ((SwNumRuleItem*)pItem)->GetValue() ) )
+/*?*/ {
+/*?*/ const String& rName = ((SwNumRuleItem*)pItem)->GetValue();
+/*?*/ USHORT nPoolId = SwStyleNameMapper::GetPoolIdFromUIName( rName, GET_POOLID_NUMRULE );
+/*?*/ if( nPoolId != USHRT_MAX )
+/*?*/ pDoc->GetNumRuleFromPool( nPoolId );
+/*?*/ else
+/*?*/ pDoc->MakeNumRule( rName );
+/*?*/ }
+/*N*/ }
+/*N*/ }
+/*N*/
+/*N*/ #ifdef NUM_RELSPACE
+/*N*/ // Wenn der Absatz ein LRSpace-Item enthaelt und in der Kapitel-Numerierung
+/*N*/ // ist muss das LRSpace-Item noch angepasst werden. Relative Werte
+/*N*/ // koennen dabei nicht vorkommen.
+/*N*/ const SwNumRule *pOutline = pDoc->GetOutlineNumRule();
+/*N*/ const SfxPoolItem *pItem;
+/*N*/ if( pAttrSet && (!pNdNum || NO_NUMBERING != pNdNum->GetLevel()) &&
+/*N*/ NO_NUMBERING != pColl->GetOutlineLevel() &&
+/*N*/ pOutline && nVersion != SWG_NUMRELSPACE )
+/*N*/ {
+/*N*/ const SwNumFmt& rNumFmt = pOutline->Get(
+/*N*/ GetRealLevel(((const SwTxtFmtColl*)pColl)->GetOutlineLevel()) );
+/*N*/ USHORT nNumLSpace = rNumFmt.GetAbsLSpace();
+/*N*/
+/*N*/ if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_LR_SPACE, FALSE,
+/*N*/ &pItem ) )
+/*N*/ {
+/*N*/ const SvxLRSpaceItem *pParaLRSpace =
+/*N*/ (const SvxLRSpaceItem *)pItem;
+/*N*/
+/*N*/ USHORT nWishLSpace = (USHORT)pParaLRSpace->GetTxtLeft();
+/*N*/ USHORT nNewLSpace =
+/*N*/ nWishLSpace > nNumLSpace ? nWishLSpace-nNumLSpace : 0U;
+/*N*/
+/*N*/ const SvxLRSpaceItem& rCollLRSpace = pColl->GetLRSpace();
+/*N*/ if( nNewLSpace == rCollLRSpace.GetTxtLeft() &&
+/*N*/ pParaLRSpace->GetRight() == rCollLRSpace.GetRight() &&
+/*N*/ pParaLRSpace->GetTxtFirstLineOfst() ==
+/*N*/ rCollLRSpace.GetTxtFirstLineOfst() )
+/*N*/ {
+/*N*/ pNd->ResetAttr( RES_LR_SPACE );
+/*N*/ }
+/*N*/ else if( nNewLSpace != pParaLRSpace->GetTxtLeft() )
+/*N*/ {
+/*?*/ SvxLRSpaceItem aLRSpace( *pParaLRSpace );
+/*?*/ short nFirst = aLRSpace.GetTxtFirstLineOfst();
+/*?*/ if( nFirst < 0 && (USHORT)-nFirst > nNewLSpace )
+/*?*/ aLRSpace.SetTxtFirstLineOfst( -(short)nNewLSpace );
+/*?*/ aLRSpace.SetTxtLeft( nNewLSpace );
+/*?*/ ((SwCntntNode *)pNd)->SetAttr( aLRSpace );
+/*N*/ }
+/*N*/
+/*N*/ if( !IsVersion(SWG_NUMRELSPACE) && nWishLSpace != nNewLSpace )
+/*N*/ lcl_sw3io__ConvertNumTabStop( *pNd, (long)nWishLSpace -
+/*N*/ (long)nNewLSpace, FALSE );
+/*N*/ }
+/*N*/ else if( nNumLSpace > 0 && !IsVersion(SWG_NUMRELSPACE) )
+/*N*/ {
+/*N*/ lcl_sw3io__ConvertNumTabStop( *pNd, nNumLSpace, FALSE );
+/*N*/ }
+/*N*/ }
+/*N*/ #endif
+/*N*/
+/*N*/
+/*N*/ if( pINetFldTexts )
+/*N*/ {
+/*N*/ ASSERT( pINetFldPoss, "INet-Feld-Texte ohne Positionen???" );
+/*N*/
+/*N*/ // Es mussen noch Texte von Internet-Feldern eingefuegt werden
+/*N*/
+/*N*/ INT32 nOffset2 = 0; // Verschiebung durch die Felder selbst
+/*N*/
+/*N*/ for( USHORT i=0; i<pINetFldTexts->Count(); i++ )
+/*N*/ {
+/*N*/ const String &rStr = *(*pINetFldTexts)[i];
+/*N*/
+/*N*/ // den Text hinter dem 0xff vom Feld einfuegen
+/*N*/ xub_StrLen nPos = xub_StrLen( nOffset2 + nOffset +
+/*N*/ (*pINetFldPoss)[i] + 1 );
+/*N*/ SwIndex aOff( pNd, nPos );
+/*N*/
+/*N*/ if( rStr.Len() )
+/*N*/ {
+/*N*/ pNd->Insert( rStr, aOff );
+/*N*/ }
+/*N*/
+/*N*/ // und das 0xff loeschen
+/*N*/ aOff.Assign( pNd, nPos-1 );
+/*N*/ pNd->Erase( aOff, 1 );
+/*N*/
+/*N*/ // und den Offset korrigieren
+/*N*/ nOffset2 += rStr.Len();
+/*N*/ nOffset2--;
+/*N*/ }
+/*N*/
+/*N*/ // die Wrong-Liste ist jetzt ungueltig
+/*N*/ delete pWrong;
+/*N*/ pWrong = 0;
+/*N*/ cFlags &= 0xdf;
+/*N*/
+/*N*/ // und die Array loeschen
+/*N*/ delete pINetFldTexts;
+/*N*/ delete pINetFldPoss;
+/*N*/ }
+/*N*/
+/*N*/ if( pErasePoss )
+/*N*/ {
+/*N*/ // Es mussen noch 0xff-Zeichen aus dem Node geloescht werden
+/*?*/ USHORT i = pErasePoss->Count();
+/*?*/ while( i )
+/*?*/ {
+/*?*/ xub_StrLen nPos = (*pErasePoss)[--i];
+/*?*/
+/*?*/ ASSERT( CH_TXTATR_BREAKWORD == pNd->GetTxt().GetChar( nPos ) ||
+/*?*/ CH_TXTATR_INWORD == pNd->GetTxt().GetChar( nPos ),
+/*?*/ "Es sollten nur 0xff geloescht werden" );
+/*?*/
+/*?*/ SwIndex aOff( pNd, nPos );
+/*?*/ pNd->Erase( aOff, 1 );
+/*?*/ }
+/*?*/
+/*?*/
+/*?*/ // die Wrong-Liste ist jetzt ungueltig
+/*?*/ delete pWrong;
+/*?*/ pWrong = 0;
+/*?*/ cFlags &= 0xdf;
+/*?*/
+/*?*/ delete pErasePoss;
+/*N*/ }
+/*N*/
+/*N*/ // Wrong-Liste uebernehmen
+/*N*/ // ACHTUNG: dirty-bit wird invers gespeichert weil in alten Doks 0 steht
+/*N*/ BOOL bWrongDirty = ( ( cFlags & 0x20 ) == 0 ) ||
+/*N*/ nVersion < SWG_DESKTOP40 ||
+/*N*/ bSpellAllAgain || bSpellWrongAgain;
+/*N*/ pNd->SetWrongDirty( bWrongDirty );
+/*N*/ pNd->SetWrong( pWrong );
+/*N*/
+/*N*/ // Condition-Collections setzen:
+/*N*/ if( IDX_DFLT_VALUE != nCondColl )
+/*N*/ {
+/*?*/ if( bInsert )
+/*?*/ {
+/*?*/ // dann muss die richtige Collection neu bestimmt werden!
+/*?*/ pNd->ChkCondColl();
+/*?*/ }
+/*?*/ else
+/*?*/ {
+/*?*/ SwTxtFmtColl* pCColl = FindTxtColl( nCondColl );
+/*?*/ pNd->SetCondFmtColl( pCColl );
+/*?*/ }
+/*N*/ }
+/*N*/
+/*N*/ #ifdef NUM_RELSPACE
+/*N*/ if( pNdNum && NO_NUMBERING != pNdNum->GetLevel() &&
+/*N*/ IsVersion(SWG_LONGIDX) )
+/*N*/ {
+/*N*/ // In Dokumenten, in denen der Einzug einer Numerierung noch
+/*N*/ // absolut war, muss der Absatz-Einzug noch angepasst werden.
+/*N*/ // Weil man dazu die bedingte Vorlage braucht, darf das erst
+/*N*/ // hier geschehen.
+/*N*/ const SwNumRule *pNumRule = pNd->GetNumRule();
+/*N*/ if( pNumRule )
+/*N*/ lcl_sw3io__ConvertNumLRSpace( *pNd, *pNumRule,
+/*N*/ pNdNum->GetLevel(),
+/*N*/ !IsVersion(SWG_NUMRELSPACE) );
+/*N*/ }
+/*N*/ #endif
+/*N*/
+/*N*/ rPos++;
+/*N*/ }
+
+// Zaehlen der Worte eines Nodes
+//!! Wird auch vom SW2-Reader benutzt!!
+
+/*N*/ void sw3io_countwords( const String& rDelimWrd, const String& rStr,
+/*N*/ ULONG &rWords, ULONG &rChars )
+/*N*/ {
+/*N*/ FASTBOOL bInWord = FALSE;
+/*N*/ USHORT nSpChars = 0;
+/*N*/
+/*N*/ for( xub_StrLen nPos = 0; nPos < rStr.Len(); nPos++ )
+/*N*/ {
+/*N*/ sal_Unicode c = rStr.GetChar( nPos );
+/*N*/ switch( c )
+/*N*/ {
+/*N*/ case CH_TXTATR_BREAKWORD:
+/*N*/ case CH_TXTATR_INWORD:
+/*N*/ ++nSpChars;
+/*N*/ break;
+/*N*/
+/*N*/ case 0x0A:
+/*N*/ ++nSpChars;
+/*N*/ if ( bInWord )
+/*N*/ {
+/*N*/ rWords++;
+/*N*/ bInWord = FALSE;
+/*N*/ }
+/*N*/ break;
+/*N*/
+/*N*/ default:
+/*N*/ if( rDelimWrd.Search( c ) == STRING_NOTFOUND )
+/*N*/ bInWord = TRUE;
+/*N*/ else if ( bInWord )
+/*N*/ {
+/*N*/ rWords++;
+/*N*/ bInWord = FALSE;
+/*N*/ }
+/*N*/ }
+/*N*/ }
+/*N*/
+/*N*/ if( bInWord )
+/*N*/ rWords++;
+/*N*/ rChars += rStr.Len() - nSpChars;
+/*N*/ }
+
+/*N*/ SwInsHardBlankSoftHyph::~SwInsHardBlankSoftHyph()
+/*N*/ {
+/*N*/ for( USHORT n = 0, nCnt = aItems.Count(); n < nCnt; ++n )
+/*N*/ delete aItems[ n ];
+/*N*/ }
+/*N*/ void SwInsHardBlankSoftHyph::AddItem( xub_StrLen nPos, sal_Unicode c )
+/*N*/ {
+/*N*/ SfxPoolItem* pItem = 0;
+/*N*/ switch ( c )
+/*N*/ {
+/*N*/ case CHAR_HARDBLANK: pItem = new SwFmtHardBlank( ' ', FALSE ); break;
+/*?*/ case CHAR_HARDHYPHEN: pItem = new SwFmtHardBlank( '-', FALSE ); break;
+/*N*/ case CHAR_SOFTHYPHEN: pItem = new SwFmtSoftHyph; break;
+/*N*/ }
+/*N*/ if( pItem )
+/*N*/ {
+/*N*/ USHORT nInsPos = aItemStarts.Count();
+/*N*/ aItemStarts.Insert( nPos, nInsPos );
+/*N*/ aItems.C40_INSERT( SfxPoolItem, pItem, nInsPos );
+/*N*/ }
+/*N*/ }
+/*N*/ void SwInsHardBlankSoftHyph::ChangePos( xub_StrLen nHtEnd, xub_StrLen nOffs )
+/*N*/ {
+/*N*/ for( USHORT n = 0, nCnt = aItemStarts.Count(); n < nCnt; ++n )
+/*N*/ {
+/*?*/ xub_StrLen& rStt = aItemStarts[ n ];
+/*?*/ if( rStt >= nHtEnd )
+/*?*/ rStt -= nOffs;
+/*N*/ }
+/*N*/ }
+/*N*/ void SwInsHardBlankSoftHyph::OutAttr( Sw3IoImp& rIo, xub_StrLen nStt,
+/*N*/ xub_StrLen nEnd )
+/*N*/ {
+/*N*/ for( USHORT n = 0, nCnt = aItemStarts.Count(); n < nCnt; ++n )
+/*N*/ {
+/*N*/ xub_StrLen nHtStt = aItemStarts[ n ];
+/*N*/ if( nHtStt >= nStt && nHtStt < nEnd )
+/*N*/ {
+/*N*/ nHtStt -= nStt;
+/*N*/ const SfxPoolItem* pAttr = aItems[ n ];
+/*N*/ rIo.OutAttr( *pAttr, nHtStt, nHtStt );
+/*N*/ }
+/*N*/ }
+/*N*/ }
+
+
+/*N*/ Sw3ExportTxtAttrs *Sw3IoImp::ExportTxtNode( const SwTxtNode& rNd,
+/*N*/ xub_StrLen nStart, xub_StrLen nEnd,
+/*N*/ rtl_TextEncoding eEnc,
+/*N*/ SwInsHardBlankSoftHyph& rHBSH )
+/*N*/ {
+/*N*/ USHORT nCntAttr = rNd.HasHints() ? rNd.GetSwpHints().Count() : 0;
+/*N*/ if( !nCntAttr )
+/*N*/ return 0;
+/*N*/
+/*N*/ // Erstmal nachschauen, ob es ueberhaupt Hints gibt, die einen Export
+/*N*/ // erfordern. Der zusaetzliche Schleifendurchlauf sollte sich in den
+/*N*/ // meisten Faellen lohnen, weil keine Arrays gewartet werden muessen.
+/*N*/ USHORT n;
+/*N*/ BOOL bExport = FALSE;
+/*N*/ for( n = 0; !bExport && n < nCntAttr; n++ )
+/*N*/ {
+/*N*/ const SwTxtAttr* pHt = rNd.GetSwpHints()[n];
+/*N*/ BOOL bHtEnd = BOOL( pHt->GetEnd() != NULL );
+/*N*/ xub_StrLen nHtStart = *pHt->GetStart();
+/*N*/ xub_StrLen nHtEnd = *pHt->GetAnyEnd();
+/*N*/
+/*N*/ if( (bHtEnd && nHtEnd > nStart && nHtStart < nEnd) ||
+/*N*/ (!bHtEnd && nHtStart >= nStart && nHtStart < nEnd ) )
+/*N*/ {
+/*N*/ switch( pHt->GetAttr().Which() )
+/*N*/ {
+/*N*/ case RES_TXTATR_INETFMT:
+/*N*/ // SwFmtINetFmt-Attribute werden als Felder exportiert
+/*N*/ bExport = TRUE;
+/*N*/ break;
+/*N*/
+/*N*/ case RES_TXTATR_FIELD:
+/*N*/ {
+/*N*/ // alle neuen Felder (ab Script-Feld) werden ignoriert
+/*N*/ const SwFmtFld& rFmtFld =
+/*N*/ (const SwFmtFld&)pHt->GetAttr();
+/*N*/ bExport = rFmtFld.GetFld()->Which() >= RES_SCRIPTFLD;
+/*N*/ }
+/*N*/ break;
+/*N*/
+/*N*/ case RES_TXTATR_FLYCNT:
+/*N*/ {
+/*N*/ // zeichengebunde Draw-Formate werden absatz-gebunden
+/*N*/ const SwFmtFlyCnt& rFlyCnt =
+/*N*/ (const SwFmtFlyCnt&)pHt->GetAttr();
+/*N*/ bExport = RES_DRAWFRMFMT == rFlyCnt.GetFrmFmt()->Which();
+/*N*/ }
+/*N*/ break;
+/*N*/ }
+/*N*/
+/*N*/ }
+/*N*/ }
+/*N*/
+/*N*/ if( !bExport )
+/*N*/ return 0;
+/*N*/
+/*N*/ Sw3ExportTxtAttrs *pInfo = new Sw3ExportTxtAttrs;
+/*N*/ xub_StrLen nINetFmtStart = 0, nINetFmtEnd = 0;
+/*N*/ for( n = 0; n < nCntAttr; n++ )
+/*N*/ {
+/*N*/ const SwTxtAttr* pHt = rNd.GetSwpHints()[n];
+/*N*/ BOOL bHtEnd = BOOL( pHt->GetEnd() != NULL );
+/*N*/ xub_StrLen nHtStart = *pHt->GetStart();
+/*N*/ xub_StrLen nHtEnd = *pHt->GetAnyEnd();
+/*N*/
+/*N*/ if( (bHtEnd && nHtEnd > nStart && nHtStart < nEnd) ||
+/*N*/ (!bHtEnd && nHtStart >= nStart && nHtStart < nEnd) )
+/*N*/ {
+/*N*/ // Der Hint liegt zumindest teilweise im Text
+/*N*/ const SfxPoolItem& rAttr = pHt->GetAttr();
+/*N*/ BOOL bInsert = FALSE, bSplit = FALSE;
+/*N*/
+/*N*/ USHORT nWhich = rAttr.Which();
+/*N*/ switch( nWhich )
+/*N*/ {
+/*N*/ case RES_TXTATR_INETFMT:
+/*N*/ // leere SwFmtINetFmt-Hint koennen und muessen ignoriert
+/*N*/ // werden
+/*N*/ if( nHtStart != nHtEnd )
+/*N*/ {
+/*N*/ if( nHtStart >= nINetFmtEnd )
+/*N*/ {
+/*N*/ // das SwFmtINetFmt ist auf dem Top-Level
+/*N*/ nINetFmtStart = nHtStart;
+/*N*/ nINetFmtEnd = nHtEnd;
+/*N*/ bInsert = TRUE;
+/*N*/ }
+/*N*/ else
+/*N*/ {
+/*N*/ // die SwFmtINetFmt-Attribute sind geschachtelt,
+/*N*/ // das auessere muss gesplittet werden
+/*N*/ ASSERT( nHtEnd <= nINetFmtEnd,
+/*N*/ "Seit wann koennen sich gleiche Attribute ueberlappen?" );
+/*N*/ bSplit = TRUE;
+/*N*/ }
+/*N*/ }
+/*N*/ break;
+/*N*/
+/*N*/ default:
+/*N*/ // laut AMA werden alle anderen Attribute an den Grenzen
+/*N*/ // von SwFmtINetFmt-Attributen aufgespannt. Wenn das mal
+/*N*/ // doch nicht der Fall ist, gibt's einen
+/*N*/ ASSERT( nHtStart >= nINetFmtEnd || nHtEnd <= nINetFmtEnd,
+/*N*/ "Ein Attribut ueberlappt sich mit einen SwFmtINetFmt" );
+/*N*/
+/*N*/ // Attribute im inneren eines SwFmtINetFmt werden ignoriert,
+/*N*/ // es sein denn, die spannen genau den Bereich des
+/*N*/ // SwFmtINetFmts auf
+/*N*/ if( nHtStart >= nINetFmtEnd ||
+/*N*/ (nHtStart == nINetFmtStart && nHtEnd == nINetFmtEnd) )
+/*N*/ {
+/*N*/ // das Attribut beginnt erst hinter einen SwFmtINetFmt
+/*N*/ // oder spannt exakt den gleichen Bereich auf
+/*N*/ bInsert = TRUE;
+/*N*/ }
+/*N*/ else if( RES_TXTATR_NOEND_BEGIN <= nWhich &&
+/*N*/ RES_TXTATR_NOEND_END > nWhich )
+/*N*/ {
+/*N*/ // ein Hint ohne Ende muss auch immer eingefuegt werden
+/*N*/ bSplit = TRUE;
+/*N*/ }
+/*N*/ break;
+/*N*/ }
+/*N*/
+/*N*/ if( bInsert )
+/*N*/ {
+/*N*/ // das Item als letztes an seiner Start-Position beginnen,
+/*N*/ // aber in jedem Fall vor einem SwFmtINetFmt
+/*N*/ USHORT nAPos = pInfo->aItemStarts.Count();
+/*N*/ while( nAPos > 0 &&
+/*N*/ ( (pInfo->aItemStarts[nAPos-1] > nHtStart) ||
+/*N*/ (pInfo->aItemStarts[nAPos-1] == nHtStart &&
+/*N*/ RES_TXTATR_INETFMT==pInfo->aItems[nAPos-1]->Which()) ) )
+/*N*/ nAPos--;
+/*N*/
+/*N*/ pInfo->aItemStarts.Insert( nHtStart, nAPos );
+/*N*/ pInfo->aItemEnds.Insert( nHtEnd, nAPos );
+/*N*/ const SfxPoolItem *pItem = &rAttr;
+/*N*/ pInfo->aItems.C40_INSERT( SfxPoolItem, pItem, nAPos );
+/*N*/ }
+/*N*/ else if( bSplit )
+/*N*/ {
+/*N*/ // Ein anderes SwFmtINetFmt splitten. Dazu muss zunaechst
+/*N*/ // das umgebende gesucht werden.
+/*?*/ USHORT nAPos = pInfo->aItemStarts.Count();
+/*?*/ while( nAPos > 0 && pInfo->aItemStarts[nAPos-1] > nHtStart )
+/*?*/ nAPos--;
+/*?*/
+/*?*/ // es muss ein Attribut geben, das zuvor geoffent wurde
+/*?*/ ASSERT( nAPos, "kein Attribut gefunden" );
+/*?*/ if( !nAPos )
+/*?*/ continue;
+/*?*/ nAPos--;
+/*?*/
+/*?*/ // Das unmittlabr vor der aktuellen Position geoffente
+/*?*/ // Attribut kann auch ein Text-Attribut ohen Ende sein
+/*?*/ const SfxPoolItem *pLastItem = pInfo->aItems[nAPos];
+/*?*/ if( RES_TXTATR_NOEND_BEGIN <= pLastItem->Which() &&
+/*?*/ RES_TXTATR_NOEND_END > pLastItem->Which())
+/*?*/ {
+/*?*/ ASSERT( bHtEnd, "zwei Hints ohne Ende an gleicher Pos.?" );
+/*?*/ // es muss dann aber an der aktuellen Position beginnen
+/*?*/ ASSERT( pInfo->aItemStarts[nAPos]==nHtStart,
+/*?*/ "Text-Attribut ohne Ende an falscher Position" );
+/*?*/ if( pInfo->aItemStarts[nAPos]==nHtStart )
+/*?*/ continue;
+/*?*/
+/*?*/ // das Feld ein Zeichen spater beginnen
+/*?*/ nHtStart++;
+/*?*/ if( nHtStart-nHtEnd == 0 )
+/*?*/ continue;
+/*?*/
+/*?*/ nAPos++;
+/*?*/ ASSERT( nAPos<pInfo->aItems.Count(),
+/*?*/ "Wo ist das SwFmtINetFmt geblieben?" );
+/*?*/ pLastItem = pInfo->aItems[nAPos];
+/*?*/ }
+/*?*/
+/*?*/ // muss ein SwFmtINetFmt-Attribut sein!
+/*?*/ xub_StrLen nLastEnd = pInfo->aItemEnds[nAPos];
+/*?*/ ASSERT( RES_TXTATR_INETFMT==pLastItem->Which(),
+/*?*/ "das umgebende Item muesste ein SwFmtINetFmt sein!!" );
+/*?*/ if( !RES_TXTATR_INETFMT==pLastItem->Which() )
+/*?*/ continue;
+/*?*/
+/*?*/ // das bisherige Attribut vorzeitig beenden, wenn es dann
+/*?*/ // nicht leer ist und sonst loeschen.
+/*?*/ if( pInfo->aItemStarts[nAPos] < nHtStart )
+/*?*/ {
+/*?*/ pInfo->aItemEnds[nAPos] = nHtStart;
+/*?*/ nAPos++;
+/*?*/ }
+/*?*/ else
+/*?*/ {
+/*?*/ pInfo->aItemStarts.Remove( nAPos, 1 );
+/*?*/ pInfo->aItemEnds.Remove( nAPos, 1 );
+/*?*/ pInfo->aItems.Remove( nAPos, 1 );
+/*?*/ }
+/*?*/
+/*?*/ // jetzt fuegen wir das neue Attribut ein
+/*?*/ pInfo->aItemStarts.Insert( nHtStart, nAPos );
+/*?*/ pInfo->aItemEnds.Insert( nHtEnd, nAPos );
+/*?*/ const SfxPoolItem *pItem = &rAttr;
+/*?*/ pInfo->aItems.C40_INSERT( SfxPoolItem, pItem, nAPos );
+/*?*/ nAPos++;
+/*?*/
+/*?*/ // und noch den Rest von dem alten Attribut, wenn er nicht
+/*?*/ // leer ist
+/*?*/ if( !bHtEnd )
+/*?*/ nHtEnd++;
+/*?*/ if( nHtEnd < nLastEnd )
+/*?*/ {
+/*?*/ pInfo->aItemStarts.Insert( nHtEnd, nAPos );
+/*?*/ pInfo->aItemEnds.Insert( nLastEnd, nAPos );
+/*?*/ pInfo->aItems.C40_INSERT( SfxPoolItem, pLastItem, nAPos );
+/*?*/ }
+/*N*/ }
+/*N*/ }
+/*N*/ }
+/*N*/
+/*N*/ // jetzt muessen noch der Text und die Positionen der Hints angepasst
+/*N*/ // werden
+/*N*/ String aText( rNd.GetTxt() );
+/*N*/ const SvxFontItem& rFont = rNd.GetSwAttrSet().GetFont();
+/*N*/ ConvertText( pInfo->aText, aText, 0, (SwTxtNode& )rNd, eEnc,
+/*N*/ rFont,
+/*N*/ &rHBSH, TRUE );
+/*N*/ for( USHORT nAPos=0; nAPos<pInfo->aItems.Count(); nAPos++ )
+/*N*/ {
+/*N*/ const SfxPoolItem *pAttr = pInfo->aItems[nAPos];
+/*N*/ xub_StrLen nHtStart = pInfo->aItemStarts[nAPos];
+/*N*/ xub_StrLen nHtEnd = pInfo->aItemEnds[nAPos];
+/*N*/ xub_StrLen nOffs = 0;
+/*N*/ BOOL bRemoveTxtAttr = FALSE;
+/*N*/ switch( pAttr->Which() )
+/*N*/ {
+/*N*/ case RES_TXTATR_INETFMT:
+/*N*/ // wieviel muss gelosecht werden ?
+/*N*/ nOffs = (nHtEnd - nHtStart) - 1;
+/*N*/
+/*N*/ // den Text ses SwFmtINetFmt merken
+/*N*/ pInfo->aINetFmtTexts.Insert(
+/*N*/ new ByteString( pInfo->aText.Copy( nHtStart, nOffs+1 ) ),
+/*N*/ pInfo->aINetFmtTexts.Count() );
+/*N*/
+/*N*/ // und noch den auszugebenden Text anpassen
+/*N*/ pInfo->aText.SetChar( nHtStart, '\xff' );
+/*N*/ nHtStart++;
+/*N*/ break;
+/*N*/
+/*?*/ case RES_TXTATR_FIELD:
+/*?*/ {
+/*?*/ const SwFmtFld *pFmtFld =
+/*?*/ (const SwFmtFld *)pAttr;
+/*?*/ if( pFmtFld->GetFld()->Which() >= RES_SCRIPTFLD )
+/*?*/ bRemoveTxtAttr = TRUE;
+/*?*/ }
+/*?*/ break;
+/*?*/
+/*?*/ case RES_TXTATR_FLYCNT:
+/*?*/ {
+/*?*/ const SwFmtFlyCnt *pFlyCnt = (const SwFmtFlyCnt *)pAttr;
+/*?*/ if( RES_DRAWFRMFMT == pFlyCnt->GetFrmFmt()->Which() )
+/*?*/ {
+/*?*/ bRemoveTxtAttr = TRUE;
+/*?*/ pInfo->nDrawFrmFmts++;
+/*?*/ }
+/*?*/ }
+/*?*/ break;
+/*N*/ }
+/*N*/
+/*N*/ if( bRemoveTxtAttr )
+/*N*/ {
+/*?*/ nOffs = 1;
+/*?*/ nHtEnd += 1;
+/*?*/ pInfo->aItemStarts.Remove( nAPos, 1 );
+/*?*/ pInfo->aItemEnds.Remove( nAPos, 1 );
+/*?*/ pInfo->aItems.Remove( nAPos, 1 );
+/*?*/ nAPos--; // nicht schoen, aber wirksam
+/*N*/ }
+/*N*/
+/*N*/ // die Start- und Ende-Positionen korregieren
+/*N*/ if( nOffs )
+/*N*/ {
+/*N*/ for( USHORT i=0; i<pInfo->aItems.Count(); i++ )
+/*N*/ {
+/*N*/ if( pInfo->aItemStarts[i] >= nHtEnd )
+/*N*/ pInfo->aItemStarts[i] -= nOffs;
+/*N*/ if( pInfo->aItemEnds[i] >= nHtEnd )
+/*N*/ pInfo->aItemEnds[i] -= nOffs;
+/*N*/ }
+/*N*/
+/*N*/ rHBSH.ChangePos( nHtEnd, nOffs );
+/*N*/ pInfo->aText.Erase( nHtStart, nOffs );
+/*N*/
+/*N*/ if( nEnd != STRING_LEN )
+/*N*/ nEnd -= nOffs;
+/*N*/ }
+/*N*/ }
+/*N*/
+/*N*/ if( nEnd == STRING_LEN || nEnd < nStart )
+/*N*/ nEnd = pInfo->aText.Len();
+/*N*/ else if ( nEnd != pInfo->aText.Len() )
+/*?*/ pInfo->aText.Erase( nEnd );
+/*N*/ if( nStart )
+/*?*/ pInfo->aText.Erase( 0, nStart );
+/*N*/
+/*N*/ return pInfo;
+/*N*/ }
+
+
+/*N*/ void lcl_sw3io__ConvertNumTabStop( const SwCntntNode& rCNd, long nOffset,
+/*N*/ SfxItemSet& rItemSet )
+/*N*/ {
+/*N*/ const SfxPoolItem* pItem;
+/*N*/ if( SFX_ITEM_SET == rCNd.GetSwAttrSet().GetItemState(
+/*N*/ RES_PARATR_TABSTOP, TRUE, &pItem ))
+/*N*/ {
+/*N*/ SvxTabStopItem aTStop( *(SvxTabStopItem*)pItem );
+/*N*/ lcl_sw3io__ConvertNumTabStop( aTStop, nOffset );
+/*N*/ rItemSet.Put( aTStop );
+/*N*/ }
+/*N*/ }
+
+// Text Node:
+// BYTE Flags
+// 0x10 - mit Numerierung
+// 0x20 - Wrong-Liste ist nicht dirty
+// UINT16 String-Index der Absatzvorlage
+// BYTE Numerierungs-Level (opt.)
+// String Text
+// SWG_ATTRSET eigene Attribute (opt.)
+// SWG_FLYFMT FlyFrame (opt).
+// SWG_SDRFMT Drawing-Objekt (opt).
+// SWG_TEXTATTR harte Attribute (opt, mehrfach).
+// SWG_WRONGLIST Liste falscher Worte (opt)
+
+/*N*/ void Sw3IoImp::OutTxtNode
+/*N*/ ( SwCntntNode & rNode, xub_StrLen nStart, xub_StrLen nEnd, ULONG nPosIdx )
+/*N*/ {
+/*N*/ SwTxtNode *pNd = &((SwTxtNode&) rNode );
+/*N*/ const SwFmtColl* pColl = &pNd->GetAnyFmtColl();
+/*N*/ ASSERT( pColl != pDoc->GetDfltTxtFmtColl(),
+/*N*/ "the default text format collection isn't allowed on a node" );
+/*N*/ BOOL bNewNumRule = FALSE;
+/*N*/ // 0x0L: Laenge der Daten
+/*N*/ // 0x10: Numerierung folgt (nur 3.1/4.0)
+/*N*/ // 0x20: Wrong-Liste ist nicht dirty
+/*N*/ BYTE cFlags = IsSw31Export() ? 0x02 : 0x04; // CollIdx & CondCollIdx
+/*N*/ USHORT nColl = aStringPool.Add( pColl->GetName(),
+/*N*/ pColl->GetPoolFmtId() );
+/*N*/ BYTE cNumLevel = NO_NUMBERING;
+/*N*/
+/*N*/ // Numerierungsregel fuer 3.1/4.0-Export ermitteln
+/*N*/ const SwNodeNum *pNdNum = pNd->GetNum();
+/*N*/ #ifdef DBG_UTIL
+/*N*/ {
+/*N*/ const SwNumRule* pNumRule = pNd->GetNumRule();
+/*N*/ ASSERT( pNumRule ? pNdNum!=0 : TRUE,
+/*N*/ "Node hat NumRule aber kein NodeNum" );
+/*N*/ ASSERT( pNdNum ? pNumRule!=0 : TRUE,
+/*N*/ "Node hat NodeNum aber keine NumRule" );
+/*N*/ }
+/*N*/ #endif
+/*N*/
+/*N*/ SfxItemSet *pExportAttrSet = 0;
+/*N*/ const SfxItemSet *pAttrSet = rNode.GetpSwAttrSet();
+/*N*/
+/*N*/ if( pNdNum && pNdNum->GetLevel() != NO_NUMBERING )
+/*N*/ {
+/*N*/ const SwNumRule* pNumRule = pNd->GetNumRule();
+/*N*/ if( pNumRule )
+/*N*/ {
+/*N*/ cNumLevel = pNdNum->GetLevel();
+/*N*/ BYTE cRealLevel = GetRealLevel( cNumLevel );
+/*N*/ if( IsSw31Or40Export() )
+/*N*/ {
+/*N*/ if( cRealLevel >= OLD_MAXLEVEL )
+/*N*/ {
+/*N*/ // Die Numerierungs-Ebene ist zu hoch => die
+/*N*/ // hoechst moegliche setzen
+/*N*/ BYTE cTmp = OLD_MAXLEVEL-1;
+/*N*/ if( cNumLevel & NO_NUMLEVEL )
+/*N*/ cTmp |= NO_NUMLEVEL;
+/*N*/ cNumLevel = cTmp;
+/*N*/ }
+/*N*/ if( IsSw31Export() )
+/*N*/ cFlags += NO_NUMLEVEL & cNumLevel ? 0x12 : 0x11;
+/*N*/ else
+/*N*/ cFlags += 0x11;
+/*N*/ if( pNumRule != pCurNumRule )
+/*N*/ {
+/*N*/ // Dann vor dem betroffenen Node ausgeben
+/*N*/ pCurNumRule = (SwNumRule *)pNumRule;
+/*N*/
+/*N*/ //JP 06.10.95: falls SH mal wieder mit der Numerierung
+/*N*/ //durcheinander kommt
+/*N*/ // bNewNumRule = TRUE;
+/*N*/ bNewNumRule = 0 != pCurNumRule;
+/*N*/ }
+/*N*/ }
+/*N*/
+/*N*/ #ifdef NUM_RELSPACE
+/*N*/ // Den Erstzeilen-Einzug immer aus der NumRule uebernehmen
+/*N*/ // und als linken Einzug die Summe aus Absatz- und
+/*N*/ // NumRule-Einzug schreiben.
+/*N*/ const SwNumFmt& rNumFmt = pNumRule->Get( cRealLevel );
+/*N*/ const SvxLRSpaceItem& rLRSpace =
+/*N*/ (const SvxLRSpaceItem&)rNode.GetAttr(RES_LR_SPACE);
+/*N*/
+/*N*/ USHORT nLeft = rNumFmt.GetAbsLSpace();
+/*N*/ USHORT nOldLeft = (USHORT)rLRSpace.GetTxtLeft();
+/*N*/ if( !pNumRule->IsAbsSpaces() )
+/*N*/ nLeft += (USHORT)rLRSpace.GetTxtLeft();
+/*N*/ short nFirstLineOffset =
+/*N*/ (cNumLevel & NO_NUMLEVEL)==0 ? rNumFmt.GetFirstLineOffset() : 0;
+/*N*/ if( nLeft != rLRSpace.GetTxtLeft() ||
+/*N*/ nFirstLineOffset != rLRSpace.GetTxtFirstLineOfst() )
+/*N*/ {
+/*N*/ if( pAttrSet )
+/*N*/ pExportAttrSet = new SfxItemSet( *pAttrSet );
+/*N*/ else
+/*?*/ pExportAttrSet = new SfxItemSet( pDoc->GetAttrPool(),
+/*?*/ pColl->GetAttrSet().GetRanges() );
+/*N*/ pAttrSet = pExportAttrSet;
+/*N*/ SvxLRSpaceItem aLRSpace( rLRSpace );
+/*N*/ aLRSpace.SetTxtFirstLineOfst( nFirstLineOffset );
+/*N*/ aLRSpace.SetTxtLeft( nLeft );
+/*N*/
+/*N*/ pExportAttrSet->Put( aLRSpace );
+/*N*/
+/*N*/ if( IsSw31Or40Export() && nOldLeft != nLeft )
+/*N*/ lcl_sw3io__ConvertNumTabStop( rNode,
+/*N*/ (long)nOldLeft - (long)nLeft,
+/*N*/ *pExportAttrSet );
+/*N*/ }
+/*N*/ #endif
+/*N*/ }
+/*N*/ else if( IsSw31Or40Export() )
+/*N*/ pCurNumRule = NULL;
+/*N*/
+/*N*/ }
+/*N*/ else if( IsSw31Or40Export() )
+/*N*/ {
+/*N*/ pCurNumRule = NULL;
+/*N*/ }
+/*N*/
+/*N*/ // Wrong-List-Dirty-Flag (wird wegen alter doks invers gespeichert)
+/*N*/ if( !IsSw31Export() && !rNode.IsWrongDirty() )
+/*N*/ cFlags += 0x20;
+/*N*/
+/*N*/ OpenRec( SWG_TEXTNODE );
+/*N*/ *pStrm << cFlags << nColl;
+/*N*/ if( IsSw31Or40Export() && (cFlags & 0x10) )
+/*N*/ {
+/*N*/ // Frueher wurde hier fuer NO_NUMLEVEL noch ein NO_NUM
+/*N*/ // rausgeschrieben. Ist jetzt nicht mehr noetig.
+/*N*/ //if( NO_NUMLEVEL & cNumLevel )
+/*N*/ // *pStrm << (BYTE)NO_NUM << cNumLevel;
+/*N*/ //else
+/*N*/ if( IsSw31Export() && (NO_NUMLEVEL & cNumLevel) )
+/*?*/ *pStrm << (BYTE)NO_NUM << cNumLevel;
+/*N*/ else
+/*N*/ *pStrm << cNumLevel;
+/*N*/ }
+/*N*/
+/*N*/ // bedingte Vorlagen nicht beim SW31-Export rausschreiben
+/*N*/ if( !IsSw31Export() )
+/*N*/ {
+/*N*/ USHORT nCondColl = IDX_DFLT_VALUE;
+/*N*/ if( pNd->GetCondFmtColl() )
+/*N*/ {
+/*N*/ // dann die bedingte Vorlage schreiben!!
+/*?*/ pColl = pNd->GetFmtColl();
+/*?*/ nCondColl =
+/*?*/ aStringPool.Add( pColl->GetName(), pColl->GetPoolFmtId() );
+/*N*/ }
+/*N*/ *pStrm << nCondColl;
+/*N*/ }
+/*N*/
+/*N*/ #ifdef NUM_RELSPACE
+/*N*/ // Wenn der Absatz ein LRSpace-Item enthaelt und in der Kapitel-Numerierung
+/*N*/ // ist muss das LRSpace-Item noch angepasst werden. Relative Werte
+/*N*/ // koennen dabei nicht vorkommen. Der Ertzeilen-Einzug geht verloren.
+/*N*/ const SwNumRule *pOutline = pDoc->GetOutlineNumRule();
+/*N*/ const SfxPoolItem *pItem;
+/*N*/ if( pAttrSet && (!pNdNum || NO_NUMBERING == pNdNum->GetLevel()) &&
+/*N*/ NO_NUMBERING != ((const SwTxtFmtColl *)pColl)->GetOutlineLevel() &&
+/*N*/ SFX_ITEM_SET == pAttrSet->GetItemState( RES_LR_SPACE, FALSE, &pItem ) &&
+/*N*/ pOutline )
+/*N*/ {
+/*?*/ const SvxLRSpaceItem *pParaLRSpace = (const SvxLRSpaceItem *)pItem;
+/*?*/
+/*?*/ const SwNumFmt& rNumFmt = pOutline->Get(
+/*?*/ GetRealLevel(((const SwTxtFmtColl *)pColl)->GetOutlineLevel()) );
+/*?*/ USHORT nLSpace = (USHORT)pParaLRSpace->GetTxtLeft();
+/*?*/ USHORT nOldLSpace = nLSpace;
+/*?*/ if( pOutline->IsAbsSpaces() )
+/*?*/ nLSpace = rNumFmt.GetAbsLSpace();
+/*?*/ else
+/*?*/ nLSpace += rNumFmt.GetAbsLSpace();
+/*?*/
+/*?*/ if( nLSpace != pParaLRSpace->GetTxtLeft() ||
+/*?*/ rNumFmt.GetFirstLineOffset()!=pParaLRSpace->GetTxtFirstLineOfst() )
+/*?*/ {
+/*?*/ if( !pExportAttrSet )
+/*?*/ {
+/*?*/ pExportAttrSet = new SfxItemSet( *pAttrSet );
+/*?*/ pAttrSet = pExportAttrSet;
+/*?*/ }
+/*?*/
+/*?*/ SvxLRSpaceItem aLRSpace( *pParaLRSpace );
+/*?*/ aLRSpace.SetTxtFirstLineOfst( rNumFmt.GetFirstLineOffset());
+/*?*/ aLRSpace.SetTxtLeft( nLSpace );
+/*?*/ pExportAttrSet->Put( aLRSpace );
+/*?*/
+/*?*/ if( IsSw31Or40Export() && nOldLSpace != nLSpace )
+/*?*/ lcl_sw3io__ConvertNumTabStop( rNode,
+/*?*/ (long)nOldLSpace - (long)nLSpace,
+/*?*/ *pExportAttrSet );
+/*?*/ }
+/*N*/ }
+/*N*/ #endif
+/*N*/
+/*N*/ if( (nEnd == STRING_LEN ? pNd->GetTxt().Len() : nEnd) > STRING_MAXLEN52 )
+/*N*/ nEnd = STRING_MAXLEN52;
+/*N*/
+/*N*/ SwInsHardBlankSoftHyph aHBSH;
+/*N*/
+/*N*/ String aText;
+/*N*/ Sw3ExportTxtAttrs *pExpInfo = IsSw31Export()
+/*N*/ ? ExportTxtNode( *pNd, nStart, nEnd, eSrcSet, aHBSH )
+/*N*/ : 0;
+/*N*/
+/*N*/ ByteString aText8;
+/*N*/ if( !pExpInfo )
+/*N*/ {
+/*N*/ aText = pNd->GetTxt();
+/*N*/ if( nEnd == STRING_LEN || nEnd < nStart )
+/*N*/ nEnd = aText.Len();
+/*N*/ else if ( nEnd != aText.Len() )
+/*?*/ aText.Erase( nEnd );
+/*N*/ if( nStart )
+/*?*/ aText.Erase( 0, nStart );
+/*N*/ const SvxFontItem& rFont = pNd->GetSwAttrSet().GetFont();
+/*N*/ ConvertText( aText8, aText, nStart, *pNd, eSrcSet,
+/*N*/ rFont, &aHBSH, TRUE );
+/*N*/ }
+/*N*/ else
+/*N*/ aText8 = pExpInfo->aText;
+/*N*/
+/*N*/ if( aText.Len() )
+/*N*/ sw3io_countwords( aDefWordDelim, aText, aStat.nWord, aStat.nChar );
+/*N*/
+/*N*/ if( aText8.Len() && pCrypter )
+ pCrypter->Encrypt( aText8 );
+/*N*/ pStrm->WriteByteString( aText8 );
+/*N*/ aStat.nPara++;
+/*N*/
+/*N*/ if( pAttrSet )
+/*N*/ OutAttrSet( *pAttrSet );
+/*N*/ delete pExportAttrSet;
+/*N*/ pAttrSet = pExportAttrSet = 0;
+/*N*/ OutNodeMarks( nPosIdx );
+/*N*/
+/*N*/ // die absatzgebunden Rahmen schreiben und beim SW31-Export ggf. auch
+/*N*/ // noch die zeichengebunden Zeichen-Objekte als abstzgebundene Objekte
+/*N*/ OutNodeFlyFrames( nPosIdx );
+/*N*/ if( pExpInfo && pExpInfo->nDrawFrmFmts )
+ ExportNodeDrawFrmFmts( *pNd, nStart, nEnd, pExpInfo->nDrawFrmFmts );
+/*N*/
+/*N*/ // Beim SW31-Export evtl. die "umgebauten" Hints ausgeben, sonst die
+/*N*/ // Original-Hints
+/*N*/ if( pExpInfo )
+/*N*/ ExportTxtAttrs( pExpInfo, nStart, nEnd );
+/*N*/ else if( ((SwTxtNode&)rNode).HasHints() )
+/*N*/ OutTxtAttrs( *pNd, nStart, nEnd );
+/*N*/ aHBSH.OutAttr( *this, nStart, nEnd );
+/*N*/
+/*N*/ // Evtl. noch die neue Numerierungsregel (3.1/4.0) oder die
+/*N*/ // SwNodeNum-Struktor (5.0 ff) ausgeben
+/*N*/ if( IsSw31Or40Export() )
+/*N*/ {
+/*N*/ if( bNewNumRule )
+/*N*/ OutNumRule( SWG_NUMRULE, *pCurNumRule );
+/*N*/ }
+/*N*/ else if( pNdNum )
+/*N*/ {
+/*N*/ OutNodeNum( *pNdNum );
+/*N*/ }
+/*N*/
+/*N*/ // Eventuell noch die Wrong-Liste
+/*N*/ const SwWrongList* pWrong = pNd->GetWrong();
+/*N*/ if( !IsSw31Export() && pWrong )
+/*N*/ {
+/*N*/ OpenRec( SWG_WRONGLIST );
+/*N*/
+/*N*/ // der Header
+/*N*/ cFlags = 0x04; // 4 Bytes Daten
+/*N*/ xub_StrLen nBegin = pWrong->GetBeginInv();
+/*N*/ if( nBegin > STRING_MAXLEN52 )
+/*N*/ nBegin = STRING_MAXLEN52;
+/*N*/
+/*N*/ xub_StrLen nEnd = pWrong->GetEndInv();
+/*N*/ if( nEnd > STRING_MAXLEN52 )
+/*N*/ nEnd = STRING_MAXLEN52;
+/*N*/
+/*N*/ *pStrm << cFlags
+/*N*/ << (UINT16)nBegin
+/*N*/ << (UINT16)nEnd;
+/*N*/
+/*N*/ // nun die eigentliche Liste
+/*N*/ OpenValuePos16( 0 );
+/*N*/ USHORT nCount = pWrong->Count();
+/*N*/ for( USHORT i=0; i<nCount; i++ )
+/*N*/ {
+/*N*/ xub_StrLen nIdx = pWrong->Pos( i );
+/*N*/ if( nIdx < STRING_MAXLEN52 )
+/*N*/ {
+/*N*/ xub_StrLen nLen = pWrong->Len( i );
+/*N*/ if( nIdx + nLen > STRING_MAXLEN52 )
+/*N*/ nLen = STRING_MAXLEN52 - nIdx;
+/*N*/ UINT32 n = nIdx + (nLen << 16);
+/*N*/ *pStrm << n;
+/*N*/ }
+/*N*/ }
+/*N*/ CloseValuePos16( nCount );
+/*N*/ CloseRec( SWG_WRONGLIST );
+/*N*/ }
+/*N*/
+/*N*/ if( !IsSw31Or40Export() )
+/*N*/ {
+/*N*/ // Redline-Markierungen rausschreiben. Muss wegen geloeschter
+/*N*/ // Redlines immer als letztes passieren, weil beim Einfuegen
+/*N*/ // eines solechen Doks Attribute schon gesetzt sein muessen!
+/*N*/ OutNodeRedlines( nPosIdx );
+/*N*/ }
+/*N*/
+/*N*/ CloseRec( SWG_TEXTNODE );
+/*N*/ }
+
+/*N*/ void Sw3IoImp::OutEmptyTxtNode( ULONG nNodeIdx, BOOL bNodeMarks )
+/*N*/ {
+/*N*/ // 0x0L: length of data
+/*N*/ // 0x20: wrong list is valid
+/*N*/ BYTE cFlags = 0x24; // CollIdx & CondCollIdx
+/*N*/ USHORT nColl = aStringPool.Add( *SwStyleNameMapper::GetTextUINameArray()
+/*N*/ [ RES_POOLCOLL_STANDARD - RES_POOLCOLL_TEXT_BEGIN ],
+/*N*/ RES_POOLCOLL_STANDARD );
+/*N*/
+/*N*/ OpenRec( SWG_TEXTNODE );
+/*N*/ *pStrm << cFlags << nColl << IDX_DFLT_VALUE;
+/*N*/ OutString( *pStrm, aEmptyStr );
+/*N*/
+/*N*/ if( bNodeMarks )
+/*?*/ OutNodeMarks( nNodeIdx );
+/*N*/
+/*N*/ aStat.nPara++;
+/*N*/ CloseRec( SWG_TEXTNODE );
+/*N*/ }
+
+// nOffset ist ungleich Null, wenn innerhalb eines Nodes eingefuegt werden
+// soll. Dann ist nOffset die Start-Position des Textes.
+
+/*N*/ void Sw3IoImp::InTxtAttr( SwTxtNode& rNd, const ByteString& rText8,
+/*N*/ xub_StrLen nOffset,
+/*N*/ SvStringsDtor **pINetFldTexts,
+/*N*/ SvXub_StrLens **pINetFldPoss,
+/*N*/ SvXub_StrLens **pErasePoss,
+/*N*/ SvUShorts **pCharSetColorEncs,
+/*N*/ SvXub_StrLens **pCharSetColorPoss )
+/*N*/ {
+/*N*/ // Dieser Record kann auch leer sein
+/*N*/ // (bei teilweisem Speichern eines Nodes, z.B.)
+/*N*/ xub_StrLen nLen = rNd.GetTxt().Len();
+/*N*/ if( nLen ) nLen --;
+/*N*/ xub_StrLen nStart, nEnd;
+/*N*/ SfxPoolItem* pItem = InAttr( nStart, nEnd, &rNd );
+/*N*/ if( !pItem )
+/*N*/ {
+/*N*/ if( bDrawFmtSkipped )
+/*N*/ {
+/*N*/ ASSERT( bInsIntoHdrFtr,
+/*?*/ "Draw-Formate durften nur in Kopf-/Fusszeilen geloecht werden" );
+/*?*/ ASSERT( CH_TXTATR_BREAKWORD == rNd.GetTxt().GetChar(nStart) ||
+/*?*/ CH_TXTATR_INWORD == rNd.GetTxt().GetChar(nStart),
+/*?*/ "Wo ist das 0xff des Draw-Formats?" );
+/*?*/
+/*?*/ if( !(*pErasePoss) )
+/*?*/ *pErasePoss = new SvXub_StrLens;
+/*?*/ (*pErasePoss)->Insert( nStart, (*pErasePoss)->Count() );
+/*?*/
+/*?*/ bDrawFmtSkipped = FALSE;
+/*?*/ return;
+/*N*/ }
+/*N*/
+/*N*/ if( !pFmtINetFmt )
+/*N*/ return;
+/*N*/
+/*N*/ // Es wurde ein INetFlield gelesen und in einen INet-Attribut
+/*N*/ // umgewandelt
+/*N*/
+/*N*/ // Text und Position merken
+/*N*/ if( !(*pINetFldTexts) )
+/*N*/ *pINetFldTexts = new SvStringsDtor;
+/*N*/ (*pINetFldTexts)->Insert( new String( aINetFldText ),
+/*N*/ (*pINetFldTexts)->Count() );
+/*N*/ if( !(*pINetFldPoss) )
+/*N*/ *pINetFldPoss = new SvXub_StrLens;
+/*N*/ (*pINetFldPoss)->Insert( nStart, (*pINetFldPoss)->Count() );
+/*N*/
+/*N*/ if( aINetFldText.Len() )
+/*N*/ {
+/*N*/ // ggf. das Attribut ueber dem =xff aufspannen
+/*N*/ // das Item wird ann unten geloescht
+/*N*/ pItem = pFmtINetFmt;
+/*N*/ nEnd++;
+/*N*/ aINetFldText.Erase();
+/*N*/ }
+/*N*/ else
+/*N*/ {
+/*N*/ // leere Felder nicht einfuegen
+/*N*/ delete pFmtINetFmt;
+/*N*/ }
+/*N*/
+/*N*/ pFmtINetFmt = 0;
+/*N*/
+/*N*/ if( !pItem )
+/*N*/ return;
+/*N*/ }
+/*N*/
+/*N*/ if( nEnd < nStart ) nEnd = nLen;
+/*N*/ nStart += nOffset;
+/*N*/ nEnd += nOffset;
+/*N*/ USHORT nWhich = pItem->Which();
+/*N*/ if( nWhich == RES_TXTATR_FTN )
+/*N*/ {
+/*N*/ //JP 02.12.96:
+/*N*/ // Das Fussnoten-Attribut liest seine Section "auf der Wiese" ein
+/*N*/ // und erzeugt auch ihr TextAttribut (weil an dem noch weitere
+/*N*/ // Informationen gesetzt werden muessen - Referenznummer)
+/*N*/ SwTxtFtn& rFtn = *((SwFmtFtn*)pItem)->GetTxtFtn();
+/*N*/ *rFtn.GetStart() = nStart;
+/*N*/ rNd.Insert( &rFtn, SETATTR_NOTXTATRCHR );
+/*N*/ return ;
+/*N*/ }
+/*N*/ else if( RES_CHRATR_CHARSETCOLOR == nWhich )
+/*N*/ {
+/*?*/ if( !(*pCharSetColorEncs) )
+/*?*/ *pCharSetColorEncs = new SvUShorts;
+/*?*/ (*pCharSetColorEncs)->Insert(
+/*?*/ ((const SvxCharSetColorItem *)pItem)->GetCharSet(),
+/*?*/ (*pCharSetColorEncs)->Count() );
+/*?*/
+/*?*/ if( !(*pCharSetColorPoss) )
+/*?*/ *pCharSetColorPoss = new SvXub_StrLens;
+/*?*/ (*pCharSetColorPoss)->Insert( nStart, (*pCharSetColorPoss)->Count() );
+/*?*/ (*pCharSetColorPoss)->Insert( nEnd, (*pCharSetColorPoss)->Count() );
+/*N*/ }
+/*N*/ else
+/*N*/ {
+/*N*/ // Bug 31560: mehrere TOX-Marks ohne Ende an der gleichen Position!
+/*N*/ if( nStart == nEnd && (( RES_TXTATR_TOXMARK == nWhich &&
+/*N*/ ((SwTOXMark*)pItem)->IsAlternativeText() ) ||
+/*N*/ ( RES_TXTATR_NOEND_BEGIN <= nWhich && nWhich < RES_TXTATR_NOEND_END )))
+/*N*/ {
+/*N*/ // teste doch mal ob das Zeichen am der Position steht und on
+/*N*/ // an der Position nicht schon ein Attribut ohne Ende gesetzt ist!
+/*N*/ if( '\xff' != rText8.GetChar(nStart-nOffset) )
+/*N*/ {
+/*N*/ nWhich = 0;
+/*N*/ ASSERT( !this, "TextAttribut ohne Ende ohne 0xFF" );
+/*N*/ }
+/*N*/ else
+/*N*/ {
+/*N*/ sal_Unicode cReplace = 0;
+/*N*/ switch( nWhich )
+/*N*/ {
+/*N*/ case RES_TXTATR_TOXMARK:
+/*N*/ {
+/*N*/ // pruefe mal auf doppelte:
+/*N*/ SwTxtAttr* pAttr = rNd.GetTxtAttr( nStart, nWhich );
+/*N*/ if( pAttr )
+/*N*/ {
+/*N*/ nWhich = 0;
+/*N*/ ASSERT( !this, "TOXMark ohne Ende doppelt" );
+/*N*/ }
+/*N*/ }
+/*N*/ break;
+/*N*/ case RES_TXTATR_SOFTHYPH:
+/*N*/ // set the unicode character into the node text
+/*N*/ cReplace = CHAR_SOFTHYPHEN;
+/*N*/ break;
+/*N*/
+/*N*/ case RES_TXTATR_HARDBLANK:
+/*N*/ cReplace = ((SwFmtHardBlank*)pItem)->GetChar();
+/*N*/ if( ' ' == cReplace )
+/*N*/ cReplace = CHAR_HARDBLANK;
+/*N*/ else if( '-' == cReplace )
+/*N*/ cReplace = CHAR_HARDHYPHEN;
+/*N*/ else
+/*N*/ cReplace = 0;
+/*N*/ break;
+/*N*/ }
+/*N*/ if( cReplace )
+/*N*/ {
+/*N*/ rNd.Replace( SwIndex( &rNd, nStart ), cReplace );
+/*N*/ nWhich = 0;
+/*N*/ }
+/*N*/ }
+/*N*/ }
+/*N*/
+/*N*/ if( nWhich )
+/*N*/ {
+/*N*/ SwTxtAttr* pAttr = rNd.Insert( *pItem, nStart, nEnd, SETATTR_NOTXTATRCHR );
+/*N*/ // Sonderbehandlung fuer einige Text-Attribute:
+/*N*/ if( pAttr && RES_TXTATR_FLYCNT == nWhich )
+/*N*/ // ein zeichengebundener FlyFrm muss noch verankert werden
+/*N*/ ((SwTxtFlyCnt*) pAttr)->SetAnchor( &rNd );
+/*N*/ }
+/*N*/ }
+/*N*/ delete pItem;
+/*N*/ }
+
+// Schreiben aller harten Attributierungen
+
+/*N*/ void Sw3IoImp::OutTxtAttrs( const SwTxtNode& rNd, xub_StrLen nStart,
+/*N*/ xub_StrLen nEnd )
+/*N*/ {
+/*N*/ USHORT nCntAttr = rNd.HasHints() ? rNd.GetSwpHints().Count() : 0;
+/*N*/ if( nCntAttr )
+/*N*/ {
+/*N*/ for( USHORT n = 0; n < nCntAttr; n++ )
+/*N*/ {
+/*N*/ const SwTxtAttr* pHt = rNd.GetSwpHints()[ n ];
+/*N*/ BOOL bHtEnd = BOOL( pHt->GetEnd() != NULL );
+/*N*/ xub_StrLen nHtStart = *pHt->GetStart();
+/*N*/ xub_StrLen nHtEnd = *pHt->GetAnyEnd();
+/*N*/
+/*N*/ // MIB 11.11.96: Der Bereich des Hints muss sich nur irgendwie
+/*N*/ // mit dem auszugenden Bereich ueberschneiden
+/*N*/ if( (bHtEnd && nHtEnd > nStart && nHtStart < nEnd) ||
+/*N*/ (!bHtEnd && nHtStart >= nStart && nHtStart < nEnd ) )
+/*N*/ {
+/*N*/ // Der Hint liegt zumindest teilweise im Text, also
+/*N*/ // Start und Ende korrigieren und Hint ausgeben
+/*N*/ nHtStart = ( nHtStart < nStart ) ? 0 : ( nHtStart - nStart );
+/*N*/ nHtEnd = ( nHtEnd > nEnd ? nEnd : nHtEnd ) - nStart;
+/*N*/ const SfxPoolItem& rAttr = pHt->GetAttr();
+/*N*/ OutAttr( rAttr, nHtStart, nHtEnd );
+/*N*/ }
+/*N*/ }
+/*N*/ }
+/*N*/ }
+
+/*N*/ void Sw3IoImp::ExportTxtAttrs( const Sw3ExportTxtAttrs* pInfo,
+/*N*/ xub_StrLen nStart, xub_StrLen nEnd )
+/*N*/ {
+/*N*/ USHORT nINetFmtCnt = 0;
+/*N*/ for( USHORT n = 0; n < pInfo->aItems.Count(); n++ )
+/*N*/ {
+/*N*/ xub_StrLen nHtStart = pInfo->aItemStarts[n];
+/*N*/ xub_StrLen nHtEnd = pInfo->aItemEnds[n];;
+/*N*/
+/*N*/ // Der Hint liegt zumindest teilweise im Text, also
+/*N*/ // Start und Ende korrigieren und Hint ausgeben
+/*N*/ nHtStart = ( nHtStart < nStart ) ? 0 : ( nHtStart - nStart );
+/*N*/ nHtEnd = ( nHtEnd > nEnd ? nEnd : nHtEnd ) - nStart;
+/*N*/ const SfxPoolItem* pAttr = pInfo->aItems[n];
+/*N*/ if( RES_TXTATR_INETFMT==pAttr->Which() )
+/*N*/ {
+/*N*/ // ein SwFmtINetFmtNet muss bei SW31-Export zum Feld werden
+/*N*/
+/*N*/ // Start OutAttr()
+/*N*/ OpenRec( SWG_ATTRIBUTE );
+/*N*/ BYTE cFlags = 0x04; // Which + Version
+/*N*/ cFlags += 0x12; // Begin
+/*N*/ USHORT nWhich = RES_TXTATR_FIELD - RES_TXTATR_NOEND_BEGIN + 0x3000;
+/*N*/ *pStrm << (BYTE) cFlags
+/*N*/ << (UINT16) nWhich
+/*N*/ << (UINT16) 0 // rAttr.GetVersion();
+/*N*/ << (UINT16)nHtStart;
+/*N*/
+/*N*/ // Start SwFmtFld::Store()
+/*N*/
+/*N*/ // Start OutField()
+/*N*/ *pStrm << (INT16) ( RES_INTERNETFLD - RES_FIELDS_BEGIN )
+/*N*/ << (INT16) 0;
+/*N*/
+/*N*/ // Start lcl_sw3io_OutINetField()
+/*N*/ OutString( *pStrm, ::binfilter::StaticBaseUrl::AbsToRel(
+/*N*/ ((const SwFmtINetFmt *)pAttr)->GetValue() URL_DECODE ) );
+/*N*/ pStrm->WriteByteString( *pInfo->aINetFmtTexts[nINetFmtCnt] );
+/*N*/ // Ende lcl_sw3io_OutINetField()
+/*N*/
+/*N*/ // Ende OutField()
+/*N*/
+/*N*/ // Ende SwFmtFld::Store()
+/*N*/
+/*N*/ CloseRec( SWG_ATTRIBUTE );
+/*N*/ // Ende OutAttr()
+/*N*/
+/*N*/ nINetFmtCnt++;
+/*N*/ }
+/*N*/ else
+/*N*/ {
+/*N*/ OutAttr( *pAttr, nHtStart, nHtEnd );
+/*N*/ }
+/*N*/ }
+/*N*/ }
+
+
+// Die Formate von Grafik- und OLE-Nodes muessen nicht registriert
+// werden; die Layout-Frames erhalten ja eine Node-Referenz.
+
+//#define SWG_GRAPHIC_EXT 'X' jetzt SWG_IMAGEMAP
+
+/*N*/ void Sw3IoImp::InGrfNode( SwNodeIndex& rPos )
+/*N*/ {
+/*N*/ Graphic aGrf;
+/*N*/ Graphic* pGrf = &aGrf;
+/*N*/ String aGrfName, aFltName, aStrmName, aURL, aTarget, aAltText;
+/*N*/ ImageMap *pImgMap = 0;
+/*N*/ PolyPolygon *pContour = 0;
+/*N*/ OpenRec( SWG_GRFNODE );
+/*N*/ BYTE cFlags = OpenFlagRec();
+/*N*/ CloseFlagRec();
+/*N*/ BOOL bLink = BOOL( ( cFlags & 0x10 ) == 0 );
+/*N*/ BOOL bEmptyGrf = BOOL( cFlags & 0x20 );
+/*N*/ BOOL bIsServerMap = BOOL( (cFlags & 0x40) != 0 );
+/*N*/
+/*N*/ InString( *pStrm, aGrfName );
+/*N*/ InString( *pStrm, aFltName );
+/*N*/
+/*N*/ if( IsVersion( SWG_DESKTOP40 ) )
+/*N*/ InString( *pStrm, aAltText );
+/*N*/
+/*N*/ aStrmName = aGrfName;
+/*N*/ SwAttrSet aSet( pDoc->GetAttrPool(), aNoTxtNodeSetRange );
+/*N*/ while( BytesLeft() )
+/*N*/ {
+/*N*/ BYTE cType = Peek();
+/*N*/ switch( cType )
+/*N*/ {
+/*N*/ case SWG_ATTRSET:
+/*N*/ InAttrSet( aSet );
+/*N*/ break;
+/*N*/ case SWG_IMAGEMAP:
+/*N*/ {
+/*N*/ BOOL bDummy; // IsURL-Map-Flag wird im Node selbst gesp.
+/*N*/ pImgMap = InImageMap( aURL, aTarget, bDummy );
+/*N*/ }
+/*N*/ break;
+/*N*/
+/*N*/ case SWG_CONTOUR:
+ pContour = InContour();
+/*N*/ break;
+/*N*/
+/*N*/ default:
+/*?*/ SkipRec();
+/*N*/ }
+/*N*/ }
+/*N*/ CloseRec( SWG_GRFNODE );
+/*N*/ if( CheckPersist() )
+/*N*/ {
+/*N*/ // Muss die Grafik noch geladen werden?
+/*N*/ if( !bEmptyGrf )
+/*N*/ {
+/*N*/ if( bLink )
+/*N*/ {
+/*N*/ pGrf = 0;
+/*N*/ if( aGrfName.Len() )
+/*N*/ aGrfName = ::binfilter::StaticBaseUrl::RelToAbs( aGrfName );
+/*N*/ }
+/*N*/ else
+/*N*/ {
+/*N*/ SvStorageRef pPicStg = pRoot->OpenStorage( N_PICTURES,
+/*N*/ STREAM_READ | STREAM_SHARE_DENYWRITE, 0 );
+/*N*/ SvStorageStreamRef pPicStrm;
+/*N*/ if( pPicStg.Is() )
+/*N*/ pPicStrm = pPicStg->OpenStream
+/*N*/ ( aGrfName, STREAM_READ | STREAM_SHARE_DENYWRITE );
+/*N*/ aGrfName.Erase(); // Ist ja gar kein Grafikname!
+/*N*/ ASSERT( pPicStrm.Is() && pPicStrm->GetError() == SVSTREAM_OK, "Grafik nicht gefunden" );
+/*N*/ if( pPicStrm.Is() && pPicStrm->GetError() == SVSTREAM_OK )
+/*N*/ {
+/*N*/ // Wenn kein DocFileName gesetzt ist, wird eine TmpFile
+/*N*/ // erzeugt, was wir im Moment nicht wollen!
+/*N*/ pPicStrm->SetVersion( pRoot->GetVersion() );
+/*N*/ String aDummy( String::CreateFromAscii("file:///Dummy") );
+/*N*/ aGrf.SetDocFileName( aDummy, 0L );
+/*N*/ BOOL bSwapOut = BOOL( !bInsert );
+/*N*/ // Beim SW3.1-Import verliern wir unserden Dok-Storage,
+/*N*/ // also darf die Grafik nicht rausgeswappt werden.
+/*N*/ // MIB 3.9.98: Ausserdem muessen Grafiken immer beim
+/*N*/ // LoadStyles reingeswappt werden, weil dann der Storage
+/*N*/ // aus dem geladen wird nicht unbedingt der Doc-Storage
+/*N*/ // sein muss. Das ist zum Beispiel beim Aktualisieren von
+/*N*/ // Vorlagen aus einer Dokument-Vorlage der Fall (#55896#)
+/*N*/ // Aufgrund eines Hackks im Organizer stimmt dort der
+/*N*/ // Dok-Storage uebrigens ...
+/*N*/ if( bBlock || bOrganizer || nVersion < SWG_MAJORVERSION )
+/*N*/ bSwapOut = FALSE;
+/*N*/ aGrf.ReadEmbedded( *pPicStrm, bSwapOut );
+/*N*/ aDummy.Erase();
+/*N*/ aGrf.SetDocFileName( aDummy, 0L );
+/*N*/ if( pPicStrm->GetError() != SVSTREAM_OK )
+/*N*/ Error( ERR_SWG_READ_ERROR );
+/*N*/ }
+/*N*/ else
+/*N*/ Warning( WARN_SWG_POOR_LOAD );
+/*N*/ }
+/*N*/ }
+/*N*/
+/*N*/ if( !nRes )
+/*N*/ {
+/*N*/ if( !IsVersion( SWG_URLANDMAP, SWG_EXPORT31, SWG_DESKTOP40 ) )
+/*N*/ {
+/*N*/ // bei importierten Dateien muss ggf noch die URL in das
+/*N*/ // Format gestopft werden
+/*N*/ SwFmtURL aFmtURL;
+/*N*/ aFmtURL.SetURL( aURL, bIsServerMap );
+/*N*/ aFmtURL.SetTargetFrameName( aTarget );
+/*N*/ if( pImgMap )
+/*?*/ aFmtURL.SetMap( pImgMap );
+/*N*/ aSet.Put( aFmtURL );
+/*N*/ }
+/*N*/ SwGrfNode* pNd = pDoc->GetNodes().MakeGrfNode( rPos,
+/*N*/ aGrfName, aFltName, pGrf,
+/*N*/ (SwGrfFmtColl*) pDoc->GetDfltGrfFmtColl(),
+/*N*/ &aSet, bLink );
+/*N*/ if( !bLink && !bBlock && !bInsert && !bOrganizer )
+/*N*/ pNd->SetStreamName( aStrmName );
+/*N*/ pNd->SetAlternateText( aAltText );
+/*N*/ pNd->SetContour( pContour );
+/*N*/ }
+/*N*/ }
+/*N*/ delete pImgMap;
+/*N*/ delete pContour;
+/*N*/ }
+
+// Ausgabe eines Grafik-Nodes
+
+/*N*/ void Sw3IoImp::OutGrfNode( const SwNoTxtNode& rNode )
+/*N*/ {
+/*N*/ if( CheckPersist() )
+/*N*/ {
+/*N*/ SwGrfNode& rGrf = (SwGrfNode&) rNode;
+/*N*/
+/*N*/ String aName, sFilterNm;
+/*N*/ BYTE cFlags = 0x00;
+/*N*/ if( !rGrf.IsGrfLink() ) // gelinkte Graphic
+/*N*/ {
+/*N*/ cFlags = 0x10;
+/*N*/ if( GRAPHIC_NONE == rGrf.GetGrf().GetType() )
+/*N*/ cFlags |= 0x20;
+/*N*/ else
+/*N*/ {
+/*N*/ // Falls die Grafik bereits im Storage ist, ist der Stream-Name
+/*N*/ // gesetzt. Dann brauchen wir sie nicht mehr zu speichern.
+/*N*/ // oder es ist ein SaveAs, dann auf jedenfall kopieren
+/*N*/ if( !rGrf.StoreGraphics( pRoot ) )
+/*N*/ {
+/*N*/ Warning( WARN_SWG_POOR_LOAD );
+/*N*/ cFlags |= 0x20; // dann als leere Grf kennzeichnen!
+/*N*/ // Error( ERR_SWG_WRITE_ERROR );
+/*N*/ }
+/*N*/ // Den Namen merken
+/*N*/ else
+/*N*/ aName = rGrf.GetStreamName();
+/*N*/ }
+/*N*/ }
+/*N*/ else
+/*N*/ {
+/*N*/ nFileFlags |= SWGF_HAS_GRFLNK;
+/*N*/ rGrf.GetFileFilterNms( &aName, &sFilterNm );
+/*N*/ aName = ::binfilter::StaticBaseUrl::AbsToRel( aName );
+/*N*/ }
+/*N*/
+/*N*/ // Beim 31-Export muss die URL noch am Node gespeichert werden
+/*N*/ const SfxPoolItem *pURLItem = 0;
+/*N*/ if( IsSw31Export() &&
+/*N*/ SFX_ITEM_SET == rNode.GetFlyFmt()->GetAttrSet().
+/*N*/ GetItemState( RES_URL, FALSE, &pURLItem ) )
+/*N*/ {
+/*N*/ if ( ((SwFmtURL*)pURLItem)->IsServerMap() )
+/*N*/ cFlags |= 0x40;
+/*N*/ }
+/*N*/
+/*N*/ OpenRec( SWG_GRFNODE );
+/*N*/ *pStrm << cFlags;
+/*N*/ OutString( *pStrm, aName );
+/*N*/ OutString( *pStrm, sFilterNm );
+/*N*/ if( !IsSw31Export() )
+/*N*/ OutString( *pStrm, rGrf.GetAlternateText() );
+/*N*/ if( rNode.GetpSwAttrSet() )
+/*N*/ OutAttrSet( *rNode.GetpSwAttrSet() );
+/*N*/
+/*N*/ if( pURLItem )
+/*N*/ {
+/*N*/ const String& rURL = ((SwFmtURL*)pURLItem)->GetURL();
+/*N*/ const String& rTarget = ((SwFmtURL*)pURLItem)->GetTargetFrameName();
+/*N*/ const ImageMap *pIMap = ((SwFmtURL*)pURLItem)->GetMap();
+/*N*/ if( rURL.Len() || rTarget.Len() || pIMap || (cFlags & 0x40) )
+/*N*/ OutImageMap( rURL, rTarget, pIMap, (cFlags & 0x40) );
+/*N*/ }
+/*N*/
+/*N*/ // wegen der while( BytesLeft() )-Schleife beim Einlesen brauchen
+/*N*/ // wir hier einen eigenen Record, der aber auch fuer andere Sachen
+/*N*/ // verwendet werden kann und sollte
+/*N*/ if( !IsSw31Export() && rNode.HasContour() )
+ OutContour( *rNode.HasContour() );
+/*N*/
+/*N*/ CloseRec( SWG_GRFNODE );
+/*N*/ aStat.nGrf++;
+/*N*/ }
+/*N*/ }
+
+// Einlesen eines OLE-Nodes
+
+/*N*/ void Sw3IoImp::InOLENode( SwNodeIndex& rPos )
+/*N*/ {
+/*N*/ SwOLENode* pOLENd = 0;
+/*N*/ SwNoTxtNode* pNoTxtNd = 0;
+/*N*/ String aObjName, aAltText;
+/*N*/
+/*N*/ OpenRec( SWG_OLENODE );
+/*N*/ InString( *pStrm, aObjName );
+/*N*/
+/*N*/ if( IsVersion( SWG_DESKTOP40 ) )
+/*N*/ InString( *pStrm, aAltText );
+/*N*/
+/*N*/ // change the StarImageObj to a graphic
+/*N*/ SvPersistRef xSrcDoc( new SvPersist() );
+/*N*/ SvInfoObjectRef xObjInfo;
+/*N*/ if( xSrcDoc->DoOwnerLoad( pRoot ) && xSrcDoc->GetObjectList() )
+/*N*/ {
+/*N*/ // Suche die richtige Info
+/*N*/ xObjInfo = xSrcDoc->Find( aObjName );
+/*N*/ ASSERT( xObjInfo.Is(), "Keine Objektinfo zum Einfuegen gefunden" );
+/*N*/ }
+/*N*/
+/*N*/ if( xObjInfo.Is() )
+/*N*/ {
+/*N*/ SvStorageRef xSimStg( pRoot->OpenStorage(
+/*N*/ xObjInfo->GetStorageName() ) );
+/*N*/ String aStmName;
+/*N*/ if( xSimStg.Is() && (
+/*N*/ xSimStg->IsStream( aStmName = String(
+/*N*/ RTL_CONSTASCII_USTRINGPARAM( "StarImageDocument" )) ) ||
+/*N*/ xSimStg->IsStream( aStmName = String(
+/*N*/ RTL_CONSTASCII_USTRINGPARAM( "StarImageDocument 4.0" ))) ))
+/*N*/ {
+/*N*/ SvStorageStreamRef xSimStm( xSimStg->OpenStream( aStmName ) );
+/*N*/
+/*N*/ if( xSimStm.Is() && !xSimStm->GetError() )
+/*N*/ {
+/*N*/ Graphic aGraphic;
+/*N*/ xSimStm->SetBufferSize( 32768 );
+/*N*/ xSimStm->SetKey( xSimStg->GetKey() );
+/*N*/ *xSimStm >> aGraphic;
+/*N*/ xSimStm->SetBufferSize( 0 );
+/*N*/
+/*N*/ pNoTxtNd = pDoc->GetNodes().MakeGrfNode( rPos, aEmptyStr,
+/*N*/ aEmptyStr, &aGraphic,
+/*N*/ (SwGrfFmtColl*) pDoc->GetDfltGrfFmtColl() );
+/*N*/ }
+/*N*/ }
+/*N*/ }
+/*N*/
+/*N*/ if( !pNoTxtNd && CheckPersist() )
+/*N*/ {
+/*N*/ // Im Insert Mode muss das OLE-Objekt in den Ziel-Storage kopiert werden
+/*N*/ if( bInsert && xObjInfo.Is() )
+/*N*/ {
+/*?*/ SvPersistRef rpDstDoc( pDoc->GetPersist() );
+/*?*/
+/*?*/ String aStgName( xObjInfo->GetStorageName() );
+/*?*/ SvStorageRef rpDst( pDoc->GetPersist()->GetStorage() );
+/*?*/ // Sind Objektname und Storagename eindeutig?
+/*?*/ if( rpDstDoc->GetObjectList() )
+/*?*/ for( ULONG i = 0; i < rpDstDoc->GetObjectList()->Count(); i++ )
+/*?*/ {
+/*?*/ SvInfoObject* pTst = rpDstDoc->GetObjectList()->GetObject(i);
+/*?*/ // TODO: unicode: is this correct?
+/*?*/ if( aObjName.EqualsIgnoreCaseAscii( pTst->GetObjName() ))
+/*?*/ aObjName = Sw3Io::UniqueName( rpDst, "Obj" );
+/*?*/ // TODO: unicode: is this correct?
+/*?*/ if( aStgName.EqualsIgnoreCaseAscii( pTst->GetStorageName() ) )
+/*?*/ aStgName = Sw3Io::UniqueName( rpDst, "Obj" );
+/*?*/ }
+/*?*/ if( !rpDstDoc->Copy( aObjName, aStgName, &xObjInfo, xSrcDoc ) )
+/*?*/ {
+/*?*/ Error( ERR_SWG_READ_ERROR );
+/*?*/ return;
+/*?*/ }
+/*N*/ }
+/*N*/ pNoTxtNd = pOLENd = pDoc->GetNodes().MakeOLENode( rPos, aObjName,
+/*N*/ (SwGrfFmtColl*) pDoc->GetDfltGrfFmtColl() );
+/*N*/ }
+/*N*/
+/*N*/ if( pNoTxtNd )
+/*N*/ {
+/*N*/ pNoTxtNd->SetAlternateText( aAltText );
+/*N*/
+/*N*/ while( BytesLeft() )
+/*N*/ {
+/*N*/ BYTE cType = Peek();
+/*N*/ switch( cType )
+/*N*/ {
+/*?*/ case SWG_ATTRSET:
+/*?*/ if( !pNoTxtNd->GetpSwAttrSet() )
+/*?*/ ((SwCntntNode*) pNoTxtNd)->NewAttrSet( pDoc->GetAttrPool() );
+/*?*/ InAttrSet( *pNoTxtNd->GetpSwAttrSet() );
+/*?*/ pNoTxtNd->GetpSwAttrSet()->SetModifyAtAttr( pNoTxtNd );
+/*?*/ break;
+/*N*/
+/*N*/ case SW_OLE_CHARTNAME:
+/*N*/ if( pOLENd )
+/*N*/ {
+/*N*/ String sStr;
+/*N*/ OpenRec( SW_OLE_CHARTNAME );
+/*N*/ InString( *pStrm, sStr );
+/*N*/ CloseRec( SW_OLE_CHARTNAME );
+/*N*/ pOLENd->SetChartTblName( sStr );
+/*N*/ }
+/*N*/ else
+/*?*/ SkipRec();
+/*N*/ break;
+/*N*/
+/*?*/ case SWG_IMAGEMAP:
+/*?*/ {
+/*?*/ String aURL, aTarget;
+/*?*/ BOOL bIsServerMap = FALSE;
+/*?*/ ImageMap *pImgMap = InImageMap( aURL, aTarget, bIsServerMap);
+/*?*/ SwFmtURL aFmtURL;
+/*?*/ aFmtURL.SetURL( aURL, bIsServerMap );
+/*?*/ aFmtURL.SetTargetFrameName( aTarget );
+/*?*/ if ( pImgMap )
+/*?*/ {
+/*?*/ aFmtURL.SetMap( pImgMap );
+/*?*/ delete pImgMap;
+/*?*/ }
+/*?*/ pNoTxtNd->SetAttr( aFmtURL );
+/*?*/ }
+/*?*/ break;
+/*?*/
+/*?*/ case SWG_CONTOUR:
+/*?*/ if( pOLENd )
+/*?*/ {
+ PolyPolygon *pContour = InContour();
+ /*?*/ pOLENd->SetContour( pContour );
+ /*?*/ delete pContour;
+/*?*/ }
+/*?*/ else
+/*?*/ SkipRec();
+/*?*/ break;
+/*N*/
+/*N*/ default:
+/*N*/ SkipRec();
+/*N*/ }
+/*N*/ }
+/*N*/ // falls ein 3.0-Dokument gelesen wird: Node merken
+/*N*/ if( pOLENd )
+/*N*/ {
+/*N*/ if( bNormal && !bInsert && !bBlock && nVersion<=SWG_SHORTFIELDS )
+/*N*/ {
+/*?*/ if( !p30OLENodes )
+/*?*/ p30OLENodes = new SwOLENodes;
+/*?*/
+/*?*/ p30OLENodes->Insert( pOLENd, p30OLENodes->Count() );
+/*N*/ }
+/*N*/
+/*N*/ if( bInsert )
+/*?*/ pOLENd->SetOLESizeInvalid( TRUE ); //wg. Druckerwechsel
+/*N*/ }
+/*N*/ }
+/*N*/ if( !xObjInfo.Is() )
+/*?*/ Warning( WARN_SWG_POOR_LOAD );
+/*N*/
+/*N*/ CloseRec( SWG_OLENODE );
+/*N*/ }
+
+// Ausgabe eines OLE-Nodes
+
+/*N*/ void Sw3IoImp::OutOLENode( const SwNoTxtNode& rNd )
+/*N*/ {
+/*N*/ if( CheckPersist() )
+/*N*/ {
+/*N*/ OpenRec( SWG_OLENODE );
+/*N*/ SwOLENode& rNode = (SwOLENode&) rNd;
+/*N*/ SwOLEObj& rObj = rNode.GetOLEObj();
+/*N*/
+/*N*/ String aName( rObj.GetName() );
+/*N*/ OutString( *pStrm, aName );
+/*N*/ if( !IsSw31Export() )
+/*?*/ OutString( *pStrm, rNode.GetAlternateText() );
+/*N*/ if( rNode.GetpSwAttrSet() )
+/*N*/ OutAttrSet( *rNode.GetpSwAttrSet() );
+/*N*/
+/*N*/ if( rNode.GetChartTblName().Len() )
+/*N*/ {
+/*N*/ OpenRec( SW_OLE_CHARTNAME );
+/*N*/ OutString( *pStrm, rNode.GetChartTblName() );
+/*N*/ CloseRec( SW_OLE_CHARTNAME );
+/*N*/ }
+/*N*/
+/*N*/ if( !IsSw31Export() && rNode.HasContour() )
+ OutContour( *rNode.HasContour() );
+/*N*/
+/*N*/ CloseRec( SWG_OLENODE );
+/*N*/ aStat.nOLE++;
+/*N*/ }
+/*N*/ }
+
+
+// Einlesen eines Text-Wiederholungs-Nodes
+
+/*N*/ void Sw3IoImp::InRepTxtNode( SwNodeIndex& rPos )
+/*N*/ {
+/*N*/ UINT32 nRepetitions;
+/*N*/
+/*N*/ OpenRec( SWG_REPTEXTNODE );
+/*N*/ *pStrm >> nRepetitions;
+/*N*/
+/*N*/ rPos--;
+/*N*/ SwTxtNode *pNode = pDoc->GetNodes()[rPos]->GetTxtNode();
+/*N*/ rPos++;
+/*N*/
+/*N*/ for( ULONG i=0; i<nRepetitions; i++ )
+/*N*/ pNode->MakeCopy( pDoc, rPos );
+/*N*/
+/*N*/ CloseRec( SWG_REPTEXTNODE );
+/*N*/ }
+/*N*/
+/*N*/
+/*N*/ // Ausgabe eines Text-Wiederholungs-Nodes
+/*N*/
+/*N*/ void Sw3IoImp::OutRepTxtNode( ULONG nRepetitions )
+/*N*/ {
+/*N*/ OpenRec( SWG_REPTEXTNODE );
+/*N*/ *pStrm << (UINT32)nRepetitions;
+/*N*/ CloseRec( SWG_REPTEXTNODE );
+/*N*/ }
+
+// Der Image-Map-Record war frueher ein SWG_GRAPHIC_EXT-Record.
+// Deshalb enthaelt er immer der URL fuer eine Server-seitige
+// Image-Map und kein ismap-Flag! Aus dem gleichen Grund wird die
+// URL fuer eine Client-seitige Image-Map ueber ein Falg gesteuert.
+// damit alte Writer-Version keine Warnung ausgeben, wenn der String
+// leer ist.
+
+/*N*/ ImageMap *Sw3IoImp::InImageMap( String& rURL, String& rTarget, BOOL& rIsMap )
+/*N*/ {
+/*N*/ OpenRec( SWG_IMAGEMAP );
+/*N*/ BYTE cFlags = OpenFlagRec();
+/*N*/ CloseFlagRec();
+/*N*/
+/*N*/ rIsMap = BOOL( (cFlags & 0x10) != 0 );
+/*N*/
+/*N*/ InString( *pStrm, rURL );
+/*N*/ if( rURL.Len() )
+/*N*/ rURL = ::binfilter::StaticBaseUrl::SmartRelToAbs( rURL );
+/*N*/
+/*N*/ // bis hier hatten wir frueher einen SWG_GRAPHIC_EXT-Record!
+/*N*/ if( IsVersion( SWG_TARGETFRAME, SWG_EXPORT31, SWG_DESKTOP40 ) )
+/*N*/ {
+/*N*/ String sDummy;
+/*N*/ InString( *pStrm, rTarget );
+/*N*/ InString( *pStrm, sDummy );
+/*N*/ }
+/*N*/
+/*N*/ ImageMap *pIMap = 0;
+/*N*/ if( cFlags & 0x20 )
+/*N*/ {
+/*?*/ pIMap = new ImageMap;
+/*?*/ pIMap->Read(
+ *pStrm,
+ ::binfilter::StaticBaseUrl::GetBaseURL(INetURLObject::NO_DECODE));
+/*N*/ }
+/*N*/
+/*N*/ CloseRec( SWG_IMAGEMAP );
+/*N*/
+/*N*/ return pIMap; // muss ggf. vom Aufrufer geloescht werden!
+/*N*/ }
+
+/*N*/ void lcl_sw3io__ConvertMarkToOutline( String& rURL )
+/*N*/ {
+/*N*/ if( rURL.Len() && '#' == rURL.GetChar( 0 ) )
+/*N*/ {
+/*N*/ String sCmp, sMark( INetURLObject::decode( rURL, INET_HEX_ESCAPE,
+/*N*/ INetURLObject::DECODE_WITH_CHARSET,
+/*N*/ RTL_TEXTENCODING_UTF8 ));
+/*N*/ xub_StrLen nPos = sMark.SearchBackward( cMarkSeperator );
+/*N*/ if( STRING_NOTFOUND != nPos &&
+/*N*/ ( sCmp = sMark.Copy( nPos + 1 ) ).EraseAllChars().Len() &&
+/*N*/ COMPARE_EQUAL == sCmp.CompareToAscii( pMarkToOutline ) )
+/*N*/ {
+/*N*/ rURL = '#';
+/*N*/ rURL += String(INetURLObject::createFragment( sMark.Copy( 1, nPos-1 ) ));
+/*N*/ rURL += cMarkSeperator;
+/*N*/ rURL.AppendAscii( pMarkToOutline );
+/*N*/ }
+/*N*/ }
+/*N*/ }
+
+/*N*/ void Sw3IoImp::OutImageMap( const String& rURL, const String& rTarget,
+/*N*/ const ImageMap *pIMap, BOOL bIsServerMap )
+/*N*/ {
+/*N*/ // Dieser Record ist fuer den 31-Export ein SWG_GRAPHIC_EXT und
+/*N*/ // enthaelt dann nur eine URL
+/*N*/ OpenRec( SWG_IMAGEMAP );
+/*N*/ BYTE cFlags = 0x00;
+/*N*/ if( !IsSw31Export() && bIsServerMap )
+/*N*/ cFlags += 0x10; // es ist eine Image-Map
+/*N*/ if( !IsSw31Export() && pIMap )
+/*N*/ cFlags += 0x20; // es folgt eine Image-Map
+/*N*/
+/*N*/ *pStrm << cFlags;
+/*N*/
+/*N*/ // Unabhaengigkeit von der AbsToRel-Schnittstelle sicherstellen!
+/*N*/ String aURL( rURL );
+/*N*/ if( aURL.Len() )
+/*N*/ {
+/*N*/ lcl_sw3io__ConvertMarkToOutline( aURL );
+/*N*/ aURL = ::binfilter::StaticBaseUrl::AbsToRel( aURL URL_DECODE);
+/*N*/ }
+/*N*/ OutString( *pStrm, aURL );
+/*N*/
+/*N*/ // bis hier hatten wir frueher einen SWG_GRAPHIC_EXT-Record!
+/*N*/
+/*N*/ if( !IsSw31Export() )
+/*N*/ {
+/*N*/ OutString( *pStrm, rTarget );
+/*N*/ OutString( *pStrm, aEmptyStr );
+/*N*/
+/*N*/ if( pIMap )
+/*?*/ pIMap->Write(
+ *pStrm,
+ ::binfilter::StaticBaseUrl::GetBaseURL(INetURLObject::NO_DECODE));
+/*N*/ }
+/*N*/
+/*N*/ CloseRec( SWG_IMAGEMAP );
+/*N*/ }
+
+ PolyPolygon *Sw3IoImp::InContour()
+ {
+ PolyPolygon *pContour = 0;
+
+ OpenRec( SWG_CONTOUR );
+ BYTE cFlags = OpenFlagRec();
+ CloseFlagRec();
+
+ if( (cFlags & 0x10) != 0 )
+ {
+ pContour = new PolyPolygon;
+ *pStrm >> *pContour;
+ }
+
+ CloseRec( SWG_CONTOUR );
+
+ return pContour;
+ }
+
+void Sw3IoImp::OutContour( const PolyPolygon& rPoly )
+{
+ OpenRec( SWG_CONTOUR );
+
+ BYTE cFlags = 0x10; // es folgt ein Contour Poly-Polygon
+ *pStrm << cFlags;
+
+ // das Contour-PolyPolygon rausschreiben
+ *pStrm << rPoly;
+
+ CloseRec( SWG_CONTOUR );
+}
+
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */