Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include <iostream>
21 :
22 : #include <com/sun/star/embed/ElementModes.hpp>
23 : #include <com/sun/star/embed/XStorage.hpp>
24 : #include <unotools/ucbstreamhelper.hxx>
25 :
26 : #include <algorithm>
27 :
28 : #include <map>
29 : #include <set>
30 :
31 : #include <hintids.hxx>
32 : #include <string.h>
33 : #include <osl/endian.h>
34 : #include <docsh.hxx>
35 :
36 : #include <unotools/fltrcfg.hxx>
37 : #include <vcl/salbtype.hxx>
38 : #include <sot/storage.hxx>
39 : #include <svl/zformat.hxx>
40 : #include <sfx2/docinf.hxx>
41 : #include <editeng/tstpitem.hxx>
42 : #include <svx/svdmodel.hxx>
43 : #include <svx/svdpage.hxx>
44 : #include <editeng/hyphenzoneitem.hxx>
45 : #include <editeng/langitem.hxx>
46 : #include <filter/msfilter/msoleexp.hxx>
47 : #include <editeng/lrspitem.hxx>
48 : #include <editeng/ulspitem.hxx>
49 : #include <editeng/boxitem.hxx>
50 : #include <editeng/brushitem.hxx>
51 : #include <swtypes.hxx>
52 : #include <swrect.hxx>
53 : #include <swtblfmt.hxx>
54 : #include <txatbase.hxx>
55 : #include <fmtcntnt.hxx>
56 : #include <fmtpdsc.hxx>
57 : #include <fmtrowsplt.hxx>
58 : #include <frmatr.hxx>
59 : #include <doc.hxx>
60 : #include <viewopt.hxx>
61 : #include <docary.hxx>
62 : #include <pam.hxx>
63 : #include <ndtxt.hxx>
64 : #include <shellio.hxx>
65 : #include <docstat.hxx>
66 : #include <pagedesc.hxx>
67 : #include <IMark.hxx>
68 : #include <swtable.hxx>
69 : #include <wrtww8.hxx>
70 : #include <ww8par.hxx>
71 : #include <fltini.hxx>
72 : #include <swmodule.hxx>
73 : #include <section.hxx>
74 : #include <swfltopt.hxx>
75 : #include <fmtinfmt.hxx>
76 : #include <txtinet.hxx>
77 : #include <fmturl.hxx>
78 : #include <fesh.hxx>
79 : #include <svtools/imap.hxx>
80 : #include <svtools/imapobj.hxx>
81 : #include <tools/urlobj.hxx>
82 : #include <mdiexp.hxx>
83 : #include <statstr.hrc>
84 : #include <fmtline.hxx>
85 : #include <fmtfsize.hxx>
86 : #include <comphelper/extract.hxx>
87 : #include <comphelper/string.hxx>
88 : #include <filter/msfilter/sprmids.hxx>
89 :
90 : #include "writerhelper.hxx"
91 : #include "writerwordglue.hxx"
92 : #include "ww8attributeoutput.hxx"
93 :
94 : #include <IDocumentMarkAccess.hxx>
95 : #include <xmloff/odffields.hxx>
96 :
97 : #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
98 : #include <com/sun/star/document/XDocumentProperties.hpp>
99 :
100 : #include "dbgoutsw.hxx"
101 :
102 : #include <sfx2/docfile.hxx>
103 : #include <sfx2/request.hxx>
104 : #include <sfx2/frame.hxx>
105 : #include <svl/stritem.hxx>
106 : #include <unotools/tempfile.hxx>
107 : #include <filter/msfilter/mscodec.hxx>
108 : #include <filter/msfilter/svxmsbas.hxx>
109 : #include <osl/time.h>
110 : #include <rtl/random.h>
111 : #include <vcl/svapp.hxx>
112 : #include "WW8Sttbf.hxx"
113 : #include <editeng/charrotateitem.hxx>
114 : #include "WW8FibData.hxx"
115 : #include "numrule.hxx"
116 :
117 : using namespace css;
118 : using namespace sw::util;
119 : using namespace sw::types;
120 :
121 : /** FKP - Formatted disK Page
122 : */
123 : class WW8_WrFkp
124 : {
125 : sal_uInt8* pFkp; // Fkp total ( first and only FCs and Sprms )
126 : sal_uInt8* pOfs; // pointer to the offset area, later copied to pFkp
127 : ePLCFT ePlc;
128 : short nStartGrp; // ab hier grpprls
129 : short nOldStartGrp;
130 : sal_uInt8 nItemSize;
131 : sal_uInt8 nIMax; // number of entry pairs
132 : sal_uInt8 nOldVarLen;
133 : bool bCombined; // true : paste not allowed
134 :
135 : sal_uInt8 SearchSameSprm( sal_uInt16 nVarLen, const sal_uInt8* pSprms );
136 : public:
137 : WW8_WrFkp(ePLCFT ePl, WW8_FC nStartFc, bool bWrtWW8);
138 : ~WW8_WrFkp();
139 : bool Append( WW8_FC nEndFc, sal_uInt16 nVarLen = 0, const sal_uInt8* pSprms = 0 );
140 : bool Combine();
141 : void Write( SvStream& rStrm, SwWW8WrGrf& rGrf );
142 :
143 775 : bool IsEqualPos(WW8_FC nEndFc) const
144 775 : { return !bCombined && nIMax && nEndFc == ((sal_Int32*)pFkp)[nIMax]; }
145 : void MergeToNew( short& rVarLen, sal_uInt8 *& pNewSprms );
146 187 : bool IsEmptySprm() const
147 187 : { return !bCombined && nIMax && !nOldVarLen; }
148 95 : void SetNewEnd( WW8_FC nEnd )
149 95 : { ((sal_Int32*)pFkp)[nIMax] = nEnd; }
150 :
151 : WW8_FC GetStartFc() const;
152 : WW8_FC GetEndFc() const;
153 :
154 : sal_uInt8 *CopyLastSprms(sal_uInt8 &rLen, bool bVer8);
155 : };
156 :
157 : // class WW8_WrPc collects all piece entries for one piece
158 : class WW8_WrPc
159 : {
160 : WW8_CP nStartCp; // Starting character position of the text
161 : WW8_FC nStartFc; // Starting file position of the text
162 : sal_uInt16 nStatus; // End of paragraph inside the piece?
163 :
164 : public:
165 12 : WW8_WrPc(WW8_FC nSFc, WW8_CP nSCp )
166 12 : : nStartCp( nSCp ), nStartFc( nSFc ), nStatus( 0x0040 )
167 12 : {}
168 :
169 402 : void SetStatus() { nStatus = 0x0050; }
170 12 : sal_uInt16 GetStatus() const { return nStatus; }
171 260 : WW8_CP GetStartCp() const { return nStartCp; }
172 12 : WW8_FC GetStartFc() const { return nStartFc; }
173 : };
174 :
175 : typedef std::map<OUString,long> BKMKNames;
176 : typedef BKMKNames::iterator BKMKNmItr;
177 : typedef std::pair<bool,OUString> BKMK;
178 : typedef std::pair<long,BKMK> BKMKCP;
179 : typedef std::multimap<long,BKMKCP*> BKMKCPs;
180 : typedef BKMKCPs::iterator CPItr;
181 :
182 : class WW8_WrtBookmarks
183 : {
184 : private:
185 : BKMKCPs aSttCps,aEndCps;
186 : BKMKNames maSwBkmkNms;
187 : WW8_WrtBookmarks(const WW8_WrtBookmarks&);
188 : WW8_WrtBookmarks& operator=(const WW8_WrtBookmarks&);
189 :
190 : public:
191 : WW8_WrtBookmarks();
192 : ~WW8_WrtBookmarks();
193 : //! Add a new bookmark to the list OR add an end position to an existing bookmark.
194 : void Append( WW8_CP nStartCp, const OUString& rNm, const ::sw::mark::IMark* pBkmk=NULL );
195 : //! Write out bookmarks to file.
196 : void Write( WW8Export& rWrt );
197 : //! Move existing field marks from one position to another.
198 : void MoveFieldMarks(WW8_CP nFrom, WW8_CP nTo);
199 : };
200 :
201 12 : WW8_WrtBookmarks::WW8_WrtBookmarks()
202 12 : {}
203 :
204 24 : WW8_WrtBookmarks::~WW8_WrtBookmarks()
205 : {
206 12 : CPItr aEnd = aSttCps.end();
207 19 : for (CPItr aItr = aSttCps.begin();aItr!=aEnd;++aItr)
208 : {
209 7 : if (aItr->second)
210 : {
211 7 : delete aItr->second;
212 7 : aItr->second = NULL;
213 : }
214 : }
215 12 : }
216 :
217 12 : void WW8_WrtBookmarks::Append( WW8_CP nStartCp, const OUString& rNm, const ::sw::mark::IMark*)
218 : {
219 12 : std::pair<BKMKNmItr,bool> aResult = maSwBkmkNms.insert(std::pair<OUString,long>(rNm,0L));
220 12 : if (aResult.second)
221 : {
222 7 : BKMK aBK(false,rNm);
223 7 : BKMKCP* pBKCP = new BKMKCP((long)nStartCp,aBK);
224 7 : aSttCps.insert(std::pair<long,BKMKCP*>(nStartCp,pBKCP));
225 7 : aResult.first->second = (long)nStartCp;
226 : }
227 : else
228 : {
229 5 : std::pair<CPItr,CPItr> aRange = aSttCps.equal_range(aResult.first->second);
230 6 : for (CPItr aItr = aRange.first;aItr != aRange.second;++aItr)
231 : {
232 6 : if (aItr->second && aItr->second->second.second == rNm)
233 : {
234 5 : if (aItr->second->second.first)
235 0 : nStartCp--;
236 5 : aItr->second->first = (long)nStartCp;
237 5 : break;
238 : }
239 : }
240 : }
241 12 : }
242 :
243 12 : void WW8_WrtBookmarks::Write( WW8Export& rWrt)
244 : {
245 12 : if (aSttCps.empty())
246 22 : return;
247 2 : CPItr aItr;
248 : long n;
249 2 : std::vector<OUString> aNames;
250 4 : SvMemoryStream aTempStrm1(65535,65535);
251 4 : SvMemoryStream aTempStrm2(65535,65535);
252 9 : for (aItr = aSttCps.begin();aItr!=aSttCps.end();++aItr)
253 : {
254 7 : if (aItr->second)
255 : {
256 7 : aEndCps.insert(std::pair<long,BKMKCP*>(aItr->second->first,aItr->second));
257 7 : aNames.push_back(aItr->second->second.second);
258 7 : SwWW8Writer::WriteLong( aTempStrm1, aItr->first);
259 : }
260 : }
261 :
262 2 : aTempStrm1.Seek(0L);
263 9 : for (aItr = aEndCps.begin(), n = 0;aItr != aEndCps.end();++aItr,++n)
264 : {
265 7 : if (aItr->second)
266 : {
267 7 : aItr->second->first = n;
268 7 : SwWW8Writer::WriteLong( aTempStrm2, aItr->first);
269 : }
270 : }
271 :
272 2 : aTempStrm2.Seek(0L);
273 2 : rWrt.WriteAsStringTable(aNames, rWrt.pFib->fcSttbfbkmk,rWrt.pFib->lcbSttbfbkmk);
274 2 : SvStream& rStrm = rWrt.bWrtWW8 ? *rWrt.pTableStrm : rWrt.Strm();
275 2 : rWrt.pFib->fcPlcfbkf = rStrm.Tell();
276 2 : rStrm.WriteStream( aTempStrm1 );
277 2 : SwWW8Writer::WriteLong(rStrm, rWrt.pFib->ccpText + rWrt.pFib->ccpTxbx);
278 9 : for (aItr = aSttCps.begin();aItr!=aSttCps.end();++aItr)
279 : {
280 7 : if (aItr->second)
281 : {
282 7 : SwWW8Writer::WriteLong(rStrm, aItr->second->first);
283 : }
284 : }
285 2 : rWrt.pFib->lcbPlcfbkf = rStrm.Tell() - rWrt.pFib->fcPlcfbkf;
286 2 : rWrt.pFib->fcPlcfbkl = rStrm.Tell();
287 2 : rStrm.WriteStream( aTempStrm2 );
288 2 : SwWW8Writer::WriteLong(rStrm, rWrt.pFib->ccpText + rWrt.pFib->ccpTxbx);
289 4 : rWrt.pFib->lcbPlcfbkl = rStrm.Tell() - rWrt.pFib->fcPlcfbkl;
290 : }
291 :
292 0 : void WW8_WrtBookmarks::MoveFieldMarks(WW8_CP nFrom, WW8_CP nTo)
293 : {
294 0 : std::pair<CPItr,CPItr> aRange = aSttCps.equal_range(nFrom);
295 0 : CPItr aItr = aRange.first;
296 0 : while (aItr != aRange.second)
297 : {
298 0 : if (aItr->second)
299 : {
300 0 : if (aItr->second->first == (long)nFrom)
301 : {
302 0 : aItr->second->second.first = true;
303 0 : aItr->second->first = nTo;
304 : }
305 0 : aSttCps.insert(std::pair<long,BKMKCP*>(nTo,aItr->second));
306 0 : aItr->second = NULL;
307 0 : aRange = aSttCps.equal_range(nFrom);
308 0 : aItr = aRange.first;
309 0 : continue;
310 : }
311 0 : ++aItr;
312 : }
313 0 : }
314 :
315 : #define ANZ_DEFAULT_STYLES 16
316 :
317 : // Names of the storage streams
318 : #define sMainStream OUString("WordDocument")
319 : #define sCompObj OUString("\1CompObj")
320 :
321 12 : static void WriteDop( WW8Export& rWrt )
322 : {
323 12 : WW8Dop& rDop = *rWrt.pDop;
324 :
325 : // i#78951#, store the value of unknown compatability options
326 12 : rDop.SetCompatabilityOptions( rWrt.pDoc->Getn32DummyCompatabilityOptions1());
327 12 : rDop.SetCompatabilityOptions2( rWrt.pDoc->Getn32DummyCompatabilityOptions2());
328 :
329 12 : rDop.fNoLeading = !rWrt.pDoc->get(IDocumentSettingAccess::ADD_EXT_LEADING);
330 12 : rDop.fUsePrinterMetrics = !rWrt.pDoc->get(IDocumentSettingAccess::USE_VIRTUAL_DEVICE);
331 :
332 : // write default TabStop
333 : const SvxTabStopItem& rTabStop =
334 12 : DefaultItemGet<SvxTabStopItem>(*rWrt.pDoc, RES_PARATR_TABSTOP);
335 12 : rDop.dxaTab = (sal_uInt16)rTabStop[0].GetTabPos();
336 :
337 : // Zoom factor
338 12 : SwViewShell *pViewShell(rWrt.pDoc->GetCurrentViewShell());
339 12 : if (pViewShell && pViewShell->GetViewOptions()->GetZoomType() == SVX_ZOOM_PERCENT)
340 12 : rDop.wScaleSaved = pViewShell->GetViewOptions()->GetZoom();
341 :
342 : // Werte aus der DocStatistik (werden aufjedenfall fuer die
343 : // DocStat-Felder benoetigt!)
344 12 : rDop.fWCFtnEdn = true; // because they are included in StarWriter
345 :
346 12 : const SwDocStat& rDStat = rWrt.pDoc->GetDocStat();
347 12 : rDop.cWords = rDStat.nWord;
348 12 : rDop.cCh = rDStat.nChar;
349 12 : rDop.cPg = static_cast< sal_Int16 >(rDStat.nPage);
350 12 : rDop.cParas = rDStat.nPara;
351 12 : rDop.cLines = rDStat.nPara;
352 :
353 12 : SwDocShell *pDocShell(rWrt.pDoc->GetDocShell());
354 : OSL_ENSURE(pDocShell, "no SwDocShell");
355 12 : uno::Reference<document::XDocumentProperties> xDocProps;
356 24 : uno::Reference<beans::XPropertySet> xProps;
357 12 : if (pDocShell) {
358 : uno::Reference<lang::XComponent> xModelComp(pDocShell->GetModel(),
359 12 : uno::UNO_QUERY);
360 24 : xProps = uno::Reference<beans::XPropertySet>(xModelComp,
361 12 : uno::UNO_QUERY);
362 : uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
363 24 : xModelComp, uno::UNO_QUERY_THROW);
364 12 : xDocProps = xDPS->getDocumentProperties();
365 : OSL_ENSURE(xDocProps.is(), "DocumentProperties is null");
366 :
367 24 : rDop.lKeyProtDoc = pDocShell->GetModifyPasswordHash();
368 : }
369 :
370 24 : if ((rWrt.pSepx && rWrt.pSepx->DocumentIsProtected()) ||
371 12 : rDop.lKeyProtDoc != 0)
372 : {
373 0 : rDop.fProtEnabled = true;
374 : }
375 : else
376 : {
377 12 : rDop.fProtEnabled = false;
378 : }
379 :
380 12 : if (!xDocProps.is())
381 : {
382 0 : rDop.dttmCreated = rDop.dttmRevised = rDop.dttmLastPrint = 0x45FBAC69;
383 : }
384 : else
385 : {
386 12 : ::util::DateTime uDT = xDocProps->getCreationDate();
387 12 : Date aD(uDT.Day, uDT.Month, uDT.Year);
388 12 : Time aT(uDT.Hours, uDT.Minutes, uDT.Seconds, uDT.NanoSeconds);
389 12 : rDop.dttmCreated = sw::ms::DateTime2DTTM(DateTime(aD,aT));
390 12 : uDT = xDocProps->getModificationDate();
391 12 : Date aD2(uDT.Day, uDT.Month, uDT.Year);
392 12 : Time aT2(uDT.Hours, uDT.Minutes, uDT.Seconds, uDT.NanoSeconds);
393 12 : rDop.dttmRevised = sw::ms::DateTime2DTTM(DateTime(aD2,aT2));
394 12 : uDT = xDocProps->getPrintDate();
395 12 : Date aD3(uDT.Day, uDT.Month, uDT.Year);
396 12 : Time aT3(uDT.Hours, uDT.Minutes, uDT.Seconds, uDT.NanoSeconds);
397 12 : rDop.dttmLastPrint = sw::ms::DateTime2DTTM(DateTime(aD3,aT3));
398 : }
399 :
400 : // Also, the DocStat fields in headers, footers are not calculated correctly.
401 : // ( we do not have this fields! )
402 :
403 : // and also for the Headers and Footers
404 12 : rDop.cWordsFtnEnd = rDStat.nWord;
405 12 : rDop.cChFtnEdn = rDStat.nChar;
406 12 : rDop.cPgFtnEdn = (sal_Int16)rDStat.nPage;
407 12 : rDop.cParasFtnEdn = rDStat.nPara;
408 12 : rDop.cLinesFtnEdn = rDStat.nPara;
409 :
410 12 : rDop.fDontUseHTMLAutoSpacing = rWrt.pDoc->get(IDocumentSettingAccess::PARA_SPACE_MAX);
411 :
412 12 : rDop.fExpShRtn = !rWrt.pDoc->get(IDocumentSettingAccess::DO_NOT_JUSTIFY_LINES_WITH_MANUAL_BREAK); // #i56856#
413 :
414 24 : rDop.Write( *rWrt.pTableStrm, *rWrt.pFib );
415 12 : }
416 :
417 67 : const sal_Unicode *WW8DopTypography::GetJapanNotBeginLevel1()
418 : {
419 : static const sal_Unicode aJapanNotBeginLevel1[nMaxFollowing] =
420 : //Japanese Level 1
421 : {
422 : 0x0021, 0x0025, 0x0029, 0x002c, 0x002e, 0x003a, 0x003b, 0x003f,
423 : 0x005d, 0x007d, 0x00a2, 0x00b0, 0x2019, 0x201d, 0x2030, 0x2032,
424 : 0x2033, 0x2103, 0x3001, 0x3002, 0x3005, 0x3009, 0x300b, 0x300d,
425 : 0x300f, 0x3011, 0x3015, 0x309b, 0x309c, 0x309d, 0x309e, 0x30fb,
426 : 0x30fd, 0x30fe, 0xff01, 0xff05, 0xff09, 0xff0c, 0xff0e, 0xff1a,
427 : 0xff1b, 0xff1f, 0xff3d, 0xff5d, 0xff61, 0xff63, 0xff64, 0xff65,
428 : 0xff9e, 0xff9f, 0xffe0
429 : };
430 67 : return &aJapanNotBeginLevel1[0];
431 : }
432 :
433 67 : const sal_Unicode *WW8DopTypography::GetJapanNotEndLevel1()
434 : {
435 : static const sal_Unicode aJapanNotEndLevel1[nMaxLeading] =
436 : //Japanese Level 1
437 : {
438 : 0x0024, 0x0028, 0x005b, 0x005c, 0x007b, 0x00a3, 0x00a5, 0x2018,
439 : 0x201c, 0x3008, 0x300a, 0x300c, 0x300e, 0x3010, 0x3014, 0xff04,
440 : 0xff08, 0xff3b, 0xff5b, 0xff62, 0xffe1, 0xffe5
441 : };
442 67 : return &aJapanNotEndLevel1[0];
443 : }
444 :
445 28 : static int lcl_CmpBeginEndChars( const OUString& rSWStr,
446 : const sal_Unicode* pMSStr, int nMSStrByteLen )
447 : {
448 28 : nMSStrByteLen /= sizeof( sal_Unicode );
449 28 : if( nMSStrByteLen > rSWStr.getLength() )
450 28 : nMSStrByteLen = rSWStr.getLength()+1;
451 28 : nMSStrByteLen *= sizeof( sal_Unicode );
452 :
453 28 : return memcmp( rSWStr.getStr(), pMSStr, nMSStrByteLen );
454 : }
455 :
456 : /*
457 : Converts the OOo Asian Typography into a best fit match for Microsoft
458 : Asian typography. This structure is actually dumped to disk within the
459 : Dop Writer. Assumption is that rTypo is cleared to 0 on entry
460 : */
461 12 : void WW8Export::ExportDopTypography(WW8DopTypography &rTypo)
462 : {
463 : static const sal_Unicode aLangNotBegin[4][WW8DopTypography::nMaxFollowing]=
464 : {
465 : //Japanese Level 1
466 : {
467 : 0x0021, 0x0025, 0x0029, 0x002c, 0x002e, 0x003a, 0x003b, 0x003f,
468 : 0x005d, 0x007d, 0x00a2, 0x00b0, 0x2019, 0x201d, 0x2030, 0x2032,
469 : 0x2033, 0x2103, 0x3001, 0x3002, 0x3005, 0x3009, 0x300b, 0x300d,
470 : 0x300f, 0x3011, 0x3015, 0x3041, 0x3043, 0x3045, 0x3047, 0x3049,
471 : 0x3063, 0x3083, 0x3085, 0x3087, 0x308e, 0x309b, 0x309c, 0x309d,
472 : 0x309e, 0x30a1, 0x30a3, 0x30a5, 0x30a7, 0x30a9, 0x30c3, 0x30e3,
473 : 0x30e5, 0x30e7, 0x30ee, 0x30f5, 0x30f6, 0x30fb, 0x30fc, 0x30fd,
474 : 0x30fe, 0xff01, 0xff05, 0xff09, 0xff0c, 0xff0e, 0xff1a, 0xff1b,
475 : 0xff1f, 0xff3d, 0xff5d, 0xff61, 0xff63, 0xff64, 0xff65, 0xff67,
476 : 0xff68, 0xff69, 0xff6a, 0xff6b, 0xff6c, 0xff6d, 0xff6e, 0xff6f,
477 : 0xff70, 0xff9e, 0xff9f, 0xffe0
478 : },
479 : //Simplified Chinese
480 : {
481 : 0x0021, 0x0029, 0x002c, 0x002e, 0x003a, 0x003b, 0x003f, 0x005d,
482 : 0x007d, 0x00a8, 0x00b7, 0x02c7, 0x02c9, 0x2015, 0x2016, 0x2019,
483 : 0x201d, 0x2026, 0x2236, 0x3001, 0x3002, 0x3003, 0x3005, 0x3009,
484 : 0x300b, 0x300d, 0x300f, 0x3011, 0x3015, 0x3017, 0xff01, 0xff02,
485 : 0xff07, 0xff09, 0xff0c, 0xff0e, 0xff1a, 0xff1b, 0xff1f, 0xff3d,
486 : 0xff40, 0xff5c, 0xff5d, 0xff5e, 0xffe0
487 : },
488 : //Korean
489 : {
490 : 0x0021, 0x0025, 0x0029, 0x002c, 0x002e, 0x003a, 0x003b, 0x003f,
491 : 0x005d, 0x007d, 0x00a2, 0x00b0, 0x2019, 0x201d, 0x2032, 0x2033,
492 : 0x2103, 0x3009, 0x300b, 0x300d, 0x300f, 0x3011, 0x3015, 0xff01,
493 : 0xff05, 0xff09, 0xff0c, 0xff0e, 0xff1a, 0xff1b, 0xff1f, 0xff3d,
494 : 0xff5d, 0xffe0
495 : },
496 : //Traditional Chinese
497 : {
498 : 0x0021, 0x0029, 0x002c, 0x002e, 0x003a, 0x003b, 0x003f, 0x005d,
499 : 0x007d, 0x00a2, 0x00b7, 0x2013, 0x2014, 0x2019, 0x201d, 0x2022,
500 : 0x2025, 0x2026, 0x2027, 0x2032, 0x2574, 0x3001, 0x3002, 0x3009,
501 : 0x300b, 0x300d, 0x300f, 0x3011, 0x3015, 0x301e, 0xfe30, 0xfe31,
502 : 0xfe33, 0xfe34, 0xfe36, 0xfe38, 0xfe3a, 0xfe3c, 0xfe3e, 0xfe40,
503 : 0xfe42, 0xfe44, 0xfe4f, 0xfe50, 0xfe51, 0xfe52, 0xfe54, 0xfe55,
504 : 0xfe56, 0xfe57, 0xfe5a, 0xfe5c, 0xfe5e, 0xff01, 0xff09, 0xff0c,
505 : 0xff0e, 0xff1a, 0xff1b, 0xff1f, 0xff5c, 0xff5d, 0xff64
506 : },
507 : };
508 :
509 : static const sal_Unicode aLangNotEnd[4][WW8DopTypography::nMaxLeading] =
510 : {
511 : //Japanese Level 1
512 : {
513 : 0x0024, 0x0028, 0x005b, 0x005c, 0x007b, 0x00a3, 0x00a5, 0x2018,
514 : 0x201c, 0x3008, 0x300a, 0x300c, 0x300e, 0x3010, 0x3014, 0xff04,
515 : 0xff08, 0xff3b, 0xff5b, 0xff62, 0xffe1, 0xffe5
516 : },
517 : //Simplified Chinese
518 : {
519 : 0x0028, 0x005b, 0x007b, 0x00b7, 0x2018, 0x201c, 0x3008, 0x300a,
520 : 0x300c, 0x300e, 0x3010, 0x3014, 0x3016, 0xff08, 0xff0e, 0xff3b,
521 : 0xff5b, 0xffe1, 0xffe5
522 : },
523 : //Korean
524 : {
525 : 0x0028, 0x005b, 0x005c, 0x007b, 0x00a3, 0x00a5, 0x2018, 0x201c,
526 : 0x3008, 0x300a, 0x300c, 0x300e, 0x3010, 0x3014, 0xff04, 0xff08,
527 : 0xff3b, 0xff5b, 0xffe6
528 : },
529 : //Traditional Chinese
530 : {
531 : 0x0028, 0x005b, 0x007b, 0x00a3, 0x00a5, 0x2018, 0x201c, 0x2035,
532 : 0x3008, 0x300a, 0x300c, 0x300e, 0x3010, 0x3014, 0x301d, 0xfe35,
533 : 0xfe37, 0xfe39, 0xfe3b, 0xfe3d, 0xfe3f, 0xfe41, 0xfe43, 0xfe59,
534 : 0xfe5b, 0xfe5d, 0xff08, 0xff5b
535 : },
536 : };
537 :
538 12 : const i18n::ForbiddenCharacters *pForbidden = 0;
539 12 : const i18n::ForbiddenCharacters *pUseMe = 0;
540 12 : sal_uInt8 nUseReserved=0;
541 12 : int nNoNeeded=0;
542 : /*
543 : Now we have some minor difficult issues, to wit...
544 : a. MicroSoft Office can only store one set of begin and end characters in
545 : a given document, not one per language.
546 : b. StarOffice has only a concept of one set of begin and end characters for
547 : a given language, i.e. not the two levels of kinsoku in japanese
548 :
549 : What is unknown as yet is if our default begin and end chars for
550 : japanese, chinese tradition, chinese simplified and korean are different
551 : in Word and Writer. I already suspect that they are different between
552 : different version of word itself.
553 :
554 : So what have come up with is to simply see if any of the four languages
555 : in OOo have been changed away from OUR defaults, and if one has then
556 : export that. If more than one has in the future we may hack in something
557 : which examines our document properties to see which language is used the
558 : most and choose that, for now we choose the first and throw an ASSERT
559 : */
560 :
561 : /*Our default Japanese Level is 2, this is a special MS hack to set this*/
562 12 : rTypo.reserved2 = 1;
563 :
564 60 : for (rTypo.reserved1=8;rTypo.reserved1>0;rTypo.reserved1-=2)
565 : {
566 96 : if (0 != (pForbidden = pDoc->getForbiddenCharacters(rTypo.GetConvertedLang(),
567 96 : false)))
568 : {
569 7 : int nIdx = (rTypo.reserved1-2)/2;
570 7 : if( lcl_CmpBeginEndChars( pForbidden->endLine,
571 14 : aLangNotEnd[ nIdx ], sizeof(aLangNotEnd[ nIdx ]) ) ||
572 : lcl_CmpBeginEndChars( pForbidden->beginLine,
573 7 : aLangNotBegin[ nIdx ], sizeof(aLangNotBegin[ nIdx ]) ) )
574 : {
575 : //One exception for Japanese, if it matches a level 1 we
576 : //can use one extra flag for that, rather than use a custom
577 7 : if (rTypo.GetConvertedLang() == LANGUAGE_JAPANESE)
578 : {
579 7 : if (
580 : !lcl_CmpBeginEndChars
581 : (
582 : pForbidden->endLine,
583 : rTypo.GetJapanNotEndLevel1(),
584 7 : rTypo.nMaxLeading * sizeof(sal_Unicode)
585 7 : )
586 14 : &&
587 : !lcl_CmpBeginEndChars
588 : (
589 : pForbidden->beginLine,
590 : rTypo.GetJapanNotBeginLevel1(),
591 7 : rTypo.nMaxFollowing * sizeof(sal_Unicode)
592 7 : )
593 : )
594 : {
595 7 : rTypo.reserved2 = 0;
596 7 : continue;
597 : }
598 : }
599 :
600 0 : if (!pUseMe)
601 : {
602 0 : pUseMe = pForbidden;
603 0 : nUseReserved = rTypo.reserved1;
604 0 : rTypo.iLevelOfKinsoku = 2;
605 : }
606 0 : nNoNeeded++;
607 : }
608 : }
609 : }
610 :
611 : OSL_ENSURE( nNoNeeded<=1, "Example of unexportable forbidden chars" );
612 12 : rTypo.reserved1=nUseReserved;
613 12 : if (rTypo.iLevelOfKinsoku && pUseMe)
614 : {
615 : rTypo.cchFollowingPunct = msword_cast<sal_Int16>
616 0 : (pUseMe->beginLine.getLength());
617 0 : if (rTypo.cchFollowingPunct > WW8DopTypography::nMaxFollowing - 1)
618 0 : rTypo.cchFollowingPunct = WW8DopTypography::nMaxFollowing - 1;
619 :
620 : rTypo.cchLeadingPunct = msword_cast<sal_Int16>
621 0 : (pUseMe->endLine.getLength());
622 0 : if (rTypo.cchLeadingPunct > WW8DopTypography::nMaxLeading - 1)
623 0 : rTypo.cchLeadingPunct = WW8DopTypography::nMaxLeading -1;
624 :
625 0 : memcpy(rTypo.rgxchFPunct,pUseMe->beginLine.getStr(),
626 0 : (rTypo.cchFollowingPunct+1)*2);
627 :
628 0 : memcpy(rTypo.rgxchLPunct,pUseMe->endLine.getStr(),
629 0 : (rTypo.cchLeadingPunct+1)*2);
630 : }
631 :
632 12 : const IDocumentSettingAccess* pIDocumentSettingAccess = GetWriter().getIDocumentSettingAccess();
633 :
634 12 : rTypo.fKerningPunct = sal_uInt16(pIDocumentSettingAccess->get(IDocumentSettingAccess::KERN_ASIAN_PUNCTUATION));
635 12 : rTypo.iJustification = pDoc->getCharacterCompressionType();
636 12 : }
637 :
638 : // It can only be found something with this method, if it is used within
639 : // WW8_SwAttrIter::OutAttr() and WW8Export::OutputItemSet()
640 2156 : const SfxPoolItem* MSWordExportBase::HasItem( sal_uInt16 nWhich ) const
641 : {
642 2156 : const SfxPoolItem* pItem=0;
643 2156 : if (pISet)
644 : {
645 : // if write a EditEngine text, then the WhichIds are greater as
646 : // ourer own Ids. So the Id have to translate from our into the
647 : // EditEngine Range
648 1854 : nWhich = sw::hack::GetSetWhichFromSwDocWhich(*pISet, *pDoc, nWhich);
649 1854 : if (nWhich && SFX_ITEM_SET != pISet->GetItemState(nWhich, true, &pItem))
650 1276 : pItem = 0;
651 : }
652 302 : else if( pChpIter )
653 30 : pItem = pChpIter->HasTextItem( nWhich );
654 : else
655 : {
656 : OSL_ENSURE( !this, "Where is my ItemSet / pChpIter ?" );
657 272 : pItem = 0;
658 : }
659 2156 : return pItem;
660 : }
661 :
662 272 : const SfxPoolItem& MSWordExportBase::GetItem(sal_uInt16 nWhich) const
663 : {
664 : const SfxPoolItem* pItem;
665 272 : if (pISet)
666 : {
667 : // if write a EditEngine text, then the WhichIds are greater as
668 : // ourer own Ids. So the Id have to translate from our into the
669 : // EditEngine Range
670 184 : nWhich = sw::hack::GetSetWhichFromSwDocWhich(*pISet, *pDoc, nWhich);
671 : OSL_ENSURE(nWhich != 0, "All broken, Impossible");
672 184 : pItem = &pISet->Get(nWhich, true);
673 : }
674 88 : else if( pChpIter )
675 88 : pItem = &pChpIter->GetItem( nWhich );
676 : else
677 : {
678 : OSL_ENSURE( !this, "Where is my ItemSet / pChpIter ?" );
679 0 : pItem = 0;
680 : }
681 272 : return *pItem;
682 : }
683 :
684 96 : WW8_WrPlc1::WW8_WrPlc1( sal_uInt16 nStructSz )
685 96 : : nStructSiz( nStructSz )
686 : {
687 96 : nDataLen = 16 * nStructSz;
688 96 : pData = new sal_uInt8[ nDataLen ];
689 96 : }
690 :
691 192 : WW8_WrPlc1::~WW8_WrPlc1()
692 : {
693 96 : delete[] pData;
694 96 : }
695 :
696 0 : WW8_CP WW8_WrPlc1::Prev() const
697 : {
698 0 : bool b = !aPos.empty();
699 : OSL_ENSURE(b,"Prev called on empty list");
700 0 : return b ? aPos.back() : 0;
701 : }
702 :
703 18 : void WW8_WrPlc1::Append( WW8_CP nCp, const void* pNewData )
704 : {
705 18 : sal_uLong nInsPos = aPos.size() * nStructSiz;
706 18 : aPos.push_back( nCp );
707 18 : if( nDataLen < nInsPos + nStructSiz )
708 : {
709 0 : sal_uInt8* pNew = new sal_uInt8[ 2 * nDataLen ];
710 0 : memcpy( pNew, pData, nDataLen );
711 0 : delete[] pData;
712 0 : pData = pNew;
713 0 : nDataLen *= 2;
714 : }
715 18 : memcpy( pData + nInsPos, pNewData, nStructSiz );
716 18 : }
717 :
718 96 : void WW8_WrPlc1::Finish( sal_uLong nLastCp, sal_uLong nSttCp )
719 : {
720 96 : if( !aPos.empty() )
721 : {
722 14 : aPos.push_back( nLastCp );
723 14 : if( nSttCp )
724 5 : for( sal_uInt32 n = 0; n < aPos.size(); ++n )
725 4 : aPos[ n ] -= nSttCp;
726 : }
727 96 : }
728 :
729 14 : void WW8_WrPlc1::Write( SvStream& rStrm )
730 : {
731 : sal_uInt32 i;
732 46 : for( i = 0; i < aPos.size(); ++i )
733 32 : SwWW8Writer::WriteLong( rStrm, aPos[i] );
734 14 : if( i )
735 14 : rStrm.Write( pData, (i-1) * nStructSiz );
736 14 : }
737 :
738 : // Class WW8_WrPlcFld for fields
739 :
740 84 : bool WW8_WrPlcFld::Write( WW8Export& rWrt )
741 : {
742 84 : if( WW8_WrPlc1::Count() <= 1 )
743 82 : return false;
744 :
745 : WW8_FC *pfc;
746 : sal_Int32 *plc;
747 2 : switch (nTxtTyp)
748 : {
749 : case TXT_MAINTEXT:
750 1 : pfc = &rWrt.pFib->fcPlcffldMom;
751 1 : plc = &rWrt.pFib->lcbPlcffldMom;
752 1 : break;
753 : case TXT_HDFT:
754 0 : pfc = &rWrt.pFib->fcPlcffldHdr;
755 0 : plc = &rWrt.pFib->lcbPlcffldHdr;
756 0 : break;
757 :
758 : case TXT_FTN:
759 0 : pfc = &rWrt.pFib->fcPlcffldFtn;
760 0 : plc = &rWrt.pFib->lcbPlcffldFtn;
761 0 : break;
762 :
763 : case TXT_EDN:
764 0 : pfc = &rWrt.pFib->fcPlcffldEdn;
765 0 : plc = &rWrt.pFib->lcbPlcffldEdn;
766 0 : break;
767 :
768 : case TXT_ATN:
769 0 : pfc = &rWrt.pFib->fcPlcffldAtn;
770 0 : plc = &rWrt.pFib->lcbPlcffldAtn;
771 0 : break;
772 :
773 : case TXT_TXTBOX:
774 1 : pfc = &rWrt.pFib->fcPlcffldTxbx;
775 1 : plc = &rWrt.pFib->lcbPlcffldTxbx;
776 1 : break;
777 :
778 : case TXT_HFTXTBOX:
779 0 : pfc = &rWrt.pFib->fcPlcffldHdrTxbx;
780 0 : plc = &rWrt.pFib->lcbPlcffldHdrTxbx;
781 0 : break;
782 :
783 : default:
784 0 : pfc = plc = 0;
785 0 : break;
786 : }
787 :
788 2 : if( pfc && plc )
789 : {
790 2 : sal_uLong nFcStart = rWrt.pTableStrm->Tell();
791 2 : WW8_WrPlc1::Write( *rWrt.pTableStrm );
792 2 : *pfc = nFcStart;
793 2 : *plc = rWrt.pTableStrm->Tell() - nFcStart;
794 : }
795 2 : return true;
796 : }
797 :
798 12 : bool WW8_WrMagicTable::Write( WW8Export& rWrt )
799 : {
800 12 : if( WW8_WrPlc1::Count() <= 1 )
801 0 : return false;
802 12 : sal_uLong nFcStart = rWrt.pTableStrm->Tell();
803 12 : WW8_WrPlc1::Write( *rWrt.pTableStrm );
804 12 : rWrt.pFib->fcPlcfTch = nFcStart;
805 12 : rWrt.pFib->lcbPlcfTch = rWrt.pTableStrm->Tell() - nFcStart;
806 12 : return true;
807 : }
808 :
809 12 : void WW8_WrMagicTable::Append( WW8_CP nCp, sal_uLong nData)
810 : {
811 : SVBT32 nLittle;
812 : /*
813 : Tell the undocumented table hack that everything between here and the last
814 : table position is nontable text, don't do it if the previous position is
815 : the same as this one, as that would be a region of 0 length
816 : */
817 12 : if ((!Count()) || (Prev() != nCp))
818 : {
819 12 : UInt32ToSVBT32(nData,nLittle);
820 12 : WW8_WrPlc1::Append(nCp, nLittle);
821 : }
822 12 : }
823 :
824 158 : void SwWW8Writer::FillCount( SvStream& rStrm, sal_uLong nCount )
825 : {
826 : static const sal_uInt32 aNulls[16] =
827 : {
828 : 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 // 64 Byte
829 : };
830 :
831 750 : while (nCount > 64)
832 : {
833 434 : rStrm.Write( aNulls, 64 ); // in steps of 64-Byte
834 434 : nCount -= 64;
835 : }
836 158 : rStrm.Write( aNulls, nCount ); // write the rest ( 0 .. 64 Bytes )
837 158 : }
838 :
839 36 : sal_uLong SwWW8Writer::FillUntil( SvStream& rStrm, sal_uLong nEndPos )
840 : {
841 36 : sal_uLong nCurPos = rStrm.Tell();
842 36 : if( !nEndPos ) // nEndPos == 0 -> next Page
843 24 : nEndPos = (nCurPos + 0x1ff) & ~0x1ffUL;
844 :
845 36 : if( nEndPos > nCurPos )
846 24 : SwWW8Writer::FillCount( rStrm, nEndPos - nCurPos );
847 : #if OSL_DEBUG_LEVEL > 0
848 : else
849 : OSL_ENSURE( nEndPos == nCurPos, "Falsches FillUntil()" );
850 : #endif
851 36 : return rStrm.Tell();
852 : }
853 :
854 24 : WW8_WrPlcPn::WW8_WrPlcPn(WW8Export& rWr, ePLCFT ePl, WW8_FC nStartFc)
855 : : rWrt(rWr)
856 : , nFkpStartPage(0)
857 : , ePlc(ePl)
858 : , bWrtWW8(true)
859 24 : , nMark(0)
860 : {
861 24 : WW8_WrFkp* pF = new WW8_WrFkp( ePlc, nStartFc, rWrt.bWrtWW8 );
862 24 : aFkps.push_back( pF );
863 24 : }
864 :
865 24 : WW8_WrPlcPn::~WW8_WrPlcPn()
866 : {
867 24 : }
868 :
869 12 : sal_uInt8 *WW8_WrPlcPn::CopyLastSprms(sal_uInt8 &rLen)
870 : {
871 12 : WW8_WrFkp& rF = aFkps.back();
872 12 : return rF.CopyLastSprms(rLen, rWrt.bWrtWW8);
873 : }
874 :
875 966 : void WW8_WrPlcPn::AppendFkpEntry(WW8_FC nEndFc,short nVarLen,const sal_uInt8* pSprms)
876 : {
877 966 : WW8_WrFkp* pF = &aFkps.back();
878 :
879 : // big sprm? build the sprmPHugePapx
880 966 : sal_uInt8* pNewSprms = (sal_uInt8*)pSprms;
881 : sal_uInt8 aHugePapx[ 8 ];
882 966 : if( rWrt.bWrtWW8 && PAP == ePlc && 488 < nVarLen )
883 : {
884 4 : sal_uInt8* p = aHugePapx;
885 4 : *p++ = *pSprms++; // set style Id
886 4 : *p++ = *pSprms++;
887 4 : nVarLen -= 2;
888 :
889 4 : long nDataPos = rWrt.pDataStrm->Tell();
890 4 : SwWW8Writer::WriteShort( *rWrt.pDataStrm, nVarLen );
891 4 : rWrt.pDataStrm->Write( pSprms, nVarLen );
892 :
893 4 : Set_UInt16( p, 0x6646 ); // set SprmCode
894 4 : Set_UInt32( p, nDataPos ); // set startpos (FC) in the datastream
895 4 : nVarLen = static_cast< short >(p - aHugePapx);
896 4 : pSprms = pNewSprms = aHugePapx;
897 : }
898 : // if append at the same FC-EndPos and there are sprms, then get the old
899 : // sprms and erase it; they will append now with the new sprms
900 962 : else if( nVarLen && pF->IsEqualPos( nEndFc ))
901 1 : pF->MergeToNew( nVarLen, pNewSprms );
902 : // has the prev EndFC an empty sprm and the current is empty too, then
903 : // expand only the old EndFc to the new EndFc
904 961 : else if( !nVarLen && pF->IsEmptySprm() )
905 : {
906 95 : pF->SetNewEnd( nEndFc );
907 95 : return ;
908 : }
909 :
910 871 : bool bOk = pF->Append(nEndFc, nVarLen, pNewSprms);
911 871 : if( !bOk )
912 : {
913 42 : pF->Combine();
914 42 : pF = new WW8_WrFkp( ePlc, pF->GetEndFc(), rWrt.bWrtWW8 ); // Start new Fkp == end of old Fkp
915 :
916 42 : aFkps.push_back( pF );
917 42 : if( !pF->Append( nEndFc, nVarLen, pNewSprms ) )
918 : {
919 : OSL_ENSURE( !this, "Sprm liess sich nicht einfuegen" );
920 : }
921 : }
922 871 : if( pNewSprms != pSprms ) //Merge to new has created a new block
923 1 : delete[] pNewSprms;
924 : }
925 :
926 24 : void WW8_WrPlcPn::WriteFkps()
927 : {
928 24 : nFkpStartPage = (sal_uInt16) ( SwWW8Writer::FillUntil( rWrt.Strm() ) >> 9 );
929 :
930 90 : for( sal_uInt16 i = 0; i < aFkps.size(); i++ )
931 66 : aFkps[ i ].Write( rWrt.Strm(), *rWrt.pGrf );
932 :
933 24 : if( CHP == ePlc )
934 : {
935 12 : rWrt.pFib->pnChpFirst = nFkpStartPage;
936 12 : rWrt.pFib->cpnBteChp = aFkps.size();
937 : }
938 : else
939 : {
940 12 : rWrt.pFib->pnPapFirst = nFkpStartPage;
941 12 : rWrt.pFib->cpnBtePap = aFkps.size();
942 : }
943 24 : }
944 :
945 24 : void WW8_WrPlcPn::WritePlc()
946 : {
947 24 : sal_uLong nFcStart = rWrt.pTableStrm->Tell();
948 : sal_uInt16 i;
949 :
950 90 : for( i = 0; i < aFkps.size(); i++ )
951 : SwWW8Writer::WriteLong( *rWrt.pTableStrm,
952 66 : aFkps[ i ].GetStartFc() );
953 :
954 : SwWW8Writer::WriteLong( *rWrt.pTableStrm,
955 24 : aFkps[ i - 1 ].GetEndFc() );
956 :
957 : // fuer jedes FKP die Page ausgeben
958 24 : if( rWrt.bWrtWW8) // for WW97 Long output
959 90 : for ( i = 0; i < aFkps.size(); i++)
960 66 : SwWW8Writer::WriteLong( *rWrt.pTableStrm, i + nFkpStartPage );
961 : else // for WW95 Short output
962 0 : for ( i = 0; i < aFkps.size(); i++)
963 0 : SwWW8Writer::WriteShort( *rWrt.pTableStrm, i + nFkpStartPage );
964 :
965 24 : if( CHP == ePlc )
966 : {
967 12 : rWrt.pFib->fcPlcfbteChpx = nFcStart;
968 12 : rWrt.pFib->lcbPlcfbteChpx = rWrt.pTableStrm->Tell() - nFcStart;
969 : }
970 : else
971 : {
972 12 : rWrt.pFib->fcPlcfbtePapx = nFcStart;
973 12 : rWrt.pFib->lcbPlcfbtePapx = rWrt.pTableStrm->Tell() - nFcStart;
974 : }
975 24 : }
976 :
977 66 : WW8_WrFkp::WW8_WrFkp(ePLCFT ePl, WW8_FC nStartFc, bool bWrtWW8)
978 : : ePlc(ePl), nStartGrp(511), nOldStartGrp(511),
979 : nItemSize( ( CHP == ePl ) ? 1 : ( bWrtWW8 ? 13 : 7 )),
980 66 : nIMax(0), nOldVarLen(0), bCombined(false)
981 : {
982 66 : pFkp = (sal_uInt8*)new sal_Int32[128]; // 512 Byte
983 66 : pOfs = (sal_uInt8*)new sal_Int32[128]; // 512 Byte
984 66 : memset( pFkp, 0, 4 * 128 );
985 66 : memset( pOfs, 0, 4 * 128 );
986 66 : ( (sal_Int32*)pFkp )[0] = nStartFc; // 0th entry FC at nStartFc
987 66 : }
988 :
989 66 : WW8_WrFkp::~WW8_WrFkp()
990 : {
991 66 : delete[] (sal_Int32 *)pFkp;
992 66 : delete[] (sal_Int32 *)pOfs;
993 66 : }
994 :
995 821 : sal_uInt8 WW8_WrFkp::SearchSameSprm( sal_uInt16 nVarLen, const sal_uInt8* pSprms )
996 : {
997 821 : if( 3 < nVarLen )
998 : {
999 : // if the sprms contained picture-references then never equal!
1000 15000 : for( sal_uInt8 n = static_cast< sal_uInt8 >(nVarLen - 1); 3 < n; --n )
1001 14334 : if( pSprms[ n ] == GRF_MAGIC_3 &&
1002 3 : pSprms[ n-1 ] == GRF_MAGIC_2 &&
1003 1 : pSprms[ n-2 ] == GRF_MAGIC_1 )
1004 1 : return 0;
1005 : }
1006 :
1007 : short i;
1008 7513 : for( i = 0; i < nIMax; i++ )
1009 : {
1010 7090 : sal_uInt8 nStart = pOfs[i * nItemSize];
1011 7090 : if( nStart )
1012 : { // has Sprms
1013 6369 : const sal_uInt8* p = pFkp + ( (sal_uInt16)nStart << 1 );
1014 12738 : if( ( CHP == ePlc
1015 4101 : ? (*p++ == nVarLen)
1016 2268 : : (((sal_uInt16)*p++ << 1 ) == (( nVarLen+1) & 0xfffe)) )
1017 12738 : && !memcmp( p, pSprms, nVarLen ) )
1018 397 : return nStart; // found it
1019 : }
1020 : }
1021 423 : return 0; // didn't found it
1022 : }
1023 :
1024 12 : sal_uInt8 *WW8_WrFkp::CopyLastSprms(sal_uInt8 &rLen, bool bVer8)
1025 : {
1026 12 : rLen=0;
1027 12 : sal_uInt8 *pStart=0,*pRet=0;
1028 :
1029 12 : if (!bCombined)
1030 12 : pStart = pOfs;
1031 : else
1032 0 : pStart = pFkp + ( nIMax + 1 ) * 4;
1033 :
1034 12 : sal_uInt8 nStart = *(pStart + (nIMax-1) * nItemSize);
1035 :
1036 12 : const sal_uInt8* p = pFkp + ( (sal_uInt16)nStart << 1 );
1037 :
1038 12 : if (!*p && bVer8)
1039 11 : p++;
1040 :
1041 12 : if (*p)
1042 : {
1043 12 : rLen = *p++;
1044 12 : if (PAP == ePlc)
1045 12 : rLen *= 2;
1046 12 : pRet = new sal_uInt8[rLen];
1047 12 : memcpy(pRet,p,rLen);
1048 : }
1049 12 : return pRet;
1050 : }
1051 :
1052 913 : bool WW8_WrFkp::Append( WW8_FC nEndFc, sal_uInt16 nVarLen, const sal_uInt8* pSprms )
1053 : {
1054 : OSL_ENSURE( !nVarLen || pSprms, "Item pointer missing" );
1055 : OSL_ENSURE( nVarLen < ( ( ePlc == PAP ) ? 497U : 502U ), "Sprms too long !" );
1056 :
1057 913 : if( bCombined )
1058 : {
1059 : OSL_ENSURE( !this, "Fkp::Append: Fkp is already combined" );
1060 0 : return false;
1061 : }
1062 913 : sal_Int32 n = ((sal_Int32*)pFkp)[nIMax]; // last entry
1063 913 : if( nEndFc <= n )
1064 : {
1065 : OSL_ENSURE( nEndFc >= n, "+Fkp: FC backwards" );
1066 : OSL_ENSURE( !nVarLen || !pSprms || nEndFc != n,
1067 : "+Fkp: selber FC mehrfach benutzt" );
1068 : // selber FC ohne Sprm wird ohne zu mosern ignoriert.
1069 :
1070 18 : return true; // ignore (do not create a new Fkp)
1071 : }
1072 :
1073 895 : sal_uInt8 nOldP = ( nVarLen ) ? SearchSameSprm( nVarLen, pSprms ) : 0;
1074 : // Combine equal entries
1075 895 : short nOffset=0, nPos = nStartGrp;
1076 895 : if (nVarLen && !nOldP)
1077 : {
1078 424 : nPos = PAP == ePlc
1079 348 : ? ( 13 == nItemSize // HACK: PAP and bWrtWW8 !!
1080 : ? (nStartGrp & 0xFFFE ) - nVarLen - 1
1081 : : (nStartGrp - (((nVarLen + 1) & 0xFFFE)+1)) & 0xFFFE )
1082 772 : : ((nStartGrp - nVarLen - 1) & 0xFFFE);
1083 424 : if( nPos < 0 )
1084 12 : return false; // doesn't fit at all
1085 412 : nOffset = nPos; // save offset (can also be uneven!)
1086 412 : nPos &= 0xFFFE; // Pos for Sprms ( gerade Pos )
1087 : }
1088 :
1089 883 : if( (sal_uInt16)nPos <= ( nIMax + 2U ) * 4U + ( nIMax + 1U ) * nItemSize )
1090 : // does it fits behind the CPs and offsets?
1091 30 : return false; // no
1092 :
1093 853 : ((sal_Int32*)pFkp)[nIMax + 1] = nEndFc; // insert FC
1094 :
1095 853 : nOldVarLen = (sal_uInt8)nVarLen;
1096 853 : if( nVarLen && !nOldP )
1097 : { // insert it for real
1098 392 : nOldStartGrp = nStartGrp;
1099 :
1100 392 : nStartGrp = nPos;
1101 392 : pOfs[nIMax * nItemSize] = (sal_uInt8)( nStartGrp >> 1 );
1102 : // ( DatenAnfg >> 1 ) insert
1103 392 : sal_uInt8 nCnt = static_cast< sal_uInt8 >(CHP == ePlc
1104 : ? ( nVarLen < 256 ) ? (sal_uInt8) nVarLen : 255
1105 392 : : ( ( nVarLen + 1 ) >> 1 ));
1106 :
1107 392 : pFkp[ nOffset ] = nCnt; // Enter data length
1108 392 : memcpy( pFkp + nOffset + 1, pSprms, nVarLen ); // store Sprms
1109 : }
1110 : else
1111 : {
1112 : // do not enter for real ( no Sprms or recurrence )
1113 : // DatenAnfg 0 ( no data ) or recurrence
1114 461 : pOfs[nIMax * nItemSize] = nOldP;
1115 : }
1116 853 : nIMax++;
1117 853 : return true;
1118 : }
1119 :
1120 108 : bool WW8_WrFkp::Combine()
1121 : {
1122 108 : if( bCombined )
1123 42 : return false;
1124 66 : if( nIMax )
1125 66 : memcpy( pFkp + ( nIMax + 1 ) * 4, pOfs, nIMax * nItemSize );
1126 66 : delete[] pOfs;
1127 66 : pOfs = 0;
1128 66 : ((sal_uInt8*)pFkp)[511] = nIMax;
1129 66 : bCombined = true;
1130 :
1131 : #if defined OSL_BIGENDIAN // only the FCs will be rotated here
1132 : sal_uInt16 i; // the Sprms must be rotated elsewhere
1133 :
1134 : sal_uInt32* p;
1135 : for( i = 0, p = (sal_uInt32*)pFkp; i <= nIMax; i++, p++ )
1136 : *p = OSL_SWAPDWORD( *p );
1137 : #endif // ifdef OSL_BIGENDIAN
1138 :
1139 66 : return true;
1140 : }
1141 :
1142 66 : void WW8_WrFkp::Write( SvStream& rStrm, SwWW8WrGrf& rGrf )
1143 : {
1144 66 : Combine(); // If not already combined
1145 :
1146 : sal_uInt8* p; // Suche Magic fuer nPicLocFc
1147 66 : sal_uInt8* pEnd = pFkp + nStartGrp;
1148 12814 : for( p = pFkp + 511 - 4; p >= pEnd; p-- )
1149 : {
1150 12748 : if( *p != GRF_MAGIC_1 ) // search for signature 0x12 0x34 0x56 0xXX
1151 25424 : continue;
1152 71 : if( *(p+1) != GRF_MAGIC_2 )
1153 70 : continue;
1154 1 : if( *(p+2) != GRF_MAGIC_3 )
1155 0 : continue;
1156 :
1157 : SVBT32 nPos; // signature found
1158 1 : UInt32ToSVBT32( rGrf.GetFPos(), nPos ); // FilePos the graphics
1159 1 : memcpy( p, nPos, 4 ); // patch FilePos over the signature
1160 : }
1161 66 : rStrm.Write( pFkp, 512 );
1162 66 : }
1163 :
1164 1 : void WW8_WrFkp::MergeToNew( short& rVarLen, sal_uInt8 *& rpNewSprms )
1165 : {
1166 1 : sal_uInt8 nStart = pOfs[ (nIMax-1) * nItemSize ];
1167 1 : if( nStart )
1168 : { // has Sprms
1169 1 : sal_uInt8* p = pFkp + ( (sal_uInt16)nStart << 1 );
1170 :
1171 : // old and new equal? Then copy only one into the new sprms
1172 1 : if( nOldVarLen == rVarLen && !memcmp( p+1, rpNewSprms, nOldVarLen ))
1173 : {
1174 0 : sal_uInt8* pNew = new sal_uInt8[ nOldVarLen ];
1175 0 : memcpy( pNew, p+1, nOldVarLen );
1176 0 : rpNewSprms = pNew;
1177 : }
1178 : else
1179 : {
1180 1 : sal_uInt8* pNew = new sal_uInt8[ nOldVarLen + rVarLen ];
1181 1 : memcpy( pNew, p+1, nOldVarLen );
1182 1 : memcpy( pNew + nOldVarLen, rpNewSprms, rVarLen );
1183 :
1184 1 : rpNewSprms = pNew;
1185 1 : rVarLen = rVarLen + nOldVarLen;
1186 : }
1187 1 : --nIMax;
1188 : // if this sprms dont used from others, remove it
1189 1 : bool bFnd = false;
1190 20 : for (sal_uInt16 n = 0; n < nIMax; ++n)
1191 : {
1192 20 : if (nStart == pOfs[n * nItemSize])
1193 : {
1194 1 : bFnd = true;
1195 1 : break;
1196 : }
1197 : }
1198 1 : if (!bFnd)
1199 : {
1200 0 : nStartGrp = nOldStartGrp;
1201 0 : memset( p, 0, nOldVarLen+1 );
1202 : }
1203 : }
1204 1 : }
1205 :
1206 66 : WW8_FC WW8_WrFkp::GetStartFc() const
1207 : {
1208 : // wenn bCombined, dann ist das Array ab pFkp schon Bytemaessig auf LittleEndian
1209 : // umgedreht, d.h. zum Herausholen der Anfangs- und Endpositionen muss
1210 : // zurueckgedreht werden.
1211 66 : if( bCombined )
1212 66 : return SVBT32ToUInt32( pFkp ); // 0. Element
1213 0 : return ((sal_Int32*)pFkp)[0];
1214 : }
1215 :
1216 66 : WW8_FC WW8_WrFkp::GetEndFc() const
1217 : {
1218 66 : if( bCombined )
1219 66 : return SVBT32ToUInt32( &(pFkp[nIMax*4]) ); // nIMax-tes SVBT32-Element
1220 0 : return ((sal_Int32*)pFkp)[nIMax];
1221 : }
1222 :
1223 : // Method for managing the piece table
1224 12 : WW8_WrPct::WW8_WrPct(WW8_FC nfcMin, bool bSaveUniCode)
1225 12 : : nOldFc(nfcMin), bIsUni(bSaveUniCode)
1226 : {
1227 12 : AppendPc( nOldFc, bIsUni );
1228 12 : }
1229 :
1230 12 : WW8_WrPct::~WW8_WrPct()
1231 : {
1232 12 : }
1233 :
1234 : // Fill the piece and create a new one
1235 12 : void WW8_WrPct::AppendPc(WW8_FC nStartFc, bool bIsUnicode)
1236 : {
1237 12 : WW8_CP nStartCp = nStartFc - nOldFc; // substract the beginning of the text
1238 12 : if ( !nStartCp )
1239 : {
1240 12 : if ( !aPcts.empty() )
1241 : {
1242 : OSL_ENSURE( 1 == aPcts.size(), "Leeres Piece !!");
1243 0 : aPcts.pop_back( );
1244 : }
1245 : }
1246 :
1247 12 : nOldFc = nStartFc; // remember StartFc as old
1248 :
1249 12 : if( bIsUni )
1250 12 : nStartCp >>= 1; // for Unicode: number of characters / 2
1251 :
1252 12 : if ( !bIsUnicode )
1253 : {
1254 0 : nStartFc <<= 1; // Address * 2
1255 0 : nStartFc |= 0x40000000; // second last bit for non-Unicode
1256 : }
1257 :
1258 12 : if( !aPcts.empty() )
1259 0 : nStartCp += aPcts.back().GetStartCp();
1260 :
1261 12 : WW8_WrPc* pPc = new WW8_WrPc( nStartFc, nStartCp );
1262 12 : aPcts.push_back( pPc );
1263 :
1264 12 : bIsUni = bIsUnicode;
1265 12 : }
1266 :
1267 12 : void WW8_WrPct::WritePc( WW8Export& rWrt )
1268 : {
1269 : sal_uLong nPctStart;
1270 : sal_uLong nOldPos, nEndPos;
1271 12 : boost::ptr_vector<WW8_WrPc>::iterator aIter;
1272 :
1273 12 : nPctStart = rWrt.pTableStrm->Tell(); // Start piece table
1274 12 : rWrt.pTableStrm->WriteChar( ( char )0x02 ); // Status byte PCT
1275 12 : nOldPos = nPctStart + 1; // remember Position
1276 12 : SwWW8Writer::WriteLong( *rWrt.pTableStrm, 0 ); // then the length
1277 :
1278 24 : for( aIter = aPcts.begin(); aIter != aPcts.end(); ++aIter ) // ranges
1279 : SwWW8Writer::WriteLong( *rWrt.pTableStrm,
1280 12 : aIter->GetStartCp() );
1281 :
1282 : // calculate the last Pos
1283 12 : sal_uLong nStartCp = rWrt.pFib->fcMac - nOldFc;
1284 12 : if( bIsUni )
1285 12 : nStartCp >>= 1; // For Unicode: number of characters / 2
1286 12 : nStartCp += aPcts.back().GetStartCp();
1287 12 : SwWW8Writer::WriteLong( *rWrt.pTableStrm, nStartCp );
1288 :
1289 : // piece references
1290 24 : for ( aIter = aPcts.begin(); aIter != aPcts.end(); ++aIter )
1291 : {
1292 12 : SwWW8Writer::WriteShort( *rWrt.pTableStrm, aIter->GetStatus());
1293 12 : SwWW8Writer::WriteLong( *rWrt.pTableStrm, aIter->GetStartFc());
1294 12 : SwWW8Writer::WriteShort( *rWrt.pTableStrm, 0); // PRM=0
1295 : }
1296 :
1297 : // entries in the FIB
1298 12 : rWrt.pFib->fcClx = nPctStart;
1299 12 : nEndPos = rWrt.pTableStrm->Tell();
1300 12 : rWrt.pFib->lcbClx = nEndPos - nPctStart;
1301 :
1302 : // and register the length as well
1303 : SwWW8Writer::WriteLong( *rWrt.pTableStrm, nOldPos,
1304 12 : nEndPos - nPctStart-5 );
1305 :
1306 12 : }
1307 :
1308 402 : void WW8_WrPct::SetParaBreak()
1309 : {
1310 : OSL_ENSURE( !aPcts.empty(),"SetParaBreak : aPcts.empty()" );
1311 402 : aPcts.back().SetStatus();
1312 402 : }
1313 :
1314 236 : WW8_CP WW8_WrPct::Fc2Cp( sal_uLong nFc ) const
1315 : {
1316 : OSL_ENSURE( nFc >= (sal_uLong)nOldFc, "FilePos lies in front of last piece" );
1317 : OSL_ENSURE( ! aPcts.empty(), "Fc2Cp no piece available" );
1318 :
1319 236 : nFc -= nOldFc;
1320 236 : if( bIsUni )
1321 236 : nFc /= 2;
1322 236 : return nFc + aPcts.back().GetStartCp();
1323 : }
1324 :
1325 695 : void WW8Export::AppendBookmarks( const SwTxtNode& rNd, sal_Int32 nAktPos, sal_Int32 nLen )
1326 : {
1327 695 : std::vector< const ::sw::mark::IMark* > aArr;
1328 : sal_uInt16 nCntnt;
1329 695 : const sal_Int32 nAktEnd = nAktPos + nLen;
1330 695 : if( GetWriter().GetBookmarks( rNd, nAktPos, nAktEnd, aArr ))
1331 : {
1332 10 : sal_uLong nNd = rNd.GetIndex(), nSttCP = Fc2Cp( Strm().Tell() );
1333 22 : for( sal_uInt16 n = 0; n < aArr.size(); ++n )
1334 : {
1335 12 : const ::sw::mark::IMark& rBkmk = *(aArr[ n ]);
1336 12 : if(dynamic_cast< const ::sw::mark::IFieldmark *>(&rBkmk))
1337 0 : continue;
1338 :
1339 12 : const SwPosition* pPos = &rBkmk.GetMarkPos();
1340 12 : const SwPosition* pOPos = 0;
1341 12 : if(rBkmk.IsExpanded())
1342 10 : pOPos = &rBkmk.GetOtherMarkPos();
1343 22 : if( pOPos && pOPos->nNode == pPos->nNode &&
1344 10 : pOPos->nContent < pPos->nContent )
1345 : {
1346 0 : pPos = pOPos;
1347 0 : pOPos = &rBkmk.GetMarkPos();
1348 : }
1349 :
1350 39 : if( !pOPos || ( nNd == pPos->nNode.GetIndex() &&
1351 25 : ( nCntnt = pPos->nContent.GetIndex() ) >= nAktPos &&
1352 5 : nCntnt < nAktEnd ) )
1353 : {
1354 7 : sal_uLong nCp = nSttCP + pPos->nContent.GetIndex() - nAktPos;
1355 7 : pBkmks->Append(nCp, BookmarkToWord(rBkmk.GetName()), &rBkmk);
1356 : }
1357 42 : if( pOPos && nNd == pOPos->nNode.GetIndex() &&
1358 42 : ( nCntnt = pOPos->nContent.GetIndex() ) >= nAktPos &&
1359 10 : nCntnt < nAktEnd )
1360 : {
1361 5 : sal_uLong nCp = nSttCP + pOPos->nContent.GetIndex() - nAktPos;
1362 5 : pBkmks->Append(nCp, BookmarkToWord(rBkmk.GetName()), &rBkmk);
1363 : }
1364 : }
1365 695 : }
1366 695 : }
1367 :
1368 695 : void WW8Export::AppendAnnotationMarks(const SwTxtNode& rNode, sal_Int32 nAktPos, sal_Int32 nLen)
1369 : {
1370 695 : IMarkVector aMarks;
1371 695 : if (GetAnnotationMarks(rNode, nAktPos, nAktPos + nLen, aMarks))
1372 : {
1373 26 : for (IMarkVector::const_iterator it = aMarks.begin(), end = aMarks.end(); it != end; ++it)
1374 : {
1375 15 : sw::mark::IMark* pMark = (*it);
1376 15 : const sal_Int32 nStart = pMark->GetMarkStart().nContent.GetIndex();
1377 15 : if (nStart == nAktPos)
1378 : {
1379 4 : pAtn->AddRangeStartPosition(pMark->GetName(), Fc2Cp(Strm().Tell()));
1380 703 : return;
1381 : }
1382 : }
1383 691 : }
1384 : }
1385 :
1386 0 : void WW8Export::MoveFieldMarks(WW8_CP nFrom, WW8_CP nTo)
1387 : {
1388 0 : pBkmks->MoveFieldMarks(nFrom, nTo);
1389 0 : }
1390 :
1391 0 : void WW8Export::AppendBookmark( const OUString& rName, bool bSkip )
1392 : {
1393 0 : sal_uLong nSttCP = Fc2Cp( Strm().Tell() ) + ( bSkip? 1: 0 );
1394 0 : pBkmks->Append( nSttCP, rName );
1395 0 : }
1396 :
1397 : // #i120928 collect all the graphics of bullets applied to paragraphs
1398 276 : int MSWordExportBase::CollectGrfsOfBullets()
1399 : {
1400 276 : m_vecBulletPic.clear();
1401 :
1402 276 : if ( pDoc )
1403 : {
1404 276 : size_t nCountRule = pDoc->GetNumRuleTbl().size();
1405 5500 : for (size_t n = 0; n < nCountRule; ++n)
1406 : {
1407 5224 : const SwNumRule &rRule = *( pDoc->GetNumRuleTbl().at(n) );
1408 5224 : sal_uInt16 nLevels = rRule.IsContinusNum() ? 1 : 9;
1409 52168 : for (sal_uInt16 nLvl = 0; nLvl < nLevels; ++nLvl)
1410 : {
1411 46944 : const SwNumFmt &rFmt = rRule.Get(nLvl);
1412 46944 : if (SVX_NUM_BITMAP != rFmt.GetNumberingType())
1413 : {
1414 46936 : continue;
1415 : }
1416 8 : const Graphic *pGraf = rFmt.GetBrush()? rFmt.GetBrush()->GetGraphic():0;
1417 8 : if ( pGraf )
1418 : {
1419 8 : bool bHas = false;
1420 9 : for (size_t i = 0; i < m_vecBulletPic.size(); ++i)
1421 : {
1422 1 : if (m_vecBulletPic[i]->GetChecksum() == pGraf->GetChecksum())
1423 : {
1424 0 : bHas = true;
1425 0 : break;
1426 : }
1427 : }
1428 8 : if (!bHas)
1429 : {
1430 8 : Size aSize(pGraf->GetPrefSize());
1431 8 : if (0 != aSize.Height() && 0 != aSize.Width())
1432 5 : m_vecBulletPic.push_back(pGraf);
1433 : }
1434 : }
1435 : }
1436 : }
1437 : }
1438 :
1439 276 : return m_vecBulletPic.size();
1440 : }
1441 :
1442 32 : void MSWordExportBase::BulletDefinitions()
1443 : {
1444 36 : for (size_t i = 0; i < m_vecBulletPic.size(); ++i)
1445 : {
1446 4 : const MapMode aMapMode(MAP_TWIP);
1447 4 : const Graphic& rGraphic = *m_vecBulletPic[i];
1448 4 : Size aSize(rGraphic.GetPrefSize());
1449 4 : if (MAP_PIXEL == rGraphic.GetPrefMapMode().GetMapUnit())
1450 0 : aSize = Application::GetDefaultDevice()->PixelToLogic(aSize, aMapMode);
1451 : else
1452 4 : aSize = OutputDevice::LogicToLogic(aSize,rGraphic.GetPrefMapMode(), aMapMode);
1453 :
1454 4 : if (0 != aSize.Height() && 0 != aSize.Width())
1455 4 : AttrOutput().BulletDefinition(i, rGraphic, aSize);
1456 4 : }
1457 32 : }
1458 :
1459 : //Export Graphic of Bullets
1460 12 : void WW8Export::ExportGrfBullet(const SwTxtNode& rNd)
1461 : {
1462 12 : int nCount = CollectGrfsOfBullets();
1463 12 : if (nCount > 0)
1464 : {
1465 0 : SwPosition aPos(rNd);
1466 0 : OUString aPicBullets("_PictureBullets");
1467 0 : AppendBookmark(aPicBullets);
1468 0 : for (int i = 0; i < nCount; i++)
1469 : {
1470 0 : sw::Frame aFrame(*(m_vecBulletPic[i]), aPos);
1471 0 : OutGrfBullets(aFrame);
1472 0 : }
1473 0 : AppendBookmark(aPicBullets);
1474 : }
1475 12 : }
1476 :
1477 : static sal_uInt8 nAttrMagicIdx = 0;
1478 0 : void WW8Export::OutGrfBullets(const sw::Frame & rFrame)
1479 : {
1480 0 : if ( !pGrf || !pChpPlc || !pO )
1481 0 : return;
1482 :
1483 0 : pGrf->Insert(rFrame);
1484 0 : pChpPlc->AppendFkpEntry( Strm().Tell(), pO->size(), pO->data() );
1485 0 : pO->clear();
1486 : //if links...
1487 0 : WriteChar( (char)1 );
1488 :
1489 : sal_uInt8 aArr[ 22 ];
1490 0 : sal_uInt8* pArr = aArr;
1491 :
1492 : // sprmCFSpec
1493 0 : if( bWrtWW8 )
1494 0 : Set_UInt16( pArr, 0x855 );
1495 : else
1496 0 : Set_UInt8( pArr, 117 );
1497 0 : Set_UInt8( pArr, 1 );
1498 :
1499 0 : Set_UInt16( pArr, 0x083c );
1500 0 : Set_UInt8( pArr, 0x81 );
1501 :
1502 : // sprmCPicLocation
1503 0 : if( bWrtWW8 )
1504 0 : Set_UInt16( pArr, 0x6a03 );
1505 : else
1506 : {
1507 0 : Set_UInt8( pArr, 68 );
1508 0 : Set_UInt8( pArr, 4 );
1509 : }
1510 0 : Set_UInt32( pArr, GRF_MAGIC_321 );
1511 :
1512 : //extern nAttrMagicIdx;
1513 0 : --pArr;
1514 0 : Set_UInt8( pArr, nAttrMagicIdx++ );
1515 0 : pChpPlc->AppendFkpEntry( Strm().Tell(), static_cast< short >(pArr - aArr), aArr );
1516 : }
1517 :
1518 4 : int MSWordExportBase::GetGrfIndex(const SvxBrushItem& rBrush)
1519 : {
1520 4 : int nIndex = -1;
1521 :
1522 4 : const Graphic* pGraphic = rBrush.GetGraphic();
1523 4 : if (pGraphic)
1524 : {
1525 5 : for (size_t i = 0; i < m_vecBulletPic.size(); ++i)
1526 : {
1527 4 : if (m_vecBulletPic[i]->GetChecksum() == pGraphic->GetChecksum())
1528 : {
1529 3 : nIndex = i;
1530 3 : break;
1531 : }
1532 : }
1533 : }
1534 :
1535 4 : return nIndex;
1536 : }
1537 :
1538 0 : void MSWordExportBase::AppendWordBookmark( const OUString& rName )
1539 : {
1540 0 : AppendBookmark( BookmarkToWord( rName ) );
1541 0 : }
1542 :
1543 0 : void WW8_WrtRedlineAuthor::Write( Writer& rWrt )
1544 : {
1545 0 : WW8Export & rWW8Wrt = *(((SwWW8Writer&)rWrt).m_pExport);
1546 : rWW8Wrt.WriteAsStringTable(maAuthors, rWW8Wrt.pFib->fcSttbfRMark,
1547 0 : rWW8Wrt.pFib->lcbSttbfRMark, rWW8Wrt.bWrtWW8 ? 0 : 2);
1548 0 : }
1549 :
1550 0 : sal_uInt16 WW8Export::AddRedlineAuthor( sal_uInt16 nId )
1551 : {
1552 0 : if( !pRedlAuthors )
1553 : {
1554 0 : pRedlAuthors = new WW8_WrtRedlineAuthor;
1555 0 : pRedlAuthors->AddName(OUString("Unknown"));
1556 : }
1557 0 : return pRedlAuthors->AddName( SW_MOD()->GetRedlineAuthor( nId ) );
1558 : }
1559 :
1560 9 : void WW8Export::WriteAsStringTable(const std::vector<OUString>& rStrings,
1561 : sal_Int32& rfcSttbf, sal_Int32& rlcbSttbf, sal_uInt16 nExtraLen)
1562 : {
1563 9 : sal_uInt16 n, nCount = static_cast< sal_uInt16 >(rStrings.size());
1564 9 : if( nCount )
1565 : {
1566 : // we have some Redlines found in the document -> the
1567 : // Author Name Stringtable
1568 8 : SvStream& rStrm = bWrtWW8 ? *pTableStrm : Strm();
1569 8 : rfcSttbf = rStrm.Tell();
1570 8 : if( bWrtWW8 )
1571 : {
1572 8 : SwWW8Writer::WriteShort( rStrm, -1 );
1573 8 : SwWW8Writer::WriteLong( rStrm, nCount );
1574 123 : for( n = 0; n < nCount; ++n )
1575 : {
1576 115 : const OUString& rNm = rStrings[n];
1577 115 : SwWW8Writer::WriteShort( rStrm, rNm.getLength() );
1578 115 : SwWW8Writer::WriteString16(rStrm, rNm, false);
1579 115 : if( nExtraLen )
1580 0 : SwWW8Writer::FillCount(rStrm, nExtraLen);
1581 : }
1582 : }
1583 : else
1584 : {
1585 0 : SwWW8Writer::WriteShort( rStrm, 0 );
1586 0 : for( n = 0; n < nCount; ++n )
1587 : {
1588 0 : const OUString &rString = rStrings[n];
1589 0 : const OUString aNm(rString.copy(0, std::min<sal_Int32>(rString.getLength(), 255)));
1590 0 : rStrm.WriteUChar( (sal_uInt8)aNm.getLength() );
1591 : SwWW8Writer::WriteString8(rStrm, aNm, false,
1592 0 : RTL_TEXTENCODING_MS_1252);
1593 0 : if (nExtraLen)
1594 0 : SwWW8Writer::FillCount(rStrm, nExtraLen);
1595 0 : }
1596 : }
1597 8 : rlcbSttbf = rStrm.Tell() - rfcSttbf;
1598 8 : if( !bWrtWW8 )
1599 0 : SwWW8Writer::WriteShort( rStrm, rfcSttbf, (sal_uInt16)rlcbSttbf );
1600 : }
1601 9 : }
1602 :
1603 : // WriteShort() traegt an FilePos nPos den Wert nVal ein und seekt auf die
1604 : // alte FilePos zurueck. Benutzt zum Nachtragen von Laengen.
1605 12 : void SwWW8Writer::WriteShort( SvStream& rStrm, sal_uLong nPos, sal_Int16 nVal )
1606 : {
1607 12 : sal_uLong nOldPos = rStrm.Tell(); // remember Pos
1608 12 : rStrm.Seek( nPos );
1609 12 : SwWW8Writer::WriteShort( rStrm, nVal );
1610 12 : rStrm.Seek( nOldPos );
1611 12 : }
1612 :
1613 28 : void SwWW8Writer::WriteLong( SvStream& rStrm, sal_uLong nPos, sal_Int32 nVal )
1614 : {
1615 28 : sal_uLong nOldPos = rStrm.Tell(); // remember Pos
1616 28 : rStrm.Seek( nPos );
1617 28 : SwWW8Writer::WriteLong( rStrm, nVal );
1618 28 : rStrm.Seek( nOldPos );
1619 28 : }
1620 :
1621 16953 : void SwWW8Writer::InsUInt16(ww::bytes &rO, sal_uInt16 n)
1622 : {
1623 : SVBT16 nL;
1624 16953 : ShortToSVBT16( n, nL );
1625 16953 : rO.push_back(nL[0]);
1626 16953 : rO.push_back(nL[1]);
1627 16953 : }
1628 :
1629 840 : void SwWW8Writer::InsUInt32(ww::bytes &rO, sal_uInt32 n)
1630 : {
1631 : SVBT32 nL;
1632 840 : UInt32ToSVBT32( n, nL );
1633 840 : rO.push_back(nL[0]);
1634 840 : rO.push_back(nL[1]);
1635 840 : rO.push_back(nL[2]);
1636 840 : rO.push_back(nL[3]);
1637 840 : }
1638 :
1639 718 : void SwWW8Writer::InsAsString16(ww::bytes &rO, const OUString& rStr)
1640 : {
1641 718 : const sal_Unicode* pStr = rStr.getStr();
1642 9058 : for (sal_Int32 n = 0, nLen = rStr.getLength(); n < nLen; ++n, ++pStr)
1643 8340 : SwWW8Writer::InsUInt16( rO, *pStr );
1644 718 : }
1645 :
1646 0 : void SwWW8Writer::InsAsString8(ww::bytes &rO, const OUString& rStr,
1647 : rtl_TextEncoding eCodeSet)
1648 : {
1649 0 : OString sTmp(OUStringToOString(rStr, eCodeSet));
1650 0 : const sal_Char *pStart = sTmp.getStr();
1651 0 : const sal_Char *pEnd = pStart + sTmp.getLength();
1652 0 : rO.reserve(rO.size() + sTmp.getLength());
1653 :
1654 0 : std::copy(pStart, pEnd, std::inserter(rO, rO.end()));
1655 0 : }
1656 :
1657 501 : void SwWW8Writer::WriteString16(SvStream& rStrm, const OUString& rStr,
1658 : bool bAddZero)
1659 : {
1660 501 : ww::bytes aBytes;
1661 501 : SwWW8Writer::InsAsString16(aBytes, rStr);
1662 501 : if (bAddZero)
1663 143 : SwWW8Writer::InsUInt16(aBytes, 0);
1664 : //vectors are guaranteed to have contiguous memory, so we can do
1665 : //this while migrating away from WW8Bytes. Meyers Effective STL, item 16
1666 501 : if (!aBytes.empty())
1667 375 : rStrm.Write(&aBytes[0], aBytes.size());
1668 501 : }
1669 :
1670 0 : void SwWW8Writer::WriteString_xstz(SvStream& rStrm, const OUString& rStr, bool bAddZero)
1671 : {
1672 0 : ww::bytes aBytes;
1673 0 : SwWW8Writer::InsUInt16(aBytes, rStr.getLength());
1674 0 : SwWW8Writer::InsAsString16(aBytes, rStr);
1675 0 : if (bAddZero)
1676 0 : SwWW8Writer::InsUInt16(aBytes, 0);
1677 0 : rStrm.Write(&aBytes[0], aBytes.size());
1678 0 : }
1679 :
1680 0 : void SwWW8Writer::WriteString8(SvStream& rStrm, const OUString& rStr,
1681 : bool bAddZero, rtl_TextEncoding eCodeSet)
1682 : {
1683 0 : ww::bytes aBytes;
1684 0 : SwWW8Writer::InsAsString8(aBytes, rStr, eCodeSet);
1685 0 : if (bAddZero)
1686 0 : aBytes.push_back(0);
1687 : //vectors are guaranteed to have contiguous memory, so we can do
1688 : ////this while migrating away from WW8Bytes. Meyers Effective STL, item 16
1689 0 : if (!aBytes.empty())
1690 0 : rStrm.Write(&aBytes[0], aBytes.size());
1691 0 : }
1692 :
1693 63 : void WW8Export::WriteStringAsPara( const OUString& rTxt, sal_uInt16 nStyleId )
1694 : {
1695 63 : if( !rTxt.isEmpty() )
1696 0 : OutSwString( rTxt, 0, rTxt.getLength(), IsUnicode(), RTL_TEXTENCODING_MS_1252 );
1697 63 : WriteCR(); // CR thereafter
1698 :
1699 63 : ww::bytes aArr;
1700 63 : SwWW8Writer::InsUInt16( aArr, nStyleId );
1701 63 : if( bOutTable )
1702 : { // Tab-Attr
1703 : // sprmPFInTable
1704 0 : if( bWrtWW8 )
1705 0 : SwWW8Writer::InsUInt16( aArr, NS_sprm::LN_PFInTable );
1706 : else
1707 0 : aArr.push_back( 24 );
1708 0 : aArr.push_back( 1 );
1709 : }
1710 :
1711 63 : sal_uLong nPos = Strm().Tell();
1712 63 : pPapPlc->AppendFkpEntry( nPos, aArr.size(), aArr.data() );
1713 63 : pChpPlc->AppendFkpEntry( nPos );
1714 63 : }
1715 :
1716 213 : void MSWordExportBase::WriteSpecialText( sal_uLong nStart, sal_uLong nEnd, sal_uInt8 nTTyp )
1717 : {
1718 213 : sal_uInt8 nOldTyp = nTxtTyp;
1719 213 : nTxtTyp = nTTyp;
1720 213 : SwPaM* pOldPam = pCurPam; //!! Simply shifting the PaM without restoring should do the job too
1721 213 : SwPaM* pOldEnd = pOrigPam;
1722 213 : bool bOldPageDescs = bOutPageDescs;
1723 213 : bOutPageDescs = false;
1724 : // bOutKF was setted / stored in WriteKF1
1725 213 : pCurPam = Writer::NewSwPaM( *pDoc, nStart, nEnd );
1726 :
1727 : // Tabelle in Sonderbereichen erkennen
1728 235 : if ( ( nStart != pCurPam->GetMark()->nNode.GetIndex() ) &&
1729 22 : pDoc->GetNodes()[ nStart ]->IsTableNode() )
1730 : {
1731 22 : pCurPam->GetMark()->nNode = nStart;
1732 : }
1733 :
1734 213 : pOrigPam = pCurPam;
1735 213 : pCurPam->Exchange();
1736 :
1737 213 : WriteText();
1738 :
1739 213 : bOutPageDescs = bOldPageDescs;
1740 213 : delete pCurPam; // delete Pam
1741 213 : pCurPam = pOldPam;
1742 213 : pOrigPam = pOldEnd;
1743 213 : nTxtTyp = nOldTyp;
1744 213 : }
1745 :
1746 201 : void WW8Export::OutSwString(const OUString& rStr, sal_Int32 nStt,
1747 : sal_Int32 nLen, bool bUnicode, rtl_TextEncoding eChrSet)
1748 :
1749 : {
1750 : SAL_INFO( "sw.ww8.level2", "<OutSwString>" );
1751 :
1752 201 : if( nLen )
1753 : {
1754 201 : if ( bUnicode != pPiece->IsUnicode() )
1755 0 : pPiece->AppendPc ( Strm().Tell(), bUnicode );
1756 :
1757 201 : if( nStt || nLen != rStr.getLength() )
1758 : {
1759 0 : OUString sOut( rStr.copy( nStt, nLen ) );
1760 :
1761 : SAL_INFO( "sw.ww8.level2", sOut );
1762 :
1763 0 : if (bUnicode)
1764 0 : SwWW8Writer::WriteString16(Strm(), sOut, false);
1765 : else
1766 0 : SwWW8Writer::WriteString8(Strm(), sOut, false, eChrSet);
1767 : }
1768 : else
1769 : {
1770 : SAL_INFO( "sw.ww8.level2", rStr );
1771 :
1772 201 : if (bUnicode)
1773 201 : SwWW8Writer::WriteString16(Strm(), rStr, false);
1774 : else
1775 0 : SwWW8Writer::WriteString8(Strm(), rStr, false, eChrSet);
1776 : }
1777 : }
1778 :
1779 : SAL_INFO( "sw.ww8.level2", "</OutSwString>" );
1780 201 : }
1781 :
1782 401 : void WW8Export::WriteCR(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner)
1783 : {
1784 401 : if (pTableTextNodeInfoInner.get() != NULL && pTableTextNodeInfoInner->getDepth() == 1 && pTableTextNodeInfoInner->isEndOfCell())
1785 127 : WriteChar('\007');
1786 : else
1787 274 : WriteChar( '\015' );
1788 :
1789 401 : pPiece->SetParaBreak();
1790 401 : }
1791 :
1792 472 : void WW8Export::WriteChar( sal_Unicode c )
1793 : {
1794 472 : if( pPiece->IsUnicode() )
1795 472 : Strm().WriteUInt16( c );
1796 : else
1797 0 : Strm().WriteUChar( (sal_uInt8)c );
1798 472 : }
1799 :
1800 242 : void MSWordExportBase::SaveData( sal_uLong nStt, sal_uLong nEnd )
1801 : {
1802 : MSWordSaveData aData;
1803 :
1804 : // WW8Export only stuff - zeroed here not to issue warnings
1805 242 : aData.pOOld = NULL;
1806 :
1807 : // Common stuff
1808 242 : aData.pOldPam = pCurPam;
1809 242 : aData.pOldEnd = pOrigPam;
1810 242 : aData.pOldFlyFmt = mpParentFrame;
1811 242 : aData.pOldPageDesc = pAktPageDesc;
1812 :
1813 242 : aData.pOldFlyOffset = pFlyOffset;
1814 242 : aData.eOldAnchorType = eNewAnchorType;
1815 :
1816 242 : aData.bOldOutTable = bOutTable;
1817 242 : aData.bOldFlyFrmAttrs = bOutFlyFrmAttrs;
1818 242 : aData.bOldStartTOX = bStartTOX;
1819 242 : aData.bOldInWriteTOX = bInWriteTOX;
1820 :
1821 242 : pCurPam = Writer::NewSwPaM( *pDoc, nStt, nEnd );
1822 :
1823 : // Recognize tables in special cases
1824 261 : if ( nStt != pCurPam->GetMark()->nNode.GetIndex() &&
1825 19 : pDoc->GetNodes()[ nStt ]->IsTableNode() )
1826 : {
1827 19 : pCurPam->GetMark()->nNode = nStt;
1828 : }
1829 :
1830 242 : pOrigPam = pCurPam;
1831 242 : pCurPam->Exchange();
1832 :
1833 242 : bOutTable = false;
1834 : // Caution: bIsInTable should not be set here
1835 242 : bOutFlyFrmAttrs = false;
1836 242 : bStartTOX = false;
1837 242 : bInWriteTOX = false;
1838 :
1839 242 : maSaveData.push( aData );
1840 242 : }
1841 :
1842 242 : void MSWordExportBase::RestoreData()
1843 : {
1844 242 : MSWordSaveData &rData = maSaveData.top();
1845 :
1846 242 : delete pCurPam;
1847 242 : pCurPam = rData.pOldPam;
1848 242 : pOrigPam = rData.pOldEnd;
1849 :
1850 242 : bOutTable = rData.bOldOutTable;
1851 242 : bOutFlyFrmAttrs = rData.bOldFlyFrmAttrs;
1852 242 : bStartTOX = rData.bOldStartTOX;
1853 242 : bInWriteTOX = rData.bOldInWriteTOX;
1854 :
1855 242 : mpParentFrame = rData.pOldFlyFmt;
1856 242 : pAktPageDesc = rData.pOldPageDesc;
1857 :
1858 242 : eNewAnchorType = rData.eOldAnchorType;
1859 242 : pFlyOffset = rData.pOldFlyOffset;
1860 :
1861 242 : maSaveData.pop();
1862 242 : }
1863 :
1864 1 : void WW8Export::SaveData( sal_uLong nStt, sal_uLong nEnd )
1865 : {
1866 1 : MSWordExportBase::SaveData( nStt, nEnd );
1867 :
1868 1 : MSWordSaveData &rData = maSaveData.top();
1869 :
1870 1 : if ( !pO->empty() )
1871 : {
1872 0 : rData.pOOld = pO;
1873 0 : pO = new ww::bytes();
1874 : }
1875 : else
1876 1 : rData.pOOld = 0; // reuse pO
1877 :
1878 1 : rData.bOldWriteAll = GetWriter().bWriteAll;
1879 1 : GetWriter().bWriteAll = true;
1880 1 : }
1881 :
1882 1 : void WW8Export::RestoreData()
1883 : {
1884 1 : MSWordSaveData &rData = maSaveData.top();
1885 :
1886 1 : GetWriter().bWriteAll = rData.bOldWriteAll;
1887 :
1888 : OSL_ENSURE( pO->empty(), "pO is not empty in WW8Export::RestoreData()" );
1889 1 : if ( rData.pOOld )
1890 : {
1891 0 : delete pO;
1892 0 : pO = rData.pOOld;
1893 : }
1894 :
1895 1 : MSWordExportBase::RestoreData();
1896 1 : }
1897 :
1898 236 : void WW8AttributeOutput::TableInfoCell( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
1899 : {
1900 236 : sal_uInt32 nDepth = pTableTextNodeInfoInner->getDepth();
1901 :
1902 236 : if ( nDepth > 0 )
1903 : {
1904 : /* Cell */
1905 236 : m_rWW8Export.InsUInt16( NS_sprm::LN_PFInTable );
1906 236 : m_rWW8Export.pO->push_back( (sal_uInt8)0x1 );
1907 236 : m_rWW8Export.InsUInt16( NS_sprm::LN_PTableDepth );
1908 236 : m_rWW8Export.InsUInt32( nDepth );
1909 :
1910 236 : if ( nDepth > 1 && pTableTextNodeInfoInner->isEndOfCell() )
1911 : {
1912 0 : m_rWW8Export.InsUInt16( NS_sprm::LN_PCell );
1913 0 : m_rWW8Export.pO->push_back( (sal_uInt8)0x1 );
1914 : }
1915 : }
1916 236 : }
1917 :
1918 33 : void WW8AttributeOutput::TableInfoRow( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
1919 : {
1920 33 : sal_uInt32 nDepth = pTableTextNodeInfoInner->getDepth();
1921 :
1922 33 : if ( nDepth > 0 )
1923 : {
1924 : /* Row */
1925 33 : if ( pTableTextNodeInfoInner->isEndOfLine() )
1926 : {
1927 33 : m_rWW8Export.InsUInt16( NS_sprm::LN_PFInTable );
1928 33 : m_rWW8Export.pO->push_back( (sal_uInt8)0x1 );
1929 :
1930 33 : if ( nDepth == 1 )
1931 : {
1932 33 : m_rWW8Export.InsUInt16( NS_sprm::LN_PFTtp );
1933 33 : m_rWW8Export.pO->push_back( (sal_uInt8)0x1 );
1934 : }
1935 :
1936 33 : m_rWW8Export.InsUInt16( NS_sprm::LN_PTableDepth );
1937 33 : m_rWW8Export.InsUInt32( nDepth );
1938 :
1939 33 : if ( nDepth > 1 )
1940 : {
1941 0 : m_rWW8Export.InsUInt16( NS_sprm::LN_PCell );
1942 0 : m_rWW8Export.pO->push_back( (sal_uInt8)0x1 );
1943 0 : m_rWW8Export.InsUInt16( NS_sprm::LN_PRow );
1944 0 : m_rWW8Export.pO->push_back( (sal_uInt8)0x1 );
1945 : }
1946 :
1947 33 : TableDefinition( pTableTextNodeInfoInner );
1948 33 : TableHeight( pTableTextNodeInfoInner );
1949 33 : TableBackgrounds( pTableTextNodeInfoInner );
1950 33 : TableDefaultBorders( pTableTextNodeInfoInner );
1951 33 : TableCanSplit( pTableTextNodeInfoInner );
1952 33 : TableBidi( pTableTextNodeInfoInner );
1953 33 : TableVerticalCell( pTableTextNodeInfoInner );
1954 33 : TableOrientation( pTableTextNodeInfoInner );
1955 33 : TableSpacing( pTableTextNodeInfoInner );
1956 33 : TableCellBorders( pTableTextNodeInfoInner );
1957 : }
1958 : }
1959 33 : }
1960 :
1961 127 : static sal_uInt16 lcl_TCFlags(SwDoc &rDoc, const SwTableBox * pBox, sal_Int32 nRowSpan)
1962 : {
1963 127 : sal_uInt16 nFlags = 0;
1964 :
1965 127 : if (nRowSpan > 1)
1966 0 : nFlags |= (3 << 5);
1967 127 : else if (nRowSpan < 0)
1968 0 : nFlags |= (1 << 5);
1969 :
1970 127 : if (pBox != NULL)
1971 : {
1972 127 : const SwFrmFmt * pFmt = pBox->GetFrmFmt();
1973 127 : switch (pFmt->GetVertOrient().GetVertOrient())
1974 : {
1975 : case text::VertOrientation::CENTER:
1976 16 : nFlags |= (1 << 7);
1977 16 : break;
1978 : case text::VertOrientation::BOTTOM:
1979 0 : nFlags |= (2 << 7);
1980 0 : break;
1981 : default:
1982 111 : break;
1983 : }
1984 127 : const SwStartNode * pSttNd = pBox->GetSttNd();
1985 127 : if(pSttNd)
1986 : {
1987 127 : SwNodeIndex aIdx( *pSttNd );
1988 127 : const SwCntntNode * pCNd = pSttNd->GetNodes().GoNext( &aIdx );
1989 127 : if( pCNd && pCNd->IsTxtNode())
1990 : {
1991 127 : SfxItemSet aCoreSet(rDoc.GetAttrPool(), RES_CHRATR_ROTATE, RES_CHRATR_ROTATE);
1992 127 : ((SwTxtNode*)pCNd)->GetAttr( aCoreSet, 0, ((SwTxtNode*)pCNd)->GetTxt().getLength());
1993 127 : const SvxCharRotateItem * pRotate = NULL;
1994 : const SfxPoolItem * pRotItem;
1995 127 : if ( SFX_ITEM_SET == aCoreSet.GetItemState(RES_CHRATR_ROTATE, true, &pRotItem))
1996 : {
1997 0 : pRotate = (SvxCharRotateItem*)pRotItem;
1998 0 : if(pRotate && pRotate->GetValue() == 900)
1999 : {
2000 0 : nFlags = nFlags | 0x0004 | 0x0008;
2001 : }
2002 0 : else if(pRotate && pRotate->GetValue() == 2700 )
2003 : {
2004 0 : nFlags = nFlags | 0x0004 | 0x0010;
2005 : }
2006 127 : }
2007 127 : }
2008 : }
2009 : }
2010 :
2011 127 : return nFlags;
2012 : }
2013 :
2014 33 : void WW8AttributeOutput::TableVerticalCell( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
2015 : {
2016 33 : const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
2017 33 : const SwTableLine * pTabLine = pTabBox->GetUpper();
2018 33 : const SwTableBoxes & rTblBoxes = pTabLine->GetTabBoxes();
2019 :
2020 33 : sal_uInt8 nBoxes = rTblBoxes.size();
2021 160 : for ( sal_uInt8 n = 0; n < nBoxes; n++ )
2022 : {
2023 127 : const SwTableBox * pTabBox1 = rTblBoxes[n];
2024 127 : const SwFrmFmt * pFrmFmt = pTabBox1->GetFrmFmt();
2025 :
2026 127 : if ( FRMDIR_VERT_TOP_RIGHT == m_rWW8Export.TrueFrameDirection( *pFrmFmt ) )
2027 : {
2028 0 : m_rWW8Export.InsUInt16( NS_sprm::LN_TTextFlow );
2029 0 : m_rWW8Export.pO->push_back( sal_uInt8(n) ); //start range
2030 0 : m_rWW8Export.pO->push_back( sal_uInt8(n + 1) ); //end range
2031 0 : m_rWW8Export.InsUInt16( 5 ); //Equals vertical writing
2032 : }
2033 : }
2034 33 : }
2035 :
2036 33 : void WW8AttributeOutput::TableCanSplit( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
2037 : {
2038 33 : const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
2039 33 : const SwTableLine * pTabLine = pTabBox->GetUpper();
2040 33 : const SwFrmFmt * pLineFmt = pTabLine->GetFrmFmt();
2041 :
2042 : /*
2043 : By default the row can be split in word, and now in writer we have a
2044 : feature equivalent to this, Word stores 1 for fCantSplit if the row
2045 : cannot be split, we set true if we can split it. An example is #i4569#
2046 : */
2047 :
2048 33 : const SwFmtRowSplit& rSplittable = pLineFmt->GetRowSplit();
2049 33 : sal_uInt8 nCantSplit = (!rSplittable.GetValue()) ? 1 : 0;
2050 33 : if ( m_rWW8Export.bWrtWW8 )
2051 : {
2052 33 : m_rWW8Export.InsUInt16( NS_sprm::LN_TFCantSplit );
2053 33 : m_rWW8Export.pO->push_back( nCantSplit );
2054 33 : m_rWW8Export.InsUInt16( NS_sprm::LN_TFCantSplit90 ); // also write fCantSplit90
2055 : }
2056 : else
2057 : {
2058 0 : m_rWW8Export.pO->push_back( 185 );
2059 : }
2060 33 : m_rWW8Export.pO->push_back( nCantSplit );
2061 33 : }
2062 :
2063 33 : void WW8AttributeOutput::TableBidi( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
2064 : {
2065 33 : const SwTable * pTable = pTableTextNodeInfoInner->getTable();
2066 33 : const SwFrmFmt * pFrmFmt = pTable->GetFrmFmt();
2067 :
2068 33 : if ( m_rWW8Export.bWrtWW8 )
2069 : {
2070 33 : if ( m_rWW8Export.TrueFrameDirection(*pFrmFmt) == FRMDIR_HORI_RIGHT_TOP )
2071 : {
2072 0 : m_rWW8Export.InsUInt16( NS_sprm::LN_TFBiDi );
2073 0 : m_rWW8Export.InsUInt16( 1 );
2074 : }
2075 : }
2076 33 : }
2077 :
2078 0 : void WW8AttributeOutput::TableRowRedline( ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner*/ )
2079 : {
2080 0 : }
2081 :
2082 0 : void WW8AttributeOutput::TableCellRedline( ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner*/ )
2083 : {
2084 0 : }
2085 :
2086 33 : void WW8AttributeOutput::TableHeight( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
2087 : {
2088 33 : const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
2089 33 : const SwTableLine * pTabLine = pTabBox->GetUpper();
2090 33 : const SwFrmFmt * pLineFmt = pTabLine->GetFrmFmt();
2091 :
2092 : // Zeilenhoehe ausgeben sprmTDyaRowHeight
2093 33 : long nHeight = 0;
2094 33 : const SwFmtFrmSize& rLSz = pLineFmt->GetFrmSize();
2095 33 : if ( ATT_VAR_SIZE != rLSz.GetHeightSizeType() && rLSz.GetHeight() )
2096 : {
2097 30 : if ( ATT_MIN_SIZE == rLSz.GetHeightSizeType() )
2098 8 : nHeight = rLSz.GetHeight();
2099 : else
2100 22 : nHeight = -rLSz.GetHeight();
2101 : }
2102 :
2103 33 : if ( nHeight )
2104 : {
2105 30 : if ( m_rWW8Export.bWrtWW8 )
2106 30 : m_rWW8Export.InsUInt16( NS_sprm::LN_TDyaRowHeight );
2107 : else
2108 0 : m_rWW8Export.pO->push_back( 189 );
2109 30 : m_rWW8Export.InsUInt16( (sal_uInt16)nHeight );
2110 : }
2111 :
2112 33 : }
2113 :
2114 33 : void WW8AttributeOutput::TableOrientation( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
2115 : {
2116 33 : const SwTable * pTable = pTableTextNodeInfoInner->getTable();
2117 :
2118 33 : const SwFrmFmt *pFmt = pTable->GetFrmFmt();
2119 : OSL_ENSURE(pFmt,"Impossible");
2120 33 : if (!pFmt)
2121 33 : return;
2122 :
2123 33 : const SwFmtHoriOrient &rHori = pFmt->GetHoriOrient();
2124 33 : const SwFmtVertOrient &rVert = pFmt->GetVertOrient();
2125 :
2126 33 : if (
2127 33 : (text::RelOrientation::PRINT_AREA == rHori.GetRelationOrient() ||
2128 0 : text::RelOrientation::FRAME == rHori.GetRelationOrient())
2129 99 : &&
2130 33 : (text::RelOrientation::PRINT_AREA == rVert.GetRelationOrient() ||
2131 0 : text::RelOrientation::FRAME == rVert.GetRelationOrient())
2132 : )
2133 : {
2134 33 : sal_Int16 eHOri = rHori.GetHoriOrient();
2135 33 : switch (eHOri)
2136 : {
2137 : case text::HoriOrientation::CENTER:
2138 : case text::HoriOrientation::RIGHT:
2139 0 : if ( m_rWW8Export.bWrtWW8 )
2140 0 : m_rWW8Export.InsUInt16( NS_sprm::LN_TJc90 );
2141 : else
2142 0 : m_rWW8Export.pO->push_back( 182 );
2143 0 : m_rWW8Export.InsUInt16( text::HoriOrientation::RIGHT == eHOri ? 2 : 1 );
2144 0 : break;
2145 : default:
2146 33 : break;
2147 : }
2148 : }
2149 : }
2150 :
2151 33 : void WW8AttributeOutput::TableSpacing(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner)
2152 : {
2153 33 : const SwTable * pTable = pTableTextNodeInfoInner->getTable();
2154 33 : const SwTableFmt * pTableFmt = pTable->GetTableFmt();
2155 :
2156 : // Writing these SPRM's will make the table a floating one, so only write
2157 : // them in case the table is already inside a frame.
2158 33 : if (pTableFmt != NULL && pTable->GetTableNode()->GetFlyFmt())
2159 : {
2160 3 : const SvxULSpaceItem & rUL = pTableFmt->GetULSpace();
2161 :
2162 3 : if (rUL.GetUpper() > 0)
2163 : {
2164 0 : sal_uInt8 nPadding = 2;
2165 0 : sal_uInt8 nPcVert = 0;
2166 0 : sal_uInt8 nPcHorz = 0;
2167 :
2168 0 : sal_uInt8 nTPc = (nPadding << 4) | (nPcVert << 2) | nPcHorz;
2169 :
2170 0 : m_rWW8Export.InsUInt16(NS_sprm::LN_TPc);
2171 0 : m_rWW8Export.pO->push_back( nTPc );
2172 :
2173 0 : m_rWW8Export.InsUInt16(NS_sprm::LN_TDyaAbs);
2174 0 : m_rWW8Export.InsUInt16(rUL.GetUpper());
2175 :
2176 0 : m_rWW8Export.InsUInt16(NS_sprm::LN_TDyaFromText);
2177 0 : m_rWW8Export.InsUInt16(rUL.GetUpper());
2178 : }
2179 :
2180 3 : if (rUL.GetLower() > 0)
2181 : {
2182 0 : m_rWW8Export.InsUInt16(NS_sprm::LN_TDyaFromTextBottom);
2183 0 : m_rWW8Export.InsUInt16(rUL.GetLower());
2184 : }
2185 : }
2186 33 : }
2187 :
2188 33 : void WW8AttributeOutput::TableDefinition( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
2189 : {
2190 33 : const SwTable * pTable = pTableTextNodeInfoInner->getTable();
2191 :
2192 33 : if ( pTable->GetRowsToRepeat() > pTableTextNodeInfoInner->getRow() )
2193 : {
2194 0 : if( m_rWW8Export.bWrtWW8 )
2195 0 : m_rWW8Export.InsUInt16( NS_sprm::LN_TTableHeader );
2196 : else
2197 0 : m_rWW8Export.pO->push_back( 186 );
2198 0 : m_rWW8Export.pO->push_back( 1 );
2199 : }
2200 :
2201 : ww8::TableBoxVectorPtr pTableBoxes =
2202 33 : pTableTextNodeInfoInner->getTableBoxesOfRow();
2203 : // number of cell written
2204 33 : sal_uInt32 nBoxes = pTableBoxes->size();
2205 33 : if (nBoxes > ww8::MAXTABLECELLS)
2206 0 : nBoxes = ww8::MAXTABLECELLS;
2207 :
2208 : // sprm header
2209 33 : m_rWW8Export.InsUInt16( NS_sprm::LN_TDefTable );
2210 33 : sal_uInt16 nSprmSize = 2 + (nBoxes + 1) * 2 + nBoxes * 20;
2211 33 : m_rWW8Export.InsUInt16( nSprmSize ); // length
2212 :
2213 : // number of boxes
2214 33 : m_rWW8Export.pO->push_back( static_cast<sal_uInt8>(nBoxes) );
2215 :
2216 : /* cellxs */
2217 : /*
2218 : ALWAYS relative when text::HoriOrientation::NONE (nPageSize + ( nPageSize / 10 )) < nTblSz,
2219 : in that case the cell width's and table width's are not real. The table
2220 : width is maxed and cells relative, so we need the frame (generally page)
2221 : width that the table is in to work out the true widths.
2222 : */
2223 : //const bool bNewTableModel = pTbl->IsNewModel();
2224 33 : const SwFrmFmt *pFmt = pTable->GetFrmFmt();
2225 : OSL_ENSURE(pFmt,"Impossible");
2226 33 : if (!pFmt)
2227 33 : return;
2228 :
2229 33 : const SwFmtHoriOrient &rHori = pFmt->GetHoriOrient();
2230 33 : const SwFmtVertOrient &rVert = pFmt->GetVertOrient();
2231 :
2232 33 : sal_uInt16 nTblOffset = 0;
2233 :
2234 33 : if (
2235 33 : (text::RelOrientation::PRINT_AREA == rHori.GetRelationOrient() ||
2236 0 : text::RelOrientation::FRAME == rHori.GetRelationOrient())
2237 99 : &&
2238 33 : (text::RelOrientation::PRINT_AREA == rVert.GetRelationOrient() ||
2239 0 : text::RelOrientation::FRAME == rVert.GetRelationOrient())
2240 : )
2241 : {
2242 33 : sal_Int16 eHOri = rHori.GetHoriOrient();
2243 33 : switch ( eHOri )
2244 : {
2245 : case text::HoriOrientation::CENTER:
2246 : case text::HoriOrientation::RIGHT:
2247 0 : break;
2248 :
2249 : default:
2250 33 : nTblOffset = rHori.GetPos();
2251 33 : const SvxLRSpaceItem& rLRSp = pFmt->GetLRSpace();
2252 33 : nTblOffset += rLRSp.GetLeft();
2253 33 : break;
2254 : }
2255 : }
2256 :
2257 33 : m_rWW8Export.InsUInt16( nTblOffset );
2258 :
2259 33 : ww8::GridColsPtr pGridCols = GetGridCols( pTableTextNodeInfoInner );
2260 193 : for ( ww8::GridCols::const_iterator it = pGridCols->begin(),
2261 33 : end = pGridCols->end(); it != end; ++it )
2262 : {
2263 127 : m_rWW8Export.InsUInt16( static_cast<sal_uInt16>( *it ) + nTblOffset );
2264 : }
2265 :
2266 : /* TCs */
2267 66 : ww8::RowSpansPtr pRowSpans = pTableTextNodeInfoInner->getRowSpansOfRow();
2268 33 : ww8::RowSpans::const_iterator aItRowSpans = pRowSpans->begin();
2269 33 : ww8::TableBoxVector::const_iterator aIt;
2270 33 : ww8::TableBoxVector::const_iterator aItEnd = pTableBoxes->end();
2271 :
2272 : #if OSL_DEBUG_LEVEL > 1
2273 : size_t nRowSpans = pRowSpans->size();
2274 : size_t nTableBoxes = pTableBoxes->size();
2275 : (void) nRowSpans;
2276 : (void) nTableBoxes;
2277 : #endif
2278 :
2279 160 : for( aIt = pTableBoxes->begin(); aIt != aItEnd; ++aIt, ++aItRowSpans)
2280 : {
2281 127 : sal_uInt16 npOCount = m_rWW8Export.pO->size();
2282 :
2283 127 : const SwTableBox * pTabBox1 = *aIt;
2284 127 : const SwFrmFmt * pBoxFmt = NULL;
2285 127 : if (pTabBox1 != NULL)
2286 127 : pBoxFmt = pTabBox1->GetFrmFmt();
2287 :
2288 127 : if ( m_rWW8Export.bWrtWW8 )
2289 : {
2290 : sal_uInt16 nFlags =
2291 127 : lcl_TCFlags(*m_rWW8Export.pDoc, pTabBox1, *aItRowSpans);
2292 127 : m_rWW8Export.InsUInt16( nFlags );
2293 : }
2294 :
2295 : static sal_uInt8 aNullBytes[] = { 0x0, 0x0 };
2296 :
2297 127 : m_rWW8Export.pO->insert( m_rWW8Export.pO->end(), aNullBytes, aNullBytes+2 ); // dummy
2298 127 : if (pBoxFmt != NULL)
2299 : {
2300 127 : const SvxBoxItem & rBoxItem = pBoxFmt->GetBox();
2301 :
2302 127 : m_rWW8Export.Out_SwFmtTableBox( *m_rWW8Export.pO, &rBoxItem ); // 8/16 Byte
2303 : }
2304 : else
2305 0 : m_rWW8Export.Out_SwFmtTableBox( *m_rWW8Export.pO, NULL); // 8/16 Byte
2306 :
2307 : SAL_INFO( "sw.ww8.level2", "<tclength>" << ( m_rWW8Export.pO->size() - npOCount ) << "</tclength>" );
2308 33 : }
2309 : }
2310 :
2311 2296 : ww8::GridColsPtr AttributeOutputBase::GetGridCols( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
2312 : {
2313 2296 : return pTableTextNodeInfoInner->getGridColsOfRow(*this);
2314 : }
2315 :
2316 94 : ww8::WidthsPtr AttributeOutputBase::GetColumnWidths( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
2317 : {
2318 : // Get the column widths based on ALL the rows, not just the current row
2319 94 : return pTableTextNodeInfoInner->getGridColsOfRow(*this, true);
2320 : }
2321 :
2322 2587 : void AttributeOutputBase::GetTablePageSize( ww8::WW8TableNodeInfoInner * pTableTextNodeInfoInner, sal_uInt32& rPageSize, bool& rRelBoxSize )
2323 : {
2324 2587 : sal_uInt32 nPageSize = 0;
2325 :
2326 2587 : const SwNode *pTxtNd = pTableTextNodeInfoInner->getNode( );
2327 2587 : const SwTable *pTable = pTableTextNodeInfoInner->getTable( );
2328 :
2329 2587 : const SwFrmFmt *pFmt = pTable->GetFrmFmt();
2330 : OSL_ENSURE(pFmt,"Impossible");
2331 2587 : if (!pFmt)
2332 2587 : return;
2333 :
2334 2587 : const SwFmtFrmSize &rSize = pFmt->GetFrmSize();
2335 2587 : int nWidthPercent = rSize.GetWidthPercent();
2336 2587 : bool bManualAligned = pFmt->GetHoriOrient().GetHoriOrient() == text::HoriOrientation::NONE;
2337 2587 : if ( (pFmt->GetHoriOrient().GetHoriOrient() == text::HoriOrientation::FULL) || bManualAligned )
2338 7 : nWidthPercent = 100;
2339 2587 : bool bRelBoxSize = nWidthPercent != 0;
2340 2587 : unsigned long nTblSz = static_cast<unsigned long>(rSize.GetWidth());
2341 2587 : if (nTblSz > USHRT_MAX/2 && !bRelBoxSize)
2342 : {
2343 : OSL_ENSURE(bRelBoxSize, "huge table width but not relative, suspicious");
2344 0 : bRelBoxSize = true;
2345 : }
2346 :
2347 2587 : if ( bRelBoxSize )
2348 : {
2349 84 : Point aPt;
2350 84 : SwRect aRect( pFmt->FindLayoutRect( false, &aPt ) );
2351 84 : if ( aRect.IsEmpty() )
2352 : {
2353 : // dann besorge mal die Seitenbreite ohne Raender !!
2354 : const SwFrmFmt* pParentFmt =
2355 11 : GetExport().mpParentFrame ?
2356 1 : &(GetExport().mpParentFrame->GetFrmFmt()) :
2357 12 : GetExport().pDoc->GetPageDesc(0).GetPageFmtOfNode(*pTxtNd, false);
2358 11 : aRect = pParentFmt->FindLayoutRect(true);
2359 11 : if ( 0 == ( nPageSize = aRect.Width() ) )
2360 : {
2361 3 : const SvxLRSpaceItem& rLR = pParentFmt->GetLRSpace();
2362 3 : nPageSize = pParentFmt->GetFrmSize().GetWidth() - rLR.GetLeft()
2363 3 : - rLR.GetRight();
2364 : }
2365 : }
2366 : else
2367 : {
2368 73 : nPageSize = aRect.Width();
2369 73 : if ( bManualAligned )
2370 : {
2371 : // #i37571# For manually aligned tables
2372 0 : const SvxLRSpaceItem &rLR = pFmt->GetLRSpace();
2373 0 : nPageSize -= (rLR.GetLeft() + rLR.GetRight());
2374 : }
2375 :
2376 : }
2377 :
2378 : OSL_ENSURE(nWidthPercent, "Impossible");
2379 84 : if (nWidthPercent)
2380 : {
2381 84 : nPageSize *= nWidthPercent;
2382 84 : nPageSize /= 100;
2383 : }
2384 : }
2385 :
2386 2587 : rPageSize = nPageSize;
2387 2587 : rRelBoxSize = bRelBoxSize;
2388 : }
2389 :
2390 33 : void WW8AttributeOutput::TableDefaultBorders( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
2391 : {
2392 33 : const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
2393 33 : const SwFrmFmt * pFrmFmt = pTabBox->GetFrmFmt();
2394 :
2395 : //Set Default, just taken from the first cell of the first
2396 : //row
2397 : static const sal_uInt16 aBorders[] =
2398 : {
2399 : BOX_LINE_TOP, BOX_LINE_LEFT,
2400 : BOX_LINE_BOTTOM, BOX_LINE_RIGHT
2401 : };
2402 :
2403 165 : for ( int i = 0; i < 4; ++i )
2404 : {
2405 132 : SwWW8Writer::InsUInt16( *m_rWW8Export.pO, 0xD634 );
2406 132 : m_rWW8Export.pO->push_back( sal_uInt8(6) );
2407 132 : m_rWW8Export.pO->push_back( sal_uInt8(0) );
2408 132 : m_rWW8Export.pO->push_back( sal_uInt8(1) );
2409 132 : m_rWW8Export.pO->push_back( sal_uInt8(1 << i) );
2410 132 : m_rWW8Export.pO->push_back( sal_uInt8(3) );
2411 :
2412 : SwWW8Writer::InsUInt16( *m_rWW8Export.pO,
2413 132 : pFrmFmt->GetBox().GetDistance( aBorders[i] ) );
2414 : }
2415 33 : }
2416 :
2417 33 : void WW8AttributeOutput::TableCellBorders(
2418 : ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
2419 : {
2420 33 : if (!m_rWW8Export.bWrtWW8)
2421 33 : return;
2422 :
2423 33 : const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
2424 33 : const SwTableLine * pTabLine = pTabBox->GetUpper();
2425 33 : const SwTableBoxes & rTabBoxes = pTabLine->GetTabBoxes();
2426 33 : sal_uInt8 nBoxes = std::min<size_t>(rTabBoxes.size(), 255);
2427 33 : const SvxBoxItem * pLastBox = 0;
2428 33 : sal_uInt8 nSeqStart = 0; // start of sequence of cells with same borders
2429 :
2430 : // Detect sequences of cells which have the same borders, and output
2431 : // a border description for each such cell range.
2432 193 : for ( unsigned n = 0; n <= nBoxes; ++n )
2433 : {
2434 160 : const SvxBoxItem * pBox = (n == nBoxes) ? 0 :
2435 160 : &rTabBoxes[n]->GetFrmFmt()->GetBox();
2436 160 : if( !pLastBox )
2437 33 : pLastBox = pBox;
2438 127 : else if( !pBox || *pLastBox != *pBox )
2439 : {
2440 : // This cell has different borders than the previous cell,
2441 : // so output the borders for the preceding cell range.
2442 89 : m_rWW8Export.Out_CellRangeBorders(pLastBox, nSeqStart, n);
2443 89 : nSeqStart = n;
2444 89 : pLastBox = pBox;
2445 : }
2446 : }
2447 : }
2448 :
2449 33 : void WW8AttributeOutput::TableBackgrounds( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
2450 : {
2451 33 : const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
2452 33 : const SwTableLine * pTabLine = pTabBox->GetUpper();
2453 33 : const SwTableBoxes & rTabBoxes = pTabLine->GetTabBoxes();
2454 :
2455 33 : sal_uInt8 nBoxes = rTabBoxes.size();
2456 33 : if ( m_rWW8Export.bWrtWW8 )
2457 33 : m_rWW8Export.InsUInt16( NS_sprm::LN_TDefTableShd80 );
2458 : else
2459 0 : m_rWW8Export.pO->push_back( (sal_uInt8)191 );
2460 33 : m_rWW8Export.pO->push_back( (sal_uInt8)(nBoxes * 2) ); // Len
2461 :
2462 160 : for ( sal_uInt8 n = 0; n < nBoxes; n++ )
2463 : {
2464 127 : const SwTableBox * pBox1 = rTabBoxes[n];
2465 127 : const SwFrmFmt * pFrmFmt = pBox1->GetFrmFmt();
2466 127 : const SfxPoolItem * pI = NULL;
2467 127 : Color aColor;
2468 :
2469 127 : if ( SFX_ITEM_ON == pFrmFmt->GetAttrSet().GetItemState( RES_BACKGROUND, false, &pI ) )
2470 : {
2471 22 : aColor = dynamic_cast<const SvxBrushItem *>(pI)->GetColor();
2472 : }
2473 : else
2474 105 : aColor = COL_AUTO;
2475 :
2476 127 : WW8_SHD aShd;
2477 127 : m_rWW8Export.TransBrush( aColor, aShd );
2478 127 : m_rWW8Export.InsUInt16( aShd.GetValue() );
2479 : }
2480 :
2481 33 : if ( m_rWW8Export.bWrtWW8 )
2482 : {
2483 : sal_uInt32 aSprmIds[] = { NS_sprm::LN_TDefTableShd,
2484 33 : NS_sprm::LN_TDefTableShdRaw };
2485 33 : sal_uInt8 nBoxes0 = rTabBoxes.size();
2486 33 : if (nBoxes0 > 21)
2487 0 : nBoxes0 = 21;
2488 :
2489 99 : for (sal_uInt32 m = 0; m < 2; m++)
2490 : {
2491 66 : m_rWW8Export.InsUInt16( aSprmIds[m] );
2492 66 : m_rWW8Export.pO->push_back( static_cast<sal_uInt8>(nBoxes0 * 10) );
2493 :
2494 320 : for ( sal_uInt8 n = 0; n < nBoxes0; n++ )
2495 : {
2496 254 : const SwTableBox * pBox1 = rTabBoxes[n];
2497 254 : const SwFrmFmt * pFrmFmt = pBox1->GetFrmFmt();
2498 254 : const SfxPoolItem * pI = NULL;
2499 254 : Color aColor;
2500 :
2501 254 : if ( SFX_ITEM_ON ==
2502 254 : pFrmFmt->GetAttrSet().
2503 254 : GetItemState( RES_BACKGROUND, false, &pI ) )
2504 : {
2505 44 : aColor = dynamic_cast<const SvxBrushItem *>(pI)->GetColor();
2506 : }
2507 : else
2508 210 : aColor = COL_AUTO;
2509 :
2510 254 : WW8SHDLong aSHD;
2511 254 : aSHD.setCvFore( 0xFF000000 );
2512 :
2513 254 : sal_uInt32 nBgColor = aColor.GetColor();
2514 254 : if ( nBgColor == COL_AUTO )
2515 210 : aSHD.setCvBack( 0xFF000000 );
2516 : else
2517 44 : aSHD.setCvBack( wwUtility::RGBToBGR( nBgColor ) );
2518 :
2519 254 : aSHD.Write( m_rWW8Export );
2520 254 : }
2521 : }
2522 : }
2523 33 : }
2524 :
2525 324 : void WW8Export::SectionBreaksAndFrames( const SwTxtNode& rNode )
2526 : {
2527 : // output page/section breaks
2528 324 : OutputSectionBreaks( rNode.GetpSwAttrSet(), rNode );
2529 :
2530 : // all textframes anchored as character for the winword 7- format
2531 324 : if ( !bWrtWW8 && !IsInTable() )
2532 0 : OutWW6FlyFrmsInCntnt( rNode );
2533 324 : }
2534 :
2535 795 : void MSWordExportBase::WriteText()
2536 : {
2537 23114 : while( pCurPam->GetPoint()->nNode < pCurPam->GetMark()->nNode ||
2538 2046 : ( pCurPam->GetPoint()->nNode == pCurPam->GetMark()->nNode &&
2539 795 : pCurPam->GetPoint()->nContent.GetIndex() <= pCurPam->GetMark()->nContent.GetIndex() ) )
2540 : {
2541 10306 : SwNode * pNd = pCurPam->GetNode();
2542 :
2543 10306 : if ( pNd->IsTxtNode() )
2544 6036 : SectionBreaksAndFrames( *pNd->GetTxtNode() );
2545 :
2546 : // output the various types of nodes
2547 10306 : if ( pNd->IsCntntNode() )
2548 : {
2549 6037 : SwCntntNode* pCNd = (SwCntntNode*)pNd;
2550 :
2551 6037 : const SwPageDesc* pTemp = pNd->FindPageDesc(sal_False);
2552 6037 : if ( pTemp )
2553 6037 : pAktPageDesc = pTemp;
2554 :
2555 6037 : pCurPam->GetPoint()->nContent.Assign( pCNd, 0 );
2556 6037 : OutputContentNode( *pCNd );
2557 : }
2558 4269 : else if ( pNd->IsTableNode() )
2559 : {
2560 114 : mpTableInfo->processSwTable( &pNd->GetTableNode()->GetTable() );
2561 : }
2562 4155 : else if ( pNd->IsSectionNode() && TXT_MAINTEXT == nTxtTyp )
2563 34 : OutputSectionNode( *pNd->GetSectionNode() );
2564 6120 : else if ( TXT_MAINTEXT == nTxtTyp && pNd->IsEndNode() &&
2565 1999 : pNd->StartOfSectionNode()->IsSectionNode() )
2566 : {
2567 34 : const SwSection& rSect = pNd->StartOfSectionNode()->GetSectionNode()
2568 34 : ->GetSection();
2569 34 : if ( bStartTOX && TOX_CONTENT_SECTION == rSect.GetType() )
2570 0 : bStartTOX = false;
2571 :
2572 34 : SwNodeIndex aIdx( *pNd, 1 );
2573 34 : if ( aIdx.GetNode().IsEndNode() && aIdx.GetNode().StartOfSectionNode()->IsSectionNode() )
2574 : ;
2575 34 : else if ( aIdx.GetNode().IsSectionNode() )
2576 : ;
2577 68 : else if ( !IsInTable()
2578 34 : && (rSect.GetType() != TOX_CONTENT_SECTION && rSect.GetType() != TOX_HEADER_SECTION )) //No sections in table
2579 : {
2580 : //#120140# Do not need to insert a page/section break after a section end. Check this case first
2581 9 : sal_Bool bNeedExportBreakHere = sal_True;
2582 9 : if ( aIdx.GetNode().IsTxtNode() )
2583 : {
2584 1 : SwTxtNode *pTempNext = aIdx.GetNode().GetTxtNode();
2585 1 : if ( pTempNext )
2586 : {
2587 1 : const SfxPoolItem * pTempItem = NULL;
2588 3 : if (pTempNext->GetpSwAttrSet() && SFX_ITEM_SET == pTempNext->GetpSwAttrSet()->GetItemState(RES_PAGEDESC, false, &pTempItem)
2589 2 : && pTempItem && ((SwFmtPageDesc*)pTempItem)->GetRegisteredIn())
2590 : {
2591 : //Next node has a new page style which means this node is a section end. Do not insert another page/section break here
2592 1 : bNeedExportBreakHere = sal_False;
2593 : }
2594 : }
2595 : }
2596 9 : if (bNeedExportBreakHere) //#120140# End of check
2597 : {
2598 8 : ReplaceCr( (char)0xc ); // indicator for Page/Section-Break
2599 :
2600 8 : const SwSectionFmt* pParentFmt = rSect.GetFmt()->GetParent();
2601 8 : if ( !pParentFmt )
2602 8 : pParentFmt = (SwSectionFmt*)0xFFFFFFFF;
2603 :
2604 : sal_uLong nRstLnNum;
2605 8 : if ( aIdx.GetNode().IsCntntNode() )
2606 0 : nRstLnNum = ((SwCntntNode&)aIdx.GetNode()).GetSwAttrSet().
2607 0 : GetLineNumber().GetStartValue();
2608 : else
2609 8 : nRstLnNum = 0;
2610 :
2611 8 : AppendSection( pAktPageDesc, pParentFmt, nRstLnNum );
2612 : }
2613 34 : }
2614 : }
2615 4087 : else if ( pNd->IsStartNode() )
2616 : {
2617 2005 : OutputStartNode( *pNd->GetStartNode() );
2618 : }
2619 2082 : else if ( pNd->IsEndNode() )
2620 : {
2621 2082 : OutputEndNode( *pNd->GetEndNode() );
2622 : }
2623 :
2624 10306 : if ( pNd == &pNd->GetNodes().GetEndOfContent() )
2625 339 : break;
2626 :
2627 9967 : SwNode * pCurrentNode = &pCurPam->GetPoint()->nNode.GetNode();
2628 9967 : const SwNode * pNextNode = mpTableInfo->getNextNode(pCurrentNode);
2629 :
2630 9967 : if (pNextNode != NULL)
2631 5335 : pCurPam->GetPoint()->nNode = SwNodeIndex(*pNextNode);
2632 : else
2633 4632 : pCurPam->GetPoint()->nNode++;
2634 :
2635 9967 : sal_uLong nPos = pCurPam->GetPoint()->nNode.GetIndex();
2636 9967 : ::SetProgressState( nPos, pCurPam->GetDoc()->GetDocShell() );
2637 : }
2638 :
2639 : SAL_INFO( "sw.ww8.level2", "</WriteText>" );
2640 795 : }
2641 :
2642 12 : void WW8Export::WriteMainText()
2643 : {
2644 : SAL_INFO( "sw.ww8.level2", "<WriteMainText>" );
2645 :
2646 12 : pFib->fcMin = Strm().Tell();
2647 :
2648 12 : pCurPam->GetPoint()->nNode = pDoc->GetNodes().GetEndOfContent().StartOfSectionNode()->GetIndex();
2649 :
2650 12 : WriteText();
2651 :
2652 12 : if( 0 == Strm().Tell() - pFib->fcMin ) // no text ?
2653 0 : WriteCR(); // then CR at the end ( otherwise WW will complain )
2654 :
2655 12 : pFib->ccpText = Fc2Cp( Strm().Tell() );
2656 12 : pFldMain->Finish( pFib->ccpText, 0 );
2657 :
2658 : // ccpText includes Footnote and KF-text
2659 : // therefore pFib->ccpText may get updated as well
2660 : // save the StyleId of the last paragraph. Because WW97 take the style
2661 : // from the last CR, that will be writen after footer/Header/footnotes/
2662 : // annotation usw.
2663 12 : const SwTxtNode* pLastNd = pCurPam->GetMark()->nNode.GetNode().GetTxtNode();
2664 12 : if( pLastNd )
2665 0 : nLastFmtId = GetId( (SwTxtFmtColl&)pLastNd->GetAnyFmtColl() );
2666 :
2667 : SAL_INFO( "sw.ww8.level2", "</WriteMainText>" );
2668 12 : }
2669 :
2670 111 : bool MSWordExportBase::IsInTable() const
2671 : {
2672 111 : bool bResult = false;
2673 :
2674 111 : if (pCurPam != NULL)
2675 : {
2676 111 : SwNode * pNode = pCurPam->GetNode();
2677 :
2678 111 : if (pNode != NULL && mpTableInfo.get() != NULL)
2679 : {
2680 111 : ww8::WW8TableNodeInfo::Pointer_t pTableNodeInfo = mpTableInfo->getTableNodeInfo(pNode);
2681 :
2682 111 : if (pTableNodeInfo.get() != NULL && pTableNodeInfo->getDepth() > 0)
2683 : {
2684 8 : bResult = true;
2685 111 : }
2686 : }
2687 : }
2688 :
2689 111 : return bResult;
2690 : }
2691 :
2692 : typedef ww8::WW8Sttb< ww8::WW8Struct > WW8SttbAssoc;
2693 :
2694 12 : void WW8Export::WriteFkpPlcUsw()
2695 : {
2696 12 : if( !bWrtWW8 )
2697 : {
2698 : static const sal_uInt8 aSpec[2] =
2699 : {
2700 : 117, 1
2701 : };
2702 :
2703 0 : pChpPlc->AppendFkpEntry( Strm().Tell() ); // Sepx with fSpecial
2704 0 : pSepx->WriteSepx( Strm() ); // Slcx.Sepx
2705 0 : pGrf->Write(); // Graphics
2706 0 : pChpPlc->AppendFkpEntry( Strm().Tell(), sizeof( aSpec ), aSpec );
2707 :
2708 0 : pChpPlc->WriteFkps(); // Fkp.Chpx
2709 0 : pPapPlc->WriteFkps(); // Fkp.Papx
2710 0 : pStyles->OutputStylesTable(); // Styles
2711 0 : pFtn->WritePlc( *this ); // Footnote-Ref & Text Plc
2712 0 : pEdn->WritePlc( *this ); // Endnote-Ref & Text Plc
2713 0 : pAtn->WritePlc( *this ); // Annotation-Ref & Text Plc
2714 0 : pSepx->WritePlcSed( *this ); // Slcx.PlcSed
2715 0 : pSepx->WritePlcHdd( *this ); // Slcx.PlcHdd
2716 0 : pChpPlc->WritePlc(); // Plcx.Chpx
2717 0 : pPapPlc->WritePlc(); // Plcx.Papx
2718 0 : maFontHelper.WriteFontTable(pTableStrm, *pFib); // FFNs
2719 0 : if( pRedlAuthors )
2720 0 : pRedlAuthors->Write( GetWriter() ); // sttbfRMark (RedlineAuthors)
2721 0 : pFldMain->Write( *this ); // Fields ( Main Text )
2722 0 : pFldHdFt->Write( *this ); // Fields ( Header/Footer )
2723 0 : pFldFtn->Write( *this ); // Fields ( FootNotes )
2724 0 : pFldEdn->Write( *this ); // Fields ( EndNotes )
2725 0 : pFldAtn->Write( *this ); // Fields ( Annotations )
2726 0 : pBkmks->Write( *this ); // Bookmarks - sttbfBkmk/
2727 : // plcfBkmkf/plcfBkmkl
2728 0 : WriteDop( *this ); // Document-Properties
2729 :
2730 : }
2731 : else
2732 : {
2733 : // Graphics in the data stream
2734 12 : pGrf->Write(); // Graphics
2735 :
2736 : // Ausgabe in WordDocument-Stream
2737 12 : pChpPlc->WriteFkps(); // Fkp.Chpx
2738 12 : pPapPlc->WriteFkps(); // Fkp.Papx
2739 12 : pSepx->WriteSepx( Strm() ); // Sepx
2740 :
2741 : // Ausagbe in Table-Stream
2742 12 : pStyles->OutputStylesTable(); // for WW8 StyleTab
2743 12 : pFtn->WritePlc( *this ); // Footnote-Ref & Text Plc
2744 12 : pEdn->WritePlc( *this ); // Endnote-Ref & Text Plc
2745 12 : pTxtBxs->WritePlc( *this ); // Textbox Text Plc
2746 12 : pHFTxtBxs->WritePlc( *this ); // Head/Foot-Textbox Text Plc
2747 12 : pAtn->WritePlc( *this ); // Annotation-Ref & Text Plc
2748 :
2749 12 : pSepx->WritePlcSed( *this ); // Slcx.PlcSed
2750 12 : pSepx->WritePlcHdd( *this ); // Slcx.PlcHdd
2751 :
2752 12 : pChpPlc->WritePlc(); // Plcx.Chpx
2753 12 : pPapPlc->WritePlc(); // Plcx.Papx
2754 :
2755 12 : if( pRedlAuthors )
2756 0 : pRedlAuthors->Write( GetWriter() ); // sttbfRMark (RedlineAuthors)
2757 12 : pFldMain->Write( *this ); // Fields ( Main Text )
2758 12 : pFldHdFt->Write( *this ); // Fields ( Header/Footer )
2759 12 : pFldFtn->Write( *this ); // Fields ( FootNotes )
2760 12 : pFldEdn->Write( *this ); // Fields ( EndNotes )
2761 12 : pFldAtn->Write( *this ); // Fields ( Annotations )
2762 12 : pFldTxtBxs->Write( *this ); // Fields ( Textboxes )
2763 12 : pFldHFTxtBxs->Write( *this ); // Fields ( Head/Foot-Textboxes )
2764 :
2765 12 : if (pEscher || pDoc->ContainsMSVBasic())
2766 : {
2767 : /*
2768 : Everytime MS 2000 creates an escher stream there is always
2769 : an ObjectPool dir (even if empty). It turns out that if a copy of
2770 : MS 2000 is used to open a document that contains escher graphics
2771 : exported from StarOffice without this empty dir then *if* that
2772 : copy of MS Office has never been used to open a MSOffice document
2773 : that has escher graphics (and an ObjectPool dir of course) and
2774 : that copy of office has not been used to draw escher graphics then
2775 : our exported graphics do not appear. Once you do open a ms
2776 : document with escher graphics or draw an escher graphic with that
2777 : copy of word, then all documents from staroffice that contain
2778 : escher work from then on. Tricky to track down, some sort of late
2779 : binding trickery in MS where solely for first time initialization
2780 : the existence of an ObjectPool dir is necessary for triggering
2781 : some magic. cmc
2782 : */
2783 : // avoid memory leak #i120098#, the unnamed obj will be released in destructor.
2784 6 : xEscherStg = GetWriter().GetStorage().OpenSotStorage(OUString(SL::aObjectPool),
2785 3 : STREAM_READWRITE | STREAM_SHARE_DENYALL);
2786 : }
2787 :
2788 : // dggInfo - escher stream
2789 12 : WriteEscher();
2790 :
2791 12 : pSdrObjs->WritePlc( *this );
2792 12 : pHFSdrObjs->WritePlc( *this );
2793 : // spamom - office drawing table
2794 : // spahdr - header office drawing table
2795 :
2796 12 : pBkmks->Write( *this ); // Bookmarks - sttbfBkmk/
2797 : // plcfBkmkf/plcfBkmkl
2798 :
2799 12 : WriteNumbering();
2800 :
2801 12 : RestoreMacroCmds();
2802 :
2803 12 : pMagicTable->Write( *this );
2804 :
2805 12 : pPiece->WritePc( *this ); // Piece-Table
2806 12 : maFontHelper.WriteFontTable(pTableStrm, *pFib); // FFNs
2807 :
2808 : //Convert OOo asian typography into MS typography structure
2809 12 : ExportDopTypography(pDop->doptypography);
2810 :
2811 12 : WriteDop( *this ); // Document-Properties
2812 :
2813 : // Write SttbfAssoc
2814 : WW8SttbAssoc * pSttbfAssoc = dynamic_cast<WW8SttbAssoc *>
2815 12 : (pDoc->getExternalData(::sw::STTBF_ASSOC).get());
2816 :
2817 12 : if ( pSttbfAssoc ) // #i106057#
2818 : {
2819 7 : ::std::vector<OUString> aStrings;
2820 :
2821 7 : ::ww8::StringVector_t & aSttbStrings = pSttbfAssoc->getStrings();
2822 7 : ::ww8::StringVector_t::const_iterator aItEnd = aSttbStrings.end();
2823 115 : for (::ww8::StringVector_t::const_iterator aIt = aSttbStrings.begin();
2824 : aIt != aItEnd; ++aIt)
2825 : {
2826 108 : aStrings.push_back(aIt->getStr());
2827 : }
2828 :
2829 : WriteAsStringTable(aStrings, pFib->fcSttbfAssoc,
2830 7 : pFib->lcbSttbfAssoc);
2831 : }
2832 : }
2833 12 : Strm().Seek( 0 );
2834 :
2835 : // Reclaim stored FIB data from document.
2836 : ::ww8::WW8FibData * pFibData = dynamic_cast<ww8::WW8FibData *>
2837 12 : (pDoc->getExternalData(::sw::FIB).get());
2838 :
2839 12 : if ( pFibData )
2840 : {
2841 7 : pFib->fReadOnlyRecommended =
2842 14 : pFibData->getReadOnlyRecommended() ? 1 : 0;
2843 7 : pFib->fWriteReservation =
2844 14 : pFibData->getWriteReservation() ? 1 : 0;
2845 : }
2846 :
2847 12 : pFib->Write( Strm() ); // FIB
2848 12 : }
2849 :
2850 12 : void WW8Export::StoreDoc1()
2851 : {
2852 12 : bool bNeedsFinalPara = false;
2853 : // Start of Text ( Mangel ueber )
2854 12 : SwWW8Writer::FillUntil( Strm(), pFib->fcMin );
2855 :
2856 12 : WriteMainText(); // main text
2857 : sal_uInt8 nSprmsLen;
2858 12 : sal_uInt8 *pLastSprms = pPapPlc->CopyLastSprms(nSprmsLen);
2859 :
2860 12 : bNeedsFinalPara |= pFtn->WriteTxt( *this ); // Footnote-Text
2861 12 : bNeedsFinalPara |= pSepx->WriteKFTxt( *this ); // K/F-Text
2862 12 : bNeedsFinalPara |= pAtn->WriteTxt( *this ); // Annotation-Text
2863 12 : bNeedsFinalPara |= pEdn->WriteTxt( *this ); // EndNote-Text
2864 :
2865 : // create the escher streams
2866 12 : if( bWrtWW8 )
2867 12 : CreateEscher();
2868 :
2869 12 : bNeedsFinalPara |= pTxtBxs->WriteTxt( *this ); //Textbox Text Plc
2870 12 : bNeedsFinalPara |= pHFTxtBxs->WriteTxt( *this );//Head/Foot-Textbox Text Plc
2871 :
2872 12 : if (bNeedsFinalPara)
2873 : {
2874 9 : WriteCR();
2875 9 : pPapPlc->AppendFkpEntry(Strm().Tell(), nSprmsLen, pLastSprms);
2876 : }
2877 12 : delete[] pLastSprms;
2878 :
2879 12 : pSepx->Finish( Fc2Cp( Strm().Tell() ));// Text + Ftn + HdFt als Section-Ende
2880 12 : pMagicTable->Finish( Fc2Cp( Strm().Tell() ),0);
2881 :
2882 12 : pFib->fcMac = Strm().Tell(); // End of all texts
2883 :
2884 12 : WriteFkpPlcUsw(); // FKP, PLC, .....
2885 12 : }
2886 :
2887 304 : void MSWordExportBase::AddLinkTarget(const OUString& rURL)
2888 : {
2889 304 : if( rURL.isEmpty() || rURL[0] != '#' )
2890 518 : return;
2891 :
2892 88 : OUString aURL( BookmarkToWriter( rURL.copy( 1 ) ) );
2893 88 : sal_Int32 nPos = aURL.lastIndexOf( cMarkSeparator );
2894 :
2895 88 : if( nPos < 2 )
2896 86 : return;
2897 :
2898 4 : OUString sCmp(comphelper::string::remove(aURL.copy(nPos+1), ' '));
2899 2 : if( sCmp.isEmpty() )
2900 0 : return;
2901 :
2902 2 : sCmp = sCmp.toAsciiLowerCase();
2903 :
2904 2 : if( sCmp == "outline" )
2905 : {
2906 0 : SwPosition aPos( *pCurPam->GetPoint() );
2907 0 : OUString aOutline( BookmarkToWriter(aURL.copy( 0, nPos )) );
2908 : // If we can find the outline this bookmark refers to
2909 : // save the name of the bookmark and the
2910 : // node index number of where it points to
2911 0 : if( pDoc->GotoOutline( aPos, aOutline ) )
2912 : {
2913 0 : sal_uLong nIdx = aPos.nNode.GetIndex();
2914 0 : aBookmarkPair aImplicitBookmark;
2915 0 : aImplicitBookmark.first = aOutline;
2916 0 : aImplicitBookmark.second = nIdx;
2917 0 : maImplicitBookmarks.push_back(aImplicitBookmark);
2918 0 : }
2919 2 : }
2920 : }
2921 :
2922 340 : void MSWordExportBase::CollectOutlineBookmarks(const SwDoc &rDoc)
2923 : {
2924 : const SwFmtINetFmt* pINetFmt;
2925 : const SwTxtINetFmt* pTxtAttr;
2926 : const SwTxtNode* pTxtNd;
2927 :
2928 340 : sal_uInt32 n, nMaxItems = rDoc.GetAttrPool().GetItemCount2( RES_TXTATR_INETFMT );
2929 685 : for( n = 0; n < nMaxItems; ++n )
2930 : {
2931 690 : if( 0 != (pINetFmt = (SwFmtINetFmt*)rDoc.GetAttrPool().GetItem2(
2932 649 : RES_TXTATR_INETFMT, n ) ) &&
2933 304 : 0 != ( pTxtAttr = pINetFmt->GetTxtINetFmt()) &&
2934 649 : 0 != ( pTxtNd = pTxtAttr->GetpTxtNode() ) &&
2935 304 : pTxtNd->GetNodes().IsDocNodes() )
2936 : {
2937 304 : AddLinkTarget( pINetFmt->GetValue() );
2938 : }
2939 : }
2940 :
2941 : const SwFmtURL *pURL;
2942 340 : nMaxItems = rDoc.GetAttrPool().GetItemCount2( RES_URL );
2943 340 : for( n = 0; n < nMaxItems; ++n )
2944 : {
2945 0 : if( 0 != (pURL = (SwFmtURL*)rDoc.GetAttrPool().GetItem2(
2946 0 : RES_URL, n ) ) )
2947 : {
2948 0 : AddLinkTarget( pURL->GetURL() );
2949 0 : const ImageMap *pIMap = pURL->GetMap();
2950 0 : if( pIMap )
2951 : {
2952 0 : for( sal_uInt16 i=0; i<pIMap->GetIMapObjectCount(); i++ )
2953 : {
2954 0 : const IMapObject* pObj = pIMap->GetIMapObject( i );
2955 0 : if( pObj )
2956 : {
2957 0 : AddLinkTarget( pObj->GetURL() );
2958 : }
2959 : }
2960 : }
2961 : }
2962 : }
2963 340 : }
2964 :
2965 : namespace
2966 : {
2967 : const sal_uLong WW_BLOCKSIZE = 0x200;
2968 :
2969 0 : void EncryptRC4(msfilter::MSCodec_Std97& rCtx, SvStream &rIn, SvStream &rOut)
2970 : {
2971 0 : rIn.Seek(STREAM_SEEK_TO_END);
2972 0 : sal_uLong nLen = rIn.Tell();
2973 0 : rIn.Seek(0);
2974 :
2975 : sal_uInt8 in[WW_BLOCKSIZE];
2976 0 : for (sal_Size nI = 0, nBlock = 0; nI < nLen; nI += WW_BLOCKSIZE, ++nBlock)
2977 : {
2978 0 : sal_Size nBS = (nLen - nI > WW_BLOCKSIZE) ? WW_BLOCKSIZE : nLen - nI;
2979 0 : nBS = rIn.Read(in, nBS);
2980 0 : rCtx.InitCipher(nBlock);
2981 0 : rCtx.Encode(in, nBS, in, nBS);
2982 0 : rOut.Write(in, nBS);
2983 : }
2984 0 : }
2985 : }
2986 :
2987 340 : void MSWordExportBase::ExportDocument( bool bWriteAll )
2988 : {
2989 340 : nCharFmtStart = ANZ_DEFAULT_STYLES;
2990 340 : nFmtCollStart = nCharFmtStart + pDoc->GetCharFmts()->size() - 1;
2991 :
2992 : bStyDef = bBreakBefore = bOutKF =
2993 : bOutFlyFrmAttrs = bOutPageDescs = bOutTable = bOutFirstPage =
2994 : bOutGrf = bInWriteEscher = bStartTOX =
2995 340 : bInWriteTOX = false;
2996 :
2997 340 : bFtnAtTxtEnd = bEndAtTxtEnd = true;
2998 :
2999 340 : mpParentFrame = 0;
3000 340 : pFlyOffset = 0;
3001 340 : eNewAnchorType = FLY_AT_PAGE;
3002 340 : nTxtTyp = TXT_MAINTEXT;
3003 340 : nStyleBeforeFly = nLastFmtId = 0;
3004 340 : pStyAttr = 0;
3005 340 : pCurrentStyle = NULL;
3006 340 : pOutFmtNode = 0;
3007 340 : pEscher = 0;
3008 340 : pRedlAuthors = 0;
3009 340 : aTOXArr.clear();
3010 :
3011 340 : if ( !pOLEExp )
3012 : {
3013 340 : sal_uInt32 nSvxMSDffOLEConvFlags = 0;
3014 340 : const SvtFilterOptions& rOpt = SvtFilterOptions::Get();
3015 340 : if ( rOpt.IsMath2MathType() )
3016 340 : nSvxMSDffOLEConvFlags |= OLE_STARMATH_2_MATHTYPE;
3017 340 : if ( rOpt.IsWriter2WinWord() )
3018 340 : nSvxMSDffOLEConvFlags |= OLE_STARWRITER_2_WINWORD;
3019 340 : if ( rOpt.IsCalc2Excel() )
3020 340 : nSvxMSDffOLEConvFlags |= OLE_STARCALC_2_EXCEL;
3021 340 : if ( rOpt.IsImpress2PowerPoint() )
3022 340 : nSvxMSDffOLEConvFlags |= OLE_STARIMPRESS_2_POWERPOINT;
3023 :
3024 340 : pOLEExp = new SvxMSExportOLEObjects( nSvxMSDffOLEConvFlags );
3025 : }
3026 :
3027 340 : if ( !pOCXExp && pDoc->GetDocShell() )
3028 339 : pOCXExp = new SwMSConvertControls( pDoc->GetDocShell(), pCurPam );
3029 :
3030 : // #i81405# - Collect anchored objects before changing the redline mode.
3031 340 : maFrames = GetFrames( *pDoc, bWriteAll? NULL : pOrigPam );
3032 :
3033 340 : mnRedlineMode = pDoc->GetRedlineMode();
3034 340 : if ( !pDoc->GetRedlineTbl().empty() )
3035 : {
3036 : pDoc->SetRedlineMode( (RedlineMode_t)(mnRedlineMode | nsRedlineMode_t::REDLINE_SHOW_DELETE |
3037 12 : nsRedlineMode_t::REDLINE_SHOW_INSERT) );
3038 : }
3039 :
3040 340 : maFontHelper.InitFontTable( SupportsUnicode(), *pDoc );
3041 340 : GatherChapterFields();
3042 :
3043 340 : CollectOutlineBookmarks(*pDoc);
3044 :
3045 : // make unique OrdNums (Z-Order) for all drawing-/fly Objects
3046 340 : if ( pDoc->GetDrawModel() )
3047 339 : pDoc->GetDrawModel()->GetPage( 0 )->RecalcObjOrdNums();
3048 :
3049 340 : ExportDocument_Impl();
3050 :
3051 340 : if ( mnRedlineMode != pDoc->GetRedlineMode() )
3052 0 : pDoc->SetRedlineMode( (RedlineMode_t)(mnRedlineMode) );
3053 340 : }
3054 :
3055 12 : bool SwWW8Writer::InitStd97CodecUpdateMedium( ::msfilter::MSCodec_Std97& rCodec )
3056 : {
3057 12 : uno::Sequence< beans::NamedValue > aEncryptionData;
3058 :
3059 12 : if ( mpMedium )
3060 : {
3061 12 : SFX_ITEMSET_ARG( mpMedium->GetItemSet(), pEncryptionDataItem, SfxUnoAnyItem, SID_ENCRYPTIONDATA, false );
3062 12 : if ( pEncryptionDataItem && ( pEncryptionDataItem->GetValue() >>= aEncryptionData ) && !rCodec.InitCodec( aEncryptionData ) )
3063 : {
3064 : OSL_ENSURE( false, "Unexpected EncryptionData!" );
3065 0 : aEncryptionData.realloc( 0 );
3066 : }
3067 :
3068 12 : if ( !aEncryptionData.getLength() )
3069 : {
3070 : // try to generate the encryption data based on password
3071 12 : SFX_ITEMSET_ARG( mpMedium->GetItemSet(), pPasswordItem, SfxStringItem, SID_PASSWORD, false );
3072 12 : if ( pPasswordItem && !pPasswordItem->GetValue().isEmpty() && pPasswordItem->GetValue().getLength() <= 15 )
3073 : {
3074 : // Generate random number with a seed of time as salt.
3075 : TimeValue aTime;
3076 0 : osl_getSystemTime( &aTime );
3077 0 : rtlRandomPool aRandomPool = rtl_random_createPool ();
3078 0 : rtl_random_addBytes ( aRandomPool, &aTime, 8 );
3079 :
3080 : sal_uInt8 pDocId[ 16 ];
3081 0 : rtl_random_getBytes( aRandomPool, pDocId, 16 );
3082 :
3083 0 : rtl_random_destroyPool( aRandomPool );
3084 :
3085 : sal_Unicode aPassword[16];
3086 0 : memset( aPassword, 0, sizeof( aPassword ) );
3087 :
3088 0 : OUString sPassword(pPasswordItem->GetValue());
3089 0 : for ( sal_Int32 nChar = 0; nChar < sPassword.getLength(); ++nChar )
3090 0 : aPassword[nChar] = sPassword[nChar];
3091 :
3092 0 : rCodec.InitKey( aPassword, pDocId );
3093 0 : aEncryptionData = rCodec.GetEncryptionData();
3094 :
3095 0 : mpMedium->GetItemSet()->Put( SfxUnoAnyItem( SID_ENCRYPTIONDATA, uno::makeAny( aEncryptionData ) ) );
3096 : }
3097 : }
3098 :
3099 12 : if ( aEncryptionData.getLength() )
3100 0 : mpMedium->GetItemSet()->ClearItem( SID_PASSWORD );
3101 : }
3102 :
3103 : // nonempty encryption data means hier that the codec was successfully initialized
3104 12 : return ( aEncryptionData.getLength() != 0 );
3105 : }
3106 :
3107 12 : void WW8Export::ExportDocument_Impl()
3108 : {
3109 12 : PrepareStorage();
3110 :
3111 12 : pFib = new WW8Fib( bWrtWW8 ? 8 : 6, m_bDot );
3112 :
3113 12 : SvStorageStreamRef xWwStrm( GetWriter().GetStorage().OpenSotStream( aMainStg ) );
3114 24 : SvStorageStreamRef xTableStrm( xWwStrm ), xDataStrm( xWwStrm );
3115 12 : xWwStrm->SetBufferSize( 32768 );
3116 :
3117 12 : if( bWrtWW8 )
3118 : {
3119 12 : pFib->fWhichTblStm = true;
3120 24 : xTableStrm = GetWriter().GetStorage().OpenSotStream(OUString(SL::a1Table),
3121 12 : STREAM_STD_WRITE );
3122 24 : xDataStrm = GetWriter().GetStorage().OpenSotStream(OUString(SL::aData),
3123 12 : STREAM_STD_WRITE );
3124 :
3125 12 : xDataStrm->SetBufferSize( 32768 ); // for graphics
3126 12 : xTableStrm->SetBufferSize( 16384 ); // for the Font-/Style-Table, etc.
3127 :
3128 12 : xTableStrm->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
3129 12 : xDataStrm->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
3130 : }
3131 :
3132 12 : GetWriter().SetStream( & *xWwStrm );
3133 12 : pTableStrm = &xTableStrm;
3134 12 : pDataStrm = &xDataStrm;
3135 :
3136 12 : Strm().SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
3137 :
3138 24 : utl::TempFile aTempMain;
3139 12 : aTempMain.EnableKillingFile();
3140 24 : utl::TempFile aTempTable;
3141 12 : aTempTable.EnableKillingFile();
3142 24 : utl::TempFile aTempData;
3143 12 : aTempData.EnableKillingFile();
3144 :
3145 24 : msfilter::MSCodec_Std97 aCtx;
3146 12 : bool bEncrypt = GetWriter().InitStd97CodecUpdateMedium(aCtx);
3147 12 : if ( bEncrypt )
3148 : {
3149 0 : GetWriter().SetStream(
3150 0 : aTempMain.GetStream( STREAM_READWRITE | STREAM_SHARE_DENYWRITE ) );
3151 :
3152 0 : pTableStrm = aTempTable.GetStream( STREAM_READWRITE | STREAM_SHARE_DENYWRITE );
3153 :
3154 0 : pDataStrm = aTempData.GetStream( STREAM_READWRITE | STREAM_SHARE_DENYWRITE );
3155 :
3156 0 : sal_uInt8 aRC4EncryptionHeader[ 52 ] = {0};
3157 0 : pTableStrm->Write( aRC4EncryptionHeader, 52 );
3158 : }
3159 :
3160 : // Default: "Standard"
3161 12 : pSepx = new WW8_WrPlcSepx( *this ); // Sections/headers/footers
3162 :
3163 12 : pFtn = new WW8_WrPlcFtnEdn( TXT_FTN ); // Footnotes
3164 12 : pEdn = new WW8_WrPlcFtnEdn( TXT_EDN ); // Endnotes
3165 12 : pAtn = new WW8_WrPlcAnnotations; // PostIts
3166 12 : pTxtBxs = new WW8_WrPlcTxtBoxes( TXT_TXTBOX );
3167 12 : pHFTxtBxs = new WW8_WrPlcTxtBoxes( TXT_HFTXTBOX );
3168 :
3169 12 : pSdrObjs = new MainTxtPlcDrawObj; // Draw-/Fly-Objects for main text
3170 12 : pHFSdrObjs = new HdFtPlcDrawObj; // Draw-/Fly-Objects for header/footer
3171 :
3172 12 : pBkmks = new WW8_WrtBookmarks; // Bookmarks
3173 12 : GetWriter().CreateBookmarkTbl();
3174 :
3175 12 : pPapPlc = new WW8_WrPlcPn( *this, PAP, pFib->fcMin );
3176 12 : pChpPlc = new WW8_WrPlcPn( *this, CHP, pFib->fcMin );
3177 12 : pO = new ww::bytes();
3178 12 : pStyles = new MSWordStyles( *this );
3179 12 : pFldMain = new WW8_WrPlcFld( 2, TXT_MAINTEXT );
3180 12 : pFldHdFt = new WW8_WrPlcFld( 2, TXT_HDFT );
3181 12 : pFldFtn = new WW8_WrPlcFld( 2, TXT_FTN );
3182 12 : pFldEdn = new WW8_WrPlcFld( 2, TXT_EDN );
3183 12 : pFldAtn = new WW8_WrPlcFld( 2, TXT_ATN );
3184 12 : pFldTxtBxs = new WW8_WrPlcFld( 2, TXT_TXTBOX );
3185 12 : pFldHFTxtBxs = new WW8_WrPlcFld( 2, TXT_HFTXTBOX );
3186 :
3187 12 : pMagicTable = new WW8_WrMagicTable;
3188 :
3189 12 : pGrf = new SwWW8WrGrf( *this );
3190 12 : pPiece = new WW8_WrPct( pFib->fcMin, bWrtWW8 );
3191 12 : pDop = new WW8Dop;
3192 :
3193 12 : pDop->fRevMarking = 0 != ( nsRedlineMode_t::REDLINE_ON & mnRedlineMode );
3194 12 : pDop->fRMView = 0 != ( nsRedlineMode_t::REDLINE_SHOW_DELETE & mnRedlineMode );
3195 12 : pDop->fRMPrint = pDop->fRMView;
3196 :
3197 : // set AutoHyphenation flag if found in default para style
3198 : const SfxPoolItem* pItem;
3199 : SwTxtFmtColl* pStdTxtFmtColl =
3200 12 : pDoc->GetTxtCollFromPool(RES_POOLCOLL_STANDARD, false);
3201 24 : if (pStdTxtFmtColl && SFX_ITEM_SET == pStdTxtFmtColl->GetItemState(
3202 12 : RES_PARATR_HYPHENZONE, false, &pItem))
3203 : {
3204 5 : pDop->fAutoHyphen = ((const SvxHyphenZoneItem*)pItem)->IsHyphen();
3205 : }
3206 :
3207 12 : StoreDoc1();
3208 :
3209 12 : if ( bEncrypt )
3210 : {
3211 : SvStream *pStrmTemp, *pTableStrmTemp, *pDataStrmTemp;
3212 0 : pStrmTemp = &xWwStrm;
3213 0 : pTableStrmTemp = &xTableStrm;
3214 0 : pDataStrmTemp = &xDataStrm;
3215 :
3216 0 : if ( pDataStrmTemp && pDataStrmTemp != pStrmTemp)
3217 0 : EncryptRC4(aCtx, *pDataStrm, *pDataStrmTemp);
3218 :
3219 0 : EncryptRC4(aCtx, *pTableStrm, *pTableStrmTemp);
3220 :
3221 : // Write Unencrypted Header 52 bytes to the start of the table stream
3222 : // EncryptionVersionInfo (4 bytes): A Version structure where Version.vMajor MUST be 0x0001, and Version.vMinor MUST be 0x0001.
3223 0 : pTableStrmTemp->Seek( 0 );
3224 0 : sal_uInt32 nEncType = 0x10001;
3225 0 : pTableStrmTemp->WriteUInt32( nEncType );
3226 :
3227 : sal_uInt8 pDocId[16];
3228 0 : aCtx.GetDocId( pDocId );
3229 :
3230 : sal_uInt8 pSaltData[16];
3231 : sal_uInt8 pSaltDigest[16];
3232 0 : aCtx.GetEncryptKey( pDocId, pSaltData, pSaltDigest );
3233 :
3234 0 : pTableStrmTemp->Write( pDocId, 16 );
3235 0 : pTableStrmTemp->Write( pSaltData, 16 );
3236 0 : pTableStrmTemp->Write( pSaltDigest, 16 );
3237 :
3238 0 : EncryptRC4(aCtx, GetWriter().Strm(), *pStrmTemp);
3239 :
3240 : // Write Unencrypted Fib 68 bytes to the start of the workdocument stream
3241 0 : pFib->fEncrypted = true; // fEncrypted indicates the document is encrypted.
3242 0 : pFib->fObfuscated = false; // Must be 0 for RC4.
3243 0 : pFib->nHash = 0x34; // encrypt header bytes count of table stream.
3244 0 : pFib->nKey = 0; // lkey2 must be 0 for RC4.
3245 :
3246 0 : pStrmTemp->Seek( 0 );
3247 0 : pFib->WriteHeader( *pStrmTemp );
3248 : }
3249 :
3250 12 : if (pUsedNumTbl) // all used NumRules
3251 : {
3252 : // clear the part of the list array that was copied from the document
3253 : // - it's an auto delete array, so the rest of the array which are
3254 : // duplicated lists that were added during the export will be deleted.
3255 3 : pUsedNumTbl->erase(pUsedNumTbl->begin(), pUsedNumTbl->begin() + pUsedNumTbl->size() - nUniqueList);
3256 3 : delete pUsedNumTbl;
3257 : }
3258 :
3259 12 : DELETEZ( pGrf );
3260 12 : DELETEZ( pMagicTable );
3261 12 : DELETEZ( pFldFtn );
3262 12 : DELETEZ( pFldTxtBxs );
3263 12 : DELETEZ( pFldHFTxtBxs );
3264 12 : DELETEZ( pFldAtn );
3265 12 : DELETEZ( pFldEdn );
3266 12 : DELETEZ( pFldHdFt );
3267 12 : DELETEZ( pFldMain );
3268 12 : DELETEZ( pStyles );
3269 12 : DELETEZ( pO );
3270 12 : DELETEZ( pChpPlc );
3271 12 : DELETEZ( pPapPlc );
3272 12 : DELETEZ( pSepx );
3273 :
3274 12 : delete pRedlAuthors;
3275 12 : delete pSdrObjs;
3276 12 : delete pHFSdrObjs;
3277 12 : delete pTxtBxs;
3278 12 : delete pHFTxtBxs;
3279 12 : delete pAtn;
3280 12 : delete pEdn;
3281 12 : delete pFtn;
3282 12 : delete pBkmks;
3283 12 : delete pPiece;
3284 12 : delete pDop;
3285 12 : delete pFib;
3286 12 : GetWriter().SetStream( 0 );
3287 :
3288 12 : xWwStrm->SetBufferSize( 0 );
3289 12 : if( bWrtWW8 )
3290 : {
3291 12 : xTableStrm->SetBufferSize( 0 );
3292 12 : xDataStrm->SetBufferSize( 0 );
3293 12 : if( 0 == pDataStrm->Seek( STREAM_SEEK_TO_END ))
3294 : {
3295 10 : xDataStrm.Clear();
3296 10 : pDataStrm = 0;
3297 10 : GetWriter().GetStorage().Remove(OUString(SL::aData));
3298 : }
3299 12 : }
3300 12 : }
3301 :
3302 12 : void WW8Export::PrepareStorage()
3303 : {
3304 : sal_uLong nLen;
3305 : const sal_uInt8* pData;
3306 : const char* pName;
3307 : sal_uInt32 nId1;
3308 :
3309 12 : if (bWrtWW8)
3310 : {
3311 : static const char aUserName[] = "Microsoft Word-Document";
3312 : static const sal_uInt8 aCompObj[] =
3313 : {
3314 : 0x01, 0x00, 0xFE, 0xFF, 0x03, 0x0A, 0x00, 0x00,
3315 : 0xFF, 0xFF, 0xFF, 0xFF, 0x06, 0x09, 0x02, 0x00,
3316 : 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00,
3317 : 0x00, 0x00, 0x00, 0x46, 0x18, 0x00, 0x00, 0x00,
3318 : 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66,
3319 : 0x74, 0x20, 0x57, 0x6F, 0x72, 0x64, 0x2D, 0x44,
3320 : 0x6F, 0x6B, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x00,
3321 : 0x0A, 0x00, 0x00, 0x00, 0x4D, 0x53, 0x57, 0x6F,
3322 : 0x72, 0x64, 0x44, 0x6F, 0x63, 0x00, 0x10, 0x00,
3323 : 0x00, 0x00, 0x57, 0x6F, 0x72, 0x64, 0x2E, 0x44,
3324 : 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E,
3325 : 0x38, 0x00, 0xF4, 0x39, 0xB2, 0x71, 0x00, 0x00,
3326 : 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3327 : 0x00, 0x00
3328 : };
3329 :
3330 12 : pName = aUserName;
3331 12 : pData = aCompObj;
3332 12 : nLen = sizeof( aCompObj );
3333 12 : nId1 = 0x00020906L;
3334 : }
3335 : else
3336 : {
3337 : static const char aUserName[] = "Microsoft Word 6.0 Document";
3338 : static const sal_uInt8 aCompObj[] =
3339 : {
3340 : 0x01, 0x00, 0xFE, 0xFF, 0x03, 0x0A, 0x00, 0x00,
3341 : 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x09, 0x02, 0x00,
3342 : 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00,
3343 : 0x00, 0x00, 0x00, 0x46, 0x1C, 0x00, 0x00, 0x00,
3344 : 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66,
3345 : 0x74, 0x20, 0x57, 0x6F, 0x72, 0x64, 0x20, 0x36,
3346 : 0x2E, 0x30, 0x2D, 0x44, 0x6F, 0x6B, 0x75, 0x6D,
3347 : 0x65, 0x6E, 0x74, 0x00, 0x0A, 0x00, 0x00, 0x00,
3348 : 0x4D, 0x53, 0x57, 0x6F, 0x72, 0x64, 0x44, 0x6F,
3349 : 0x63, 0x00, 0x10, 0x00, 0x00, 0x00, 0x57, 0x6F,
3350 : 0x72, 0x64, 0x2E, 0x44, 0x6F, 0x63, 0x75, 0x6D,
3351 : 0x65, 0x6E, 0x74, 0x2E, 0x36, 0x00, 0x00, 0x00,
3352 : 0x00, 0x00
3353 : };
3354 :
3355 0 : pName = aUserName;
3356 0 : pData = aCompObj;
3357 0 : nLen = sizeof( aCompObj );
3358 0 : nId1 = 0x00020900L;
3359 : }
3360 :
3361 : SvGlobalName aGName( nId1, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00,
3362 12 : 0x00, 0x00, 0x00, 0x46 );
3363 12 : GetWriter().GetStorage().SetClass( aGName, 0, OUString::createFromAscii( pName ));
3364 24 : SvStorageStreamRef xStor( GetWriter().GetStorage().OpenSotStream(sCompObj) );
3365 12 : xStor->Write( pData, nLen );
3366 :
3367 12 : SwDocShell* pDocShell = pDoc->GetDocShell ();
3368 : OSL_ENSURE(pDocShell, "no SwDocShell");
3369 :
3370 12 : if (pDocShell) {
3371 : uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
3372 12 : pDocShell->GetModel(), uno::UNO_QUERY_THROW);
3373 : uno::Reference<document::XDocumentProperties> xDocProps(
3374 24 : xDPS->getDocumentProperties());
3375 : OSL_ENSURE(xDocProps.is(), "DocumentProperties is null");
3376 :
3377 12 : if (xDocProps.is())
3378 : {
3379 12 : if ( SvtFilterOptions::Get().IsEnableWordPreview() )
3380 : {
3381 : ::boost::shared_ptr<GDIMetaFile> pMetaFile =
3382 0 : pDocShell->GetPreviewMetaFile(false);
3383 : uno::Sequence<sal_uInt8> metaFile(
3384 0 : sfx2::convertMetaFile(pMetaFile.get()));
3385 0 : sfx2::SaveOlePropertySet(xDocProps, &GetWriter().GetStorage(), &metaFile);
3386 : }
3387 : else
3388 12 : sfx2::SaveOlePropertySet( xDocProps, &GetWriter().GetStorage() );
3389 12 : }
3390 12 : }
3391 12 : }
3392 :
3393 12 : sal_uLong SwWW8Writer::WriteStorage()
3394 : {
3395 : // #i34818# - update layout (if present), for SwWriteTable
3396 12 : SwViewShell* pViewShell = NULL;
3397 12 : pDoc->GetEditShell( &pViewShell );
3398 12 : if( pViewShell != NULL )
3399 12 : pViewShell->CalcLayout();
3400 :
3401 12 : long nMaxNode = pDoc->GetNodes().Count();
3402 12 : ::StartProgress( STR_STATSTR_W4WWRITE, 0, nMaxNode, pDoc->GetDocShell() );
3403 :
3404 : // Respect table at the beginning of the document
3405 : {
3406 12 : SwTableNode * pTNd = pCurPam->GetNode()->FindTableNode();
3407 12 : if( pTNd && bWriteAll )
3408 : // start with the table node !!
3409 0 : pCurPam->GetPoint()->nNode = *pTNd;
3410 : }
3411 :
3412 : // Do the actual export
3413 : {
3414 12 : bool bDot = mpMedium->GetFilter()->GetName().endsWith("Vorlage");
3415 12 : WW8Export aExport( this, pDoc, pCurPam, pOrigPam, m_bWrtWW8, bDot );
3416 12 : m_pExport = &aExport;
3417 12 : aExport.ExportDocument( bWriteAll );
3418 12 : m_pExport = NULL;
3419 : }
3420 :
3421 12 : ::EndProgress( pDoc->GetDocShell() );
3422 12 : return 0;
3423 : }
3424 :
3425 0 : sal_uLong SwWW8Writer::WriteMedium( SfxMedium& )
3426 : {
3427 0 : return WriteStorage();
3428 : }
3429 :
3430 12 : sal_uLong SwWW8Writer::Write( SwPaM& rPaM, SfxMedium& rMed,
3431 : const OUString* pFileName )
3432 : {
3433 12 : mpMedium = &rMed;
3434 12 : sal_uLong nRet = StgWriter::Write( rPaM, rMed, pFileName );
3435 12 : mpMedium = NULL;
3436 12 : return nRet;
3437 : }
3438 :
3439 340 : MSWordExportBase::MSWordExportBase( SwDoc *pDocument, SwPaM *pCurrentPam, SwPaM *pOriginalPam )
3440 : : aMainStg(sMainStream)
3441 : , pISet(0)
3442 : , pPiece(NULL)
3443 : , pUsedNumTbl(0)
3444 : , mpTopNodeOfHdFtPage(0)
3445 : , pBkmks(0)
3446 : , pRedlAuthors(0)
3447 : , pBmpPal(0)
3448 : , pOLEExp(0)
3449 : , pOCXExp(0)
3450 0 : , mpTableInfo(new ww8::WW8TableInfo())
3451 : , nCharFmtStart(0)
3452 : , nFmtCollStart(0)
3453 : , nStyleBeforeFly(0)
3454 : , nLastFmtId(0)
3455 : , nUniqueList(0)
3456 : , mnHdFtIndex(0)
3457 : , mnRedlineMode(0)
3458 : , pAktPageDesc(0)
3459 : , pPapPlc(0)
3460 : , pChpPlc(0)
3461 : , pChpIter(0)
3462 : , pStyles(NULL)
3463 : , pAtn(0)
3464 : , pTxtBxs(0)
3465 : , pHFTxtBxs(0)
3466 : , mpParentFrame(0)
3467 : , pFlyOffset(0)
3468 : , eNewAnchorType(FLY_AS_CHAR)
3469 : , pFldMain(0)
3470 : , pFldHdFt(0)
3471 : , pFldFtn(0)
3472 : , pFldEdn(0)
3473 : , pFldAtn(0)
3474 : , pFldTxtBxs(0)
3475 : , pFldHFTxtBxs(0)
3476 : , pMagicTable(0)
3477 : , pGrf(0)
3478 : , pStyAttr(0)
3479 : , pOutFmtNode(0)
3480 : , pCurrentStyle(0)
3481 : , pSdrObjs(0)
3482 : , pHFSdrObjs(0)
3483 : , pEscher(0)
3484 : , nTxtTyp(0)
3485 : , bStyDef(false)
3486 : , bBreakBefore(false)
3487 : , bOutKF(false)
3488 : , bOutFlyFrmAttrs(false)
3489 : , bOutPageDescs(false)
3490 : , bOutFirstPage(false)
3491 : , bOutTable(false)
3492 : , bOutGrf(false)
3493 : , bInWriteEscher(false)
3494 : , bStartTOX(false)
3495 : , bInWriteTOX(false)
3496 : , bFtnAtTxtEnd(false)
3497 : , bEndAtTxtEnd(false)
3498 : , bHasHdr(false)
3499 : , bHasFtr(false)
3500 : , bSubstituteBullets(true)
3501 : , bTabInTOC(false)
3502 : , bHideTabLeaderAndPageNumbers(false)
3503 : , mbExportModeRTF(false)
3504 : , mbOutOutlineOnly(false)
3505 : , pDoc(pDocument)
3506 : , pCurPam(pCurrentPam)
3507 340 : , pOrigPam(pOriginalPam)
3508 : {
3509 340 : }
3510 :
3511 680 : MSWordExportBase::~MSWordExportBase()
3512 : {
3513 340 : delete pBmpPal;
3514 340 : delete pOLEExp;
3515 340 : delete pOCXExp;
3516 340 : }
3517 :
3518 12 : WW8Export::WW8Export( SwWW8Writer *pWriter,
3519 : SwDoc *pDocument, SwPaM *pCurrentPam, SwPaM *pOriginalPam,
3520 : bool bIsWW8, bool bDot )
3521 : : MSWordExportBase( pDocument, pCurrentPam, pOriginalPam ),
3522 : pO( NULL ),
3523 : pSepx( NULL ),
3524 : bWrtWW8( bIsWW8 ),
3525 : m_bDot(bDot),
3526 : m_pWriter( pWriter ),
3527 12 : m_pAttrOutput( new WW8AttributeOutput( *this ) )
3528 : {
3529 12 : }
3530 :
3531 24 : WW8Export::~WW8Export()
3532 : {
3533 12 : delete m_pAttrOutput, m_pAttrOutput = NULL;
3534 12 : }
3535 :
3536 10117 : AttributeOutputBase& WW8Export::AttrOutput() const
3537 : {
3538 10117 : return *m_pAttrOutput;
3539 : }
3540 :
3541 0 : MSWordSections& WW8Export::Sections() const
3542 : {
3543 0 : return *pSepx;
3544 : }
3545 :
3546 12 : SwWW8Writer::SwWW8Writer(const OUString& rFltName, const OUString& rBaseURL)
3547 : : StgWriter(),
3548 12 : m_bWrtWW8( rFltName == FILTER_WW8 ),
3549 : m_pExport( NULL ),
3550 24 : mpMedium( 0 )
3551 : {
3552 12 : SetBaseURL( rBaseURL );
3553 12 : }
3554 :
3555 24 : SwWW8Writer::~SwWW8Writer()
3556 : {
3557 24 : }
3558 :
3559 0 : extern "C" SAL_DLLPUBLIC_EXPORT sal_uLong SAL_CALL SaveOrDelMSVBAStorage_ww8( SfxObjectShell& rDoc, SotStorage& rStor, sal_Bool bSaveInto, const OUString& rStorageName )
3560 : {
3561 0 : SvxImportMSVBasic aTmp( rDoc, rStor );
3562 0 : return aTmp.SaveOrDelMSVBAStorage( bSaveInto, rStorageName );
3563 : }
3564 :
3565 12 : extern "C" SAL_DLLPUBLIC_EXPORT void SAL_CALL ExportDOC( const OUString& rFltName, const OUString& rBaseURL, WriterRef& xRet )
3566 : {
3567 12 : xRet = new SwWW8Writer( rFltName, rBaseURL );
3568 12 : }
3569 :
3570 0 : extern "C" SAL_DLLPUBLIC_EXPORT sal_uLong SAL_CALL GetSaveWarningOfMSVBAStorage_ww8( SfxObjectShell &rDocS )
3571 : {
3572 0 : return SvxImportMSVBasic::GetSaveWarningOfMSVBAStorage( rDocS );
3573 : }
3574 :
3575 24 : bool WW8_WrPlcFtnEdn::WriteTxt( WW8Export& rWrt )
3576 : {
3577 24 : bool bRet = false;
3578 24 : if (TXT_FTN == nTyp)
3579 : {
3580 12 : bRet = WriteGenericTxt( rWrt, TXT_FTN, rWrt.pFib->ccpFtn );
3581 12 : rWrt.pFldFtn->Finish( rWrt.Fc2Cp( rWrt.Strm().Tell() ),
3582 24 : rWrt.pFib->ccpText );
3583 : }
3584 : else
3585 : {
3586 12 : bRet = WriteGenericTxt( rWrt, TXT_EDN, rWrt.pFib->ccpEdn );
3587 12 : rWrt.pFldEdn->Finish( rWrt.Fc2Cp( rWrt.Strm().Tell() ),
3588 12 : rWrt.pFib->ccpText + rWrt.pFib->ccpFtn
3589 24 : + rWrt.pFib->ccpHdr + rWrt.pFib->ccpAtn );
3590 : }
3591 24 : return bRet;
3592 : }
3593 :
3594 24 : void WW8_WrPlcFtnEdn::WritePlc( WW8Export& rWrt ) const
3595 : {
3596 24 : if( TXT_FTN == nTyp )
3597 : {
3598 : WriteGenericPlc( rWrt, TXT_FTN, rWrt.pFib->fcPlcffndTxt,
3599 : rWrt.pFib->lcbPlcffndTxt, rWrt.pFib->fcPlcffndRef,
3600 12 : rWrt.pFib->lcbPlcffndRef );
3601 : }
3602 : else
3603 : {
3604 : WriteGenericPlc( rWrt, TXT_EDN, rWrt.pFib->fcPlcfendTxt,
3605 : rWrt.pFib->lcbPlcfendTxt, rWrt.pFib->fcPlcfendRef,
3606 12 : rWrt.pFib->lcbPlcfendRef );
3607 : }
3608 24 : }
3609 :
3610 12 : bool WW8_WrPlcAnnotations::WriteTxt( WW8Export& rWrt )
3611 : {
3612 12 : bool bRet = WriteGenericTxt( rWrt, TXT_ATN, rWrt.pFib->ccpAtn );
3613 12 : rWrt.pFldAtn->Finish( rWrt.Fc2Cp( rWrt.Strm().Tell() ),
3614 12 : rWrt.pFib->ccpText + rWrt.pFib->ccpFtn
3615 24 : + rWrt.pFib->ccpHdr );
3616 12 : return bRet;
3617 : }
3618 :
3619 12 : void WW8_WrPlcAnnotations::WritePlc( WW8Export& rWrt ) const
3620 : {
3621 : WriteGenericPlc( rWrt, TXT_ATN, rWrt.pFib->fcPlcfandTxt,
3622 : rWrt.pFib->lcbPlcfandTxt, rWrt.pFib->fcPlcfandRef,
3623 12 : rWrt.pFib->lcbPlcfandRef );
3624 12 : }
3625 :
3626 24 : void WW8_WrPlcTxtBoxes::WritePlc( WW8Export& rWrt ) const
3627 : {
3628 24 : if( TXT_TXTBOX == nTyp )
3629 : {
3630 : WriteGenericPlc( rWrt, nTyp, rWrt.pFib->fcPlcftxbxBkd,
3631 : rWrt.pFib->lcbPlcftxbxBkd, rWrt.pFib->fcPlcftxbxTxt,
3632 12 : rWrt.pFib->lcbPlcftxbxTxt );
3633 : }
3634 : else
3635 : {
3636 : WriteGenericPlc( rWrt, nTyp, rWrt.pFib->fcPlcfHdrtxbxBkd,
3637 : rWrt.pFib->lcbPlcfHdrtxbxBkd, rWrt.pFib->fcPlcfHdrtxbxTxt,
3638 12 : rWrt.pFib->lcbPlcfHdrtxbxTxt );
3639 : }
3640 24 : }
3641 :
3642 12 : void WW8Export::RestoreMacroCmds()
3643 : {
3644 12 : pFib->fcCmds = pTableStrm->Tell();
3645 :
3646 12 : uno::Reference < embed::XStorage > xSrcRoot(pDoc->GetDocShell()->GetStorage());
3647 : try
3648 : {
3649 : uno::Reference < io::XStream > xSrcStream =
3650 18 : xSrcRoot->openStreamElement( OUString(SL::aMSMacroCmds), embed::ElementModes::READ );
3651 6 : SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( xSrcStream );
3652 :
3653 6 : if ( pStream && SVSTREAM_OK == pStream->GetError())
3654 : {
3655 6 : pStream->Seek(STREAM_SEEK_TO_END);
3656 6 : pFib->lcbCmds = pStream->Tell();
3657 6 : pStream->Seek(0);
3658 :
3659 6 : sal_uInt8 *pBuffer = new sal_uInt8[pFib->lcbCmds];
3660 6 : bool bReadOk = checkRead(*pStream, pBuffer, pFib->lcbCmds);
3661 6 : if (bReadOk)
3662 6 : pTableStrm->Write(pBuffer, pFib->lcbCmds);
3663 6 : delete[] pBuffer;
3664 :
3665 : }
3666 :
3667 6 : delete pStream;
3668 : }
3669 6 : catch ( const uno::Exception& )
3670 : {
3671 : }
3672 :
3673 : // set len to FIB
3674 12 : pFib->lcbCmds = pTableStrm->Tell() - pFib->fcCmds;
3675 12 : }
3676 :
3677 254 : void WW8SHDLong::Write( WW8Export& rExport )
3678 : {
3679 254 : rExport.InsUInt32( m_cvFore );
3680 254 : rExport.InsUInt32( m_cvBack );
3681 254 : rExport.InsUInt16( m_ipat );
3682 254 : }
3683 :
3684 0 : void WW8Export::WriteFormData( const ::sw::mark::IFieldmark& rFieldmark )
3685 : {
3686 : OSL_ENSURE( bWrtWW8, "No 95 export yet" );
3687 0 : if ( !bWrtWW8 )
3688 0 : return;
3689 :
3690 0 : const ::sw::mark::IFieldmark* pFieldmark = &rFieldmark;
3691 0 : const ::sw::mark::ICheckboxFieldmark* pAsCheckbox = dynamic_cast< const ::sw::mark::ICheckboxFieldmark* >( pFieldmark );
3692 :
3693 : OSL_ENSURE(rFieldmark.GetFieldname() == ODF_FORMTEXT ||
3694 : rFieldmark.GetFieldname() == ODF_FORMDROPDOWN ||
3695 : rFieldmark.GetFieldname() == ODF_FORMCHECKBOX, "Unknown field type!!!");
3696 0 : if ( ! ( rFieldmark.GetFieldname() == ODF_FORMTEXT ||
3697 0 : rFieldmark.GetFieldname() == ODF_FORMDROPDOWN ||
3698 0 : rFieldmark.GetFieldname() == ODF_FORMCHECKBOX ) )
3699 0 : return;
3700 :
3701 0 : int type = 0; // TextFieldmark
3702 0 : if ( pAsCheckbox )
3703 0 : type = 1;
3704 0 : if ( rFieldmark.GetFieldname() == ODF_FORMDROPDOWN )
3705 0 : type=2;
3706 :
3707 0 : ::sw::mark::IFieldmark::parameter_map_t::const_iterator pNameParameter = rFieldmark.GetParameters()->find("name");
3708 0 : OUString ffname;
3709 0 : if(pNameParameter != rFieldmark.GetParameters()->end())
3710 0 : pNameParameter->second >>= ffname;
3711 :
3712 0 : sal_uLong nDataStt = pDataStrm->Tell();
3713 0 : pChpPlc->AppendFkpEntry(Strm().Tell());
3714 :
3715 0 : WriteChar(0x01);
3716 : static sal_uInt8 aArr1[] =
3717 : {
3718 : 0x03, 0x6a, 0,0,0,0, // sprmCPicLocation
3719 :
3720 : 0x06, 0x08, 0x01, // sprmCFData
3721 : 0x55, 0x08, 0x01, // sprmCFSpec
3722 : 0x02, 0x08, 0x01 // sprmCFFldVanish
3723 : };
3724 0 : sal_uInt8* pDataAdr = aArr1 + 2;
3725 0 : Set_UInt32(pDataAdr, nDataStt);
3726 :
3727 0 : pChpPlc->AppendFkpEntry( Strm().Tell(), sizeof( aArr1 ), aArr1 );
3728 :
3729 : struct FFDataHeader
3730 : {
3731 : sal_uInt32 version;
3732 : sal_uInt16 bits;
3733 : sal_uInt16 cch;
3734 : sal_uInt16 hps;
3735 0 : FFDataHeader() : version( 0xFFFFFFFF ), bits(0), cch(0), hps(0) {}
3736 : };
3737 :
3738 0 : FFDataHeader aFldHeader;
3739 0 : aFldHeader.bits |= (type & 0x03);
3740 :
3741 0 : sal_Int32 ffres = 0; // rFieldmark.GetFFRes();
3742 0 : if ( pAsCheckbox && pAsCheckbox->IsChecked() )
3743 0 : ffres = 1;
3744 0 : else if ( type == 2 )
3745 : {
3746 0 : ::sw::mark::IFieldmark::parameter_map_t::const_iterator pResParameter = rFieldmark.GetParameters()->find(ODF_FORMDROPDOWN_RESULT);
3747 0 : if(pResParameter != rFieldmark.GetParameters()->end())
3748 0 : pResParameter->second >>= ffres;
3749 : else
3750 0 : ffres = 0;
3751 : }
3752 0 : aFldHeader.bits |= ( (ffres<<2) & 0x7C );
3753 :
3754 0 : std::vector< OUString > aListItems;
3755 0 : if (type==2)
3756 : {
3757 0 : aFldHeader.bits |= 0x8000; // ffhaslistbox
3758 0 : const ::sw::mark::IFieldmark::parameter_map_t* const pParameters = rFieldmark.GetParameters();
3759 0 : ::sw::mark::IFieldmark::parameter_map_t::const_iterator pListEntries = pParameters->find(ODF_FORMDROPDOWN_LISTENTRY);
3760 0 : if(pListEntries != pParameters->end())
3761 : {
3762 0 : uno::Sequence< OUString > vListEntries;
3763 0 : pListEntries->second >>= vListEntries;
3764 0 : copy(vListEntries.begin(), vListEntries.end(), back_inserter(aListItems));
3765 : }
3766 : }
3767 :
3768 0 : const OUString ffdeftext;
3769 0 : const OUString ffformat;
3770 0 : const OUString ffhelptext;
3771 0 : const OUString ffstattext;
3772 0 : const OUString ffentrymcr;
3773 0 : const OUString ffexitmcr;
3774 :
3775 : const sal_uInt8 aFldData[] =
3776 : {
3777 : 0x44,0, // the start of "next" data
3778 : 0,0,0,0,0,0,0,0,0,0, // PIC-Structure! /10
3779 : 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // | /16
3780 : 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // | /16
3781 : 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // | /16
3782 : 0,0,0,0, // / /4
3783 0 : };
3784 : sal_uInt32 slen = sizeof(sal_uInt32)
3785 0 : + sizeof(aFldData)
3786 0 : + sizeof( aFldHeader.version ) + sizeof( aFldHeader.bits ) + sizeof( aFldHeader.cch ) + sizeof( aFldHeader.hps )
3787 0 : + 2*ffname.getLength() + 4
3788 0 : + 2*ffformat.getLength() + 4
3789 0 : + 2*ffhelptext.getLength() + 4
3790 0 : + 2*ffstattext.getLength() + 4
3791 0 : + 2*ffentrymcr.getLength() + 4
3792 0 : + 2*ffexitmcr.getLength() + 4;
3793 0 : if ( type )
3794 0 : slen += 2; // wDef
3795 : else
3796 0 : slen += 2*ffdeftext.getLength() + 4; //xstzTextDef
3797 0 : if ( type==2 ) {
3798 0 : slen += 2; // sttb ( fExtend )
3799 0 : slen += 4; // for num of list items
3800 0 : const int items = aListItems.size();
3801 0 : for( int i = 0; i < items; i++ ) {
3802 0 : OUString item = aListItems[i];
3803 0 : slen += 2 * item.getLength() + 2;
3804 0 : }
3805 : }
3806 :
3807 0 : pDataStrm->WriteUInt32( slen );
3808 :
3809 0 : int len = sizeof( aFldData );
3810 : OSL_ENSURE( len == 0x44-sizeof(sal_uInt32), "SwWW8Writer::WriteFormData(..) - wrong aFldData length" );
3811 0 : pDataStrm->Write( aFldData, len );
3812 :
3813 0 : pDataStrm->WriteUInt32( aFldHeader.version ).WriteUInt16( aFldHeader.bits ).WriteUInt16( aFldHeader.cch ).WriteUInt16( aFldHeader.hps );
3814 :
3815 0 : SwWW8Writer::WriteString_xstz( *pDataStrm, ffname, true ); // Form field name
3816 :
3817 0 : if ( !type )
3818 0 : SwWW8Writer::WriteString_xstz( *pDataStrm, ffdeftext, true );
3819 0 : if ( type )
3820 0 : pDataStrm->WriteUInt16( sal_uInt16(0) );
3821 :
3822 0 : SwWW8Writer::WriteString_xstz( *pDataStrm, OUString( ffformat ), true );
3823 0 : SwWW8Writer::WriteString_xstz( *pDataStrm, OUString( ffhelptext ), true );
3824 0 : SwWW8Writer::WriteString_xstz( *pDataStrm, OUString( ffstattext ), true );
3825 0 : SwWW8Writer::WriteString_xstz( *pDataStrm, OUString( ffentrymcr ), true );
3826 0 : SwWW8Writer::WriteString_xstz( *pDataStrm, OUString( ffexitmcr ), true );
3827 0 : if (type==2) {
3828 0 : pDataStrm->WriteUInt16( (sal_uInt16)0xFFFF );
3829 0 : const int items=aListItems.size();
3830 0 : pDataStrm->WriteUInt32( (sal_uInt32)items );
3831 0 : for(int i=0;i<items;i++) {
3832 0 : OUString item=aListItems[i];
3833 0 : SwWW8Writer::WriteString_xstz( *pDataStrm, item, false );
3834 0 : }
3835 0 : }
3836 : }
3837 :
3838 0 : void WW8Export::WriteHyperlinkData( const sw::mark::IFieldmark& /*rFieldmark*/ )
3839 : {
3840 : //@TODO implement me !!!
3841 0 : }
3842 :
3843 254 : void WW8AttributeOutput::TableNodeInfoInner( ww8::WW8TableNodeInfoInner::Pointer_t pNodeInfoInner )
3844 : {
3845 : SVBT16 nStyle;
3846 254 : ShortToSVBT16( m_rWW8Export.nStyleBeforeFly, nStyle );
3847 :
3848 : #ifdef DBG_UTIL
3849 : SAL_INFO( "sw.ww8", "<OutWW8_TableNodeInfoInner>" << pNodeInfoInner->toString());
3850 : #endif
3851 :
3852 254 : m_rWW8Export.pO->clear();
3853 :
3854 254 : sal_uInt32 nShadowsBefore = pNodeInfoInner->getShadowsBefore();
3855 254 : if (nShadowsBefore > 0)
3856 : {
3857 : ww8::WW8TableNodeInfoInner::Pointer_t
3858 0 : pTmpNodeInfoInner(new ww8::WW8TableNodeInfoInner(NULL));
3859 :
3860 0 : pTmpNodeInfoInner->setDepth(pNodeInfoInner->getDepth());
3861 0 : pTmpNodeInfoInner->setEndOfCell(true);
3862 :
3863 0 : for (sal_uInt32 n = 0; n < nShadowsBefore; ++n)
3864 : {
3865 0 : m_rWW8Export.WriteCR(pTmpNodeInfoInner);
3866 :
3867 0 : m_rWW8Export.pO->insert( m_rWW8Export.pO->end(), (sal_uInt8*)&nStyle, (sal_uInt8*)&nStyle+2 ); // Style #
3868 0 : TableInfoCell(pTmpNodeInfoInner);
3869 : m_rWW8Export.pPapPlc->AppendFkpEntry
3870 0 : ( m_rWW8Export.Strm().Tell(), m_rWW8Export.pO->size(), m_rWW8Export.pO->data() );
3871 :
3872 0 : m_rWW8Export.pO->clear();
3873 0 : }
3874 : }
3875 :
3876 254 : if (pNodeInfoInner->isEndOfCell())
3877 : {
3878 : SAL_INFO( "sw.ww8", "<endOfCell/>" );
3879 :
3880 0 : m_rWW8Export.WriteCR(pNodeInfoInner);
3881 :
3882 0 : m_rWW8Export.pO->insert( m_rWW8Export.pO->end(), (sal_uInt8*)&nStyle, (sal_uInt8*)&nStyle+2 ); // Style #
3883 0 : TableInfoCell(pNodeInfoInner);
3884 0 : m_rWW8Export.pPapPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), m_rWW8Export.pO->size(), m_rWW8Export.pO->data() );
3885 :
3886 0 : m_rWW8Export.pO->clear();
3887 : }
3888 :
3889 254 : sal_uInt32 nShadowsAfter = pNodeInfoInner->getShadowsAfter();
3890 254 : if (nShadowsAfter > 0)
3891 : {
3892 : ww8::WW8TableNodeInfoInner::Pointer_t
3893 0 : pTmpNodeInfoInner(new ww8::WW8TableNodeInfoInner(NULL));
3894 :
3895 0 : pTmpNodeInfoInner->setDepth(pNodeInfoInner->getDepth());
3896 0 : pTmpNodeInfoInner->setEndOfCell(true);
3897 :
3898 0 : for (sal_uInt32 n = 0; n < nShadowsAfter; ++n)
3899 : {
3900 0 : m_rWW8Export.WriteCR(pTmpNodeInfoInner);
3901 :
3902 0 : m_rWW8Export.pO->insert( m_rWW8Export.pO->end(), (sal_uInt8*)&nStyle, (sal_uInt8*)&nStyle+2 ); // Style #
3903 0 : TableInfoCell(pTmpNodeInfoInner);
3904 0 : m_rWW8Export.pPapPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), m_rWW8Export.pO->size(), m_rWW8Export.pO->data() );
3905 :
3906 0 : m_rWW8Export.pO->clear();
3907 0 : }
3908 : }
3909 :
3910 254 : if (pNodeInfoInner->isEndOfLine())
3911 : {
3912 : SAL_INFO( "sw.ww8", "<endOfLine/>" );
3913 :
3914 0 : TableRowEnd(pNodeInfoInner->getDepth());
3915 :
3916 0 : ShortToSVBT16(0, nStyle);
3917 0 : m_rWW8Export.pO->insert( m_rWW8Export.pO->end(), (sal_uInt8*)&nStyle, (sal_uInt8*)&nStyle+2 ); // Style #
3918 0 : TableInfoRow(pNodeInfoInner);
3919 0 : m_rWW8Export.pPapPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), m_rWW8Export.pO->size(), m_rWW8Export.pO->data() );
3920 :
3921 0 : m_rWW8Export.pO->clear();
3922 : }
3923 : SAL_INFO( "sw.ww8", "</OutWW8_TableNodeInfoInner>" );
3924 254 : }
3925 :
3926 2005 : void MSWordExportBase::OutputStartNode( const SwStartNode & rNode)
3927 : {
3928 :
3929 : ww8::WW8TableNodeInfo::Pointer_t pNodeInfo =
3930 2005 : mpTableInfo->getTableNodeInfo( &rNode );
3931 :
3932 2005 : if (pNodeInfo.get() != NULL)
3933 : {
3934 : #ifdef DBG_UTIL
3935 : SAL_INFO( "sw.ww8", pNodeInfo->toString());
3936 : #endif
3937 1665 : const ww8::WW8TableNodeInfo::Inners_t aInners = pNodeInfo->getInners();
3938 1665 : ww8::WW8TableNodeInfo::Inners_t::const_reverse_iterator aIt(aInners.rbegin());
3939 1665 : ww8::WW8TableNodeInfo::Inners_t::const_reverse_iterator aEnd(aInners.rend());
3940 5102 : while (aIt != aEnd)
3941 : {
3942 1772 : ww8::WW8TableNodeInfoInner::Pointer_t pInner = aIt->second;
3943 :
3944 1772 : AttrOutput().TableNodeInfoInner(pInner);
3945 1772 : ++aIt;
3946 3437 : }
3947 : }
3948 2005 : SAL_INFO( "sw.ww8", "</OutWW8_SwStartNode>" );
3949 2005 : }
3950 :
3951 2082 : void MSWordExportBase::OutputEndNode( const SwEndNode &rNode )
3952 : {
3953 : #ifdef DBG_UTIL
3954 : SAL_INFO( "sw.ww8", "<OutWW8_SwEndNode>" << dbg_out(&rNode));
3955 : #endif
3956 :
3957 2082 : ww8::WW8TableNodeInfo::Pointer_t pNodeInfo = mpTableInfo->getTableNodeInfo( &rNode );
3958 :
3959 2082 : if (pNodeInfo.get() != NULL)
3960 : {
3961 : #ifdef DBG_UTIL
3962 : SAL_INFO( "sw.ww8", pNodeInfo->toString());
3963 : #endif
3964 :
3965 1653 : const ww8::WW8TableNodeInfo::Inners_t aInners = pNodeInfo->getInners();
3966 1653 : ww8::WW8TableNodeInfo::Inners_t::const_iterator aIt(aInners.begin());
3967 1653 : ww8::WW8TableNodeInfo::Inners_t::const_iterator aEnd(aInners.end());
3968 5072 : while (aIt != aEnd)
3969 : {
3970 1766 : ww8::WW8TableNodeInfoInner::Pointer_t pInner = aIt->second;
3971 1766 : AttrOutput().TableNodeInfoInner(pInner);
3972 1766 : ++aIt;
3973 3419 : }
3974 : }
3975 2082 : SAL_INFO( "sw.ww8", "</OutWW8_SwEndNode>" );
3976 2082 : }
3977 :
3978 4 : const NfKeywordTable & MSWordExportBase::GetNfKeywordTable()
3979 : {
3980 4 : if (pKeyMap.get() == NULL)
3981 : {
3982 4 : pKeyMap.reset(new NfKeywordTable);
3983 4 : NfKeywordTable & rKeywordTable = *pKeyMap;
3984 4 : rKeywordTable[NF_KEY_D] = "d";
3985 4 : rKeywordTable[NF_KEY_DD] = "dd";
3986 4 : rKeywordTable[NF_KEY_DDD] = "ddd";
3987 4 : rKeywordTable[NF_KEY_DDDD] = "dddd";
3988 4 : rKeywordTable[NF_KEY_M] = "M";
3989 4 : rKeywordTable[NF_KEY_MM] = "MM";
3990 4 : rKeywordTable[NF_KEY_MMM] = "MMM";
3991 4 : rKeywordTable[NF_KEY_MMMM] = "MMMM";
3992 4 : rKeywordTable[NF_KEY_NN] = "ddd";
3993 4 : rKeywordTable[NF_KEY_NNN] = "dddd";
3994 4 : rKeywordTable[NF_KEY_NNNN] = "dddd";
3995 4 : rKeywordTable[NF_KEY_YY] = "yy";
3996 4 : rKeywordTable[NF_KEY_YYYY] = "yyyy";
3997 4 : rKeywordTable[NF_KEY_H] = "H";
3998 4 : rKeywordTable[NF_KEY_HH] = "HH";
3999 4 : rKeywordTable[NF_KEY_MI] = "m";
4000 4 : rKeywordTable[NF_KEY_MMI] = "mm";
4001 4 : rKeywordTable[NF_KEY_S] = "s";
4002 4 : rKeywordTable[NF_KEY_SS] = "ss";
4003 4 : rKeywordTable[NF_KEY_AMPM] = "AM/PM";
4004 : }
4005 :
4006 4 : return *pKeyMap;
4007 33 : }
4008 :
4009 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|