1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <tools/urlobj.hxx>
22 #include <svl/urihelper.hxx>
23 #include <rtl/tencinfo.h>
27 #include <shellio.hxx>
29 #include <fmtanchr.hxx>
33 #include "ww8glsy.hxx"
37 WW8Glossary::WW8Glossary(SvStorageStreamRef
&refStrm
, sal_uInt8 nVersion
,
39 : pGlossary(0), rStrm(refStrm
), xStg(pStg
), nStrings(0)
41 refStrm
->SetNumberFormatInt(NUMBERFORMAT_INT_LITTLEENDIAN
);
42 WW8Fib
aWwFib(*refStrm
, nVersion
);
44 if (aWwFib
.nFibBack
>= 0x6A) //Word97
46 xTableStream
= pStg
->OpenSotStream(OUString::createFromAscii(
47 aWwFib
.fWhichTblStm
? SL::a1Table
: SL::a0Table
), STREAM_STD_READ
);
49 if (xTableStream
.Is() && SVSTREAM_OK
== xTableStream
->GetError())
51 xTableStream
->SetNumberFormatInt(NUMBERFORMAT_INT_LITTLEENDIAN
);
53 new WW8GlossaryFib(*refStrm
, nVersion
, *xTableStream
, aWwFib
);
58 bool WW8Glossary::HasBareGraphicEnd(SwDoc
*pDoc
,SwNodeIndex
&rIdx
)
61 for( sal_uInt16 nCnt
= pDoc
->GetSpzFrmFmts()->size(); nCnt
; )
63 SwFrmFmt
* pFrmFmt
= (*pDoc
->GetSpzFrmFmts())[ --nCnt
];
64 if ( RES_FLYFRMFMT
!= pFrmFmt
->Which() &&
65 RES_DRAWFRMFMT
!= pFrmFmt
->Which() )
67 const SwFmtAnchor
& rAnchor
= pFrmFmt
->GetAnchor();
68 SwPosition
const*const pAPos
= rAnchor
.GetCntntAnchor();
70 ((FLY_AT_PARA
== rAnchor
.GetAnchorId()) ||
71 (FLY_AT_CHAR
== rAnchor
.GetAnchorId())) &&
72 rIdx
== pAPos
->nNode
.GetIndex() )
81 bool WW8Glossary::MakeEntries(SwDoc
*pD
, SwTextBlocks
&rBlocks
,
82 bool bSaveRelFile
, const std::vector
<String
>& rStrings
,
83 const std::vector
<ww::bytes
>& rExtra
)
85 // this code will be called after reading all text into the
87 const String
aOldURL( rBlocks
.GetBaseURL() );
92 URIHelper::SmartRel2Abs(
93 INetURLObject(), rBlocks
.GetFileName(),
94 URIHelper::GetMaybeFileHdl()));
97 rBlocks
.SetBaseURL( aEmptyStr
);
99 SwNodeIndex
aDocEnd( pD
->GetNodes().GetEndOfContent() );
100 SwNodeIndex
aStart( *aDocEnd
.GetNode().StartOfSectionNode(), 1 );
102 // search the first NormalStartNode
103 while( !( aStart
.GetNode().IsStartNode() && SwNormalStartNode
==
104 aStart
.GetNode().GetStartNode()->GetStartNodeType()) &&
108 if( aStart
< aDocEnd
)
110 SwTxtFmtColl
* pColl
= pD
->GetTxtCollFromPool
111 (RES_POOLCOLL_STANDARD
, false);
112 sal_uInt16 nGlosEntry
= 0;
113 SwCntntNode
* pCNd
= 0;
115 SwPaM
aPam( aStart
);
117 SwNodeIndex
& rIdx
= aPam
.GetPoint()->nNode
;
119 if( 0 == ( pCNd
= rIdx
.GetNode().GetTxtNode() ) )
121 pCNd
= pD
->GetNodes().MakeTxtNode( rIdx
, pColl
);
125 aPam
.GetPoint()->nContent
.Assign( pCNd
, 0 );
128 SwNodeIndex
& rIdx
= aPam
.GetPoint()->nNode
;
129 rIdx
= aStart
.GetNode().EndOfSectionIndex() - 1;
130 if(( 0 == ( pCNd
= rIdx
.GetNode().GetCntntNode() ) )
131 || HasBareGraphicEnd(pD
,rIdx
))
134 pCNd
= pD
->GetNodes().MakeTxtNode( rIdx
, pColl
);
138 aPam
.GetPoint()->nContent
.Assign( pCNd
, pCNd
->Len() );
140 // now we have the right selection for one entry. Copy this to
141 // the definied TextBlock, but only if it is not an autocorrection
142 // entry (== -1) otherwise the group indicates the group in the
143 // sttbfglsystyle list that this entry belongs to. Unused at the
145 const ww::bytes
&rData
= rExtra
[nGlosEntry
];
146 sal_uInt16 n
= SVBT16ToShort( &(rData
[2]) );
150 const String
&rLNm
= rStrings
[nGlosEntry
];
152 String sShortcut
= rLNm
;
154 // Need to check make sure the shortcut is not already being used
155 sal_Int32 nStart
= 0;
156 sal_uInt16 nCurPos
= rBlocks
.GetIndex( sShortcut
);
157 xub_StrLen nLen
= sShortcut
.Len();
158 while( (sal_uInt16
)-1 != nCurPos
)
160 sShortcut
.Erase( nLen
) +=
161 OUString::valueOf(++nStart
); // add an Number to it
162 nCurPos
= rBlocks
.GetIndex( sShortcut
);
165 if( rBlocks
.BeginPutDoc( sShortcut
, sShortcut
)) // Make the shortcut and the name the same
168 SwDoc
* pGlDoc
= rBlocks
.GetDoc();
169 SwNodeIndex
aIdx( pGlDoc
->GetNodes().GetEndOfContent(),
171 pCNd
= aIdx
.GetNode().GetCntntNode();
172 SwPosition
aPos( aIdx
, SwIndex( pCNd
, pCNd
->Len() ));
173 pD
->CopyRange( aPam
, aPos
, false );
177 aStart
= aStart
.GetNode().EndOfSectionIndex() + 1;
179 } while( aStart
.GetNode().IsStartNode() &&
180 SwNormalStartNode
== aStart
.GetNode().
181 GetStartNode()->GetStartNodeType());
185 // this code will be called after reading all text into the empty sections
187 rBlocks
.SetBaseURL( aOldURL
);
192 bool WW8Glossary::Load( SwTextBlocks
&rBlocks
, bool bSaveRelFile
)
195 if (pGlossary
&& pGlossary
->IsGlossaryFib() && rBlocks
.StartPutMuchBlockEntries())
197 //read the names of the autotext entries
198 std::vector
<String
> aStrings
;
199 std::vector
<ww::bytes
> aData
;
201 rtl_TextEncoding eStructCharSet
=
202 WW8Fib::GetFIBCharset(pGlossary
->chseTables
);
204 WW8ReadSTTBF(true, *xTableStream
, pGlossary
->fcSttbfglsy
,
205 pGlossary
->lcbSttbfglsy
, 0, eStructCharSet
, aStrings
, &aData
);
209 if ( 0 != (nStrings
= static_cast< sal_uInt16
>(aStrings
.size())))
211 SfxObjectShellLock
xDocSh(new SwDocShell(SFX_CREATE_MODE_INTERNAL
));
212 if (xDocSh
->DoInitNew(0))
214 SwDoc
*pD
= ((SwDocShell
*)(&xDocSh
))->GetDoc();
215 SwWW8ImplReader
* pRdr
= new SwWW8ImplReader(pGlossary
->nVersion
,
216 xStg
, &rStrm
, *pD
, rBlocks
.GetBaseURL(), true);
219 *pD
->GetNodes().GetEndOfContent().StartOfSectionNode(), 1);
220 if( !aIdx
.GetNode().IsTxtNode() )
222 OSL_ENSURE( !this, "wo ist der TextNode?" );
223 pD
->GetNodes().GoNext( &aIdx
);
226 aPamo
.GetPoint()->nContent
.Assign(aIdx
.GetNode().GetCntntNode(),
228 pRdr
->LoadDoc(aPamo
,this);
230 bRet
= MakeEntries(pD
, rBlocks
, bSaveRelFile
, aStrings
, aData
);
235 rBlocks
.EndPutMuchBlockEntries();
242 bool WW8GlossaryFib::IsGlossaryFib()
244 // fGlsy will indicate whether this has AutoText or not
248 sal_uInt32
WW8GlossaryFib::FindGlossaryFibOffset(SvStream
& /* rTableStrm */,
249 SvStream
& /* rStrm */,
252 sal_uInt32 nGlossaryFibOffset
= 0;
253 if ( rFib
.fDot
) // its a template
256 nGlossaryFibOffset
= ( rFib
.pnNext
* 512 );
258 return nGlossaryFibOffset
;
261 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */