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