xref: /trunk/main/sw/source/filter/ww8/ww8glsy.cxx (revision 870262e3)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sw.hxx"
26 
27 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
28 #include <tools/urlobj.hxx>
29 #include <svl/urihelper.hxx>
30 #include <rtl/tencinfo.h>
31 #include <swerror.h>
32 #include <ndtxt.hxx>
33 #include <pam.hxx>
34 #include <shellio.hxx>
35 #include <docsh.hxx>
36 #include <fmtanchr.hxx>
37 #include <frmfmt.hxx>
38 #include <doc.hxx>
39 #include <docary.hxx>
40 #include "ww8glsy.hxx"
41 #include "ww8par.hxx"
42 
43 
WW8Glossary(SvStorageStreamRef & refStrm,sal_uInt8 nVersion,SvStorage * pStg)44 WW8Glossary::WW8Glossary(SvStorageStreamRef &refStrm, sal_uInt8 nVersion,
45     SvStorage *pStg)
46     : pGlossary(0), rStrm(refStrm), xStg(pStg), nStrings(0)
47 {
48     refStrm->SetNumberFormatInt(NUMBERFORMAT_INT_LITTLEENDIAN);
49     WW8Fib aWwFib(*refStrm, nVersion);
50 
51     if (aWwFib.nFibBack >= 0x6A)   //Word97
52     {
53         xTableStream = pStg->OpenSotStream(String::CreateFromAscii(
54             aWwFib.fWhichTblStm ? SL::a1Table : SL::a0Table), STREAM_STD_READ);
55 
56         if (xTableStream.Is() && SVSTREAM_OK == xTableStream->GetError())
57         {
58             xTableStream->SetNumberFormatInt(NUMBERFORMAT_INT_LITTLEENDIAN);
59             pGlossary =
60                 new WW8GlossaryFib(*refStrm, nVersion, *xTableStream, aWwFib);
61         }
62     }
63 }
64 
HasBareGraphicEnd(SwDoc * pDoc,SwNodeIndex & rIdx)65 bool WW8Glossary::HasBareGraphicEnd(SwDoc *pDoc,SwNodeIndex &rIdx)
66 {
67     bool bRet=false;
68     for( sal_uInt16 nCnt = pDoc->GetSpzFrmFmts()->Count(); nCnt; )
69     {
70         SwFrmFmt* pFrmFmt = (*pDoc->GetSpzFrmFmts())[ --nCnt ];
71         if ( RES_FLYFRMFMT != pFrmFmt->Which() &&
72             RES_DRAWFRMFMT != pFrmFmt->Which() )
73                 continue;
74         const SwFmtAnchor& rAnchor = pFrmFmt->GetAnchor();
75         SwPosition const*const pAPos = rAnchor.GetCntntAnchor();
76         if (pAPos &&
77             ((FLY_AT_PARA == rAnchor.GetAnchorId()) ||
78              (FLY_AT_CHAR == rAnchor.GetAnchorId())) &&
79             rIdx == pAPos->nNode.GetIndex() )
80             {
81                 bRet=true;
82                 break;
83             }
84     }
85     return bRet;
86 }
87 
MakeEntries(SwDoc * pD,SwTextBlocks & rBlocks,bool bSaveRelFile,const std::vector<String> & rStrings,const std::vector<ww::bytes> & rExtra)88 bool WW8Glossary::MakeEntries(SwDoc *pD, SwTextBlocks &rBlocks,
89     bool bSaveRelFile, const std::vector<String>& rStrings,
90     const std::vector<ww::bytes>& rExtra)
91 {
92     // this code will be called after reading all text into the
93     // empty sections
94     const String aOldURL( rBlocks.GetBaseURL() );
95     bool bRet=false;
96     if( bSaveRelFile )
97     {
98         rBlocks.SetBaseURL(
99             URIHelper::SmartRel2Abs(
100                 INetURLObject(), rBlocks.GetFileName(),
101                 URIHelper::GetMaybeFileHdl()));
102     }
103     else
104         rBlocks.SetBaseURL( aEmptyStr );
105 
106     SwNodeIndex aDocEnd( pD->GetNodes().GetEndOfContent() );
107     SwNodeIndex aStart( *aDocEnd.GetNode().StartOfSectionNode(), 1 );
108 
109     // search the first NormalStartNode
110     while( !( aStart.GetNode().IsStartNode() && SwNormalStartNode ==
111            aStart.GetNode().GetStartNode()->GetStartNodeType()) &&
112             aStart < aDocEnd )
113         aStart++;
114 
115     if( aStart < aDocEnd )
116     {
117         SwTxtFmtColl* pColl = pD->GetTxtCollFromPool
118             (RES_POOLCOLL_STANDARD, false);
119         sal_uInt16 nGlosEntry = 0;
120         SwCntntNode* pCNd = 0;
121         do {
122             SwPaM aPam( aStart );
123             {
124                 SwNodeIndex& rIdx = aPam.GetPoint()->nNode;
125                 rIdx++;
126                 if( 0 == ( pCNd = rIdx.GetNode().GetTxtNode() ) )
127                 {
128 					pCNd = pD->GetNodes().MakeTxtNode( rIdx, pColl );
129 					rIdx = *pCNd;
130                 }
131             }
132             aPam.GetPoint()->nContent.Assign( pCNd, 0 );
133             aPam.SetMark();
134             {
135                 SwNodeIndex& rIdx = aPam.GetPoint()->nNode;
136                 rIdx = aStart.GetNode().EndOfSectionIndex() - 1;
137                 if(( 0 == ( pCNd = rIdx.GetNode().GetCntntNode() ) )
138                         || HasBareGraphicEnd(pD,rIdx))
139                 {
140                     rIdx++;
141                     pCNd = pD->GetNodes().MakeTxtNode( rIdx, pColl );
142                     rIdx = *pCNd;
143                 }
144             }
145             aPam.GetPoint()->nContent.Assign( pCNd, pCNd->Len() );
146 
147             // now we have the right selection for one entry.  Copy this to
148             // the definied TextBlock, but only if it is not an autocorrection
149             // entry (== -1) otherwise the group indicates the group in the
150             // sttbfglsystyle list that this entry belongs to. Unused at the
151             // moment
152             const ww::bytes &rData = rExtra[nGlosEntry];
153             sal_uInt16 n = SVBT16ToShort( &(rData[2]) );
154             if(n != 0xFFFF)
155             {
156                 rBlocks.ClearDoc();
157                 const String &rLNm = rStrings[nGlosEntry];
158 
159                 String sShortcut = rLNm;
160 
161                 // Need to check make sure the shortcut is not already being used
162                 xub_StrLen nStart = 0;
163                 sal_uInt16 nCurPos = rBlocks.GetIndex( sShortcut );
164                 xub_StrLen nLen = sShortcut.Len();
165                 while( (sal_uInt16)-1 != nCurPos )
166                 {
167                     sShortcut.Erase( nLen ) +=
168                         String::CreateFromInt32( ++nStart );    // add an Number to it
169                     nCurPos = rBlocks.GetIndex( sShortcut );
170                 }
171 
172                 if( rBlocks.BeginPutDoc( sShortcut, sShortcut ))    // Make the shortcut and the name the same
173 
174                 {
175                     SwDoc* pGlDoc = rBlocks.GetDoc();
176                     SwNodeIndex aIdx( pGlDoc->GetNodes().GetEndOfContent(),
177                         -1 );
178                     pCNd = aIdx.GetNode().GetCntntNode();
179                     SwPosition aPos( aIdx, SwIndex( pCNd, pCNd->Len() ));
180                     pD->CopyRange( aPam, aPos, false );
181                     rBlocks.PutDoc();
182                 }
183             }
184             aStart = aStart.GetNode().EndOfSectionIndex() + 1;
185             ++nGlosEntry;
186         } while( aStart.GetNode().IsStartNode() &&
187                 SwNormalStartNode == aStart.GetNode().
188                     GetStartNode()->GetStartNodeType());
189         bRet=true;
190     }
191 
192 // this code will be called after reading all text into the empty sections
193 
194     rBlocks.SetBaseURL( aOldURL );
195     return bRet;
196 }
197 
198 
Load(SwTextBlocks & rBlocks,bool bSaveRelFile)199 bool WW8Glossary::Load( SwTextBlocks &rBlocks, bool bSaveRelFile )
200 {
201     bool bRet=false;
202     if (pGlossary && pGlossary->IsGlossaryFib() && rBlocks.StartPutMuchBlockEntries())
203     {
204         //read the names of the autotext entries
205         std::vector<String> aStrings;
206         std::vector<ww::bytes> aData;
207 
208         rtl_TextEncoding eStructCharSet =
209             WW8Fib::GetFIBCharset(pGlossary->chseTables);
210 
211         WW8ReadSTTBF(true, *xTableStream, pGlossary->fcSttbfglsy,
212             pGlossary->lcbSttbfglsy, 0, eStructCharSet, aStrings, &aData );
213 
214         rStrm->Seek(0);
215 
216         if ( 0 != (nStrings = static_cast< sal_uInt16 >(aStrings.size())))
217         {
218             SfxObjectShellLock xDocSh(new SwDocShell(SFX_CREATE_MODE_INTERNAL));
219             if (xDocSh->DoInitNew(0))
220             {
221                 SwDoc *pD =  ((SwDocShell*)(&xDocSh))->GetDoc();
222                 SwWW8ImplReader* pRdr = new SwWW8ImplReader(pGlossary->nVersion,
223                     xStg, &rStrm, *pD, rBlocks.GetBaseURL(), true);
224 
225                 SwNodeIndex aIdx(
226                     *pD->GetNodes().GetEndOfContent().StartOfSectionNode(), 1);
227                 if( !aIdx.GetNode().IsTxtNode() )
228                 {
229                     ASSERT( sal_False, "where is the TextNode?" );
230                     pD->GetNodes().GoNext( &aIdx );
231                 }
232                 SwPaM aPamo( aIdx );
233                 aPamo.GetPoint()->nContent.Assign(aIdx.GetNode().GetCntntNode(),
234                     0);
235                 pRdr->LoadDoc(aPamo,this);
236 
237                 bRet = MakeEntries(pD, rBlocks, bSaveRelFile, aStrings, aData);
238 
239                 delete pRdr;
240             }
241             xDocSh->DoClose();
242             rBlocks.EndPutMuchBlockEntries();
243         }
244     }
245     return bRet;
246 }
247 
248 
IsGlossaryFib()249 bool WW8GlossaryFib::IsGlossaryFib()
250 {
251     // fGlsy will indicate whether this has AutoText or not
252     return fGlsy;
253 }
254 
FindGlossaryFibOffset(SvStream &,SvStream &,const WW8Fib & rFib)255 sal_uInt32 WW8GlossaryFib::FindGlossaryFibOffset(SvStream & /* rTableStrm */,
256                                              SvStream & /* rStrm */,
257                                              const WW8Fib &rFib)
258 {
259     sal_uInt32 nGlossaryFibOffset = 0;
260     if ( rFib.fDot ) // its a template
261     {
262         if ( rFib.pnNext  )
263             nGlossaryFibOffset = ( rFib.pnNext * 512 );
264     }
265     return nGlossaryFibOffset;
266 }
267 
268 /* vi:set tabstop=4 shiftwidth=4 expandtab: */
269