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