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