bump product version to 4.1.6.2
[LibreOffice.git] / sw / source / filter / ww8 / ww8glsy.cxx
blobb40813e274cccdb5cb3ca83b0b4b14bdf9028dc4
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
24 #include <swerror.h>
25 #include <ndtxt.hxx>
26 #include <pam.hxx>
27 #include <shellio.hxx>
28 #include <docsh.hxx>
29 #include <fmtanchr.hxx>
30 #include <frmfmt.hxx>
31 #include <doc.hxx>
32 #include <docary.hxx>
33 #include "ww8glsy.hxx"
34 #include "ww8par.hxx"
37 WW8Glossary::WW8Glossary(SvStorageStreamRef &refStrm, sal_uInt8 nVersion,
38 SvStorage *pStg)
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);
52 pGlossary =
53 new WW8GlossaryFib(*refStrm, nVersion, *xTableStream, aWwFib);
58 bool WW8Glossary::HasBareGraphicEnd(SwDoc *pDoc,SwNodeIndex &rIdx)
60 bool bRet=false;
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() )
66 continue;
67 const SwFmtAnchor& rAnchor = pFrmFmt->GetAnchor();
68 SwPosition const*const pAPos = rAnchor.GetCntntAnchor();
69 if (pAPos &&
70 ((FLY_AT_PARA == rAnchor.GetAnchorId()) ||
71 (FLY_AT_CHAR == rAnchor.GetAnchorId())) &&
72 rIdx == pAPos->nNode.GetIndex() )
74 bRet=true;
75 break;
78 return bRet;
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
86 // empty sections
87 const String aOldURL( rBlocks.GetBaseURL() );
88 bool bRet=false;
89 if( bSaveRelFile )
91 rBlocks.SetBaseURL(
92 URIHelper::SmartRel2Abs(
93 INetURLObject(), rBlocks.GetFileName(),
94 URIHelper::GetMaybeFileHdl()));
96 else
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()) &&
105 aStart < aDocEnd )
106 ++aStart;
108 if( aStart < aDocEnd )
110 SwTxtFmtColl* pColl = pD->GetTxtCollFromPool
111 (RES_POOLCOLL_STANDARD, false);
112 sal_uInt16 nGlosEntry = 0;
113 SwCntntNode* pCNd = 0;
114 do {
115 SwPaM aPam( aStart );
117 SwNodeIndex& rIdx = aPam.GetPoint()->nNode;
118 ++rIdx;
119 if( 0 == ( pCNd = rIdx.GetNode().GetTxtNode() ) )
121 pCNd = pD->GetNodes().MakeTxtNode( rIdx, pColl );
122 rIdx = *pCNd;
125 aPam.GetPoint()->nContent.Assign( pCNd, 0 );
126 aPam.SetMark();
128 SwNodeIndex& rIdx = aPam.GetPoint()->nNode;
129 rIdx = aStart.GetNode().EndOfSectionIndex() - 1;
130 if(( 0 == ( pCNd = rIdx.GetNode().GetCntntNode() ) )
131 || HasBareGraphicEnd(pD,rIdx))
133 ++rIdx;
134 pCNd = pD->GetNodes().MakeTxtNode( rIdx, pColl );
135 rIdx = *pCNd;
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
144 // moment
145 const ww::bytes &rData = rExtra[nGlosEntry];
146 sal_uInt16 n = SVBT16ToShort( &(rData[2]) );
147 if(n != 0xFFFF)
149 rBlocks.ClearDoc();
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(),
170 -1 );
171 pCNd = aIdx.GetNode().GetCntntNode();
172 SwPosition aPos( aIdx, SwIndex( pCNd, pCNd->Len() ));
173 pD->CopyRange( aPam, aPos, false );
174 rBlocks.PutDoc();
177 aStart = aStart.GetNode().EndOfSectionIndex() + 1;
178 ++nGlosEntry;
179 } while( aStart.GetNode().IsStartNode() &&
180 SwNormalStartNode == aStart.GetNode().
181 GetStartNode()->GetStartNodeType());
182 bRet=true;
185 // this code will be called after reading all text into the empty sections
187 rBlocks.SetBaseURL( aOldURL );
188 return bRet;
192 bool WW8Glossary::Load( SwTextBlocks &rBlocks, bool bSaveRelFile )
194 bool bRet=false;
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 );
207 rStrm->Seek(0);
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);
218 SwNodeIndex aIdx(
219 *pD->GetNodes().GetEndOfContent().StartOfSectionNode(), 1);
220 if( !aIdx.GetNode().IsTxtNode() )
222 OSL_ENSURE( !this, "wo ist der TextNode?" );
223 pD->GetNodes().GoNext( &aIdx );
225 SwPaM aPamo( aIdx );
226 aPamo.GetPoint()->nContent.Assign(aIdx.GetNode().GetCntntNode(),
228 pRdr->LoadDoc(aPamo,this);
230 bRet = MakeEntries(pD, rBlocks, bSaveRelFile, aStrings, aData);
232 delete pRdr;
234 xDocSh->DoClose();
235 rBlocks.EndPutMuchBlockEntries();
238 return bRet;
242 bool WW8GlossaryFib::IsGlossaryFib()
244 // fGlsy will indicate whether this has AutoText or not
245 return fGlsy;
248 sal_uInt32 WW8GlossaryFib::FindGlossaryFibOffset(SvStream & /* rTableStrm */,
249 SvStream & /* rStrm */,
250 const WW8Fib &rFib)
252 sal_uInt32 nGlossaryFibOffset = 0;
253 if ( rFib.fDot ) // its a template
255 if ( rFib.pnNext )
256 nGlossaryFibOffset = ( rFib.pnNext * 512 );
258 return nGlossaryFibOffset;
261 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */