Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include <vector>
31 : : #include <list>
32 : : #include <utility>
33 : : #include <algorithm>
34 : : #include <functional>
35 : : #include <iostream>
36 : :
37 : : #include <hintids.hxx>
38 : : #include <comphelper/string.hxx>
39 : : #include <tools/urlobj.hxx>
40 : : #include <editeng/boxitem.hxx>
41 : : #include <editeng/cmapitem.hxx>
42 : : #include <editeng/langitem.hxx>
43 : : #include <editeng/svxfont.hxx>
44 : : #include <editeng/lrspitem.hxx>
45 : : #include <editeng/brshitem.hxx>
46 : : #include <editeng/fontitem.hxx>
47 : : #include <editeng/keepitem.hxx>
48 : : #include <editeng/fhgtitem.hxx>
49 : : #include <editeng/ulspitem.hxx>
50 : : #include <editeng/brkitem.hxx>
51 : : #include <editeng/frmdiritem.hxx>
52 : : #include <editeng/tstpitem.hxx>
53 : : #include "svl/urihelper.hxx"
54 : : #include <svl/whiter.hxx>
55 : : #include <fmtpdsc.hxx>
56 : : #include <fmtfsize.hxx>
57 : : #include <fmtornt.hxx>
58 : : #include <fmtlsplt.hxx>
59 : : #include <fmtflcnt.hxx>
60 : : #include <fmtanchr.hxx>
61 : : #include <fmtcntnt.hxx>
62 : : #include <frmatr.hxx>
63 : : #include <paratr.hxx>
64 : : #include <txatbase.hxx>
65 : : #include <fmtinfmt.hxx>
66 : : #include <fmtrfmrk.hxx>
67 : : #include <fchrfmt.hxx>
68 : : #include <fmtautofmt.hxx>
69 : : #include <charfmt.hxx>
70 : : #include <tox.hxx>
71 : : #include <ndtxt.hxx>
72 : : #include <pam.hxx>
73 : : #include <doc.hxx>
74 : : #include <docary.hxx>
75 : : #include <swtable.hxx>
76 : : #include <swtblfmt.hxx>
77 : : #include <section.hxx>
78 : : #include <pagedesc.hxx>
79 : : #include <swrect.hxx>
80 : : #include <reffld.hxx>
81 : : #include <redline.hxx>
82 : : #include <wrtswtbl.hxx>
83 : : #include <htmltbl.hxx>
84 : : #include <txttxmrk.hxx>
85 : : #include <fmtline.hxx>
86 : : #include <fmtruby.hxx>
87 : : #include <breakit.hxx>
88 : : #include <txtatr.hxx>
89 : : #include <fmtsrnd.hxx>
90 : : #include <fmtrowsplt.hxx>
91 : : #include <com/sun/star/i18n/ScriptType.hpp>
92 : : #include <com/sun/star/i18n/WordType.hpp>
93 : :
94 : : #include <writerfilter/doctok/sprmids.hxx>
95 : :
96 : : #include "writerhelper.hxx"
97 : : #include "writerwordglue.hxx"
98 : : #include <numrule.hxx>
99 : : #include "wrtww8.hxx"
100 : : #include "ww8par.hxx"
101 : : #include <IMark.hxx>
102 : : #include "ww8attributeoutput.hxx"
103 : :
104 : : #include <ndgrf.hxx>
105 : : #include <ndole.hxx>
106 : :
107 : : #include <cstdio>
108 : :
109 : : using namespace ::com::sun::star;
110 : : using namespace ::com::sun::star::i18n;
111 : : using namespace sw::util;
112 : : using namespace sw::types;
113 : : using namespace sw::mark;
114 : : using namespace nsFieldFlags;
115 : :
116 : 6 : static String lcl_getFieldCode( const IFieldmark* pFieldmark ) {
117 : : OSL_ENSURE(pFieldmark!=NULL, "where is my fieldmark???");
118 : :
119 [ - + ]: 6 : if ( !pFieldmark) {
120 : 0 : return String();
121 [ - + ]: 6 : } else if ( pFieldmark->GetFieldname( ) == ODF_FORMTEXT ) {
122 [ # # ]: 0 : return rtl::OUString(" FORMTEXT ");
123 [ - + ]: 6 : } else if ( pFieldmark->GetFieldname( ) == ODF_FORMDROPDOWN ) {
124 [ # # ]: 0 : return rtl::OUString(" FORMDROPDOWN ");
125 [ - + ]: 6 : } else if ( pFieldmark->GetFieldname( ) == ODF_FORMCHECKBOX ) {
126 [ # # ]: 0 : return rtl::OUString(" FORMCHECKBOX ");
127 [ - + ]: 6 : } else if ( pFieldmark->GetFieldname( ) == ODF_TOC ) {
128 [ # # ]: 0 : return rtl::OUString(" TOC ");
129 [ - + ]: 6 : } else if ( pFieldmark->GetFieldname( ) == ODF_HYPERLINK ) {
130 [ # # ]: 0 : return rtl::OUString(" HYPERLINK ");
131 [ - + ]: 6 : } else if ( pFieldmark->GetFieldname( ) == ODF_PAGEREF ) {
132 [ # # ]: 0 : return rtl::OUString(" PAGEREF ");
133 : : } else {
134 [ + - ]: 6 : return pFieldmark->GetFieldname();
135 : : }
136 : : }
137 : :
138 : 12 : ww::eField lcl_getFieldId( const IFieldmark* pFieldmark ) {
139 : : OSL_ENSURE(pFieldmark!=NULL, "where is my fieldmark???");
140 [ - + ]: 12 : if ( !pFieldmark ) {
141 : 0 : return ww::eUNKNOWN;
142 [ - + ]: 12 : } else if ( pFieldmark->GetFieldname( ) == ODF_FORMTEXT ) {
143 : 0 : return ww::eFORMTEXT;
144 [ - + ]: 12 : } else if ( pFieldmark->GetFieldname( ) == ODF_FORMDROPDOWN ) {
145 : 0 : return ww::eFORMDROPDOWN;
146 [ - + ]: 12 : } else if ( pFieldmark->GetFieldname( ) == ODF_FORMCHECKBOX ) {
147 : 0 : return ww::eFORMCHECKBOX;
148 [ - + ]: 12 : } else if ( pFieldmark->GetFieldname( ) == ODF_TOC ) {
149 : 0 : return ww::eTOC;
150 [ - + ]: 12 : } else if ( pFieldmark->GetFieldname( ) == ODF_HYPERLINK ) {
151 : 0 : return ww::eHYPERLINK;
152 [ - + ]: 12 : } else if ( pFieldmark->GetFieldname( ) == ODF_PAGEREF ) {
153 : 0 : return ww::ePAGEREF;
154 : : } else {
155 : 12 : return ww::eUNKNOWN;
156 : : }
157 : : }
158 : :
159 : 303 : MSWordAttrIter::MSWordAttrIter( MSWordExportBase& rExport )
160 : 303 : : pOld( rExport.pChpIter ), m_rExport( rExport )
161 : : {
162 : 303 : m_rExport.pChpIter = this;
163 : 303 : }
164 : :
165 : 303 : MSWordAttrIter::~MSWordAttrIter()
166 : : {
167 : 303 : m_rExport.pChpIter = pOld;
168 [ - + ]: 303 : }
169 : :
170 : : class sortswflys :
171 : : public std::binary_function<const sw::Frame&, const sw::Frame&, bool>
172 : : {
173 : : public:
174 : 0 : bool operator()(const sw::Frame &rOne, const sw::Frame &rTwo) const
175 : : {
176 : 0 : return rOne.GetPosition() < rTwo.GetPosition();
177 : : }
178 : : };
179 : :
180 : 681 : void SwWW8AttrIter::IterToCurrent()
181 : : {
182 : : OSL_ENSURE(maCharRuns.begin() != maCharRuns.end(), "Impossible");
183 : 681 : mnScript = maCharRunIter->mnScript;
184 : 681 : meChrSet = maCharRunIter->meCharSet;
185 : 681 : mbCharIsRTL = maCharRunIter->mbRTL;
186 : 681 : }
187 : :
188 : 300 : SwWW8AttrIter::SwWW8AttrIter(MSWordExportBase& rWr, const SwTxtNode& rTxtNd) :
189 : : MSWordAttrIter(rWr),
190 : : rNd(rTxtNd),
191 [ + - ]: 300 : maCharRuns(GetPseudoCharRuns(rTxtNd, 0, !rWr.SupportsUnicode())),
192 : : pCurRedline(0),
193 : : nAktSwPos(0),
194 : : nCurRedlinePos(USHRT_MAX),
195 [ + - ][ + - ]: 600 : mrSwFmtDrop(rTxtNd.GetSwAttrSet().GetDrop())
[ + - ][ + - ]
196 : : {
197 : :
198 [ + - ]: 300 : SwPosition aPos(rTxtNd);
199 [ + - ][ - + ]: 300 : if (FRMDIR_HORI_RIGHT_TOP == rWr.pDoc->GetTextDirection(aPos))
200 : 0 : mbParaIsRTL = true;
201 : : else
202 : 300 : mbParaIsRTL = false;
203 : :
204 [ + - ]: 300 : maCharRunIter = maCharRuns.begin();
205 [ + - ]: 300 : IterToCurrent();
206 : :
207 : : /*
208 : : #i2916#
209 : : Get list of any graphics which may be anchored from this paragraph.
210 : : */
211 [ + - ]: 300 : maFlyFrms = GetFramesInNode(rWr.maFrames, rNd);
212 [ + - ]: 300 : std::sort(maFlyFrms.begin(), maFlyFrms.end(), sortswflys());
213 : :
214 : : /*
215 : : #i18480#
216 : : If we are inside a frame then anything anchored inside this frame can
217 : : only be supported by word anchored inline ("as character"), so force
218 : : this in the supportable case.
219 : : */
220 [ + - ][ + - ]: 300 : if (rWr.SupportsUnicode() && rWr.bInWriteEscher)
[ - + ][ - + ]
221 : : {
222 : : std::for_each(maFlyFrms.begin(), maFlyFrms.end(),
223 [ # # ][ # # ]: 0 : std::mem_fun_ref(&sw::Frame::ForceTreatAsInline));
224 : : }
225 : :
226 : 300 : maFlyIter = maFlyFrms.begin();
227 : :
228 [ - + ][ + - ]: 300 : if ( !m_rExport.pDoc->GetRedlineTbl().empty() )
229 : : {
230 [ # # ][ # # ]: 0 : SwPosition aPosition( rNd, SwIndex( (SwTxtNode*)&rNd ) );
[ # # ][ # # ]
[ # # ]
231 [ # # ][ # # ]: 0 : pCurRedline = m_rExport.pDoc->GetRedline( aPosition, &nCurRedlinePos );
232 : : }
233 : :
234 [ + - ][ + - ]: 300 : nAktSwPos = SearchNext(1);
235 : 300 : }
236 : :
237 : 1362 : xub_StrLen lcl_getMinPos( xub_StrLen pos1, xub_StrLen pos2 )
238 : : {
239 : 1362 : xub_StrLen min = STRING_NOTFOUND;
240 [ + + ][ - + ]: 1362 : if ( pos1 == STRING_NOTFOUND && pos2 != STRING_NOTFOUND )
241 : 0 : min = pos2;
242 [ + + ][ + + ]: 1362 : else if ( pos2 == STRING_NOTFOUND && pos1 != STRING_NOTFOUND )
243 : 18 : min = pos1;
244 [ + + ][ + - ]: 1344 : else if ( pos1 != STRING_NOTFOUND && pos2 != STRING_NOTFOUND )
245 : : {
246 [ - + ]: 6 : if ( pos1 < pos2 )
247 : 0 : min = pos1;
248 : : else
249 : 6 : min = pos2;
250 : : }
251 : :
252 : 1362 : return min;
253 : : }
254 : :
255 : 681 : xub_StrLen SwWW8AttrIter::SearchNext( xub_StrLen nStartPos )
256 : : {
257 : : xub_StrLen nPos;
258 : 681 : xub_StrLen nMinPos = STRING_MAXLEN;
259 : 681 : xub_StrLen i=0;
260 : :
261 [ + - ]: 681 : const String aTxt = rNd.GetTxt();
262 [ + - ]: 681 : xub_StrLen fieldEndPos = aTxt.Search(CH_TXT_ATR_FIELDEND, nStartPos);
263 [ + - ]: 681 : xub_StrLen fieldStartPos = aTxt.Search(CH_TXT_ATR_FIELDSTART, nStartPos);
264 [ + - ]: 681 : xub_StrLen formElementPos = aTxt.Search(CH_TXT_ATR_FORMELEMENT, nStartPos);
265 : :
266 : 681 : xub_StrLen pos = lcl_getMinPos( fieldEndPos, fieldStartPos );
267 : 681 : pos = lcl_getMinPos( pos, formElementPos );
268 : :
269 [ + + ]: 681 : if (pos!=STRING_NOTFOUND)
270 : 12 : nMinPos=pos;
271 : :
272 : : // first the redline, then the attributes
273 [ - + ]: 681 : if( pCurRedline )
274 : : {
275 [ # # ]: 0 : const SwPosition* pEnd = pCurRedline->End();
276 [ # # ][ # # ]: 0 : if (pEnd->nNode == rNd && ((i = pEnd->nContent.GetIndex()) >= nStartPos) && i < nMinPos )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # # ]
277 : 0 : nMinPos = i;
278 : : }
279 : :
280 [ + - ][ - + ]: 681 : if ( nCurRedlinePos < m_rExport.pDoc->GetRedlineTbl().size() )
281 : : {
282 : : // nCurRedlinePos point to the next redline
283 : 0 : nPos = nCurRedlinePos;
284 [ # # ]: 0 : if( pCurRedline )
285 : 0 : ++nPos;
286 : :
287 [ # # ][ # # ]: 0 : for ( ; nPos < m_rExport.pDoc->GetRedlineTbl().size(); ++nPos )
288 : : {
289 [ # # ][ # # ]: 0 : const SwRedline* pRedl = m_rExport.pDoc->GetRedlineTbl()[ nPos ];
290 : :
291 [ # # ]: 0 : const SwPosition* pStt = pRedl->Start();
292 : 0 : const SwPosition* pEnd = pStt == pRedl->GetPoint()
293 : 0 : ? pRedl->GetMark()
294 [ # # ]: 0 : : pRedl->GetPoint();
295 : :
296 [ # # ][ # # ]: 0 : if( pStt->nNode == rNd )
[ # # ]
297 : : {
298 [ # # ][ # # ]: 0 : if( ( i = pStt->nContent.GetIndex() ) >= nStartPos &&
[ # # ]
299 : : i < nMinPos )
300 : 0 : nMinPos = i;
301 : : }
302 : : else
303 : 0 : break;
304 : :
305 [ # # ][ # # ]: 0 : if( pEnd->nNode == rNd &&
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # # ]
306 : 0 : ( i = pEnd->nContent.GetIndex() ) < nMinPos &&
307 : : i >= nStartPos )
308 : 0 : nMinPos = i;
309 : : }
310 : : }
311 : :
312 : :
313 [ - + ][ # # ]: 681 : if (mrSwFmtDrop.GetWholeWord() && nStartPos <= rNd.GetDropLen(0))
[ # # ][ - + ]
314 [ # # ]: 0 : nMinPos = rNd.GetDropLen(0);
315 [ - + ]: 681 : else if(nStartPos <= mrSwFmtDrop.GetChars())
316 : 0 : nMinPos = mrSwFmtDrop.GetChars();
317 : :
318 [ + + ]: 681 : if(const SwpHints* pTxtAttrs = rNd.GetpSwpHints())
319 : : {
320 : :
321 : : // kann noch optimiert werden, wenn ausgenutzt wird, dass die TxtAttrs
322 : : // nach der Anfangsposition geordnet sind. Dann muessten
323 : : // allerdings noch 2 Indices gemerkt werden
324 [ + + ]: 1320 : for( i = 0; i < pTxtAttrs->Count(); i++ )
325 : : {
326 [ + - ]: 876 : const SwTxtAttr* pHt = (*pTxtAttrs)[i];
327 : 876 : nPos = *pHt->GetStart(); // gibt erstes Attr-Zeichen
328 [ + + ][ + + ]: 876 : if( nPos >= nStartPos && nPos <= nMinPos )
329 : 87 : nMinPos = nPos;
330 : :
331 [ + - ][ + + ]: 876 : if( pHt->GetEnd() ) // Attr mit Ende
332 : : {
333 [ + - ]: 75 : nPos = *pHt->GetEnd(); // gibt letztes Attr-Zeichen + 1
334 [ + + ][ + + ]: 75 : if( nPos >= nStartPos && nPos <= nMinPos )
335 : 36 : nMinPos = nPos;
336 : : }
337 [ + + ]: 876 : if (pHt->HasDummyChar())
338 : : {
339 : : // pos + 1 because of CH_TXTATR in Text
340 : 801 : nPos = *pHt->GetStart() + 1;
341 [ + + ][ + + ]: 801 : if( nPos >= nStartPos && nPos <= nMinPos )
342 : 222 : nMinPos = nPos;
343 : : }
344 : : }
345 : : }
346 : :
347 [ + - ][ + + ]: 681 : if (maCharRunIter != maCharRuns.end())
348 : : {
349 [ + + ]: 381 : if (maCharRunIter->mnEndPos < nMinPos)
350 : 126 : nMinPos = maCharRunIter->mnEndPos;
351 [ + - ]: 381 : IterToCurrent();
352 : : }
353 : :
354 : : /*
355 : : #i2916#
356 : : Check to see if there are any graphics anchored to characters in this
357 : : paragraph's text. Set nMinPos to 1 past the placement for anchored to
358 : : character because anchors in Word appear after the character they are
359 : : anchored to.
360 : : */
361 [ + - ][ + + ]: 681 : if (maFlyIter != maFlyFrms.end())
362 : : {
363 : 9 : const SwPosition &rAnchor = maFlyIter->GetPosition();
364 : :
365 : 9 : nPos = rAnchor.nContent.GetIndex();
366 [ # # ][ - + ]: 9 : if (nPos >= nStartPos && nPos <= nMinPos)
367 : 0 : nMinPos = nPos;
368 : :
369 [ + - ][ + + ]: 9 : if (maFlyIter->GetFrmFmt().GetAnchor().GetAnchorId() == FLY_AT_CHAR)
370 : : {
371 : 3 : ++nPos;
372 [ + - ][ + - ]: 3 : if (nPos >= nStartPos && nPos <= nMinPos)
373 : 3 : nMinPos = nPos;
374 : : }
375 : : }
376 : :
377 : : //nMinPos found and not going to change at this point
378 : :
379 [ + - ][ + + ]: 681 : if (maCharRunIter != maCharRuns.end())
380 : : {
381 [ + + ]: 381 : if (maCharRunIter->mnEndPos == nMinPos)
382 : 300 : ++maCharRunIter;
383 : : }
384 : :
385 [ + - ]: 681 : return nMinPos;
386 : : }
387 : :
388 : 0 : bool lcl_isFontsizeItem( const SfxPoolItem& rItem )
389 : : {
390 : 0 : return ( rItem.Which( ) == RES_CHRATR_FONTSIZE ||
391 : 0 : rItem.Which( ) == RES_CHRATR_CJK_FONTSIZE ||
392 [ # # ]: 0 : rItem.Which( ) == RES_CHRATR_CTL_FONTSIZE );
[ # # # # ]
393 : : }
394 : :
395 : 384 : void SwWW8AttrIter::OutAttr( xub_StrLen nSwPos, bool bRuby )
396 : : {
397 [ + - ][ + - ]: 384 : m_rExport.AttrOutput().RTLAndCJKState( IsCharRTL(), GetScript() );
398 : :
399 : : /*
400 : : Depending on whether text is in CTL/CJK or Western, get the id of that
401 : : script, the idea is that the font that is actually in use to render this
402 : : range of text ends up in pFont
403 : : */
404 [ + - ]: 384 : sal_uInt16 nFontId = GetWhichOfScript( RES_CHRATR_FONT, GetScript() );
405 : :
406 : : const SvxFontItem &rParentFont = ItemGet<SvxFontItem>(
407 [ + - ]: 384 : (const SwTxtFmtColl&)rNd.GetAnyFmtColl(), nFontId);
408 : 384 : const SvxFontItem *pFont = &rParentFont;
409 : :
410 [ + - ]: 384 : SfxItemSet aExportSet(*rNd.GetSwAttrSet().GetPool(),
411 [ + - ]: 384 : RES_CHRATR_BEGIN, RES_TXTATR_END - 1);
412 : :
413 : : //The hard formatting properties that affect the entire paragraph
414 [ + - ][ + + ]: 384 : if (rNd.HasSwAttrSet())
415 : : {
416 : 270 : sal_Bool bDeep = sal_False;
417 : : // only copy hard attributes - bDeep = false
418 [ + - ][ + - ]: 270 : aExportSet.Set(rNd.GetSwAttrSet(), bDeep);
419 : : // get the current font item. Use rNd.GetSwAttrSet instead of aExportSet:
420 [ + - ][ + - ]: 270 : const SvxFontItem &rNdFont = ItemGet<SvxFontItem>(rNd.GetSwAttrSet(), nFontId);
421 : 270 : pFont = &rNdFont;
422 [ + - ]: 270 : aExportSet.ClearItem(nFontId);
423 : : }
424 : :
425 : : //The additional hard formatting properties that affect this range in the
426 : : //paragraph
427 [ + - ]: 384 : sw::PoolItems aRangeItems;
428 [ + + ]: 384 : if (const SwpHints* pTxtAttrs = rNd.GetpSwpHints())
429 : : {
430 [ + + ]: 768 : for (xub_StrLen i = 0; i < pTxtAttrs->Count(); ++i)
431 : : {
432 [ + - ]: 504 : const SwTxtAttr* pHt = (*pTxtAttrs)[i];
433 [ + - ]: 504 : const xub_StrLen* pEnd = pHt->GetEnd();
434 : :
435 [ + + ][ + + ]: 969 : if (pEnd ? ( nSwPos >= *pHt->GetStart() && nSwPos < *pEnd)
[ + - ][ + + ]
436 : 465 : : nSwPos == *pHt->GetStart() )
437 : : {
438 : 231 : sal_uInt16 nWhich = pHt->GetAttr().Which();
439 [ + + ]: 231 : if (nWhich == RES_TXTATR_AUTOFMT)
440 : : {
441 : 6 : const SwFmtAutoFmt& rAutoFmt = static_cast<const SwFmtAutoFmt&>(pHt->GetAttr());
442 [ + - ]: 6 : const boost::shared_ptr<SfxItemSet> pSet = rAutoFmt.GetStyleHandle();
443 [ + - ]: 6 : SfxWhichIter aIter( *pSet );
444 : : const SfxPoolItem* pItem;
445 [ + - ]: 6 : sal_uInt16 nWhichId = aIter.FirstWhich();
446 [ + + ]: 258 : while( nWhichId )
447 : : {
448 [ + - ][ + + ]: 252 : if( SFX_ITEM_SET == pSet->GetItemState( nWhichId, sal_False, &pItem ))
449 : : {
450 [ + + ]: 15 : if (nWhichId == nFontId)
451 [ + - ]: 3 : pFont = &(item_cast<SvxFontItem>(*pItem));
452 : : else
453 [ + - ]: 12 : aRangeItems[nWhichId] = pItem;
454 : : }
455 [ + - ]: 252 : nWhichId = aIter.NextWhich();
456 [ + - ][ + - ]: 6 : }
457 : : }
458 : : else
459 [ + - ]: 231 : aRangeItems[nWhich] = (&(pHt->GetAttr()));
460 : : }
461 [ + + ]: 273 : else if (nSwPos < *pHt->GetStart())
462 : 102 : break;
463 : : }
464 : : }
465 : :
466 : : /*
467 : : For #i24291# we need to explictly remove any properties from the
468 : : aExportSet which a SwCharFmt would override, we can't rely on word doing
469 : : this for us like writer does
470 : : */
471 : : const SwFmtCharFmt *pCharFmtItem =
472 [ + - ]: 384 : HasItem< SwFmtCharFmt >( aRangeItems, RES_TXTATR_CHARFMT );
473 [ - + ]: 384 : if ( pCharFmtItem )
474 [ # # ]: 0 : ClearOverridesFromSet( *pCharFmtItem, aExportSet );
475 : :
476 [ + - ]: 384 : sw::PoolItems aExportItems;
477 [ + - ]: 384 : GetPoolItems( aExportSet, aExportItems, false );
478 : :
479 [ + - ]: 384 : sw::cPoolItemIter aEnd = aRangeItems.end();
480 [ + - ][ + - ]: 621 : for ( sw::cPoolItemIter aI = aRangeItems.begin(); aI != aEnd; ++aI )
[ + - ][ + + ]
481 : : {
482 [ - + ][ # # ]: 237 : if ( !bRuby || !lcl_isFontsizeItem( *aI->second ) )
[ # # ][ + - ]
483 [ + - ][ + - ]: 237 : aExportItems[aI->first] = aI->second;
[ + - ]
484 : : }
485 : :
486 [ + + ]: 384 : if ( !aExportItems.empty() )
487 : : {
488 : 300 : const SwModify* pOldMod = m_rExport.pOutFmtNode;
489 : 300 : m_rExport.pOutFmtNode = &rNd;
490 [ + - ]: 300 : m_rExport.m_aCurrentCharPropStarts.push( nSwPos );
491 : :
492 [ + - ]: 300 : m_rExport.ExportPoolItemsToCHP( aExportItems, GetScript() );
493 : :
494 : : // HasTextItem nur in dem obigen Bereich erlaubt
495 [ + - ]: 300 : m_rExport.m_aCurrentCharPropStarts.pop();
496 : 300 : m_rExport.pOutFmtNode = pOldMod;
497 : : }
498 : :
499 : : OSL_ENSURE( pFont, "must be *some* font associated with this txtnode" );
500 [ + - ]: 384 : if ( pFont )
501 : : {
502 [ + - ]: 384 : SvxFontItem aFont( *pFont );
503 : :
504 : : /*
505 : : If we are a nonunicode aware format then we set the charset we want to
506 : : use for export of this range. If necessary this will generate a pseudo
507 : : font to use for this range.
508 : :
509 : : So now we are guaranteed to have a font with the correct charset set
510 : : for WW6/95 which will match the script we have exported this range in,
511 : : this makes older nonunicode aware versions of word display the correct
512 : : characters.
513 : : */
514 [ + - ][ - + ]: 384 : if ( !m_rExport.SupportsUnicode() )
515 : 0 : aFont.SetCharSet( GetCharSet() );
516 : :
517 [ + - ][ + + ]: 384 : if ( rParentFont != aFont )
518 [ + - ][ + - ]: 384 : m_rExport.AttrOutput().OutputItem( aFont );
[ + - ]
519 [ + - ]: 384 : }
520 : 384 : }
521 : :
522 : 684 : void SwWW8AttrIter::OutFlys(xub_StrLen nSwPos)
523 : : {
524 : : /*
525 : : #i2916#
526 : : May have an anchored graphic to be placed, loop through sorted array
527 : : and output all at this position
528 : : */
529 [ + - ][ + + ]: 693 : while ( maFlyIter != maFlyFrms.end() )
530 : : {
531 : 9 : const SwPosition &rAnchor = maFlyIter->GetPosition();
532 : 9 : xub_StrLen nPos = rAnchor.nContent.GetIndex();
533 : :
534 [ - + ]: 9 : if ( nPos != nSwPos )
535 : 0 : break;
536 : : else
537 : : {
538 : 9 : m_rExport.AttrOutput().OutputFlyFrame( *maFlyIter );
539 : 9 : ++maFlyIter;
540 : : }
541 : : }
542 : 684 : }
543 : :
544 : 384 : bool SwWW8AttrIter::IsTxtAttr( xub_StrLen nSwPos )
545 : : {
546 : : // search for attrs with CH_TXTATR
547 [ + + ]: 384 : if (const SwpHints* pTxtAttrs = rNd.GetpSwpHints())
548 : : {
549 [ + + ]: 471 : for (sal_uInt16 i = 0; i < pTxtAttrs->Count(); ++i)
550 : : {
551 : 429 : const SwTxtAttr* pHt = (*pTxtAttrs)[i];
552 [ + + ][ + + ]: 429 : if ( pHt->HasDummyChar() && (*pHt->GetStart() == nSwPos) )
[ + + ]
553 : 222 : return true;
554 : : }
555 : : }
556 : :
557 : 384 : return false;
558 : : }
559 : :
560 : 384 : bool SwWW8AttrIter::IsDropCap( int nSwPos )
561 : : {
562 : : // see if the current position falls on a DropCap
563 : 384 : int nDropChars = mrSwFmtDrop.GetChars();
564 : 384 : bool bWholeWord = mrSwFmtDrop.GetWholeWord();
565 [ - + ]: 384 : if (bWholeWord)
566 : : {
567 : 0 : short nWordLen = rNd.GetDropLen(0);
568 [ # # ][ # # ]: 0 : if(nSwPos == nWordLen && nSwPos != 0)
569 : 0 : return true;
570 : : }
571 : : else
572 : : {
573 [ + + ][ - + ]: 384 : if (nSwPos == nDropChars && nSwPos != 0)
574 : 0 : return true;
575 : : }
576 : 384 : return false;
577 : : }
578 : :
579 : 300 : bool SwWW8AttrIter::RequiresImplicitBookmark()
580 : : {
581 : 300 : SwImplBookmarksIter bkmkIterEnd = m_rExport.maImplicitBookmarks.end();
582 [ # # ][ + - ]: 300 : for ( SwImplBookmarksIter aIter = m_rExport.maImplicitBookmarks.begin(); aIter != bkmkIterEnd; ++aIter )
[ - + ]
583 : : {
584 [ # # ]: 0 : sal_uLong sample = aIter->second;
585 : :
586 [ # # ]: 0 : if ( sample == rNd.GetIndex() )
587 : 0 : return true;
588 : : }
589 : 300 : return false;
590 : : }
591 : :
592 : : // HasItem ist fuer die Zusammenfassung des Doppel-Attributes Underline
593 : : // und WordLineMode als TextItems. OutAttr() ruft die Ausgabefunktion,
594 : : // die dann ueber HasItem() nach anderen Items an der
595 : : // Attribut-Anfangposition fragen kann.
596 : : // Es koennen nur Attribute mit Ende abgefragt werden.
597 : : // Es wird mit bDeep gesucht
598 : 114 : const SfxPoolItem* SwWW8AttrIter::HasTextItem( sal_uInt16 nWhich ) const
599 : : {
600 : 114 : const SfxPoolItem* pRet = 0;
601 : 114 : const SwpHints* pTxtAttrs = rNd.GetpSwpHints();
602 : :
603 [ + - ][ + + ]: 114 : if (pTxtAttrs && !m_rExport.m_aCurrentCharPropStarts.empty())
[ + + ]
604 : : {
605 : 36 : xub_StrLen nTmpSwPos = m_rExport.m_aCurrentCharPropStarts.top();
606 [ + + ]: 72 : for (sal_uInt16 i = 0; i < pTxtAttrs->Count(); ++i)
607 : : {
608 : 36 : const SwTxtAttr* pHt = (*pTxtAttrs)[i];
609 : 36 : const SfxPoolItem* pItem = &pHt->GetAttr();
610 : 36 : const xub_StrLen* pAtrEnd = 0;
611 [ # # ][ - + ]: 48 : if( 0 != ( pAtrEnd = pHt->GetEnd() ) && // nur Attr mit Ende
[ + + - +
# # ]
612 : 12 : nWhich == pItem->Which() && //
613 : 0 : nTmpSwPos >= *pHt->GetStart() && nTmpSwPos < *pAtrEnd )
614 : : {
615 : 0 : pRet = pItem; // gefunden
616 : 0 : break;
617 : : }
618 [ + + ]: 36 : else if (nTmpSwPos < *pHt->GetStart())
619 : 21 : break; // dann kommt da nichts mehr
620 : : }
621 : : }
622 : 114 : return pRet;
623 : : }
624 : :
625 : 9 : void WW8Export::GetCurrentItems(ww::bytes &rItems) const
626 : : {
627 : 9 : rItems.insert(rItems.end(), pO->begin(), pO->end());
628 : 9 : }
629 : :
630 : 114 : const SfxPoolItem& SwWW8AttrIter::GetItem(sal_uInt16 nWhich) const
631 : : {
632 : 114 : const SfxPoolItem* pRet = HasTextItem(nWhich);
633 [ + - ]: 114 : return pRet ? *pRet : rNd.SwCntntNode::GetAttr(nWhich);
634 : : }
635 : :
636 : 0 : void WW8AttributeOutput::StartRuby( const SwTxtNode& rNode, xub_StrLen /*nPos*/, const SwFmtRuby& rRuby )
637 : : {
638 [ # # ]: 0 : String aStr( FieldString( ww::eEQ ) );
639 [ # # ]: 0 : aStr.APPEND_CONST_ASC( "\\* jc" );
640 : 0 : sal_Int32 nJC = 0;
641 : 0 : sal_Char cDirective = 0;
642 [ # # # # : 0 : switch ( rRuby.GetAdjustment() )
# # ]
643 : : {
644 : : case 0:
645 : 0 : nJC = 3;
646 : 0 : cDirective = 'l';
647 : 0 : break;
648 : : case 1:
649 : : //defaults to 0
650 : 0 : break;
651 : : case 2:
652 : 0 : nJC = 4;
653 : 0 : cDirective = 'r';
654 : 0 : break;
655 : : case 3:
656 : 0 : nJC = 1;
657 : 0 : cDirective = 'd';
658 : 0 : break;
659 : : case 4:
660 : 0 : nJC = 2;
661 : 0 : cDirective = 'd';
662 : 0 : break;
663 : : default:
664 : : OSL_ENSURE( !this,"Unhandled Ruby justication code" );
665 : 0 : break;
666 : : }
667 [ # # ][ # # ]: 0 : aStr += String::CreateFromInt32( nJC );
[ # # ]
668 : :
669 : : /*
670 : : MS needs to know the name and size of the font used in the ruby item,
671 : : but we coud have written it in a mixture of asian and western
672 : : scripts, and each of these can be a different font and size than the
673 : : other, so we make a guess based upon the first character of the text,
674 : : defaulting to asian.
675 : : */
676 : : sal_uInt16 nRubyScript;
677 [ # # ][ # # ]: 0 : if( pBreakIt->GetBreakIter().is() )
678 [ # # ][ # # ]: 0 : nRubyScript = pBreakIt->GetBreakIter()->getScriptType( rRuby.GetText(), 0);
[ # # ][ # # ]
679 : : else
680 : 0 : nRubyScript = i18n::ScriptType::ASIAN;
681 : :
682 : 0 : const SwTxtRuby* pRubyTxt = rRuby.GetTxtRuby();
683 [ # # ][ # # ]: 0 : const SwCharFmt* pFmt = pRubyTxt ? pRubyTxt->GetCharFmt() : 0;
684 [ # # ]: 0 : String sFamilyName;
685 : : long nHeight;
686 [ # # ]: 0 : if ( pFmt )
687 : : {
688 : : const SvxFontItem &rFont = ItemGet< SvxFontItem >( *pFmt,
689 [ # # ][ # # ]: 0 : GetWhichOfScript(RES_CHRATR_FONT,nRubyScript) );
690 [ # # ]: 0 : sFamilyName = rFont.GetFamilyName();
691 : :
692 : : const SvxFontHeightItem &rHeight = ItemGet< SvxFontHeightItem >( *pFmt,
693 [ # # ][ # # ]: 0 : GetWhichOfScript( RES_CHRATR_FONTSIZE, nRubyScript ) );
694 : 0 : nHeight = rHeight.GetHeight();
695 : : }
696 : : else
697 : : {
698 : : /*Get defaults if no formatting on ruby text*/
699 : :
700 [ # # ]: 0 : const SfxItemPool *pPool = rNode.GetSwAttrSet().GetPool();
701 [ # # ]: 0 : pPool = pPool ? pPool : &m_rWW8Export.pDoc->GetAttrPool();
702 : :
703 : : const SvxFontItem &rFont = DefaultItemGet< SvxFontItem >( *pPool,
704 [ # # ][ # # ]: 0 : GetWhichOfScript( RES_CHRATR_FONT,nRubyScript ) );
705 [ # # ]: 0 : sFamilyName = rFont.GetFamilyName();
706 : :
707 : : const SvxFontHeightItem &rHeight = DefaultItemGet< SvxFontHeightItem >
708 [ # # ][ # # ]: 0 : ( *pPool, GetWhichOfScript( RES_CHRATR_FONTSIZE, nRubyScript ) );
709 : 0 : nHeight = rHeight.GetHeight();
710 : : }
711 : 0 : nHeight = (nHeight + 5)/10;
712 : :
713 [ # # ]: 0 : aStr.APPEND_CONST_ASC( " \\* \"Font:" );
714 [ # # ]: 0 : aStr.Append( sFamilyName );
715 [ # # ]: 0 : aStr.APPEND_CONST_ASC( "\" \\* hps" );
716 [ # # ][ # # ]: 0 : aStr += String::CreateFromInt32( nHeight );
[ # # ]
717 [ # # ]: 0 : aStr.APPEND_CONST_ASC( " \\o" );
718 [ # # ]: 0 : if ( cDirective )
719 : : {
720 [ # # ]: 0 : aStr.APPEND_CONST_ASC( "\\a" );
721 [ # # ]: 0 : aStr.Append( cDirective );
722 : : }
723 [ # # ]: 0 : aStr.APPEND_CONST_ASC( "(\\s\\up " );
724 : :
725 : :
726 [ # # ][ # # ]: 0 : if ( pBreakIt->GetBreakIter().is() )
727 [ # # ][ # # ]: 0 : nRubyScript = pBreakIt->GetBreakIter()->getScriptType( rNode.GetTxt(),
728 [ # # ][ # # ]: 0 : *( pRubyTxt->GetStart() ) );
729 : : else
730 : 0 : nRubyScript = i18n::ScriptType::ASIAN;
731 : :
732 [ # # ]: 0 : const SwAttrSet& rSet = rNode.GetSwAttrSet();
733 : : const SvxFontHeightItem &rHeightItem =
734 : : ( const SvxFontHeightItem& )rSet.Get(
735 [ # # ][ # # ]: 0 : GetWhichOfScript( RES_CHRATR_FONTSIZE, nRubyScript ) );
736 : 0 : nHeight = (rHeightItem.GetHeight() + 10)/20-1;
737 [ # # ][ # # ]: 0 : aStr += String::CreateFromInt32(nHeight);
[ # # ]
738 [ # # ]: 0 : aStr += '(';
739 [ # # ]: 0 : aStr += rRuby.GetText();
740 [ # # ]: 0 : aStr.APPEND_CONST_ASC( ")" );
741 : :
742 : : // The parameter separator depends on the FIB.lid
743 [ # # ][ # # ]: 0 : if ( m_rWW8Export.pFib->getNumDecimalSep() == '.' )
744 [ # # ]: 0 : aStr.APPEND_CONST_ASC( "," );
745 : : else
746 [ # # ]: 0 : aStr.APPEND_CONST_ASC( ";" );
747 : :
748 : : m_rWW8Export.OutputField( 0, ww::eEQ, aStr,
749 [ # # ][ # # ]: 0 : WRITEFIELD_START | WRITEFIELD_CMD_START );
[ # # ]
750 : 0 : }
751 : :
752 : 0 : void WW8AttributeOutput::EndRuby()
753 : : {
754 : 0 : m_rWW8Export.WriteChar( ')' );
755 : 0 : m_rWW8Export.OutputField( 0, ww::eEQ, aEmptyStr, WRITEFIELD_END | WRITEFIELD_CLOSE );
756 : 0 : }
757 : :
758 : : /*#i15387# Better ideas welcome*/
759 : 12 : String &TruncateBookmark( String &rRet )
760 : : {
761 [ - + ]: 12 : if ( rRet.Len() > 40 )
762 : 0 : rRet.Erase( 40 );
763 : : OSL_ENSURE( rRet.Len() <= 40, "Word cannot have bookmarks longer than 40 chars" );
764 : 12 : return rRet;
765 : : }
766 : :
767 : 3 : bool AttributeOutputBase::AnalyzeURL( const String& rUrl, const String& /*rTarget*/, String* pLinkURL, String* pMark )
768 : : {
769 : 3 : bool bBookMarkOnly = false;
770 : :
771 [ + - ][ + - ]: 3 : INetURLObject aURL( rUrl );
772 [ + - ]: 3 : String sMark;
773 [ + - ]: 3 : String sURL;
774 : :
775 [ + - ][ - + ]: 3 : if ( rUrl.Len() > 1 && rUrl.GetChar(0) == INET_MARK_TOKEN )
[ - + ]
776 : : {
777 [ # # ][ # # ]: 0 : sMark = BookmarkToWriter( rUrl.Copy(1) );
[ # # ][ # # ]
[ # # ]
778 : :
779 [ # # ]: 0 : xub_StrLen nPos = sMark.SearchBackward( cMarkSeperator );
780 : :
781 [ # # ][ # # ]: 0 : String sRefType(comphelper::string::remove(sMark.Copy(nPos+1), ' '));
[ # # ][ # # ]
782 : :
783 : : // #i21465# Only interested in outline references
784 [ # # ][ # # ]: 0 : if ( sRefType.EqualsAscii( pMarkToOutline ) )
785 : : {
786 [ # # ]: 0 : String sLink = sMark.Copy(0, nPos);
787 [ # # ]: 0 : SwImplBookmarksIter bkmkIterEnd = GetExport().maImplicitBookmarks.end();
788 [ # # ][ # # ]: 0 : for ( SwImplBookmarksIter aIter = GetExport().maImplicitBookmarks.begin(); aIter != bkmkIterEnd; ++aIter )
[ # # ][ # # ]
789 : : {
790 [ # # ][ # # ]: 0 : String bkmkName = aIter->first;
791 : :
792 [ # # ][ # # ]: 0 : if ( bkmkName == sLink )
793 : : {
794 [ # # ][ # # ]: 0 : sMark = String( "_toc" );
[ # # ]
795 [ # # ][ # # ]: 0 : sMark += String::CreateFromInt32( aIter->second );
[ # # ][ # # ]
796 : : }
797 [ # # ][ # # ]: 0 : }
798 [ # # ]: 0 : }
799 : : }
800 : : else
801 : : {
802 [ + - ][ + - ]: 3 : sURL = aURL.GetURLNoMark( INetURLObject::DECODE_UNAMBIGUOUS );
803 [ + - ][ + - ]: 3 : sMark = aURL.GetMark( INetURLObject::DECODE_UNAMBIGUOUS );
804 : :
805 : : }
806 : :
807 [ + - ][ - + ]: 3 : if ( sMark.Len() && !sURL.Len() )
[ - + ]
808 : 0 : bBookMarkOnly = true;
809 : :
810 : :
811 : :
812 [ + - ]: 3 : *pMark = sMark;
813 [ + - ]: 3 : *pLinkURL = sURL;
814 [ + - ][ + - ]: 3 : return bBookMarkOnly;
[ + - ]
815 : : }
816 : :
817 : 0 : bool WW8AttributeOutput::AnalyzeURL( const String& rUrl, const String& rTarget, String* pLinkURL, String* pMark )
818 : : {
819 [ # # ]: 0 : bool bBookMarkOnly = AttributeOutputBase::AnalyzeURL( rUrl, rTarget, pLinkURL, pMark );
820 : :
821 [ # # ]: 0 : String sURL = *pLinkURL;
822 [ # # ]: 0 : String sMark = *pMark;
823 : :
824 [ # # ]: 0 : if ( sURL.Len() )
825 [ # # ][ # # ]: 0 : sURL = URIHelper::simpleNormalizedMakeRelative( m_rWW8Export.GetWriter().GetBaseURL(), sURL );
[ # # ][ # # ]
826 : :
827 [ # # ]: 0 : if ( bBookMarkOnly )
828 [ # # ][ # # ]: 0 : sURL = FieldString( ww::eHYPERLINK );
[ # # ]
829 : : else
830 : : {
831 [ # # ]: 0 : String sFld( FieldString( ww::eHYPERLINK ) );
832 [ # # ]: 0 : sFld.APPEND_CONST_ASC( "\"" );
833 [ # # ]: 0 : sURL.Insert( sFld, 0 );
834 [ # # ][ # # ]: 0 : sURL += '\"';
835 : : }
836 : :
837 [ # # ]: 0 : if ( sMark.Len() )
838 [ # # ][ # # ]: 0 : ( ( sURL.APPEND_CONST_ASC( " \\l \"" ) ) += sMark ) += '\"';
[ # # ]
839 : :
840 [ # # ]: 0 : if ( rTarget.Len() )
841 [ # # ][ # # ]: 0 : ( sURL.APPEND_CONST_ASC( " \\n " ) ) += rTarget;
842 : :
843 [ # # ]: 0 : *pLinkURL = sURL;
844 [ # # ]: 0 : *pMark = sMark;
845 : :
846 [ # # ][ # # ]: 0 : return bBookMarkOnly;
847 : : }
848 : :
849 : 0 : bool WW8AttributeOutput::StartURL( const String &rUrl, const String &rTarget )
850 : : {
851 : : // hyperlinks only in WW8
852 [ # # ]: 0 : if ( !m_rWW8Export.bWrtWW8 )
853 : 0 : return false;
854 : :
855 [ # # ][ # # ]: 0 : INetURLObject aURL( rUrl );
856 [ # # ]: 0 : String sURL;
857 [ # # ]: 0 : String sMark;
858 : :
859 [ # # ]: 0 : bool bBookMarkOnly = AnalyzeURL( rUrl, rTarget, &sURL, &sMark );
860 : :
861 : :
862 [ # # ]: 0 : m_rWW8Export.OutputField( 0, ww::eHYPERLINK, sURL, WRITEFIELD_START | WRITEFIELD_CMD_START );
863 : :
864 : : // write the refence to the "picture" structure
865 : 0 : sal_uLong nDataStt = m_rWW8Export.pDataStrm->Tell();
866 [ # # ][ # # ]: 0 : m_rWW8Export.pChpPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell() );
867 : :
868 : : // WinWord 2000 doesn't write this - so its a temp solution by W97 ?
869 [ # # ]: 0 : m_rWW8Export.WriteChar( 0x01 );
870 : :
871 : : static sal_uInt8 aArr1[] = {
872 : : 0x03, 0x6a, 0,0,0,0, // sprmCPicLocation
873 : :
874 : : 0x06, 0x08, 0x01, // sprmCFData
875 : : 0x55, 0x08, 0x01, // sprmCFSpec
876 : : 0x02, 0x08, 0x01 // sprmCFFldVanish
877 : : };
878 : 0 : sal_uInt8* pDataAdr = aArr1 + 2;
879 : 0 : Set_UInt32( pDataAdr, nDataStt );
880 : :
881 [ # # ][ # # ]: 0 : m_rWW8Export.pChpPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), sizeof( aArr1 ), aArr1 );
882 : :
883 [ # # ]: 0 : m_rWW8Export.OutputField( 0, ww::eHYPERLINK, sURL, WRITEFIELD_CMD_END );
884 : :
885 : : // now write the picture structur
886 [ # # ][ # # ]: 0 : sURL = aURL.GetURLNoMark();
887 : :
888 : : // Compare the URL written by AnalyzeURL with the original one to see if
889 : : // the output URL is absolute or relative.
890 [ # # ]: 0 : String sRelativeURL;
891 [ # # ]: 0 : if ( rUrl.Len() )
892 [ # # ][ # # ]: 0 : sRelativeURL = URIHelper::simpleNormalizedMakeRelative( m_rWW8Export.GetWriter().GetBaseURL(), rUrl );
[ # # ][ # # ]
893 [ # # ]: 0 : bool bAbsolute = sRelativeURL.Equals( rUrl );
894 : :
895 : : static sal_uInt8 aURLData1[] = {
896 : : 0,0,0,0, // len of struct
897 : : 0x44,0, // the start of "next" data
898 : : 0,0,0,0,0,0,0,0,0,0, // PIC-Structure!
899 : : 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // |
900 : : 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // |
901 : : 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // |
902 : : 0,0,0,0, // /
903 : : };
904 : : static sal_uInt8 MAGIC_A[] = {
905 : : // start of "next" data
906 : : 0xD0,0xC9,0xEA,0x79,0xF9,0xBA,0xCE,0x11,
907 : : 0x8C,0x82,0x00,0xAA,0x00,0x4B,0xA9,0x0B
908 : : };
909 : :
910 [ # # ]: 0 : m_rWW8Export.pDataStrm->Write( aURLData1, sizeof( aURLData1 ) );
911 : : /* Write HFD Structure */
912 : 0 : sal_uInt8 nAnchor = 0x00;
913 [ # # ]: 0 : if ( sMark.Len() )
914 : 0 : nAnchor = 0x08;
915 [ # # ]: 0 : m_rWW8Export.pDataStrm->Write( &nAnchor, 1 ); // HFDBits
916 [ # # ]: 0 : m_rWW8Export.pDataStrm->Write( MAGIC_A, sizeof(MAGIC_A) ); //clsid
917 : :
918 : : /* Write Hyperlink Object see [MS-OSHARED] spec*/
919 [ # # ]: 0 : SwWW8Writer::WriteLong( *m_rWW8Export.pDataStrm, 0x00000002);
920 [ # # ]: 0 : sal_uInt32 nFlag = bBookMarkOnly ? 0 : 0x01;
921 [ # # ]: 0 : if ( bAbsolute )
922 : 0 : nFlag |= 0x02;
923 [ # # ]: 0 : if ( sMark.Len() )
924 : 0 : nFlag |= 0x08;
925 [ # # ]: 0 : SwWW8Writer::WriteLong( *m_rWW8Export.pDataStrm, nFlag );
926 : :
927 : 0 : INetProtocol eProto = aURL.GetProtocol();
928 [ # # ][ # # ]: 0 : if ( eProto == INET_PROT_FILE || eProto == INET_PROT_SMB )
929 : : {
930 : : // version 1 (for a document)
931 : :
932 : : static sal_uInt8 MAGIC_C[] = {
933 : : 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
934 : : 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
935 : : 0x00, 0x00
936 : : };
937 : :
938 : : static sal_uInt8 MAGIC_D[] = {
939 : : 0xFF, 0xFF, 0xAD, 0xDE, 0x00, 0x00, 0x00, 0x00,
940 : : 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
941 : : 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
942 : : };
943 : :
944 : : // save the links to files as relative
945 [ # # ][ # # ]: 0 : sURL = URIHelper::simpleNormalizedMakeRelative( m_rWW8Export.GetWriter().GetBaseURL(), sURL );
[ # # ][ # # ]
946 [ # # ][ # # ]: 0 : if ( eProto == INET_PROT_FILE && sURL.EqualsAscii( "/", 0, 1 ) )
[ # # ][ # # ]
947 [ # # ][ # # ]: 0 : sURL = aURL.PathToFileName();
948 : :
949 : : // special case for the absolute windows names
950 : : // (convert '/c:/foo/bar.doc' into 'c:\foo\bar.doc')
951 [ # # ]: 0 : sal_Unicode aDrive = ( sURL.Len() > 1 )? sURL.GetChar( 1 ): 0;
952 [ # # ][ # # ]: 0 : if ( sURL.EqualsAscii( "/", 0, 1 ) &&
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
953 : : ( ( aDrive >= 'A' && aDrive <= 'Z' ) || ( aDrive >= 'a' && aDrive <= 'z' ) ) &&
954 [ # # ]: 0 : sURL.EqualsAscii( ":", 2, 1 ) )
955 : : {
956 [ # # ]: 0 : sURL.Erase( 0, 1 );
957 [ # # ]: 0 : sURL.SearchAndReplaceAll( '/', '\\' );
958 : : }
959 : :
960 : : // n#261623 convert smb notation to '\\'
961 : 0 : const char pSmb[] = "smb://";
962 [ # # ][ # # ]: 0 : if ( eProto == INET_PROT_SMB &&
[ # # ]
963 [ # # ]: 0 : sURL.EqualsAscii( pSmb, 0, sizeof( pSmb ) - 1 ) )
964 : : {
965 [ # # ]: 0 : sURL.Erase( 0, sizeof( pSmb ) - 3 );
966 [ # # ]: 0 : sURL.SearchAndReplaceAll( '/', '\\' );
967 : : }
968 : :
969 [ # # ]: 0 : m_rWW8Export.pDataStrm->Write( MAGIC_C, sizeof(MAGIC_C) );
970 [ # # ]: 0 : SwWW8Writer::WriteLong( *m_rWW8Export.pDataStrm, sURL.Len()+1 );
971 : : SwWW8Writer::WriteString8( *m_rWW8Export.pDataStrm, sURL, true,
972 [ # # ]: 0 : RTL_TEXTENCODING_MS_1252 );
973 [ # # ]: 0 : m_rWW8Export.pDataStrm->Write( MAGIC_D, sizeof( MAGIC_D ) );
974 : :
975 [ # # ]: 0 : SwWW8Writer::WriteLong( *m_rWW8Export.pDataStrm, 2*sURL.Len() + 6 );
976 [ # # ]: 0 : SwWW8Writer::WriteLong( *m_rWW8Export.pDataStrm, 2*sURL.Len() );
977 [ # # ]: 0 : SwWW8Writer::WriteShort( *m_rWW8Export.pDataStrm, 3 );
978 [ # # ]: 0 : SwWW8Writer::WriteString16( *m_rWW8Export.pDataStrm, sURL, false );
979 : : }
980 [ # # ]: 0 : else if ( eProto != INET_PROT_NOT_VALID )
981 : : {
982 : : // version 2 (simple url)
983 : : // an write some data to the data stream, but dont ask
984 : : // what the data mean, except for the URL.
985 : : // The First piece is the WW8_PIC structure.
986 : : //
987 : : static sal_uInt8 MAGIC_B[] = {
988 : : 0xE0,0xC9,0xEA,0x79,0xF9,0xBA,0xCE,0x11,
989 : : 0x8C,0x82,0x00,0xAA,0x00,0x4B,0xA9,0x0B
990 : : };
991 : :
992 [ # # ]: 0 : m_rWW8Export.pDataStrm->Write( MAGIC_B, sizeof(MAGIC_B) );
993 [ # # ]: 0 : SwWW8Writer::WriteLong( *m_rWW8Export.pDataStrm, 2 * ( sURL.Len() + 1 ) );
994 [ # # ]: 0 : SwWW8Writer::WriteString16( *m_rWW8Export.pDataStrm, sURL, true );
995 : : }
996 : :
997 [ # # ]: 0 : if ( sMark.Len() )
998 : : {
999 [ # # ]: 0 : SwWW8Writer::WriteLong( *m_rWW8Export.pDataStrm, sMark.Len()+1 );
1000 [ # # ]: 0 : SwWW8Writer::WriteString16( *m_rWW8Export.pDataStrm, sMark, true );
1001 : : }
1002 : : SwWW8Writer::WriteLong( *m_rWW8Export.pDataStrm, nDataStt,
1003 [ # # ]: 0 : m_rWW8Export.pDataStrm->Tell() - nDataStt );
1004 : :
1005 [ # # ][ # # ]: 0 : return true;
[ # # ][ # # ]
1006 : : }
1007 : :
1008 : 0 : bool WW8AttributeOutput::EndURL()
1009 : : {
1010 : : // hyperlinks only in WW8
1011 [ # # ]: 0 : if ( !m_rWW8Export.bWrtWW8 )
1012 : 0 : return false;
1013 : :
1014 : 0 : m_rWW8Export.OutputField( 0, ww::eHYPERLINK, aEmptyStr, WRITEFIELD_CLOSE );
1015 : :
1016 : 0 : return true;
1017 : : }
1018 : :
1019 : 12 : String BookmarkToWord(const String &rBookmark)
1020 : : {
1021 : : String sRet(INetURLObject::encode(rBookmark,
1022 : : INetURLObject::PART_REL_SEGMENT_EXTRA, '%',
1023 [ + - ][ + - ]: 12 : INetURLObject::ENCODE_ALL, RTL_TEXTENCODING_ASCII_US));
[ + - ]
1024 [ + - ][ + - ]: 12 : return TruncateBookmark(sRet);
[ + - ]
1025 : : }
1026 : :
1027 : 6 : String BookmarkToWriter(const String &rBookmark)
1028 : : {
1029 : : return INetURLObject::decode(rBookmark, '%',
1030 [ + - ][ + - ]: 6 : INetURLObject::DECODE_UNAMBIGUOUS, RTL_TEXTENCODING_ASCII_US);
1031 : : }
1032 : :
1033 : 0 : void SwWW8AttrIter::OutSwFmtRefMark(const SwFmtRefMark& rAttr, bool)
1034 : : {
1035 [ # # ]: 0 : if ( m_rExport.HasRefToObject( REF_SETREFATTR, &rAttr.GetRefName(), 0 ) )
1036 : : m_rExport.AppendBookmark( m_rExport.GetBookmarkName( REF_SETREFATTR,
1037 [ # # ][ # # ]: 0 : &rAttr.GetRefName(), 0 ));
1038 : 0 : }
1039 : :
1040 : 0 : void WW8AttributeOutput::FieldVanish( const String& rTxt, ww::eField /*eType*/ )
1041 : : {
1042 [ # # ]: 0 : ww::bytes aItems;
1043 [ # # ]: 0 : m_rWW8Export.GetCurrentItems( aItems );
1044 : :
1045 : : // sprmCFFldVanish
1046 [ # # ]: 0 : if ( m_rWW8Export.bWrtWW8 )
1047 [ # # ]: 0 : SwWW8Writer::InsUInt16( aItems, NS_sprm::LN_CFFldVanish );
1048 : : else
1049 [ # # ]: 0 : aItems.push_back( 67 );
1050 [ # # ]: 0 : aItems.push_back( 1 );
1051 : :
1052 : 0 : sal_uInt16 nStt_sprmCFSpec = aItems.size();
1053 : :
1054 : : // sprmCFSpec -- fSpec-Attribut true
1055 [ # # ]: 0 : if ( m_rWW8Export.bWrtWW8 )
1056 [ # # ]: 0 : SwWW8Writer::InsUInt16( aItems, 0x855 );
1057 : : else
1058 [ # # ]: 0 : aItems.push_back( 117 );
1059 [ # # ]: 0 : aItems.push_back( 1 );
1060 : :
1061 [ # # ]: 0 : m_rWW8Export.WriteChar( '\x13' );
1062 [ # # ]: 0 : m_rWW8Export.pChpPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), aItems.size(),
1063 [ # # # # ]: 0 : aItems.data() );
1064 : 0 : m_rWW8Export.OutSwString( rTxt, 0, rTxt.Len(), m_rWW8Export.IsUnicode(),
1065 [ # # ]: 0 : RTL_TEXTENCODING_MS_1252 );
1066 [ # # ]: 0 : m_rWW8Export.pChpPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), nStt_sprmCFSpec,
1067 [ # # # # ]: 0 : aItems.data() );
1068 [ # # ]: 0 : m_rWW8Export.WriteChar( '\x15' );
1069 [ # # ]: 0 : m_rWW8Export.pChpPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), aItems.size(),
1070 [ # # # # ]: 0 : aItems.data() );
1071 : 0 : }
1072 : :
1073 : 0 : void AttributeOutputBase::TOXMark( const SwTxtNode& rNode, const SwTOXMark& rAttr )
1074 : : {
1075 : : // its a field; so get the Text form the Node and build the field
1076 [ # # ]: 0 : String sTxt;
1077 : 0 : ww::eField eType = ww::eNONE;
1078 : :
1079 : 0 : const SwTxtTOXMark& rTxtTOXMark = *rAttr.GetTxtTOXMark();
1080 : 0 : const xub_StrLen* pTxtEnd = rTxtTOXMark.GetEnd();
1081 [ # # ]: 0 : if ( pTxtEnd ) // has range?
1082 : : {
1083 : 0 : sTxt = rNode.GetExpandTxt( *rTxtTOXMark.GetStart(),
1084 [ # # ][ # # ]: 0 : *pTxtEnd - *rTxtTOXMark.GetStart() );
[ # # ]
1085 : : }
1086 : : else
1087 [ # # ]: 0 : sTxt = rAttr.GetAlternativeText();
1088 : :
1089 [ # # # # ]: 0 : switch ( rAttr.GetTOXType()->GetType() )
1090 : : {
1091 : : case TOX_INDEX:
1092 : 0 : eType = ww::eXE;
1093 [ # # ]: 0 : if ( rAttr.GetPrimaryKey().Len() )
1094 : : {
1095 [ # # ]: 0 : if ( rAttr.GetSecondaryKey().Len() )
1096 : : {
1097 [ # # ]: 0 : sTxt.Insert( ':', 0 );
1098 [ # # ]: 0 : sTxt.Insert( rAttr.GetSecondaryKey(), 0 );
1099 : : }
1100 : :
1101 [ # # ]: 0 : sTxt.Insert( ':', 0 );
1102 [ # # ]: 0 : sTxt.Insert( rAttr.GetPrimaryKey(), 0 );
1103 : : }
1104 [ # # ]: 0 : sTxt.InsertAscii( " XE \"", 0 );
1105 [ # # ]: 0 : sTxt.InsertAscii( "\" " );
1106 : 0 : break;
1107 : :
1108 : : case TOX_USER:
1109 [ # # ]: 0 : ( sTxt.APPEND_CONST_ASC( "\" \\f \"" ) )
1110 [ # # ][ # # ]: 0 : += (sal_Char)( 'A' + GetExport( ).GetId( *rAttr.GetTOXType() ) );
[ # # ]
1111 : : // fall through - no break;
1112 : : case TOX_CONTENT:
1113 : : {
1114 : 0 : eType = ww::eTC;
1115 [ # # ]: 0 : sTxt.InsertAscii( " TC \"", 0 );
1116 : 0 : sal_uInt16 nLvl = rAttr.GetLevel();
1117 [ # # ]: 0 : if (nLvl > WW8ListManager::nMaxLevel)
1118 : 0 : nLvl = WW8ListManager::nMaxLevel;
1119 : :
1120 [ # # ]: 0 : ((sTxt.APPEND_CONST_ASC( "\" \\l " ))
1121 [ # # ][ # # ]: 0 : += String::CreateFromInt32( nLvl )) += ' ';
[ # # ][ # # ]
1122 : : }
1123 : 0 : break;
1124 : : default:
1125 : : OSL_ENSURE( !this, "Unhandled option for toc export" );
1126 : 0 : break;
1127 : : }
1128 : :
1129 [ # # ]: 0 : if ( sTxt.Len() )
1130 [ # # ][ # # ]: 0 : FieldVanish( sTxt, eType );
1131 : 0 : }
1132 : :
1133 : 642 : int SwWW8AttrIter::OutAttrWithRange(xub_StrLen nPos)
1134 : : {
1135 : 642 : int nRet = 0;
1136 [ + + ]: 642 : if ( const SwpHints* pTxtAttrs = rNd.GetpSwpHints() )
1137 : : {
1138 : 447 : m_rExport.m_aCurrentCharPropStarts.push( nPos );
1139 : : const xub_StrLen* pEnd;
1140 [ + + ]: 1326 : for ( sal_uInt16 i = 0; i < pTxtAttrs->Count(); ++i )
1141 : : {
1142 : 879 : const SwTxtAttr* pHt = (*pTxtAttrs)[i];
1143 : 879 : const SfxPoolItem* pItem = &pHt->GetAttr();
1144 [ + - - - : 879 : switch ( pItem->Which() )
+ ]
1145 : : {
1146 : : case RES_TXTATR_INETFMT:
1147 [ + + ]: 6 : if ( nPos == *pHt->GetStart() )
1148 : : {
1149 : 3 : const SwFmtINetFmt *rINet = static_cast< const SwFmtINetFmt* >( pItem );
1150 [ + - ]: 3 : if ( m_rExport.AttrOutput().StartURL( rINet->GetValue(), rINet->GetTargetFrame() ) )
1151 : 3 : ++nRet;
1152 : : }
1153 [ + - ][ + + ]: 6 : if ( 0 != ( pEnd = pHt->GetEnd() ) && nPos == *pEnd )
[ + + ]
1154 : : {
1155 [ + - ]: 3 : if ( m_rExport.AttrOutput().EndURL() )
1156 : 3 : --nRet;
1157 : : }
1158 : 6 : break;
1159 : : case RES_TXTATR_REFMARK:
1160 [ # # ]: 0 : if ( nPos == *pHt->GetStart() )
1161 : : {
1162 : 0 : OutSwFmtRefMark( *static_cast< const SwFmtRefMark* >( pItem ), true );
1163 : 0 : ++nRet;
1164 : : }
1165 [ # # ][ # # ]: 0 : if ( 0 != ( pEnd = pHt->GetEnd() ) && nPos == *pEnd )
[ # # ]
1166 : : {
1167 : 0 : OutSwFmtRefMark( *static_cast< const SwFmtRefMark* >( pItem ), false );
1168 : 0 : --nRet;
1169 : : }
1170 : 0 : break;
1171 : : case RES_TXTATR_TOXMARK:
1172 [ # # ]: 0 : if ( nPos == *pHt->GetStart() )
1173 : 0 : m_rExport.AttrOutput().TOXMark( rNd, *static_cast< const SwTOXMark* >( pItem ) );
1174 : 0 : break;
1175 : : case RES_TXTATR_CJK_RUBY:
1176 [ # # ]: 0 : if ( nPos == *pHt->GetStart() )
1177 : : {
1178 : 0 : m_rExport.AttrOutput().StartRuby( rNd, nPos, *static_cast< const SwFmtRuby* >( pItem ) );
1179 : 0 : ++nRet;
1180 : : }
1181 [ # # ][ # # ]: 0 : if ( 0 != ( pEnd = pHt->GetEnd() ) && nPos == *pEnd )
[ # # ]
1182 : : {
1183 : 0 : m_rExport.AttrOutput().EndRuby();
1184 : 0 : --nRet;
1185 : : }
1186 : 0 : break;
1187 : : }
1188 : : }
1189 : 447 : m_rExport.m_aCurrentCharPropStarts.pop(); // HasTextItem nur in dem obigen Bereich erlaubt
1190 : : }
1191 : 642 : return nRet;
1192 : : }
1193 : :
1194 : 129 : bool SwWW8AttrIter::IsRedlineAtEnd( xub_StrLen nEnd ) const
1195 : : {
1196 : 129 : bool bRet = false;
1197 : : // search next Redline
1198 [ - + ]: 258 : for( sal_uInt16 nPos = nCurRedlinePos;
1199 : 129 : nPos < m_rExport.pDoc->GetRedlineTbl().size(); ++nPos )
1200 : : {
1201 : 0 : const SwPosition* pEnd = m_rExport.pDoc->GetRedlineTbl()[ nPos ]->End();
1202 [ # # ]: 0 : if( pEnd->nNode == rNd )
1203 : : {
1204 [ # # ]: 0 : if( pEnd->nContent.GetIndex() == nEnd )
1205 : : {
1206 : 0 : bRet = true;
1207 : 0 : break;
1208 : : }
1209 : : }
1210 : : else
1211 : 0 : break;
1212 : : }
1213 : 129 : return bRet;
1214 : : }
1215 : :
1216 : 384 : const SwRedlineData* SwWW8AttrIter::GetRedline( xub_StrLen nPos )
1217 : : {
1218 [ - + ]: 384 : if( pCurRedline )
1219 : : {
1220 : 0 : const SwPosition* pEnd = pCurRedline->End();
1221 [ # # # # ]: 0 : if( pEnd->nNode == rNd &&
[ # # ]
[ # # # # ]
[ # # ]
1222 : 0 : pEnd->nContent.GetIndex() <= nPos )
1223 : : {
1224 : 0 : pCurRedline = 0;
1225 : 0 : ++nCurRedlinePos;
1226 : : }
1227 : : else
1228 : : {
1229 : : // write data of current redline
1230 : 0 : return &( pCurRedline->GetRedlineData() );
1231 : : }
1232 : : }
1233 : :
1234 [ + - ]: 384 : if( !pCurRedline )
1235 : : {
1236 : : // search next Redline
1237 [ - + ]: 384 : for( ; nCurRedlinePos < m_rExport.pDoc->GetRedlineTbl().size();
1238 : : ++nCurRedlinePos )
1239 : : {
1240 : 0 : const SwRedline* pRedl = m_rExport.pDoc->GetRedlineTbl()[ nCurRedlinePos ];
1241 : :
1242 : 0 : const SwPosition* pStt = pRedl->Start();
1243 : 0 : const SwPosition* pEnd = pStt == pRedl->GetPoint()
1244 : 0 : ? pRedl->GetMark()
1245 [ # # ]: 0 : : pRedl->GetPoint();
1246 : :
1247 [ # # ]: 0 : if( pStt->nNode == rNd )
1248 : : {
1249 [ # # ]: 0 : if( pStt->nContent.GetIndex() >= nPos )
1250 : : {
1251 [ # # ]: 0 : if( pStt->nContent.GetIndex() == nPos )
1252 : : {
1253 : : // write data of this redline
1254 : 0 : pCurRedline = pRedl;
1255 : 0 : return &( pCurRedline->GetRedlineData() );
1256 : : }
1257 : 0 : break;
1258 : : }
1259 : : }
1260 : : else
1261 : 0 : break;
1262 : :
1263 [ # # ]: 0 : if( pEnd->nNode == rNd &&
[ # # # # ]
[ # # ]
[ # # # # ]
1264 : 0 : pEnd->nContent.GetIndex() < nPos )
1265 : : {
1266 : 0 : pCurRedline = pRedl;
1267 : 0 : break;
1268 : : }
1269 : : }
1270 : : }
1271 : 384 : return NULL;
1272 : : }
1273 : :
1274 : :
1275 : 3 : short MSWordExportBase::GetCurrentPageDirection() const
1276 : : {
1277 : : const SwFrmFmt &rFmt = pAktPageDesc
1278 : 3 : ? pAktPageDesc->GetMaster()
1279 [ + - ]: 3 : : pDoc->GetPageDesc( 0 ).GetMaster();
1280 : 3 : return rFmt.GetFrmDir().GetValue();
1281 : : }
1282 : :
1283 : 6 : short MSWordExportBase::GetDefaultFrameDirection( ) const
1284 : : {
1285 : 6 : short nDir = FRMDIR_ENVIRONMENT;
1286 : :
1287 [ - + ]: 6 : if ( bOutPageDescs )
1288 : 0 : nDir = GetCurrentPageDirection( );
1289 [ + - ]: 6 : else if ( pOutFmtNode )
1290 : : {
1291 [ - + ]: 6 : if ( bOutFlyFrmAttrs ) //frame
1292 : : {
1293 : 0 : nDir = TrueFrameDirection( *( const SwFrmFmt * ) pOutFmtNode );
1294 : : }
1295 [ - + ]: 6 : else if ( pOutFmtNode->ISA( SwCntntNode ) ) //pagagraph
1296 : : {
1297 : 0 : const SwCntntNode *pNd = ( const SwCntntNode * ) pOutFmtNode;
1298 [ # # ]: 0 : SwPosition aPos( *pNd );
1299 [ # # ][ # # ]: 0 : nDir = pDoc->GetTextDirection( aPos );
1300 : : }
1301 [ + - ]: 6 : else if ( pOutFmtNode->ISA( SwTxtFmtColl ) )
1302 : 6 : nDir = FRMDIR_HORI_LEFT_TOP; //what else can we do :-(
1303 : : }
1304 : :
1305 [ - + ]: 6 : if ( nDir == FRMDIR_ENVIRONMENT )
1306 : 0 : nDir = FRMDIR_HORI_LEFT_TOP; //Set something
1307 : :
1308 : 6 : return nDir;
1309 : : }
1310 : :
1311 : 6 : short MSWordExportBase::TrueFrameDirection( const SwFrmFmt &rFlyFmt ) const
1312 : : {
1313 : 6 : const SwFrmFmt *pFlyFmt = &rFlyFmt;
1314 : 6 : const SvxFrameDirectionItem* pItem = 0;
1315 [ + + ]: 12 : while ( pFlyFmt )
1316 : : {
1317 : 6 : pItem = &pFlyFmt->GetFrmDir();
1318 [ + + ]: 6 : if ( FRMDIR_ENVIRONMENT == pItem->GetValue() )
1319 : : {
1320 : 3 : pItem = 0;
1321 : 3 : const SwFmtAnchor* pAnchor = &pFlyFmt->GetAnchor();
1322 [ + - ]: 6 : if ((FLY_AT_PAGE != pAnchor->GetAnchorId()) &&
[ + - + - ]
1323 : 3 : pAnchor->GetCntntAnchor() )
1324 : : {
1325 : 3 : pFlyFmt = pAnchor->GetCntntAnchor()->nNode.GetNode().GetFlyFmt();
1326 : : }
1327 : : else
1328 : 0 : pFlyFmt = 0;
1329 : : }
1330 : : else
1331 : 3 : pFlyFmt = 0;
1332 : : }
1333 : :
1334 : : short nRet;
1335 [ + + ]: 6 : if ( pItem )
1336 : 3 : nRet = pItem->GetValue();
1337 : : else
1338 : 3 : nRet = GetCurrentPageDirection();
1339 : :
1340 : : OSL_ENSURE( nRet != FRMDIR_ENVIRONMENT, "leaving with environment direction" );
1341 : 6 : return nRet;
1342 : : }
1343 : :
1344 : 3 : const SvxBrushItem* WW8Export::GetCurrentPageBgBrush() const
1345 : : {
1346 : : const SwFrmFmt &rFmt = pAktPageDesc
1347 : 3 : ? pAktPageDesc->GetMaster()
1348 [ + - ][ # # ]: 3 : : pDoc->GetPageDesc(0).GetMaster();
1349 : :
1350 : 3 : const SfxPoolItem* pItem = 0;
1351 : : //If not set, or "no fill", get real bg
1352 [ + - ]: 3 : SfxItemState eState = rFmt.GetItemState(RES_BACKGROUND, true, &pItem);
1353 : :
1354 : 3 : const SvxBrushItem* pRet = (const SvxBrushItem*)pItem;
1355 [ - + ][ # # ]: 6 : if (SFX_ITEM_SET != eState || (!pRet->GetGraphic() &&
[ # # # # ]
[ + - ]
1356 [ - + ][ # # ]: 3 : pRet->GetColor() == COL_TRANSPARENT))
1357 : : {
1358 [ + - ]: 3 : pRet = &(DefaultItemGet<SvxBrushItem>(*pDoc,RES_BACKGROUND));
1359 : : }
1360 : 3 : return pRet;
1361 : : }
1362 : :
1363 : 3 : SvxBrushItem WW8Export::TrueFrameBgBrush(const SwFrmFmt &rFlyFmt) const
1364 : : {
1365 : 3 : const SwFrmFmt *pFlyFmt = &rFlyFmt;
1366 : 3 : const SvxBrushItem* pRet = 0;
1367 : :
1368 [ + + ]: 6 : while (pFlyFmt)
1369 : : {
1370 : : //If not set, or "no fill", get real bg
1371 : 3 : const SfxPoolItem* pItem = 0;
1372 : : SfxItemState eState =
1373 [ + - ]: 3 : pFlyFmt->GetItemState(RES_BACKGROUND, true, &pItem);
1374 : 3 : pRet = (const SvxBrushItem*)pItem;
1375 [ - + ][ # # ]: 6 : if (SFX_ITEM_SET != eState || (!pRet->GetGraphic() &&
[ # # # # ]
[ + - ]
1376 [ - + ][ # # ]: 3 : pRet->GetColor() == COL_TRANSPARENT))
1377 : : {
1378 : 3 : pRet = 0;
1379 [ + - ]: 3 : const SwFmtAnchor* pAnchor = &pFlyFmt->GetAnchor();
1380 [ + - ][ + - ]: 6 : if ((FLY_AT_PAGE != pAnchor->GetAnchorId()) &&
[ + - ]
1381 [ + - ]: 3 : pAnchor->GetCntntAnchor())
1382 : : {
1383 : : pFlyFmt =
1384 [ + - ][ + - ]: 3 : pAnchor->GetCntntAnchor()->nNode.GetNode().GetFlyFmt();
1385 : : }
1386 : : else
1387 : 0 : pFlyFmt = 0;
1388 : : }
1389 : : else
1390 : 3 : pFlyFmt = 0;
1391 : : }
1392 : :
1393 [ + - ]: 3 : if (!pRet)
1394 [ + - ]: 3 : pRet = GetCurrentPageBgBrush();
1395 : :
1396 : 3 : const Color aTmpColor( COL_WHITE );
1397 [ + - ]: 3 : SvxBrushItem aRet( aTmpColor, RES_BACKGROUND );
1398 [ + - ][ + - ]: 3 : if (pRet && (pRet->GetGraphic() ||( pRet->GetColor() != COL_TRANSPARENT)))
[ + - ][ - + ]
[ + - ]
[ - + # # ]
1399 [ # # ]: 3 : aRet = *pRet;
1400 : :
1401 : 3 : return aRet;
1402 : : }
1403 : :
1404 : :
1405 : : /*
1406 : : Convert characters that need to be converted, the basic replacements and the
1407 : : ridicously complicated title case attribute mapping to hardcoded upper case
1408 : : because word doesn't have the feature
1409 : : */
1410 : 120 : String SwWW8AttrIter::GetSnippet(const String &rStr, xub_StrLen nAktPos,
1411 : : xub_StrLen nLen) const
1412 : : {
1413 : 120 : String aSnippet(rStr, nAktPos, nLen);
1414 [ + + ]: 120 : if (!nLen)
1415 : 6 : return aSnippet;
1416 : :
1417 : : // 0x0a ( Hard Line Break ) -> 0x0b
1418 : : // 0xad ( soft hyphen ) -> 0x1f
1419 : : // 0x2011 ( hard hyphen ) -> 0x1e
1420 [ + - ]: 114 : aSnippet.SearchAndReplaceAll(0x0A, 0x0B);
1421 [ + - ]: 114 : aSnippet.SearchAndReplaceAll(CHAR_HARDHYPHEN, 0x1e);
1422 [ + - ]: 114 : aSnippet.SearchAndReplaceAll(CHAR_SOFTHYPHEN, 0x1f);
1423 : :
1424 [ + - ]: 114 : m_rExport.m_aCurrentCharPropStarts.push( nAktPos );
1425 [ + - ]: 114 : const SfxPoolItem &rItem = GetItem(RES_CHRATR_CASEMAP);
1426 : :
1427 [ - + ]: 114 : if (SVX_CASEMAP_TITEL == ((const SvxCaseMapItem&)rItem).GetValue())
1428 : : {
1429 : 0 : sal_uInt16 nScriptType = i18n::ScriptType::LATIN;
1430 [ # # ][ # # ]: 0 : if (pBreakIt->GetBreakIter().is())
1431 [ # # ][ # # ]: 0 : nScriptType = pBreakIt->GetBreakIter()->getScriptType(aSnippet, 0);
[ # # ][ # # ]
1432 : :
1433 : : LanguageType nLanguage;
1434 [ # # # ]: 0 : switch (nScriptType)
1435 : : {
1436 : : case i18n::ScriptType::ASIAN:
1437 [ # # ]: 0 : nLanguage = ((const SvxLanguageItem&)GetItem(RES_CHRATR_CJK_LANGUAGE)).GetLanguage();
1438 : 0 : break;
1439 : : case i18n::ScriptType::COMPLEX:
1440 [ # # ]: 0 : nLanguage = ((const SvxLanguageItem&)GetItem(RES_CHRATR_CTL_LANGUAGE)).GetLanguage();
1441 : 0 : break;
1442 : : case i18n::ScriptType::LATIN:
1443 : : default:
1444 [ # # ]: 0 : nLanguage = ((const SvxLanguageItem&)GetItem(RES_CHRATR_LANGUAGE)).GetLanguage();
1445 : 0 : break;
1446 : : }
1447 : :
1448 [ # # ]: 0 : SvxFont aFontHelper;
1449 : 0 : aFontHelper.SetCaseMap(SVX_CASEMAP_TITEL);
1450 [ # # ]: 0 : aFontHelper.SetLanguage(nLanguage);
1451 [ # # ][ # # ]: 0 : aSnippet = aFontHelper.CalcCaseMap(aSnippet);
[ # # ]
1452 : :
1453 : : //If we weren't at the begin of a word undo the case change.
1454 : : //not done before doing the casemap because the sequence might start
1455 : : //with whitespace
1456 [ # # ][ # # ]: 0 : if (pBreakIt->GetBreakIter().is() && !pBreakIt->GetBreakIter()->isBeginWord(
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # #
# # # # ]
1457 [ # # ]: 0 : rStr, nAktPos, pBreakIt->GetLocale(nLanguage),
1458 [ # # ][ # # ]: 0 : i18n::WordType::ANYWORD_IGNOREWHITESPACES ) )
[ # # ][ # # ]
1459 : : {
1460 [ # # ]: 0 : aSnippet.SetChar(0, rStr.GetChar(nAktPos));
1461 [ # # ]: 0 : }
1462 : : }
1463 [ + - ]: 114 : m_rExport.m_aCurrentCharPropStarts.pop();
1464 : :
1465 : 120 : return aSnippet;
1466 : : }
1467 : :
1468 : : /** Delivers the right paragraph style
1469 : :
1470 : : Because of the different style handling for delete operations,
1471 : : the track changes have to be analysed. A deletion, starting in paragraph A
1472 : : with style A, ending in paragraph B with style B, needs a hack.
1473 : : */
1474 : 300 : static SwTxtFmtColl& lcl_getFormatCollection( MSWordExportBase& rExport, const SwTxtNode* pTxtNode )
1475 : : {
1476 : 300 : sal_uInt16 nPos = 0;
1477 : 300 : sal_uInt16 nMax = rExport.pDoc->GetRedlineTbl().size();
1478 [ - + ]: 300 : while( nPos < nMax )
1479 : : {
1480 : 0 : const SwRedline* pRedl = rExport.pDoc->GetRedlineTbl()[ nPos++ ];
1481 : 0 : const SwPosition* pStt = pRedl->Start();
1482 : 0 : const SwPosition* pEnd = pStt == pRedl->GetPoint()
1483 : 0 : ? pRedl->GetMark()
1484 [ # # ]: 0 : : pRedl->GetPoint();
1485 : : // Looking for deletions, which ends in current pTxtNode
1486 [ # # ][ # # : 0 : if( nsRedlineType_t::REDLINE_DELETE == pRedl->GetRedlineData().GetType() &&
# # # # #
# ][ # # ]
1487 [ # # ][ # # ]: 0 : pEnd->nNode == *pTxtNode && pStt->nNode != *pTxtNode &&
[ # # ][ # # ]
[ # # ]
[ # # # # ]
1488 : 0 : pStt->nNode.GetNode().IsTxtNode() )
1489 : : {
1490 : 0 : pTxtNode = pStt->nNode.GetNode().GetTxtNode();
1491 : 0 : nMax = nPos;
1492 : 0 : nPos = 0;
1493 : : }
1494 : : }
1495 : 300 : return static_cast<SwTxtFmtColl&>( pTxtNode->GetAnyFmtColl() );
1496 : : }
1497 : :
1498 : 0 : void WW8AttributeOutput::FormatDrop( const SwTxtNode& rNode, const SwFmtDrop &rSwFmtDrop, sal_uInt16 nStyle,
1499 : : ww8::WW8TableNodeInfo::Pointer_t pTextNodeInfo, ww8::WW8TableNodeInfoInner::Pointer_t pTextNodeInfoInner )
1500 : : {
1501 : 0 : short nDropLines = rSwFmtDrop.GetLines();
1502 : 0 : short nDistance = rSwFmtDrop.GetDistance();
1503 : : int rFontHeight, rDropHeight, rDropDescent;
1504 : :
1505 : : SVBT16 nSty;
1506 : 0 : ShortToSVBT16( nStyle, nSty );
1507 [ # # ]: 0 : m_rWW8Export.pO->insert( m_rWW8Export.pO->end(), (sal_uInt8*)&nSty, (sal_uInt8*)&nSty+2 ); // Style #
1508 : :
1509 [ # # ]: 0 : if ( m_rWW8Export.bWrtWW8 )
1510 : : {
1511 [ # # ]: 0 : m_rWW8Export.InsUInt16( NS_sprm::LN_PPc ); // Alignment (sprmPPc)
1512 [ # # ]: 0 : m_rWW8Export.pO->push_back( 0x20 );
1513 : :
1514 [ # # ]: 0 : m_rWW8Export.InsUInt16( NS_sprm::LN_PWr ); // Wrapping (sprmPWr)
1515 [ # # ]: 0 : m_rWW8Export.pO->push_back( 0x02 );
1516 : :
1517 [ # # ]: 0 : m_rWW8Export.InsUInt16( NS_sprm::LN_PDcs ); // Dropcap (sprmPDcs)
1518 : 0 : int nDCS = ( nDropLines << 3 ) | 0x01;
1519 [ # # ]: 0 : m_rWW8Export.InsUInt16( static_cast< sal_uInt16 >( nDCS ) );
1520 : :
1521 [ # # ]: 0 : m_rWW8Export.InsUInt16( NS_sprm::LN_PDxaFromText ); // Distance from text (sprmPDxaFromText)
1522 [ # # ]: 0 : m_rWW8Export.InsUInt16( nDistance );
1523 : :
1524 [ # # ][ # # ]: 0 : if ( rNode.GetDropSize( rFontHeight, rDropHeight, rDropDescent ) )
1525 : : {
1526 [ # # ]: 0 : m_rWW8Export.InsUInt16( NS_sprm::LN_PDyaLine ); // Line spacing
1527 [ # # ]: 0 : m_rWW8Export.InsUInt16( static_cast< sal_uInt16 >( -rDropHeight ) );
1528 [ # # ]: 0 : m_rWW8Export.InsUInt16( 0 );
1529 : : }
1530 : : }
1531 : : else
1532 : : {
1533 [ # # ]: 0 : m_rWW8Export.pO->push_back( 29 ); // Alignment (sprmPPc)
1534 [ # # ]: 0 : m_rWW8Export.pO->push_back( 0x20 );
1535 : :
1536 [ # # ]: 0 : m_rWW8Export.pO->push_back( 37 ); // Wrapping (sprmPWr)
1537 [ # # ]: 0 : m_rWW8Export.pO->push_back( 0x02 );
1538 : :
1539 [ # # ]: 0 : m_rWW8Export.pO->push_back( 46 ); // Dropcap (sprmPDcs)
1540 : 0 : int nDCS = ( nDropLines << 3 ) | 0x01;
1541 [ # # ]: 0 : m_rWW8Export.InsUInt16( static_cast< sal_uInt16 >( nDCS ) );
1542 : :
1543 [ # # ]: 0 : m_rWW8Export.pO->push_back( 49 ); // Distance from text (sprmPDxaFromText)
1544 [ # # ]: 0 : m_rWW8Export.InsUInt16( nDistance );
1545 : :
1546 [ # # ][ # # ]: 0 : if (rNode.GetDropSize(rFontHeight, rDropHeight, rDropDescent))
1547 : : {
1548 [ # # ]: 0 : m_rWW8Export.pO->push_back( 20 ); // Line spacing
1549 [ # # ]: 0 : m_rWW8Export.InsUInt16( static_cast< sal_uInt16 >( -rDropHeight ) );
1550 [ # # ]: 0 : m_rWW8Export.InsUInt16( 0 );
1551 : : }
1552 : : }
1553 : :
1554 [ # # ][ # # ]: 0 : m_rWW8Export.WriteCR( pTextNodeInfoInner );
[ # # ]
1555 : :
1556 [ # # ]: 0 : if ( pTextNodeInfo.get() != NULL )
1557 : : {
1558 : : #ifdef DBG_UTIL
1559 : : ::std::clog << pTextNodeInfo->toString() << ::std::endl;
1560 : : #endif
1561 : :
1562 [ # # ][ # # ]: 0 : TableInfoCell( pTextNodeInfoInner );
[ # # ]
1563 : : }
1564 : :
1565 [ # # ][ # # ]: 0 : m_rWW8Export.pPapPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), m_rWW8Export.pO->size(), m_rWW8Export.pO->data() );
[ # # ]
1566 : 0 : m_rWW8Export.pO->clear();
1567 : :
1568 [ # # ][ # # ]: 0 : if ( rNode.GetDropSize( rFontHeight, rDropHeight, rDropDescent ) )
1569 : : {
1570 [ # # ]: 0 : if ( m_rWW8Export.bWrtWW8 )
1571 : : {
1572 : 0 : const SwCharFmt *pSwCharFmt = rSwFmtDrop.GetCharFmt();
1573 [ # # ]: 0 : if ( pSwCharFmt )
1574 : : {
1575 [ # # ]: 0 : m_rWW8Export.InsUInt16( NS_sprm::LN_CIstd );
1576 [ # # ][ # # ]: 0 : m_rWW8Export.InsUInt16( m_rWW8Export.GetId( *pSwCharFmt ) );
1577 : : }
1578 : :
1579 [ # # ]: 0 : m_rWW8Export.InsUInt16( NS_sprm::LN_CHpsPos ); // Lower the chars
1580 [ # # ]: 0 : m_rWW8Export.InsUInt16( static_cast< sal_uInt16 >( -((nDropLines - 1)*rDropDescent) / 10 ) );
1581 : :
1582 [ # # ]: 0 : m_rWW8Export.InsUInt16( NS_sprm::LN_CHps ); // Font Size
1583 [ # # ]: 0 : m_rWW8Export.InsUInt16( static_cast< sal_uInt16 >( rFontHeight / 10 ) );
1584 : : }
1585 : : else
1586 : : {
1587 : 0 : const SwCharFmt *pSwCharFmt = rSwFmtDrop.GetCharFmt();
1588 [ # # ]: 0 : if ( pSwCharFmt )
1589 : : {
1590 [ # # ]: 0 : m_rWW8Export.InsUInt16( 80 );
1591 [ # # ][ # # ]: 0 : m_rWW8Export.InsUInt16( m_rWW8Export.GetId( *pSwCharFmt ) );
1592 : : }
1593 : :
1594 [ # # ]: 0 : m_rWW8Export.pO->push_back( 101 ); // Lower the chars
1595 [ # # ]: 0 : m_rWW8Export.InsUInt16( static_cast< sal_uInt16 >( -((nDropLines - 1)*rDropDescent) / 10 ) );
1596 : :
1597 [ # # ]: 0 : m_rWW8Export.pO->push_back( 99 ); // Font Size
1598 [ # # ]: 0 : m_rWW8Export.InsUInt16( static_cast< sal_uInt16 >( rFontHeight / 10 ) );
1599 : : }
1600 : : }
1601 : :
1602 [ # # ][ # # ]: 0 : m_rWW8Export.pChpPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), m_rWW8Export.pO->size(), m_rWW8Export.pO->data() );
[ # # ]
1603 : 0 : m_rWW8Export.pO->clear();
1604 : 0 : }
1605 : :
1606 : 384 : xub_StrLen MSWordExportBase::GetNextPos( SwWW8AttrIter* aAttrIter, const SwTxtNode& rNode, xub_StrLen nAktPos )
1607 : : {
1608 : : // Get the bookmarks for the normal run
1609 : 384 : xub_StrLen nNextPos = aAttrIter->WhereNext();
1610 : 384 : xub_StrLen nNextBookmark = nNextPos;
1611 : :
1612 [ + + ]: 384 : if( nNextBookmark > nAktPos ) //no need to search for bookmarks otherwise (checked in UpdatePosition())
1613 : : {
1614 [ + - ]: 342 : GetSortedBookmarks( rNode, nAktPos, nNextBookmark - nAktPos );
1615 [ + - ]: 342 : NearestBookmark( nNextBookmark, nAktPos, false );
1616 : : }
1617 [ + - ]: 384 : return std::min( nNextPos, nNextBookmark );
1618 : : }
1619 : :
1620 : 384 : void MSWordExportBase::UpdatePosition( SwWW8AttrIter* aAttrIter, xub_StrLen nAktPos, xub_StrLen /*nEnd*/ )
1621 : : {
1622 : : xub_StrLen nNextPos;
1623 : :
1624 : : // go to next attribute if no bookmark is found or if the bookmark is behind the next attribute position
1625 : : // It may happend that the WhereNext() wasn't used in the previous increment because there was a
1626 : : // bookmark before it. Use that position before trying to find another one.
1627 [ + - ]: 384 : bool bNextBookmark = NearestBookmark( nNextPos, nAktPos, true );
1628 [ + + ][ - + ]: 384 : if( nAktPos == aAttrIter->WhereNext() && ( !bNextBookmark || nNextPos > aAttrIter->WhereNext() ) )
[ # # ][ + + ]
1629 [ + - ]: 381 : aAttrIter->NextPos();
1630 : 384 : }
1631 : :
1632 : 873 : bool MSWordExportBase::GetBookmarks( const SwTxtNode& rNd, xub_StrLen nStt,
1633 : : xub_StrLen nEnd, IMarkVector& rArr )
1634 : : {
1635 : 873 : IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
1636 : 873 : sal_uLong nNd = rNd.GetIndex( );
1637 : :
1638 : 873 : const sal_Int32 nMarks = pMarkAccess->getMarksCount();
1639 [ + + ]: 972 : for ( sal_Int32 i = 0; i < nMarks; i++ )
1640 : : {
1641 [ + - ][ + - ]: 99 : IMark* pMark = ( pMarkAccess->getMarksBegin() + i )->get();
1642 : :
1643 : : // Only keep the bookmarks starting or ending in this node
1644 [ + + - + ]: 105 : if ( pMark->GetMarkStart().nNode == nNd ||
[ + + ][ + - ]
1645 [ + - ]: 6 : pMark->GetMarkEnd().nNode == nNd )
1646 : : {
1647 [ + - ]: 93 : xub_StrLen nBStart = pMark->GetMarkStart().nContent.GetIndex();
1648 [ + - ]: 93 : xub_StrLen nBEnd = pMark->GetMarkEnd().nContent.GetIndex();
1649 : :
1650 : : // Keep only the bookmars starting or ending in the snippet
1651 [ + - ][ + + ]: 93 : bool bIsStartOk = ( nBStart >= nStt ) && ( nBStart <= nEnd );
1652 [ + + ][ + + ]: 93 : bool bIsEndOk = ( nBEnd >= nStt ) && ( nBEnd <= nEnd );
1653 : :
1654 [ - + ]: 93 : IFieldmark* pFieldmark = dynamic_cast<IFieldmark*>(pMark);
1655 [ + + ][ + - ]: 93 : if (pFieldmark && pFieldmark->GetFieldname() == ODF_COMMENTRANGE)
[ + - ][ + + ]
[ + + # # ]
1656 : 66 : continue;
1657 : :
1658 [ + + ][ + + ]: 27 : if ( bIsStartOk || bIsEndOk )
1659 [ + - ]: 33 : rArr.push_back( pMark );
1660 : : }
1661 : : }
1662 : 873 : return ( rArr.size() > 0 );
1663 : : }
1664 : :
1665 : : class CompareMarksEnd : public std::binary_function < const IMark *, const IMark *, bool >
1666 : : {
1667 : : public:
1668 : 6 : inline bool operator() ( const IMark * pOneB, const IMark * pTwoB ) const
1669 : : {
1670 : 6 : xub_StrLen nOEnd = pOneB->GetMarkEnd().nContent.GetIndex();
1671 : 6 : xub_StrLen nTEnd = pTwoB->GetMarkEnd().nContent.GetIndex();
1672 : :
1673 : 6 : return nOEnd < nTEnd;
1674 : : }
1675 : : };
1676 : :
1677 : 726 : bool MSWordExportBase::NearestBookmark( xub_StrLen& rNearest, const xub_StrLen nAktPos, bool bNextPositionOnly )
1678 : : {
1679 : 726 : bool bHasBookmark = false;
1680 : :
1681 [ - + ]: 726 : if ( !m_rSortedMarksStart.empty() )
1682 : : {
1683 : 0 : IMark* pMarkStart = m_rSortedMarksStart.front();
1684 : 0 : xub_StrLen nNext = pMarkStart->GetMarkStart().nContent.GetIndex();
1685 [ # # ][ # # ]: 0 : if( !bNextPositionOnly || (nNext > nAktPos ))
1686 : : {
1687 : 0 : rNearest = nNext;
1688 : 0 : bHasBookmark = true;
1689 : : }
1690 : : }
1691 : :
1692 [ + + ]: 726 : if ( !m_rSortedMarksEnd.empty() )
1693 : : {
1694 [ + - ]: 6 : IMark* pMarkEnd = m_rSortedMarksEnd[0];
1695 [ + - ]: 6 : xub_StrLen nNext = pMarkEnd->GetMarkEnd().nContent.GetIndex();
1696 [ - + ][ + + ]: 6 : if( !bNextPositionOnly || nNext > nAktPos )
1697 : : {
1698 [ + - ]: 3 : if ( !bHasBookmark )
1699 : 3 : rNearest = nNext;
1700 : : else
1701 [ # # ]: 0 : rNearest = std::min( rNearest, nNext );
1702 : 6 : bHasBookmark = true;
1703 : : }
1704 : : }
1705 : :
1706 : 726 : return bHasBookmark;
1707 : : }
1708 : :
1709 : 342 : void MSWordExportBase::GetSortedBookmarks( const SwTxtNode& rNode, xub_StrLen nAktPos, xub_StrLen nLen )
1710 : : {
1711 [ + - ]: 342 : IMarkVector aMarksStart;
1712 [ + - ][ + + ]: 342 : if ( GetBookmarks( rNode, nAktPos, nAktPos + nLen, aMarksStart ) )
1713 : : {
1714 [ + - ]: 9 : IMarkVector aSortedEnd;
1715 [ + - ]: 9 : IMarkVector aSortedStart;
1716 [ + - ][ + - ]: 24 : for ( IMarkVector::const_iterator it = aMarksStart.begin(), end = aMarksStart.end();
[ + - ][ + - ]
[ + + ]
1717 : : it != end; ++it )
1718 : : {
1719 [ + - ]: 15 : IMark* pMark = (*it);
1720 : :
1721 : : // Remove the positions egals to the current pos
1722 [ + - ]: 15 : xub_StrLen nStart = pMark->GetMarkStart().nContent.GetIndex();
1723 [ + - ]: 15 : xub_StrLen nEnd = pMark->GetMarkEnd().nContent.GetIndex();
1724 : :
1725 [ # # ][ # # ]: 15 : if ( nStart > nAktPos && ( pMark->GetMarkStart().nNode == rNode.GetIndex()) )
[ - + ][ - + ]
1726 [ # # ]: 0 : aSortedStart.push_back( pMark );
1727 : :
1728 [ + + ][ + - ]: 15 : if ( nEnd > nAktPos && nEnd <= ( nAktPos + nLen ) && (pMark->GetMarkEnd().nNode == rNode.GetIndex()) )
[ + - ][ + - ]
[ + + ]
1729 [ + - ]: 6 : aSortedEnd.push_back( pMark );
1730 : : }
1731 : :
1732 : : // Sort the bookmarks by end position
1733 [ + - ]: 9 : std::sort( aSortedEnd.begin(), aSortedEnd.end(), CompareMarksEnd() );
1734 : :
1735 : 9 : m_rSortedMarksStart.swap( aSortedStart );
1736 : 9 : m_rSortedMarksEnd.swap( aSortedEnd );
1737 : : }
1738 : : else
1739 : : {
1740 : 333 : m_rSortedMarksStart.clear( );
1741 : 333 : m_rSortedMarksEnd.clear( );
1742 : 342 : }
1743 : 342 : }
1744 : :
1745 : 300 : void MSWordExportBase::OutputTextNode( const SwTxtNode& rNode )
1746 : : {
1747 : : #ifdef DBG_UTIL
1748 : : ::std::clog << "<OutWW8_SwTxtNode>" << ::std::endl;
1749 : : #endif
1750 : :
1751 [ + - ]: 300 : ww8::WW8TableNodeInfo::Pointer_t pTextNodeInfo( mpTableInfo->getTableNodeInfo( &rNode ) );
1752 : :
1753 [ + - ][ + - ]: 300 : AttrOutput().StartParagraph( pTextNodeInfo );
[ + - ][ + - ]
1754 : :
1755 [ - + ][ # # ]: 300 : bool bFlyInTable = mpParentFrame && IsInTable();
[ # # ]
1756 : :
1757 [ + - ]: 300 : if ( !bFlyInTable )
1758 [ + - ][ + - ]: 300 : nStyleBeforeFly = GetId( lcl_getFormatCollection( *this, &rNode ) );
1759 : :
1760 : : // nStyleBeforeFly may change when we recurse into another node, so we
1761 : : // have to remember it in nStyle
1762 : 300 : sal_uInt16 nStyle = nStyleBeforeFly;
1763 : :
1764 [ + - ]: 300 : SwWW8AttrIter aAttrIter( *this, rNode );
1765 : 300 : rtl_TextEncoding eChrSet = aAttrIter.GetCharSet();
1766 : :
1767 [ - + ]: 300 : if ( bStartTOX )
1768 : : {
1769 : : // ignore TOX header section
1770 [ # # ]: 0 : const SwSectionNode* pSectNd = rNode.FindSectionNode();
1771 [ # # ][ # # ]: 0 : if ( pSectNd && TOX_CONTENT_SECTION == pSectNd->GetSection().GetType() )
[ # # ]
1772 : : {
1773 [ # # ][ # # ]: 0 : AttrOutput().StartTOX( pSectNd->GetSection() );
1774 [ # # ]: 0 : m_aCurrentCharPropStarts.push( 0 );
1775 : : }
1776 : : }
1777 : :
1778 : 300 : const SwSection* pTOXSect = 0;
1779 [ - + ]: 300 : if( bInWriteTOX )
1780 : : {
1781 : : // check for end of TOX
1782 [ # # ]: 0 : SwNodeIndex aIdx( rNode, 1 );
1783 [ # # ]: 0 : if( !aIdx.GetNode().IsTxtNode() )
1784 : : {
1785 [ # # ]: 0 : const SwSectionNode* pTOXSectNd = rNode.FindSectionNode();
1786 : 0 : pTOXSect = &pTOXSectNd->GetSection();
1787 : :
1788 [ # # ][ # # ]: 0 : const SwNode* pNxt = rNode.GetNodes().GoNext( &aIdx );
1789 [ # # ][ # # ]: 0 : if( pNxt && pNxt->FindSectionNode() == pTOXSectNd )
[ # # ][ # # ]
1790 : 0 : pTOXSect = 0;
1791 [ # # ]: 0 : }
1792 : : }
1793 : :
1794 [ + - ][ - + ]: 300 : if ( aAttrIter.RequiresImplicitBookmark() )
1795 : : {
1796 [ # # ]: 0 : String sBkmkName = String( "_toc" );
1797 [ # # ][ # # ]: 0 : sBkmkName += String::CreateFromInt32( rNode.GetIndex() );
[ # # ]
1798 [ # # ][ # # ]: 0 : AppendWordBookmark( sBkmkName );
1799 : : }
1800 : :
1801 [ + - ]: 300 : String aStr( rNode.GetTxt() );
1802 : :
1803 : 300 : xub_StrLen nAktPos = 0;
1804 : 300 : xub_StrLen const nEnd = aStr.Len();
1805 : 300 : bool bRedlineAtEnd = false;
1806 : 300 : int nOpenAttrWithRange = 0;
1807 : :
1808 [ + - ]: 300 : ww8::WW8TableNodeInfoInner::Pointer_t pTextNodeInfoInner;
1809 [ - + ]: 300 : if ( pTextNodeInfo.get() != NULL )
1810 [ # # ][ # # ]: 0 : pTextNodeInfoInner = pTextNodeInfo->getFirstInner();
[ # # ]
1811 : :
1812 [ + + ]: 384 : do {
1813 [ + - ]: 384 : const SwRedlineData* pRedlineData = aAttrIter.GetRedline( nAktPos );
1814 : :
1815 [ + - ]: 384 : xub_StrLen nNextAttr = GetNextPos( &aAttrIter, rNode, nAktPos );
1816 : : // Is this the only run in this paragraph and it's empty?
1817 [ + + ][ + + ]: 384 : bool bSingleEmptyRun = nAktPos == 0 && nNextAttr == 0;
1818 [ + - ][ + - ]: 384 : AttrOutput().StartRun( pRedlineData, bSingleEmptyRun );
1819 [ + + ][ - + ]: 384 : if( nTxtTyp == TXT_FTN || nTxtTyp == TXT_EDN )
1820 [ + - ][ + - ]: 3 : AttrOutput().FootnoteEndnoteRefTag();
1821 : :
1822 [ - + ]: 384 : if( nNextAttr > nEnd )
1823 : 0 : nNextAttr = nEnd;
1824 : :
1825 [ + - ]: 384 : aAttrIter.OutFlys( nAktPos );
1826 : : //Append bookmarks in this range after flys, exclusive of final
1827 : : //position of this range
1828 [ + - ]: 384 : AppendBookmarks( rNode, nAktPos, nNextAttr - nAktPos );
1829 [ + - ]: 384 : bool bTxtAtr = aAttrIter.IsTxtAttr( nAktPos );
1830 [ + - ]: 384 : nOpenAttrWithRange += aAttrIter.OutAttrWithRange(nAktPos);
1831 : :
1832 : 384 : xub_StrLen nLen = nNextAttr - nAktPos;
1833 [ + + ][ + + ]: 384 : if ( !bTxtAtr && nLen )
1834 : : {
1835 : 120 : sal_Unicode ch = aStr.GetChar( nAktPos );
1836 [ + + ][ - + ]: 120 : int ofs = ( ch == CH_TXT_ATR_FIELDSTART || ch == CH_TXT_ATR_FIELDEND || ch == CH_TXT_ATR_FORMELEMENT? 1: 0 );
[ + + ]
1837 : :
1838 [ + - ]: 120 : IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
1839 [ + + ]: 120 : if ( ch == CH_TXT_ATR_FIELDSTART )
1840 : : {
1841 [ + - ][ + - ]: 6 : SwPosition aPosition( rNode, SwIndex( const_cast< SwTxtNode* >( &rNode ), nAktPos ) );
[ + - ][ + - ]
[ + - ]
1842 [ + - ]: 6 : ::sw::mark::IFieldmark const * const pFieldmark = pMarkAccess->getFieldmarkFor( aPosition );
1843 : : OSL_ENSURE( pFieldmark, "Looks like this doc is broken...; where is the Fieldmark for the FIELDSTART??" );
1844 : :
1845 [ + - ][ + - ]: 6 : if ( pFieldmark && pFieldmark->GetFieldname() == ODF_FORMTEXT )
[ - + ][ + - ]
[ - + # # ]
1846 [ # # ][ # # ]: 0 : AppendBookmark( pFieldmark->GetName(), false );
1847 [ + - ]: 6 : ww::eField eFieldId = lcl_getFieldId( pFieldmark );
1848 [ + - ]: 6 : String sCode = lcl_getFieldCode( pFieldmark );
1849 [ + - ][ + - ]: 6 : if ( pFieldmark && pFieldmark->GetFieldname() == ODF_UNHANDLED )
[ - + ][ + - ]
[ - + # # ]
1850 : : {
1851 [ # # ][ # # ]: 0 : IFieldmark::parameter_map_t::const_iterator it = pFieldmark->GetParameters()->find( ODF_ID_PARAM );
1852 [ # # ][ # # ]: 0 : if ( it != pFieldmark->GetParameters()->end() )
1853 : : {
1854 : 0 : rtl::OUString sFieldId;
1855 : 0 : it->second >>= sFieldId;
1856 : 0 : eFieldId = (ww::eField)sFieldId.toInt32();
1857 : : }
1858 : :
1859 [ # # ][ # # ]: 0 : it = pFieldmark->GetParameters()->find( ODF_CODE_PARAM );
1860 [ # # ][ # # ]: 0 : if ( it != pFieldmark->GetParameters()->end() )
1861 : : {
1862 : 0 : rtl::OUString sOUCode;
1863 : 0 : it->second >>= sOUCode;
1864 [ # # ]: 0 : sCode = sOUCode;
1865 : : }
1866 : : }
1867 : :
1868 [ + - ][ + - ]: 6 : bool bCommentRange = pFieldmark && pFieldmark->GetFieldname() == ODF_COMMENTRANGE;
[ + - ][ + - ]
[ # # ]
1869 [ + - ]: 6 : if (bCommentRange)
1870 [ + - ][ + - ]: 6 : AttrOutput().WritePostitFieldStart();
1871 : : else
1872 [ # # ]: 0 : OutputField( NULL, eFieldId, sCode, WRITEFIELD_START | WRITEFIELD_CMD_START );
1873 : :
1874 [ + - ][ + - ]: 6 : if ( pFieldmark && pFieldmark->GetFieldname( ) == ODF_FORMTEXT )
[ - + ][ + - ]
[ - + # # ]
1875 [ # # ]: 0 : WriteFormData( *pFieldmark );
1876 [ + - ][ + - ]: 6 : else if ( pFieldmark && pFieldmark->GetFieldname( ) == ODF_HYPERLINK )
[ - + ][ + - ]
[ - + # # ]
1877 [ # # ]: 0 : WriteHyperlinkData( *pFieldmark );
1878 [ - + ]: 6 : if (!bCommentRange)
1879 [ # # ][ # # ]: 0 : OutputField( NULL, lcl_getFieldId( pFieldmark ), String(), WRITEFIELD_CMD_END );
[ # # ][ # # ]
1880 : :
1881 [ + - ][ + - ]: 6 : if ( pFieldmark && pFieldmark->GetFieldname() == ODF_UNHANDLED )
[ - + ][ + - ]
[ - + # # ]
1882 : : {
1883 : : // Check for the presence of a linked OLE object
1884 [ # # ][ # # ]: 0 : IFieldmark::parameter_map_t::const_iterator it = pFieldmark->GetParameters()->find( ODF_OLE_PARAM );
1885 [ # # ][ # # ]: 0 : if ( it != pFieldmark->GetParameters()->end() )
1886 : : {
1887 : 0 : rtl::OUString sOleId;
1888 : 0 : uno::Any aValue = it->second;
1889 : 0 : aValue >>= sOleId;
1890 [ # # ]: 0 : if ( !sOleId.isEmpty() )
1891 [ # # ]: 0 : OutputLinkedOLE( sOleId );
1892 : : }
1893 [ + - ][ + - ]: 6 : }
1894 : : }
1895 [ + + ]: 114 : else if ( ch == CH_TXT_ATR_FIELDEND )
1896 : : {
1897 [ + - ][ + - ]: 6 : SwPosition aPosition( rNode, SwIndex( const_cast< SwTxtNode* >( &rNode ), nAktPos ) );
[ + - ][ + - ]
[ + - ]
1898 [ + - ]: 6 : ::sw::mark::IFieldmark const * const pFieldmark = pMarkAccess->getFieldmarkFor( aPosition );
1899 : :
1900 : : OSL_ENSURE( pFieldmark, "Looks like this doc is broken...; where is the Fieldmark for the FIELDEND??" );
1901 : :
1902 [ + - ]: 6 : ww::eField eFieldId = lcl_getFieldId( pFieldmark );
1903 [ + - ][ + - ]: 6 : if ( pFieldmark && pFieldmark->GetFieldname() == ODF_UNHANDLED )
[ - + ][ + - ]
[ - + # # ]
1904 : : {
1905 [ # # ][ # # ]: 0 : IFieldmark::parameter_map_t::const_iterator it = pFieldmark->GetParameters()->find( ODF_ID_PARAM );
1906 [ # # ][ # # ]: 0 : if ( it != pFieldmark->GetParameters()->end() )
1907 : : {
1908 : 0 : rtl::OUString sFieldId;
1909 : 0 : it->second >>= sFieldId;
1910 : 0 : eFieldId = (ww::eField)sFieldId.toInt32();
1911 : : }
1912 : : }
1913 : :
1914 [ + - ][ + - ]: 6 : if (pFieldmark && pFieldmark->GetFieldname() == ODF_COMMENTRANGE)
[ + - ][ + - ]
[ + - # # ]
1915 [ + - ][ + - ]: 6 : AttrOutput().WritePostitFieldEnd();
1916 : : else
1917 [ # # ][ # # ]: 0 : OutputField( NULL, eFieldId, String(), WRITEFIELD_CLOSE );
[ # # ]
1918 : :
1919 [ + - ][ + - ]: 6 : if ( pFieldmark && pFieldmark->GetFieldname() == ODF_FORMTEXT )
[ - + ][ + - ]
[ - + # # ]
1920 [ # # ][ # # ]: 6 : AppendBookmark( pFieldmark->GetName(), false );
[ + - ]
1921 : : }
1922 [ - + ]: 108 : else if ( ch == CH_TXT_ATR_FORMELEMENT )
1923 : : {
1924 [ # # ][ # # ]: 0 : SwPosition aPosition( rNode, SwIndex( const_cast< SwTxtNode* >( &rNode ), nAktPos ) );
[ # # ][ # # ]
[ # # ]
1925 [ # # ]: 0 : ::sw::mark::IFieldmark const * const pFieldmark = pMarkAccess->getFieldmarkFor( aPosition );
1926 : : OSL_ENSURE( pFieldmark, "Looks like this doc is broken...; where is the Fieldmark for the FIELDSTART??" );
1927 : :
1928 [ # # ][ # # ]: 0 : bool isDropdownOrCheckbox = pFieldmark && (pFieldmark->GetFieldname( ) == ODF_FORMDROPDOWN ||
[ # # ]
1929 [ # # # # ]: 0 : pFieldmark->GetFieldname( ) == ODF_FORMCHECKBOX );
[ # # ][ # # ]
[ # # ][ # # ]
1930 : :
1931 [ # # ]: 0 : if ( isDropdownOrCheckbox )
1932 [ # # ][ # # ]: 0 : AppendBookmark( pFieldmark->GetName(), 0 );
1933 : : OutputField( NULL, lcl_getFieldId( pFieldmark ),
1934 : : lcl_getFieldCode( pFieldmark ),
1935 [ # # ][ # # ]: 0 : WRITEFIELD_START | WRITEFIELD_CMD_START );
[ # # ][ # # ]
1936 [ # # ]: 0 : if ( isDropdownOrCheckbox )
1937 [ # # ]: 0 : WriteFormData( *pFieldmark );
1938 [ # # ][ # # ]: 0 : OutputField( NULL, lcl_getFieldId( pFieldmark ), String(), WRITEFIELD_CLOSE );
[ # # ][ # # ]
1939 [ # # ]: 0 : if ( isDropdownOrCheckbox )
1940 [ # # ][ # # ]: 0 : AppendBookmark( pFieldmark->GetName(), false );
[ # # ]
1941 : : }
1942 : 120 : nLen -= static_cast< sal_uInt16 >( ofs );
1943 : :
1944 [ + - ]: 120 : String aSnippet( aAttrIter.GetSnippet( aStr, nAktPos + static_cast< sal_uInt16 >( ofs ), nLen ) );
1945 [ + - ][ + + ]: 120 : if ( ( nTxtTyp == TXT_EDN || nTxtTyp == TXT_FTN ) && nAktPos == 0 && nLen > 0 )
[ + - ][ + - ]
1946 : : {
1947 : : // Insert tab for aesthetic puposes #i24762#
1948 [ + - ]: 3 : if ( aSnippet.GetChar( 0 ) != 0x09 )
1949 [ + - ]: 3 : aSnippet.Insert( 0x09, 0 );
1950 : : }
1951 [ + - ][ + - ]: 120 : AttrOutput().RunText( aSnippet, eChrSet );
[ + - ]
1952 : : }
1953 : :
1954 [ + - ][ - + ]: 384 : if ( aAttrIter.IsDropCap( nNextAttr ) )
1955 [ # # ][ # # ]: 0 : AttrOutput().FormatDrop( rNode, aAttrIter.GetSwFmtDrop(), nStyle, pTextNodeInfo, pTextNodeInfoInner );
[ # # ][ # # ]
[ # # ][ # # ]
1956 : :
1957 [ + + ]: 384 : if (0 != nEnd)
1958 : : {
1959 : : // Output the character attributes
1960 : : // #i51277# do this before writing flys at end of paragraph
1961 [ + - ][ + - ]: 342 : AttrOutput().StartRunProperties();
1962 [ + - ]: 342 : aAttrIter.OutAttr( nAktPos );
1963 [ + - ][ + - ]: 342 : AttrOutput().EndRunProperties( pRedlineData );
1964 : : }
1965 : :
1966 : : // At the end of line, output the attributes until the CR.
1967 : : // Exception: footnotes at the end of line
1968 [ + + ]: 384 : if ( nNextAttr == nEnd )
1969 : : {
1970 : : OSL_ENSURE( nOpenAttrWithRange >= 0, "odd to see this happening, expected >= 0" );
1971 [ + + ][ + + ]: 300 : if ( !bTxtAtr && nOpenAttrWithRange <= 0 )
1972 : : {
1973 [ + - ][ - + ]: 129 : if ( aAttrIter.IsRedlineAtEnd( nEnd ) )
1974 : 0 : bRedlineAtEnd = true;
1975 : : else
1976 : : {
1977 : : // insert final graphic anchors if any before CR
1978 [ + - ]: 129 : aAttrIter.OutFlys( nEnd );
1979 : : // insert final bookmarks if any before CR and after flys
1980 [ + - ]: 129 : AppendBookmarks( rNode, nEnd, 1 );
1981 [ - + ]: 129 : if ( pTOXSect )
1982 : : {
1983 [ # # ]: 0 : m_aCurrentCharPropStarts.pop();
1984 [ # # ][ # # ]: 0 : AttrOutput().EndTOX( *pTOXSect );
1985 : : }
1986 [ + - ][ + - ]: 129 : WriteCR( pTextNodeInfoInner );
[ + - ]
1987 : : }
1988 : : }
1989 : : }
1990 : :
1991 [ + + ]: 384 : if (0 == nEnd)
1992 : : {
1993 : : // Output the character attributes
1994 : : // do it after WriteCR for an empty paragraph (otherwise
1995 : : // WW8_WrFkp::Append throws SPRMs away...)
1996 [ + - ][ + - ]: 42 : AttrOutput().StartRunProperties();
1997 [ + - ]: 42 : aAttrIter.OutAttr( nAktPos );
1998 [ + - ][ + - ]: 42 : AttrOutput().EndRunProperties( pRedlineData );
1999 : : }
2000 : :
2001 : : // Exception: footnotes at the end of line
2002 [ + + ]: 384 : if ( nNextAttr == nEnd )
2003 : : {
2004 : : OSL_ENSURE(nOpenAttrWithRange >= 0,
2005 : : "odd to see this happening, expected >= 0");
2006 : 300 : bool bAttrWithRange = (nOpenAttrWithRange > 0);
2007 [ + + ]: 300 : if ( nAktPos != nEnd )
2008 : : {
2009 [ + - ]: 258 : nOpenAttrWithRange += aAttrIter.OutAttrWithRange(nEnd);
2010 : : OSL_ENSURE(nOpenAttrWithRange == 0,
2011 : : "odd to see this happening, expected 0");
2012 : : }
2013 : :
2014 [ + - ][ + - ]: 300 : AttrOutput().OutputFKP();
2015 : :
2016 [ + + ][ + + ]: 300 : if ( bTxtAtr || bAttrWithRange || bRedlineAtEnd )
[ - + ]
2017 : : {
2018 : : // insert final graphic anchors if any before CR
2019 [ + - ]: 171 : aAttrIter.OutFlys( nEnd );
2020 : : // insert final bookmarks if any before CR and after flys
2021 [ + - ]: 171 : AppendBookmarks( rNode, nEnd, 1 );
2022 : :
2023 [ - + ]: 171 : if ( pTOXSect )
2024 : : {
2025 [ # # ]: 0 : m_aCurrentCharPropStarts.pop();
2026 [ # # ][ # # ]: 0 : AttrOutput().EndTOX( *pTOXSect );
2027 : : }
2028 : :
2029 [ + - ][ + - ]: 171 : WriteCR( pTextNodeInfoInner );
[ + - ]
2030 : :
2031 [ - + ]: 171 : if ( bRedlineAtEnd )
2032 : : {
2033 [ # # ][ # # ]: 0 : AttrOutput().Redline( aAttrIter.GetRedline( nEnd ) );
[ # # ]
2034 [ # # ][ # # ]: 0 : AttrOutput().OutputFKP();
2035 : : }
2036 : : }
2037 : : }
2038 : :
2039 [ + - ][ + - ]: 384 : AttrOutput().WritePostitFieldReference();
2040 : :
2041 [ + - ][ + - ]: 384 : AttrOutput().EndRun();
2042 : :
2043 : 384 : nAktPos = nNextAttr;
2044 [ + - ]: 384 : UpdatePosition( &aAttrIter, nAktPos, nEnd );
2045 : 384 : eChrSet = aAttrIter.GetCharSet();
2046 : : }
2047 : : while ( nAktPos < nEnd );
2048 : :
2049 [ + - ][ + - ]: 300 : AttrOutput().StartParagraphProperties( rNode );
2050 : :
2051 [ + - ][ + - ]: 300 : AttrOutput().ParagraphStyle( nStyle );
2052 : :
2053 [ - + ][ # # ]: 300 : if ( mpParentFrame && IsInTable() ) // Fly-Attrs
[ # # ][ - + ]
2054 [ # # ]: 0 : OutputFormat( mpParentFrame->GetFrmFmt(), false, false, true );
2055 : :
2056 [ - + ]: 300 : if ( pTextNodeInfo.get() != NULL )
2057 : : {
2058 : : #ifdef DBG_UTIL
2059 : : ::std::clog << pTextNodeInfo->toString() << ::std::endl;
2060 : : #endif
2061 : :
2062 [ # # ][ # # ]: 0 : AttrOutput().TableInfoCell( pTextNodeInfoInner );
[ # # ][ # # ]
2063 [ # # ][ # # ]: 0 : if (pTextNodeInfoInner->isFirstInTable())
2064 : : {
2065 [ # # ]: 0 : const SwTable * pTable = pTextNodeInfoInner->getTable();
2066 : :
2067 : 0 : const SwTableFmt * pTabFmt = pTable->GetTableFmt();
2068 [ # # ]: 0 : if (pTabFmt != NULL)
2069 : : {
2070 [ # # ][ # # ]: 0 : if (pTabFmt->GetBreak().GetBreak() == SVX_BREAK_PAGE_BEFORE)
2071 [ # # ][ # # ]: 0 : AttrOutput().PageBreakBefore(true);
2072 : : }
2073 : : }
2074 : : }
2075 : :
2076 [ + - ]: 300 : if ( !bFlyInTable )
2077 : : {
2078 : 300 : SfxItemSet* pTmpSet = 0;
2079 [ + - ]: 300 : const sal_uInt8 nPrvNxtNd = rNode.HasPrevNextLayNode();
2080 : :
2081 [ + + ]: 300 : if( (ND_HAS_PREV_LAYNODE|ND_HAS_NEXT_LAYNODE ) != nPrvNxtNd )
2082 : : {
2083 : : const SfxPoolItem* pItem;
2084 [ + - ][ + + ]: 405 : if( SFX_ITEM_SET == rNode.GetSwAttrSet().GetItemState(
[ + + + - ]
[ + + + + ]
[ + + ]
2085 [ + - ]: 186 : RES_UL_SPACE, true, &pItem ) &&
2086 : 21 : ( ( !( ND_HAS_PREV_LAYNODE & nPrvNxtNd ) &&
2087 : 18 : ((SvxULSpaceItem*)pItem)->GetUpper()) ||
2088 : 21 : ( !( ND_HAS_NEXT_LAYNODE & nPrvNxtNd ) &&
2089 : 15 : ((SvxULSpaceItem*)pItem)->GetLower()) ))
2090 : : {
2091 [ + - ][ + - ]: 3 : pTmpSet = new SfxItemSet( rNode.GetSwAttrSet() );
[ + - ]
2092 [ + - ]: 3 : SvxULSpaceItem aUL( *(SvxULSpaceItem*)pItem );
2093 : : // #i25901#- consider compatibility option
2094 [ + - ][ - + ]: 3 : if (!pDoc->get(IDocumentSettingAccess::PARA_SPACE_MAX_AT_PAGES))
2095 : : {
2096 [ # # ]: 0 : if( !(ND_HAS_PREV_LAYNODE & nPrvNxtNd ))
2097 : 0 : aUL.SetUpper( 0 );
2098 : : }
2099 : : // #i25901# - consider compatibility option
2100 [ + - ][ - + ]: 3 : if (!pDoc->get(IDocumentSettingAccess::ADD_PARA_SPACING_TO_TABLE_CELLS))
2101 : : {
2102 [ # # ]: 0 : if( !(ND_HAS_NEXT_LAYNODE & nPrvNxtNd ))
2103 : 0 : aUL.SetLower( 0 );
2104 : : }
2105 [ + - ][ + - ]: 186 : pTmpSet->Put( aUL );
2106 : : }
2107 : : }
2108 : :
2109 : 300 : sal_Bool bParaRTL = sal_False;
2110 : : const SvxFrameDirectionItem* pItem = (const SvxFrameDirectionItem*)
2111 [ + - ][ + - ]: 300 : rNode.GetSwAttrSet().GetItem(RES_FRAMEDIR);
2112 [ - + ]: 300 : if ( aAttrIter.IsParaRTL())
2113 : 0 : bParaRTL = sal_True;
2114 : :
2115 [ + - ][ - + ]: 300 : if( rNode.IsNumbered())
2116 : : {
2117 [ # # ]: 0 : const SwNumRule* pRule = rNode.GetNumRule();
2118 [ # # ]: 0 : sal_uInt8 nLvl = static_cast< sal_uInt8 >( rNode.GetActualListLevel() );
2119 [ # # ]: 0 : const SwNumFmt* pFmt = pRule->GetNumFmt( nLvl );
2120 [ # # ]: 0 : if( !pFmt )
2121 [ # # ]: 0 : pFmt = &pRule->Get( nLvl );
2122 : :
2123 [ # # ]: 0 : if( !pTmpSet )
2124 [ # # ][ # # ]: 0 : pTmpSet = new SfxItemSet( rNode.GetSwAttrSet() );
[ # # ]
2125 : :
2126 [ # # ][ # # ]: 0 : SvxLRSpaceItem aLR(ItemGet<SvxLRSpaceItem>(*pTmpSet, RES_LR_SPACE));
2127 : : // #i86652#
2128 [ # # ][ # # ]: 0 : if ( pFmt->GetPositionAndSpaceMode() ==
2129 : : SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
2130 : : {
2131 [ # # ][ # # ]: 0 : aLR.SetTxtLeft( aLR.GetTxtLeft() + pFmt->GetAbsLSpace() );
2132 : : }
2133 : :
2134 [ # # ][ # # ]: 0 : if( rNode.IsNumbered() && rNode.IsCountedInList() )
[ # # ][ # # ]
[ # # ]
2135 : : {
2136 : : // #i86652#
2137 [ # # ][ # # ]: 0 : if ( pFmt->GetPositionAndSpaceMode() ==
2138 : : SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
2139 : : {
2140 [ # # ]: 0 : if (bParaRTL)
2141 [ # # ][ # # ]: 0 : aLR.SetTxtFirstLineOfstValue(pFmt->GetAbsLSpace() - pFmt->GetFirstLineOffset());
2142 : : else
2143 [ # # ][ # # ]: 0 : aLR.SetTxtFirstLineOfst(GetWordFirstLineOffset(*pFmt));
2144 : : }
2145 : :
2146 : : // correct fix for issue i94187
2147 [ # # ]: 0 : if (SFX_ITEM_SET !=
2148 [ # # ]: 0 : pTmpSet->GetItemState(RES_PARATR_NUMRULE, false) )
2149 : : {
2150 : : // List style set via paragraph style - then put it into the itemset.
2151 : : // This is needed to get list level and list id exported for
2152 : : // the paragraph.
2153 [ # # ][ # # ]: 0 : pTmpSet->Put( SwNumRuleItem( pRule->GetName() ));
[ # # ]
2154 : :
2155 : : // Put indent values into the itemset in case that the list
2156 : : // style is applied via paragraph style and the list level
2157 : : // indent values are not applicable.
2158 [ # # ][ # # ]: 0 : if ( pFmt->GetPositionAndSpaceMode() ==
[ # # ][ # # ]
2159 : : SvxNumberFormat::LABEL_ALIGNMENT &&
2160 [ # # ]: 0 : !rNode.AreListLevelIndentsApplicable() )
2161 : : {
2162 [ # # ]: 0 : pTmpSet->Put( aLR );
2163 : : }
2164 : : }
2165 : : }
2166 : : else
2167 [ # # ]: 0 : pTmpSet->ClearItem(RES_PARATR_NUMRULE);
2168 : :
2169 : : // #i86652#
2170 [ # # ][ # # ]: 0 : if ( pFmt->GetPositionAndSpaceMode() ==
2171 : : SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
2172 : : {
2173 [ # # ]: 0 : pTmpSet->Put(aLR);
2174 : :
2175 : : //#i21847#
2176 : : SvxTabStopItem aItem(
2177 [ # # ][ # # ]: 0 : ItemGet<SvxTabStopItem>(*pTmpSet, RES_PARATR_TABSTOP));
2178 [ # # ][ # # ]: 0 : SvxTabStop aTabStop(pFmt->GetAbsLSpace());
2179 [ # # ]: 0 : aItem.Insert(aTabStop);
2180 [ # # ]: 0 : pTmpSet->Put(aItem);
2181 : :
2182 [ # # ][ # # ]: 0 : MSWordExportBase::CorrectTabStopInSet(*pTmpSet, pFmt->GetAbsLSpace());
[ # # ]
2183 [ # # ]: 0 : }
2184 : : }
2185 : :
2186 : : /*
2187 : : If a given para is using the FRMDIR_ENVIRONMENT direction we
2188 : : cannot export that, its its ltr then that's ok as thats word's
2189 : : default. Otherwise we must add a RTL attribute to our export list
2190 : : */
2191 : : pItem = (const SvxFrameDirectionItem*)
2192 [ + - ][ + - ]: 300 : rNode.GetSwAttrSet().GetItem(RES_FRAMEDIR);
2193 [ + - + + : 738 : if (
- + ][ - + ]
2194 : 300 : (!pItem || pItem->GetValue() == FRMDIR_ENVIRONMENT) &&
2195 : 138 : aAttrIter.IsParaRTL()
2196 : : )
2197 : : {
2198 [ # # ]: 0 : if ( !pTmpSet )
2199 [ # # ][ # # ]: 0 : pTmpSet = new SfxItemSet(rNode.GetSwAttrSet());
[ # # ]
2200 : :
2201 [ # # ][ # # ]: 0 : pTmpSet->Put(SvxFrameDirectionItem(FRMDIR_HORI_RIGHT_TOP, RES_FRAMEDIR));
[ # # ]
2202 : : }
2203 : : // move code for handling of numbered,
2204 : : // but not counted paragraphs to this place. Otherwise, the paragraph
2205 : : // isn't exported as numbered, but not counted, if no other attribute
2206 : : // is found in <pTmpSet>
2207 : : // #i44815# adjust numbering/indents for numbered paragraphs
2208 : : // without number (NO_NUMLEVEL)
2209 : : // #i47013# need to check rNode.GetNumRule()!=NULL as well.
2210 [ + - ][ - + ]: 300 : if ( ! rNode.IsCountedInList() && rNode.GetNumRule()!=NULL )
[ # # ][ # # ]
[ - + ]
2211 : : {
2212 : : // WW8 does not know numbered paragraphs without number
2213 : : // (NO_NUMLEVEL). In WW8AttributeOutput::ParaNumRule(), we will export
2214 : : // the RES_PARATR_NUMRULE as list-id 0, which in WW8 means
2215 : : // no numbering. Here, we will adjust the indents to match
2216 : : // visually.
2217 : :
2218 [ # # ]: 0 : if ( !pTmpSet )
2219 [ # # ][ # # ]: 0 : pTmpSet = new SfxItemSet(rNode.GetSwAttrSet());
[ # # ]
2220 : :
2221 : : // create new LRSpace item, based on the current (if present)
2222 : 0 : const SfxPoolItem* pPoolItem = NULL;
2223 [ # # ]: 0 : pTmpSet->GetItemState(RES_LR_SPACE, sal_True, &pPoolItem);
2224 : : SvxLRSpaceItem aLRSpace(
2225 : : ( pPoolItem == NULL )
2226 : : ? SvxLRSpaceItem(0, 0, 0, 0, RES_LR_SPACE)
2227 [ # # ][ # # ]: 0 : : *static_cast<const SvxLRSpaceItem*>( pPoolItem ) );
[ # # ]
2228 : :
2229 : : // new left margin = old left + label space
2230 [ # # ]: 0 : const SwNumRule* pRule = rNode.GetNumRule();
2231 [ # # ][ # # ]: 0 : const SwNumFmt& rNumFmt = pRule->Get( static_cast< sal_uInt16 >(rNode.GetActualListLevel()) );
2232 : : // #i86652#
2233 [ # # ][ # # ]: 0 : if ( rNumFmt.GetPositionAndSpaceMode() ==
2234 : : SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
2235 : : {
2236 [ # # ][ # # ]: 0 : aLRSpace.SetTxtLeft( aLRSpace.GetLeft() + rNumFmt.GetAbsLSpace() );
2237 : :
2238 : : // new first line indent = 0
2239 : : // (first line indent is ignored for NO_NUMLEVEL)
2240 [ # # ]: 0 : if (!bParaRTL)
2241 [ # # ]: 0 : aLRSpace.SetTxtFirstLineOfst( 0 );
2242 : :
2243 : : // put back the new item
2244 [ # # ]: 0 : pTmpSet->Put( aLRSpace );
2245 : : }
2246 : :
2247 : : // assure that numbering rule is in <pTmpSet>
2248 [ # # ][ # # ]: 0 : if (SFX_ITEM_SET != pTmpSet->GetItemState(RES_PARATR_NUMRULE, false) )
2249 : : {
2250 [ # # ][ # # ]: 0 : pTmpSet->Put( SwNumRuleItem( pRule->GetName() ));
[ # # ]
2251 [ # # ]: 0 : }
2252 : : }
2253 : :
2254 : : // #i75457#
2255 : : // Export page break after attribute from paragraph style.
2256 : : // If page break attribute at the text node exist, an existing page
2257 : : // break after at the paragraph style hasn't got to be considered.
2258 [ + - ][ + + ]: 492 : if ( !rNode.GetpSwAttrSet() ||
[ + - ][ + - ]
2259 [ + - ][ + - ]: 192 : SFX_ITEM_SET != rNode.GetpSwAttrSet()->GetItemState(RES_BREAK, false) )
2260 : : {
2261 : : const SvxFmtBreakItem* pBreakAtParaStyle =
2262 [ + - ][ + - ]: 300 : &(ItemGet<SvxFmtBreakItem>(rNode.GetSwAttrSet(), RES_BREAK));
2263 [ + - - + ]: 600 : if ( pBreakAtParaStyle &&
[ - + ]
2264 : 300 : pBreakAtParaStyle->GetBreak() == SVX_BREAK_PAGE_AFTER )
2265 : : {
2266 [ # # ]: 0 : if ( !pTmpSet )
2267 : : {
2268 [ # # ][ # # ]: 0 : pTmpSet = new SfxItemSet(rNode.GetSwAttrSet());
[ # # ]
2269 : : }
2270 [ # # ]: 0 : pTmpSet->Put( *pBreakAtParaStyle );
2271 : : }
2272 [ + + ]: 300 : else if( pTmpSet )
2273 : : { // Even a pagedesc item is set, the break item can be set 'NONE',
2274 : : // this has to be overruled.
2275 : : const SwFmtPageDesc& rPageDescAtParaStyle =
2276 [ + - ]: 3 : ItemGet<SwFmtPageDesc>( rNode, RES_PAGEDESC );
2277 [ + - ][ + - ]: 3 : if( rPageDescAtParaStyle.KnowsPageDesc() )
2278 [ + - ]: 3 : pTmpSet->ClearItem( RES_BREAK );
2279 : : }
2280 : : }
2281 : :
2282 : : // #i76520# Emulate non-splitting tables
2283 [ - + ]: 300 : if ( bOutTable )
2284 : : {
2285 [ # # ]: 0 : const SwTableNode* pTableNode = rNode.FindTableNode();
2286 : :
2287 [ # # ]: 0 : if ( pTableNode )
2288 : : {
2289 : 0 : const SwTable& rTable = pTableNode->GetTable();
2290 [ # # ]: 0 : const SvxFmtKeepItem& rKeep = rTable.GetFrmFmt()->GetKeep();
2291 : 0 : const bool bKeep = rKeep.GetValue();
2292 : 0 : const bool bDontSplit = !bKeep ?
2293 [ # # ]: 0 : !rTable.GetFrmFmt()->GetLayoutSplit().GetValue() :
2294 [ # # # # ]: 0 : false;
2295 : :
2296 [ # # ][ # # ]: 0 : if ( bKeep || bDontSplit )
2297 : : {
2298 : : // bKeep: set keep at first paragraphs in all lines
2299 : : // bDontSplit : set keep at first paragraphs in all lines except from last line
2300 : : // but only for non-complex tables
2301 [ # # ]: 0 : const SwTableBox* pBox = rNode.GetTblBox();
2302 [ # # ]: 0 : const SwTableLine* pLine = pBox ? pBox->GetUpper() : 0;
2303 : :
2304 [ # # ][ # # ]: 0 : if ( pLine && !pLine->GetUpper() )
[ # # ]
2305 : : {
2306 : : // check if box is first in that line:
2307 [ # # ][ # # ]: 0 : if ( 0 == pLine->GetTabBoxes().GetPos( pBox ) && pBox->GetSttNd() )
[ # # ][ # # ]
2308 : : {
2309 : : // check if paragraph is first in that line:
2310 [ # # ]: 0 : if ( 1 == ( rNode.GetIndex() - pBox->GetSttNd()->GetIndex() ) )
2311 : : {
2312 : 0 : bool bSetAtPara = false;
2313 [ # # ]: 0 : if ( bKeep )
2314 : 0 : bSetAtPara = true;
2315 [ # # ]: 0 : else if ( bDontSplit )
2316 : : {
2317 : : // check if pLine isn't last line in table
2318 [ # # ][ # # ]: 0 : if ( rTable.GetTabLines().size() - rTable.GetTabLines().GetPos( pLine ) != 1 )
2319 : 0 : bSetAtPara = true;
2320 : : }
2321 : :
2322 [ # # ]: 0 : if ( bSetAtPara )
2323 : : {
2324 [ # # ]: 0 : if ( !pTmpSet )
2325 [ # # ][ # # ]: 0 : pTmpSet = new SfxItemSet(rNode.GetSwAttrSet());
[ # # ]
2326 : :
2327 [ # # ]: 0 : const SvxFmtKeepItem aKeepItem( sal_True, RES_KEEP );
2328 [ # # ][ # # ]: 0 : pTmpSet->Put( aKeepItem );
2329 : : }
2330 : : }
2331 : : }
2332 : : }
2333 : : }
2334 : : }
2335 : : }
2336 : :
2337 [ + + ][ + - ]: 300 : const SfxItemSet* pNewSet = pTmpSet ? pTmpSet : rNode.GetpSwAttrSet();
2338 [ + + ]: 300 : if( pNewSet )
2339 : : { // Para-Attrs
2340 : 192 : pStyAttr = &rNode.GetAnyFmtColl().GetAttrSet();
2341 : :
2342 : 192 : const SwModify* pOldMod = pOutFmtNode;
2343 : 192 : pOutFmtNode = &rNode;
2344 : :
2345 : : // Pap-Attrs, so script is not necessary
2346 [ + - ]: 192 : OutputItemSet( *pNewSet, true, false, i18n::ScriptType::LATIN, false);
2347 : :
2348 : 192 : pStyAttr = 0;
2349 : 192 : pOutFmtNode = pOldMod;
2350 : :
2351 [ + - ][ + + ]: 192 : if( pNewSet != rNode.GetpSwAttrSet() )
2352 [ + - ][ + - ]: 3 : delete pNewSet;
2353 : : }
2354 : : }
2355 : :
2356 [ + - ][ + - ]: 300 : AttrOutput().EndParagraphProperties();
2357 : :
2358 [ + - ][ + - ]: 300 : AttrOutput().EndParagraph( pTextNodeInfoInner );
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
2359 : :
2360 : : #ifdef DBG_UTIL
2361 : : ::std::clog << "</OutWW8_SwTxtNode>" << ::std::endl;
2362 : : #endif
2363 : 300 : }
2364 : :
2365 : 0 : void WW8AttributeOutput::TableNodeInfo( ww8::WW8TableNodeInfo::Pointer_t pNodeInfo )
2366 : : {
2367 : : SVBT16 nSty;
2368 [ # # ]: 0 : ShortToSVBT16( GetExport().nStyleBeforeFly, nSty );
2369 : :
2370 [ # # ]: 0 : ww8::WW8TableNodeInfo::Inners_t::const_iterator aIt( pNodeInfo->getInners().begin() );
2371 [ # # ]: 0 : ww8::WW8TableNodeInfo::Inners_t::const_iterator aItEnd( pNodeInfo->getInners().end() );
2372 : :
2373 [ # # ]: 0 : while (aIt != aItEnd)
2374 : : {
2375 [ # # ]: 0 : ww8::WW8TableNodeInfoInner::Pointer_t pInner = aIt->second;
2376 [ # # ][ # # ]: 0 : if ( pInner->isEndOfCell() )
2377 : : {
2378 [ # # ][ # # ]: 0 : TableRowEnd( pInner->getDepth() );
2379 : :
2380 [ # # ]: 0 : m_rWW8Export.pO->insert( m_rWW8Export.pO->end(), (sal_uInt8*)&nSty, (sal_uInt8*)&nSty+2); // Style #
2381 [ # # ][ # # ]: 0 : TableInfoRow( pInner );
[ # # ]
2382 [ # # ][ # # ]: 0 : m_rWW8Export.pPapPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), m_rWW8Export.pO->size(), m_rWW8Export.pO->data());
[ # # ]
2383 : 0 : m_rWW8Export.pO->clear();
2384 : : }
2385 : :
2386 [ # # ]: 0 : if ( pInner->isEndOfLine() )
2387 : : {
2388 : : }
2389 : :
2390 : 0 : ++aIt;
2391 [ # # ]: 0 : }
2392 : 0 : }
2393 : : //---------------------------------------------------------------------------
2394 : : // Tabellen
2395 : : //---------------------------------------------------------------------------
2396 : :
2397 : 0 : void WW8AttributeOutput::EmptyParagraph()
2398 : : {
2399 : 0 : m_rWW8Export.WriteStringAsPara( aEmptyStr );
2400 : 0 : }
2401 : :
2402 : 0 : bool MSWordExportBase::NoPageBreakSection( const SfxItemSet* pSet )
2403 : : {
2404 : 0 : bool bRet = false;
2405 : : const SfxPoolItem* pI;
2406 [ # # ]: 0 : if( pSet)
2407 : : {
2408 : 0 : bool bNoPageBreak = false;
2409 [ # # ]: 0 : if ( SFX_ITEM_ON != pSet->GetItemState(RES_PAGEDESC, true, &pI)
[ # # # # ]
[ # # ]
2410 : 0 : || 0 == ((SwFmtPageDesc*)pI)->GetPageDesc() )
2411 : : {
2412 : 0 : bNoPageBreak = true;
2413 : : }
2414 : :
2415 [ # # ]: 0 : if (bNoPageBreak)
2416 : : {
2417 [ # # ][ # # ]: 0 : if (SFX_ITEM_ON != pSet->GetItemState(RES_BREAK, true, &pI))
2418 : 0 : bNoPageBreak = true;
2419 : : else
2420 : : {
2421 : 0 : SvxBreak eBreak = ((const SvxFmtBreakItem*)pI)->GetBreak();
2422 [ # # ]: 0 : switch (eBreak)
2423 : : {
2424 : : case SVX_BREAK_PAGE_BEFORE:
2425 : : case SVX_BREAK_PAGE_AFTER:
2426 : 0 : bNoPageBreak = false;
2427 : 0 : break;
2428 : : default:
2429 : 0 : break;
2430 : : }
2431 : : }
2432 : : }
2433 : 0 : bRet = bNoPageBreak;
2434 : : }
2435 : 0 : return bRet;
2436 : : }
2437 : :
2438 : :
2439 : 0 : void MSWordExportBase::OutputSectionNode( const SwSectionNode& rSectionNode )
2440 : : {
2441 : 0 : const SwSection& rSection = rSectionNode.GetSection();
2442 : :
2443 [ # # ]: 0 : SwNodeIndex aIdx( rSectionNode, 1 );
2444 : 0 : const SwNode& rNd = aIdx.GetNode();
2445 [ # # ][ # # ]: 0 : if ( !rNd.IsSectionNode() && !IsInTable() ) //No sections in table
[ # # ][ # # ]
2446 : : {
2447 : : // Bug 74245 - if the first Node inside the section has an own
2448 : : // PageDesc or PageBreak attribut, then dont write
2449 : : // here the section break
2450 : 0 : sal_uLong nRstLnNum = 0;
2451 : : const SfxItemSet* pSet;
2452 [ # # ]: 0 : if ( rNd.IsTableNode() )
2453 : 0 : pSet = &rNd.GetTableNode()->GetTable().GetFrmFmt()->GetAttrSet();
2454 [ # # ]: 0 : else if ( rNd.IsCntntNode() )
2455 : : {
2456 [ # # ]: 0 : pSet = &rNd.GetCntntNode()->GetSwAttrSet();
2457 : : nRstLnNum = ((SwFmtLineNumber&)pSet->Get(
2458 [ # # ]: 0 : RES_LINENUMBER )).GetStartValue();
2459 : : }
2460 : : else
2461 : 0 : pSet = 0;
2462 : :
2463 [ # # ][ # # ]: 0 : if ( pSet && NoPageBreakSection( pSet ) )
[ # # ][ # # ]
2464 : 0 : pSet = 0;
2465 : :
2466 [ # # ]: 0 : if ( !pSet )
2467 : : {
2468 : : // new Section with no own PageDesc/-Break
2469 : : // -> write follow section break;
2470 : 0 : const SwSectionFmt& rFmt = *rSection.GetFmt();
2471 [ # # ]: 0 : ReplaceCr( msword::PageBreak ); // Indikator fuer Page/Section-Break
2472 : :
2473 : : //Get the page in use at the top of this section
2474 [ # # ]: 0 : SwNodeIndex aIdxTmp(rSectionNode, 1);
2475 : : const SwPageDesc *pCurrent =
2476 [ # # ]: 0 : SwPageDesc::GetPageDescOfNode(aIdxTmp.GetNode());
2477 [ # # ]: 0 : if (!pCurrent)
2478 : 0 : pCurrent = pAktPageDesc;
2479 : :
2480 [ # # ][ # # ]: 0 : AppendSection( pCurrent, &rFmt, nRstLnNum );
2481 : : }
2482 : : }
2483 [ # # ]: 0 : if ( TOX_CONTENT_SECTION == rSection.GetType() )
2484 [ # # ]: 0 : bStartTOX = true;
2485 : 0 : }
2486 : :
2487 : :
2488 : 0 : void WW8Export::AppendSection( const SwPageDesc *pPageDesc, const SwSectionFmt* pFmt, sal_uLong nLnNum )
2489 : : {
2490 : 0 : pSepx->AppendSep(Fc2Cp(Strm().Tell()), pPageDesc, pFmt, nLnNum);
2491 : 0 : }
2492 : :
2493 : :
2494 : : //---------------------------------------------------------------------------
2495 : : // Flys
2496 : : //---------------------------------------------------------------------------
2497 : :
2498 : 0 : void WW8Export::OutWW6FlyFrmsInCntnt( const SwTxtNode& rNd )
2499 : : {
2500 : : OSL_ENSURE(!bWrtWW8, "I shouldn't be needed for Word >=8");
2501 [ # # ]: 0 : if ( bWrtWW8 )
2502 : 0 : return;
2503 : :
2504 [ # # ]: 0 : if (const SwpHints* pTxtAttrs = rNd.GetpSwpHints())
2505 : : {
2506 [ # # ]: 0 : for( sal_uInt16 n=0; n < pTxtAttrs->Count(); ++n )
2507 : : {
2508 : 0 : const SwTxtAttr* pAttr = (*pTxtAttrs)[ n ];
2509 [ # # ]: 0 : if( RES_TXTATR_FLYCNT == pAttr->Which() )
2510 : : {
2511 : : // zeichengebundenes Attribut
2512 : 0 : const SwFmtFlyCnt& rFlyCntnt = pAttr->GetFlyCnt();
2513 : 0 : const SwFlyFrmFmt& rFlyFrmFmt = *(SwFlyFrmFmt*)rFlyCntnt.GetFrmFmt();
2514 : 0 : const SwNodeIndex* pNodeIndex = rFlyFrmFmt.GetCntnt().GetCntntIdx();
2515 : :
2516 [ # # ]: 0 : if( pNodeIndex )
2517 : : {
2518 : 0 : sal_uLong nStt = pNodeIndex->GetIndex()+1,
2519 : 0 : nEnd = pNodeIndex->GetNode().EndOfSectionIndex();
2520 : :
2521 [ # # ][ # # ]: 0 : if( (nStt < nEnd) && !pDoc->GetNodes()[ nStt ]->IsNoTxtNode() )
[ # # ]
2522 : : {
2523 : 0 : Point aOffset;
2524 : : // Rechtecke des Flys und des Absatzes besorgen
2525 [ # # ]: 0 : SwRect aParentRect(rNd.FindLayoutRect(false, &aOffset)),
2526 [ # # ]: 0 : aFlyRect(rFlyFrmFmt.FindLayoutRect(false, &aOffset ) );
2527 : :
2528 : 0 : aOffset = aFlyRect.Pos() - aParentRect.Pos();
2529 : :
2530 : : // PaM umsetzen: auf Inhalt des Fly-Frameformats
2531 [ # # ]: 0 : SaveData( nStt, nEnd );
2532 : :
2533 : : // wird in OutputFormat() ausgewertet
2534 : 0 : pFlyOffset = &aOffset;
2535 [ # # ]: 0 : eNewAnchorType = rFlyFrmFmt.GetAnchor().GetAnchorId();
2536 [ # # ][ # # ]: 0 : sw::Frame aFrm(rFlyFrmFmt, SwPosition(rNd));
[ # # ]
2537 : 0 : mpParentFrame = &aFrm;
2538 : : // Ok, rausschreiben:
2539 [ # # ]: 0 : WriteText();
2540 : :
2541 [ # # ][ # # ]: 0 : RestoreData();
2542 : : }
2543 : : }
2544 : : }
2545 : : }
2546 : : }
2547 : : }
2548 : :
2549 : 6 : void WW8AttributeOutput::OutputFlyFrame_Impl( const sw::Frame& rFmt, const Point& rNdTopLeft )
2550 : : {
2551 : 6 : const SwFrmFmt &rFrmFmt = rFmt.GetFrmFmt();
2552 : 6 : const SwFmtAnchor& rAnch = rFrmFmt.GetAnchor();
2553 : :
2554 : 6 : bool bUseEscher = m_rWW8Export.bWrtWW8;
2555 : :
2556 [ - + ][ - + ]: 6 : if ( m_rWW8Export.bWrtWW8 && rFmt.IsInline() )
[ + - ]
2557 : : {
2558 : 0 : sw::Frame::WriterSource eType = rFmt.GetWriterType();
2559 [ # # ][ # # ]: 0 : if ((eType == sw::Frame::eGraphic) || (eType == sw::Frame::eOle))
2560 : 0 : bUseEscher = false;
2561 : : else
2562 : 0 : bUseEscher = true;
2563 : :
2564 : : /*
2565 : : A special case for converting some inline form controls to form fields
2566 : : when in winword 8+ mode
2567 : : */
2568 [ # # ][ # # ]: 0 : if ((bUseEscher == true) && (eType == sw::Frame::eFormControl))
2569 : : {
2570 [ # # ]: 0 : if ( m_rWW8Export.MiserableFormFieldExportHack( rFrmFmt ) )
2571 : 0 : return ;
2572 : : }
2573 : : }
2574 : :
2575 [ + - ]: 6 : if (bUseEscher)
2576 : : {
2577 : : OSL_ENSURE( m_rWW8Export.bWrtWW8, "this has gone horribly wrong" );
2578 : : // write as escher
2579 : 6 : m_rWW8Export.AppendFlyInFlys(rFmt, rNdTopLeft);
2580 : : }
2581 : : else
2582 : : {
2583 : 0 : bool bDone = false;
2584 : :
2585 : : // Hole vom Node und vom letzten Node die Position in der Section
2586 : 0 : const SwNodeIndex* pNodeIndex = rFrmFmt.GetCntnt().GetCntntIdx();
2587 : :
2588 [ # # ]: 0 : sal_uLong nStt = pNodeIndex ? pNodeIndex->GetIndex()+1 : 0;
2589 [ # # ]: 0 : sal_uLong nEnd = pNodeIndex ? pNodeIndex->GetNode().EndOfSectionIndex() : 0;
2590 : :
2591 [ # # ]: 0 : if( nStt >= nEnd ) // kein Bereich, also kein gueltiger Node
2592 : 0 : return;
2593 : :
2594 [ # # ][ # # ]: 0 : if ( !m_rWW8Export.IsInTable() && rFmt.IsInline() )
[ # # ]
2595 : : {
2596 : : //Test to see if this textbox contains only a single graphic/ole
2597 : 0 : SwTxtNode* pParTxtNode = rAnch.GetCntntAnchor()->nNode.GetNode().GetTxtNode();
2598 [ # # ][ # # ]: 0 : if ( pParTxtNode && !m_rWW8Export.pDoc->GetNodes()[ nStt ]->IsNoTxtNode() )
[ # # ]
2599 : 0 : bDone = true;
2600 : : }
2601 [ # # ]: 0 : if( !bDone )
2602 : : {
2603 : :
2604 [ # # ]: 0 : m_rWW8Export.SaveData( nStt, nEnd );
2605 : :
2606 : 0 : Point aOffset;
2607 [ # # ]: 0 : if ( m_rWW8Export.mpParentFrame )
2608 : : {
2609 : : /* Munge flys in fly into absolutely positioned elements for word 6 */
2610 [ # # ]: 0 : const SwTxtNode* pParTxtNode = rAnch.GetCntntAnchor()->nNode.GetNode().GetTxtNode();
2611 [ # # ]: 0 : const SwRect aPageRect = pParTxtNode->FindPageFrmRect( sal_False, 0, sal_False );
2612 : :
2613 [ # # ]: 0 : aOffset = rFrmFmt.FindLayoutRect().Pos();
2614 : 0 : aOffset -= aPageRect.Pos();
2615 : :
2616 : 0 : m_rWW8Export.pFlyOffset = &aOffset;
2617 : 0 : m_rWW8Export.eNewAnchorType = FLY_AT_PAGE;
2618 : : }
2619 : :
2620 : 0 : m_rWW8Export.mpParentFrame = &rFmt;
2621 [ # # # # : 0 : if (
# # ][ # # ]
2622 [ # # ]: 0 : m_rWW8Export.IsInTable() &&
2623 : 0 : (FLY_AT_PAGE != rAnch.GetAnchorId()) &&
2624 [ # # ][ # # ]: 0 : !m_rWW8Export.pDoc->GetNodes()[ nStt ]->IsNoTxtNode()
2625 : : )
2626 : : {
2627 : : // Beachten: Flag bOutTable wieder setzen,
2628 : : // denn wir geben ja ganz normalen Content der
2629 : : // Tabelenzelle aus und keinen Rahmen
2630 : : // (Flag wurde oben in aSaveData() geloescht)
2631 : 0 : m_rWW8Export.bOutTable = true;
2632 : 0 : const String& rName = rFrmFmt.GetName();
2633 [ # # ]: 0 : m_rWW8Export.StartCommentOutput(rName);
2634 [ # # ]: 0 : m_rWW8Export.WriteText();
2635 [ # # ]: 0 : m_rWW8Export.EndCommentOutput(rName);
2636 : : }
2637 : : else
2638 [ # # ]: 0 : m_rWW8Export.WriteText();
2639 : :
2640 [ # # ]: 6 : m_rWW8Export.RestoreData();
2641 : : }
2642 : : }
2643 : : }
2644 : :
2645 : 9 : void AttributeOutputBase::OutputFlyFrame( const sw::Frame& rFmt )
2646 : : {
2647 [ + - ]: 9 : if ( !rFmt.GetCntntNode() )
2648 : 9 : return;
2649 : :
2650 : 9 : const SwCntntNode &rNode = *rFmt.GetCntntNode();
2651 : 9 : Point aNdPos, aPgPos;
2652 : : Point* pLayPos;
2653 : 9 : bool bValidNdPos = false, bValidPgPos = false;
2654 : :
2655 [ - + ][ + - ]: 9 : if (FLY_AT_PAGE == rFmt.GetFrmFmt().GetAnchor().GetAnchorId())
2656 : : {
2657 : : // get the Layout Node-Position.
2658 [ # # ]: 0 : if ( !bValidPgPos )
2659 : : {
2660 [ # # ]: 0 : aPgPos = rNode.FindPageFrmRect(false, &aPgPos).Pos();
2661 : 0 : bValidPgPos = true;
2662 : : }
2663 : 0 : pLayPos = &aPgPos;
2664 : : }
2665 : : else
2666 : : {
2667 : : // get the Layout Node-Position.
2668 [ + - ]: 9 : if ( !bValidNdPos )
2669 : : {
2670 [ + - ]: 9 : aNdPos = rNode.FindLayoutRect(false, &aNdPos).Pos();
2671 : 9 : bValidNdPos = true;
2672 : : }
2673 : 9 : pLayPos = &aNdPos;
2674 : : }
2675 : :
2676 [ + - ]: 9 : OutputFlyFrame_Impl( rFmt, *pLayPos );
2677 : : }
2678 : :
2679 : : // write data of any redline
2680 : 81 : void WW8AttributeOutput::Redline( const SwRedlineData* pRedline )
2681 : : {
2682 [ + - ]: 81 : if ( !pRedline )
2683 : 81 : return;
2684 : :
2685 [ # # ]: 0 : if ( pRedline->Next() )
2686 : 0 : Redline( pRedline->Next() );
2687 : :
2688 : : static sal_uInt16 aSprmIds[ 2 * 2 * 3 ] =
2689 : : {
2690 : : // Ids for insert
2691 : : NS_sprm::LN_CFRMark, NS_sprm::LN_CIbstRMark, NS_sprm::LN_CDttmRMark, // for WW8
2692 : : 0x0042, 0x0045, 0x0046, // for WW6
2693 : : // Ids for delete
2694 : : NS_sprm::LN_CFRMarkDel, NS_sprm::LN_CIbstRMarkDel, NS_sprm::LN_CDttmRMarkDel, // for WW8
2695 : : 0x0041, 0x0045, 0x0046 // for WW6
2696 : : };
2697 : :
2698 : 0 : const sal_uInt16* pSprmIds = 0;
2699 [ # # # # ]: 0 : switch( pRedline->GetType() )
2700 : : {
2701 : : case nsRedlineType_t::REDLINE_INSERT:
2702 : 0 : pSprmIds = aSprmIds;
2703 : 0 : break;
2704 : :
2705 : : case nsRedlineType_t::REDLINE_DELETE:
2706 : 0 : pSprmIds = aSprmIds + (2 * 3);
2707 : 0 : break;
2708 : :
2709 : : case nsRedlineType_t::REDLINE_FORMAT:
2710 [ # # ]: 0 : if( m_rWW8Export.bWrtWW8 )
2711 : : {
2712 : 0 : m_rWW8Export.InsUInt16( NS_sprm::LN_CPropRMark );
2713 [ # # ]: 0 : m_rWW8Export.pO->push_back( 7 ); // len
2714 [ # # ]: 0 : m_rWW8Export.pO->push_back( 1 );
2715 : 0 : m_rWW8Export.InsUInt16( m_rWW8Export.AddRedlineAuthor( pRedline->GetAuthor() ) );
2716 : 0 : m_rWW8Export.InsUInt32( sw::ms::DateTime2DTTM( pRedline->GetTimeStamp() ));
2717 : : }
2718 : 0 : break;
2719 : : default:
2720 : : OSL_ENSURE(!this, "Unhandled redline type for export");
2721 : 0 : break;
2722 : : }
2723 : :
2724 [ # # ]: 0 : if ( pSprmIds )
2725 : : {
2726 [ # # ]: 0 : if ( !m_rWW8Export.bWrtWW8 )
2727 : 0 : pSprmIds += 3;
2728 : :
2729 [ # # ]: 0 : if ( m_rWW8Export.bWrtWW8 )
2730 : 0 : m_rWW8Export.InsUInt16( pSprmIds[0] );
2731 : : else
2732 [ # # ]: 0 : m_rWW8Export.pO->push_back( msword_cast<sal_uInt8>(pSprmIds[0]) );
2733 [ # # ]: 0 : m_rWW8Export.pO->push_back( 1 );
2734 : :
2735 [ # # ]: 0 : if ( m_rWW8Export.bWrtWW8 )
2736 : 0 : m_rWW8Export.InsUInt16( pSprmIds[1] );
2737 : : else
2738 [ # # ]: 0 : m_rWW8Export.pO->push_back( msword_cast<sal_uInt8>(pSprmIds[1]) );
2739 : 0 : m_rWW8Export.InsUInt16( m_rWW8Export.AddRedlineAuthor( pRedline->GetAuthor() ) );
2740 : :
2741 [ # # ]: 0 : if ( m_rWW8Export.bWrtWW8 )
2742 : 0 : m_rWW8Export.InsUInt16( pSprmIds[2] );
2743 : : else
2744 [ # # ]: 0 : m_rWW8Export.pO->push_back( msword_cast<sal_uInt8>(pSprmIds[2]) );
2745 : 0 : m_rWW8Export.InsUInt32( sw::ms::DateTime2DTTM( pRedline->GetTimeStamp() ));
2746 : : }
2747 : : }
2748 : :
2749 : :
2750 : 300 : void MSWordExportBase::OutputContentNode( const SwCntntNode& rNode )
2751 : : {
2752 [ + - - - ]: 300 : switch ( rNode.GetNodeType() )
2753 : : {
2754 : : case ND_TEXTNODE:
2755 : : {
2756 : 300 : const SwTxtNode& rTextNode = *rNode.GetTxtNode();
2757 [ # # ][ + - ]: 300 : if( !mbOutOutlineOnly || rTextNode.IsOutline() )
[ - + ]
2758 : 300 : OutputTextNode( rTextNode );
2759 : : }
2760 : 300 : break;
2761 : : case ND_GRFNODE:
2762 : 0 : OutputGrfNode( *rNode.GetGrfNode() );
2763 : 0 : break;
2764 : : case ND_OLENODE:
2765 : 0 : OutputOLENode( *rNode.GetOLENode() );
2766 : 0 : break;
2767 : : default:
2768 : : OSL_TRACE("Unhandled node, type == %d", rNode.GetNodeType() );
2769 : 0 : break;
2770 : : }
2771 [ + - ][ + - ]: 354 : }
2772 : :
2773 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|