Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : /*
21 : * This file contains methods for the WW8 output
22 : * (nodes, attributes, formats und chars).
23 : */
24 :
25 : #include <hintids.hxx>
26 :
27 : #include <vcl/svapp.hxx>
28 : #include <vcl/salbtype.hxx>
29 : #include <vcl/settings.hxx>
30 :
31 : #include <svl/zformat.hxx>
32 : #include <svl/itemiter.hxx>
33 : #include <svl/whiter.hxx>
34 : #include <svl/grabbagitem.hxx>
35 : #include <editeng/fontitem.hxx>
36 : #include <editeng/tstpitem.hxx>
37 : #include <editeng/adjustitem.hxx>
38 : #include <editeng/spltitem.hxx>
39 : #include <editeng/widwitem.hxx>
40 : #include <editeng/lspcitem.hxx>
41 : #include <editeng/keepitem.hxx>
42 : #include <editeng/shaditem.hxx>
43 : #include <editeng/brushitem.hxx>
44 : #include <editeng/postitem.hxx>
45 : #include <editeng/wghtitem.hxx>
46 : #include <editeng/kernitem.hxx>
47 : #include <editeng/crossedoutitem.hxx>
48 : #include <editeng/cmapitem.hxx>
49 : #include <editeng/wrlmitem.hxx>
50 : #include <editeng/udlnitem.hxx>
51 : #include <editeng/langitem.hxx>
52 : #include <editeng/escapementitem.hxx>
53 : #include <editeng/fhgtitem.hxx>
54 : #include <editeng/colritem.hxx>
55 : #include <editeng/hyphenzoneitem.hxx>
56 : #include <editeng/formatbreakitem.hxx>
57 : #include <editeng/lrspitem.hxx>
58 : #include <editeng/ulspitem.hxx>
59 : #include <editeng/boxitem.hxx>
60 : #include <editeng/contouritem.hxx>
61 : #include <editeng/shdditem.hxx>
62 : #include <editeng/autokernitem.hxx>
63 : #include <editeng/pbinitem.hxx>
64 : #include <editeng/emphasismarkitem.hxx>
65 : #include <editeng/twolinesitem.hxx>
66 : #include <editeng/charscaleitem.hxx>
67 : #include <editeng/charrotateitem.hxx>
68 : #include <editeng/charreliefitem.hxx>
69 : #include <editeng/paravertalignitem.hxx>
70 : #include <editeng/pgrditem.hxx>
71 : #include <editeng/frmdiritem.hxx>
72 : #include <editeng/blinkitem.hxx>
73 : #include <editeng/charhiddenitem.hxx>
74 : #include <editeng/paperinf.hxx>
75 : #include <svx/xfillit0.hxx>
76 : #include <svx/xflgrit.hxx>
77 : #include <fmtfld.hxx>
78 : #include <fchrfmt.hxx>
79 : #include <fmtfsize.hxx>
80 : #include <fmtpdsc.hxx>
81 : #include <fmtornt.hxx>
82 : #include <fmtanchr.hxx>
83 : #include <fmtclds.hxx>
84 : #include <fmtsrnd.hxx>
85 : #include <fmtftn.hxx>
86 : #include <fmtflcnt.hxx>
87 : #include <frmatr.hxx>
88 : #include <swtable.hxx>
89 : #include <fmtinfmt.hxx>
90 : #include <txtfld.hxx>
91 : #include <txtftn.hxx>
92 : #include <poolfmt.hxx>
93 : #include <doc.hxx>
94 : #include <IDocumentSettingAccess.hxx>
95 : #include <IDocumentFieldsAccess.hxx>
96 : #include <IDocumentStylePoolAccess.hxx>
97 : #include <docary.hxx>
98 : #include <pam.hxx>
99 : #include <paratr.hxx>
100 : #include <fldbas.hxx>
101 : #include <docufld.hxx>
102 : #include <expfld.hxx>
103 : #include <pagedesc.hxx>
104 : #include <flddat.hxx>
105 : #include <ndtxt.hxx>
106 : #include <swrect.hxx>
107 : #include <reffld.hxx>
108 : #include <ftninfo.hxx>
109 : #include <charfmt.hxx>
110 : #include <section.hxx>
111 : #include <lineinfo.hxx>
112 : #include <fmtline.hxx>
113 : #include <tox.hxx>
114 : #include <fmtftntx.hxx>
115 : #include <breakit.hxx>
116 : #include <com/sun/star/i18n/ScriptType.hpp>
117 : #include <unotools/localedatawrapper.hxx>
118 : #include <svx/unobrushitemhelper.hxx>
119 : #include <svx/xenum.hxx>
120 : #include <tgrditem.hxx>
121 : #include <flddropdown.hxx>
122 : #include <chpfld.hxx>
123 : #include <fmthdft.hxx>
124 : #include <authfld.hxx>
125 :
126 : #include <sprmids.hxx>
127 :
128 : #include <fmtcntnt.hxx>
129 : #include "writerhelper.hxx"
130 : #include "writerwordglue.hxx"
131 : #include "wrtww8.hxx"
132 : #include "ww8par.hxx"
133 : #include "ww8attributeoutput.hxx"
134 : #include "fields.hxx"
135 : #include <vcl/outdev.hxx>
136 : #include <i18nlangtag/languagetag.hxx>
137 :
138 : using ::editeng::SvxBorderLine;
139 : using namespace ::com::sun::star;
140 : using namespace nsFieldFlags;
141 : using namespace nsSwDocInfoSubType;
142 : using namespace sw::util;
143 : using namespace sw::types;
144 :
145 4438 : bool WW8Export::CollapseScriptsforWordOk( sal_uInt16 nScript, sal_uInt16 nWhich )
146 : {
147 4438 : bool bRet = true;
148 4438 : if ( nScript == i18n::ScriptType::ASIAN )
149 : {
150 : //for asian in ww8, there is only one fontsize
151 : //and one fontstyle (posture/weight) for ww6
152 : //there is the additional problem that there
153 : //is only one font setting for all three scripts
154 0 : switch ( nWhich )
155 : {
156 : case RES_CHRATR_FONTSIZE:
157 : case RES_CHRATR_POSTURE:
158 : case RES_CHRATR_WEIGHT:
159 0 : bRet = false;
160 0 : break;
161 : case RES_CHRATR_LANGUAGE:
162 : case RES_CHRATR_CTL_FONT:
163 : case RES_CHRATR_CTL_FONTSIZE:
164 : case RES_CHRATR_CTL_LANGUAGE:
165 : case RES_CHRATR_CTL_POSTURE:
166 : case RES_CHRATR_CTL_WEIGHT:
167 0 : if (bWrtWW8 == 0)
168 0 : bRet = false;
169 : default:
170 0 : break;
171 : }
172 : }
173 4438 : else if ( nScript == i18n::ScriptType::COMPLEX )
174 : {
175 : //Complex is ok in ww8, but for ww6 there is only
176 : //one font, one fontsize, one fontsize (weight/posture)
177 : //and only one language
178 0 : if ( bWrtWW8 == 0 )
179 : {
180 0 : switch ( nWhich )
181 : {
182 : case RES_CHRATR_CJK_FONT:
183 : case RES_CHRATR_CJK_FONTSIZE:
184 : case RES_CHRATR_CJK_POSTURE:
185 : case RES_CHRATR_CJK_WEIGHT:
186 : case RES_CHRATR_CJK_LANGUAGE:
187 : case RES_CHRATR_FONT:
188 : case RES_CHRATR_FONTSIZE:
189 : case RES_CHRATR_POSTURE:
190 : case RES_CHRATR_WEIGHT:
191 : case RES_CHRATR_LANGUAGE:
192 0 : bRet = false;
193 0 : break;
194 : default:
195 0 : break;
196 : }
197 : }
198 : }
199 : else
200 : {
201 : //for western in ww8, there is only one fontsize
202 : //and one fontstyle (posture/weight) for ww6
203 : //there is the additional problem that there
204 : //is only one font setting for all three scripts
205 4438 : switch ( nWhich )
206 : {
207 : case RES_CHRATR_CJK_FONTSIZE:
208 : case RES_CHRATR_CJK_POSTURE:
209 : case RES_CHRATR_CJK_WEIGHT:
210 960 : bRet = false;
211 960 : break;
212 : case RES_CHRATR_CJK_LANGUAGE:
213 : case RES_CHRATR_CTL_FONT:
214 : case RES_CHRATR_CTL_FONTSIZE:
215 : case RES_CHRATR_CTL_LANGUAGE:
216 : case RES_CHRATR_CTL_POSTURE:
217 : case RES_CHRATR_CTL_WEIGHT:
218 1546 : if ( bWrtWW8 == 0 )
219 0 : bRet = false;
220 : default:
221 3478 : break;
222 : }
223 : }
224 4438 : return bRet;
225 : }
226 :
227 : // Hilfsroutinen fuer Styles
228 :
229 32810 : void MSWordExportBase::ExportPoolItemsToCHP( sw::PoolItems &rItems, sal_uInt16 nScript )
230 : {
231 32810 : sw::cPoolItemIter aEnd = rItems.end();
232 186040 : for ( sw::cPoolItemIter aI = rItems.begin(); aI != aEnd; ++aI )
233 : {
234 153230 : const SfxPoolItem *pItem = aI->second;
235 153230 : sal_uInt16 nWhich = pItem->Which();
236 153230 : if ( ( isCHRATR( nWhich ) || isTXTATR( nWhich ) ) && CollapseScriptsforWordOk( nScript, nWhich ) )
237 : {
238 : //In the id definition, RES_TXTATR_INETFMT must precede RES_TXTATR_CHARFMT, so that link style can overwrite char style.
239 : //and in #i24291# it describes "All we want to do is ensure for now is that if a charfmt exist in the character
240 : //properties that it rises to the top and is exported first."
241 : //In bug 119649, it is in such situation, so we need to ignore the link style when doing ms word filter exports and
242 : //add the second judgement for #i24291# definition.
243 88442 : if ( nWhich == RES_TXTATR_INETFMT && ( rItems.begin()->second->Which() == RES_TXTATR_CHARFMT ) )
244 32 : continue;
245 88410 : AttrOutput().OutputItem( *pItem );
246 : }
247 : }
248 32810 : }
249 :
250 : /*
251 : * Format wie folgt ausgeben:
252 : * - gebe die Attribute aus; ohne Parents!
253 : */
254 :
255 47110 : void MSWordExportBase::OutputItemSet( const SfxItemSet& rSet, bool bPapFmt, bool bChpFmt, sal_uInt16 nScript,
256 : bool bExportParentItemSet )
257 : {
258 47110 : if( bExportParentItemSet || rSet.Count() )
259 : {
260 : const SfxPoolItem* pItem;
261 44614 : pISet = &rSet; // fuer Doppel-Attribute
262 :
263 : // If frame dir is set, but not adjust, then force adjust as well
264 44614 : if ( bPapFmt && SfxItemState::SET == rSet.GetItemState( RES_FRAMEDIR, bExportParentItemSet ) )
265 : {
266 : // No explicit adjust set ?
267 1968 : if ( SfxItemState::SET != rSet.GetItemState( RES_PARATR_ADJUST, bExportParentItemSet ) )
268 : {
269 400 : if ( 0 != ( pItem = rSet.GetItem( RES_PARATR_ADJUST, bExportParentItemSet ) ) )
270 : {
271 : // then set the adjust used by the parent format
272 22 : AttrOutput().OutputItem( *pItem );
273 : }
274 : }
275 : }
276 :
277 44614 : if ( bPapFmt && SfxItemState::SET == rSet.GetItemState( RES_PARATR_NUMRULE, bExportParentItemSet, &pItem ) )
278 : {
279 1312 : AttrOutput().OutputItem( *pItem );
280 :
281 : // switch off the numerbering?
282 2962 : if ( ( (SwNumRuleItem*)pItem )->GetValue().isEmpty() &&
283 1630 : SfxItemState::SET != rSet.GetItemState( RES_LR_SPACE, false) &&
284 318 : SfxItemState::SET == rSet.GetItemState( RES_LR_SPACE, true, &pItem ) )
285 : {
286 : // the set the LR-Space of the parentformat!
287 24 : AttrOutput().OutputItem( *pItem );
288 : }
289 : }
290 :
291 44614 : sw::PoolItems aItems;
292 44614 : GetPoolItems( rSet, aItems, bExportParentItemSet );
293 44614 : if ( bChpFmt )
294 19316 : ExportPoolItemsToCHP(aItems, nScript);
295 44614 : if ( bPapFmt )
296 : {
297 25298 : sw::cPoolItemIter aEnd = aItems.end();
298 172298 : for ( sw::cPoolItemIter aI = aItems.begin(); aI != aEnd; ++aI )
299 : {
300 147000 : pItem = aI->second;
301 147000 : sal_uInt16 nWhich = pItem->Which();
302 : // Handle fill attributes just like frame attributes for now.
303 147000 : if ( (nWhich >= RES_PARATR_BEGIN && nWhich < RES_FRMATR_END && nWhich != RES_PARATR_NUMRULE ) ||
304 2596 : (nWhich >= XATTR_FILL_FIRST && nWhich < XATTR_FILL_LAST))
305 84830 : AttrOutput().OutputItem( *pItem );
306 : }
307 : }
308 44614 : pISet = 0; // fuer Doppel-Attribute
309 : }
310 47110 : }
311 :
312 : #include "switerator.hxx"
313 :
314 1032 : void MSWordExportBase::GatherChapterFields()
315 : {
316 : //If the header/footer contains a chapter field
317 1032 : SwFieldType* pType = pDoc->getIDocumentFieldsAccess().GetSysFldType( RES_CHAPTERFLD );
318 1032 : SwIterator<SwFmtFld,SwFieldType> aFmtFlds( *pType );
319 1032 : for ( SwFmtFld* pFld = aFmtFlds.First(); pFld; pFld = aFmtFlds.Next() )
320 : {
321 0 : if (const SwTxtFld *pTxtFld = pFld->GetTxtFld())
322 : {
323 0 : const SwTxtNode &rTxtNode = pTxtFld->GetTxtNode();
324 0 : maChapterFieldLocs.push_back(rTxtNode.GetIndex());
325 : }
326 1032 : }
327 1032 : }
328 :
329 0 : bool MSWordExportBase::CntntContainsChapterField(const SwFmtCntnt &rCntnt) const
330 : {
331 0 : bool bRet = false;
332 0 : if ( const SwNodeIndex* pSttIdx = rCntnt.GetCntntIdx() )
333 : {
334 0 : SwNodeIndex aIdx( *pSttIdx, 1 );
335 0 : SwNodeIndex aEnd( *pSttIdx->GetNode().EndOfSectionNode() );
336 0 : sal_uLong nStart = aIdx.GetIndex();
337 0 : sal_uLong nEnd = aEnd.GetIndex();
338 : //If the header/footer contains a chapter field
339 0 : mycCFIter aIEnd = maChapterFieldLocs.end();
340 0 : for ( mycCFIter aI = maChapterFieldLocs.begin(); aI != aIEnd; ++aI )
341 : {
342 0 : if ( ( nStart <= *aI ) && ( *aI <= nEnd ) )
343 : {
344 0 : bRet = true;
345 0 : break;
346 : }
347 0 : }
348 : }
349 0 : return bRet;
350 : }
351 :
352 162 : bool MSWordExportBase::FmtHdFtContainsChapterField(const SwFrmFmt &rFmt) const
353 : {
354 162 : if ( maChapterFieldLocs.empty() )
355 162 : return false;
356 :
357 0 : const SwFrmFmt *pFmt = 0;
358 :
359 0 : pFmt = rFmt.GetHeader().GetHeaderFmt();
360 0 : if ( pFmt && CntntContainsChapterField( pFmt->GetCntnt() ) )
361 0 : return true;
362 :
363 0 : pFmt = rFmt.GetFooter().GetFooterFmt();
364 0 : if ( pFmt && CntntContainsChapterField( pFmt->GetCntnt() ) )
365 0 : return true;
366 :
367 0 : return false;
368 : }
369 :
370 184 : bool MSWordExportBase::SetAktPageDescFromNode(const SwNode &rNd)
371 : {
372 184 : bool bNewPageDesc = false;
373 184 : const SwPageDesc* pCurrent = SwPageDesc::GetPageDescOfNode(rNd);
374 : OSL_ENSURE(pCurrent && pAktPageDesc, "Not possible surely");
375 184 : if (pAktPageDesc && pCurrent)
376 : {
377 184 : if (pCurrent != pAktPageDesc)
378 : {
379 22 : if (pAktPageDesc->GetFollow() != pCurrent)
380 0 : bNewPageDesc = true;
381 : else
382 : {
383 22 : const SwFrmFmt& rTitleFmt = pAktPageDesc->GetFirstMaster();
384 22 : const SwFrmFmt& rFollowFmt = pCurrent->GetMaster();
385 :
386 : bNewPageDesc = !IsPlausableSingleWordSection(rTitleFmt,
387 22 : rFollowFmt);
388 : }
389 22 : pAktPageDesc = pCurrent;
390 : }
391 : else
392 : {
393 162 : const SwFrmFmt &rFmt = pCurrent->GetMaster();
394 162 : bNewPageDesc = FmtHdFtContainsChapterField(rFmt);
395 : }
396 : }
397 184 : return bNewPageDesc;
398 : }
399 :
400 : // Da WW nur Break-After ( Pagebreak und Sectionbreaks ) kennt, im SW aber
401 : // Bagebreaks "vor" und "nach" und Pagedescs nur "vor" existieren, werden
402 : // die Breaks 2* durchgeklimpert, naemlich vor und hinter jeder Zeile.
403 : // Je nach BreakTyp werden sie vor oder nach der Zeile gesetzt.
404 : // Es duerfen nur Funktionen gerufen werden, die nicht in den
405 : // Ausgabebereich pO schreiben, da dieser nur einmal fuer CHP und PAP existiert
406 : // und damit im falschen landen wuerden.
407 8708 : void MSWordExportBase::OutputSectionBreaks( const SfxItemSet *pSet, const SwNode& rNd, bool isCellOpen, bool isTextNodeEmpty)
408 : {
409 8708 : if ( bStyDef || bOutKF || bInWriteEscher || bOutPageDescs )
410 9006 : return;
411 :
412 8410 : bBreakBefore = true;
413 8410 : bool bNewPageDesc = false;
414 8410 : const SfxPoolItem* pItem=0;
415 8410 : const SwFmtPageDesc *pPgDesc=0;
416 :
417 : //Output a sectionbreak if theres a new pagedesciptor. otherwise output a
418 : //pagebreak if there is a pagebreak here, unless the new page (follow
419 : //style) is different to the current one, in which case plump for a
420 : //section.
421 8410 : bool bBreakSet = false;
422 :
423 8410 : const SwPageDesc * pPageDesc = rNd.FindPageDesc(false);
424 :
425 : // Even if pAktPageDesc != pPageDesc ,it might be because of the different header & footer types.
426 8410 : if (pAktPageDesc != pPageDesc)
427 : {
428 140 : if ( ( isCellOpen && ( pAktPageDesc->GetName() != pPageDesc->GetName() )) ||
429 70 : ( isTextNodeEmpty || bPrevTextNodeIsEmpty ))
430 : {
431 : /* Do not output a section break in the following scenarios.
432 : 1) Table cell is open and page header types are different
433 : 2) PageBreak is present but text node has no string - it is an empty node.
434 : 3) If the previous node was an empty text node and current node is a non empty text node or vice versa.
435 : 4) If previous node and current node both are empty text nodes.
436 : Converting a page break to section break would cause serious issues while importing
437 : the RT files with different first page being set.
438 : */
439 44 : bNewPageDesc = false;
440 :
441 : /*
442 : * If Table cell is open and page header types are different
443 : * set pSet to NULL as we don't want to add any section breaks.
444 : */
445 44 : if ( isCellOpen && ( pAktPageDesc->GetName() != pPageDesc->GetName() ) )
446 2 : pSet = NULL;
447 : }
448 52 : else if (!sw::util::IsPlausableSingleWordSection(pAktPageDesc->GetFirstMaster(), pPageDesc->GetMaster()))
449 : {
450 16 : bBreakSet = true;
451 16 : bNewPageDesc = true;
452 16 : pAktPageDesc = pPageDesc;
453 : }
454 : }
455 :
456 8410 : if ( pSet && pSet->Count() )
457 : {
458 5676 : if ( SfxItemState::SET == pSet->GetItemState( RES_PAGEDESC, false, &pItem ) &&
459 82 : static_cast<const SwFmtPageDesc*>(pItem)->GetRegisteredIn() != NULL)
460 : {
461 82 : bBreakSet = true;
462 82 : bNewPageDesc = true;
463 82 : pPgDesc = static_cast<const SwFmtPageDesc*>(pItem);
464 82 : pAktPageDesc = pPgDesc->GetPageDesc();
465 : }
466 5512 : else if ( SfxItemState::SET == pSet->GetItemState( RES_BREAK, false, &pItem ) )
467 : {
468 : // Word does not like hard break attributes in some table cells
469 284 : bool bRemoveHardBreakInsideTable = false;
470 284 : if ( bOutTable )
471 : {
472 0 : const SwTableNode* pTableNode = rNd.FindTableNode();
473 0 : if ( pTableNode )
474 : {
475 0 : const SwTableBox* pBox = rNd.GetTblBox();
476 0 : const SwTableLine* pLine = pBox ? pBox->GetUpper() : 0;
477 : // but only for non-complex tables
478 0 : if ( pLine && !pLine->GetUpper() )
479 : {
480 : // check if box is not first in that line:
481 0 : if ( 0 < pLine->GetTabBoxes().GetPos( pBox ) && pBox->GetSttNd() )
482 : {
483 0 : bRemoveHardBreakInsideTable = true;
484 : }
485 : }
486 : }
487 : }
488 284 : bNewPageDesc = false; // if next node has RES_BREAK(page break) then bNewPageDesc value should be false.
489 284 : bBreakSet = true;
490 :
491 284 : if ( !bRemoveHardBreakInsideTable )
492 : {
493 : OSL_ENSURE(pAktPageDesc, "should not be possible");
494 : /*
495 : If because of this pagebreak the page desc following the page
496 : break is the follow style of the current page desc then output a
497 : section break using that style instead. At least in those cases
498 : we end up with the same style in word and writer, nothing can be
499 : done when it happens when we get a new pagedesc because we
500 : overflow from the first page style.
501 : */
502 284 : if ( pAktPageDesc )
503 : {
504 : // #i76301# - assure that there is a page break before set at the node.
505 284 : const SvxFmtBreakItem* pBreak = dynamic_cast<const SvxFmtBreakItem*>(pItem);
506 568 : if ( pBreak &&
507 284 : pBreak->GetBreak() == SVX_BREAK_PAGE_BEFORE )
508 : {
509 178 : bNewPageDesc |= SetAktPageDescFromNode( rNd );
510 : }
511 284 : if( isTextNodeEmpty )
512 68 : bNewPageDesc = false;
513 : }
514 284 : if ( !bNewPageDesc )
515 284 : AttrOutput().OutputItem( *pItem );
516 : }
517 : }
518 : }
519 :
520 : /*
521 : #i9301#
522 : No explicit page break, lets see if the style had one and we've moved to a
523 : new page style because of it, if we have to then we take the opportunity to
524 : set the equivalent word section here. We *could* do it for every paragraph
525 : that moves onto a new page because of layout, but that would be insane.
526 : */
527 8410 : bool bHackInBreak = false;
528 8410 : if ( !bBreakSet )
529 : {
530 8042 : if ( const SwCntntNode *pNd = rNd.GetCntntNode() )
531 : {
532 : const SvxFmtBreakItem &rBreak =
533 7948 : ItemGet<SvxFmtBreakItem>( *pNd, RES_BREAK );
534 7948 : if ( rBreak.GetBreak() == SVX_BREAK_PAGE_BEFORE )
535 6 : bHackInBreak = true;
536 : else
537 : { // Even a pagedesc item is set, the break item can be set 'NONE',
538 : // but a pagedesc item is an implicit page break before...
539 : const SwFmtPageDesc &rPageDesc =
540 7942 : ItemGet<SwFmtPageDesc>( *pNd, RES_PAGEDESC );
541 7942 : if ( rPageDesc.KnowsPageDesc() )
542 0 : bHackInBreak = true;
543 : }
544 : }
545 : }
546 :
547 8410 : if ( bHackInBreak )
548 : {
549 : OSL_ENSURE( pAktPageDesc, "should not be possible" );
550 6 : if ( pAktPageDesc )
551 6 : bNewPageDesc = SetAktPageDescFromNode( rNd );
552 : }
553 :
554 8410 : if ( bNewPageDesc && pAktPageDesc )
555 : {
556 84 : PrepareNewPageDesc( pSet, rNd, pPgDesc, pAktPageDesc );
557 : }
558 8410 : bBreakBefore = false;
559 8410 : bPrevTextNodeIsEmpty = isTextNodeEmpty ;
560 : }
561 :
562 : // #i76300#
563 0 : bool MSWordExportBase::OutputFollowPageDesc( const SfxItemSet* pSet, const SwTxtNode* pNd )
564 : {
565 0 : bool bRet = false;
566 :
567 0 : if ( pNd &&
568 0 : pAktPageDesc &&
569 0 : pAktPageDesc != pAktPageDesc->GetFollow() )
570 : {
571 0 : PrepareNewPageDesc( pSet, *pNd, 0, pAktPageDesc->GetFollow() );
572 0 : bRet = true;
573 : }
574 :
575 0 : return bRet;
576 : }
577 :
578 60 : const SwSectionFmt* MSWordExportBase::GetSectionFormat( const SwNode& rNd ) const
579 : {
580 60 : const SwSectionFmt* pFmt = NULL;
581 60 : const SwSectionNode* pSect = rNd.FindSectionNode();
582 62 : if ( pSect &&
583 2 : CONTENT_SECTION == pSect->GetSection().GetType() )
584 : {
585 0 : pFmt = pSect->GetSection().GetFmt();
586 : }
587 :
588 60 : return pFmt;
589 : }
590 :
591 60 : sal_uLong MSWordExportBase::GetSectionLineNo( const SfxItemSet* pSet, const SwNode& rNd ) const
592 : {
593 60 : const SwFmtLineNumber* pNItem = 0;
594 60 : if ( pSet )
595 : {
596 60 : pNItem = &( ItemGet<SwFmtLineNumber>( *pSet, RES_LINENUMBER ) );
597 : }
598 0 : else if ( const SwCntntNode *pNd = rNd.GetCntntNode() )
599 : {
600 0 : pNItem = &( ItemGet<SwFmtLineNumber>( *pNd, RES_LINENUMBER ) );
601 : }
602 :
603 60 : return pNItem? pNItem->GetStartValue() : 0;
604 : }
605 :
606 30 : void WW8Export::PrepareNewPageDesc( const SfxItemSet*pSet,
607 : const SwNode& rNd,
608 : const SwFmtPageDesc* pNewPgDescFmt,
609 : const SwPageDesc* pNewPgDesc )
610 : {
611 : // Die PageDescs werden beim Auftreten von PageDesc-Attributen nur in
612 : // WW8Writer::pSepx mit der entsprechenden Position eingetragen. Das
613 : // Aufbauen und die Ausgabe der am PageDesc haengenden Attribute und
614 : // Kopf/Fusszeilen passiert nach dem Haupttext und seinen Attributen.
615 :
616 30 : sal_uLong nFcPos = ReplaceCr( msword::PageBreak ); // Page/Section-Break
617 :
618 : // tatsaechlich wird hier NOCH NICHTS ausgegeben, sondern
619 : // nur die Merk-Arrays aCps, aSects entsprechend ergaenzt
620 30 : if ( !nFcPos )
621 54 : return;
622 :
623 6 : const SwSectionFmt* pFmt = GetSectionFormat( rNd );
624 6 : const sal_uLong nLnNm = GetSectionLineNo( pSet, rNd );
625 :
626 : OSL_ENSURE( pNewPgDescFmt || pNewPgDesc, "Neither page desc format nor page desc provided." );
627 :
628 6 : if ( pNewPgDescFmt )
629 : {
630 4 : pSepx->AppendSep( Fc2Cp( nFcPos ), *pNewPgDescFmt, rNd, pFmt, nLnNm );
631 : }
632 2 : else if ( pNewPgDesc )
633 : {
634 2 : pSepx->AppendSep( Fc2Cp( nFcPos ), pNewPgDesc, rNd, pFmt, nLnNm );
635 : }
636 : }
637 :
638 80 : void MSWordExportBase::CorrectTabStopInSet( SfxItemSet& rSet, sal_uInt16 nAbsLeft )
639 : {
640 : const SvxTabStopItem *pItem =
641 80 : sw::util::HasItem<SvxTabStopItem>( rSet, RES_PARATR_TABSTOP );
642 :
643 80 : if ( pItem )
644 : {
645 : // dann muss das fuer die Ausgabe korrigiert werden
646 80 : SvxTabStopItem aTStop(*pItem);
647 170 : for ( sal_uInt16 nCnt = 0; nCnt < aTStop.Count(); ++nCnt )
648 : {
649 90 : SvxTabStop& rTab = (SvxTabStop&)aTStop[ nCnt ];
650 170 : if ( SVX_TAB_ADJUST_DEFAULT != rTab.GetAdjustment() &&
651 80 : rTab.GetTabPos() >= nAbsLeft )
652 : {
653 78 : rTab.GetTabPos() -= nAbsLeft;
654 : }
655 : else
656 : {
657 12 : aTStop.Remove( nCnt );
658 12 : --nCnt;
659 : }
660 : }
661 80 : rSet.Put( aTStop );
662 : }
663 80 : }
664 :
665 310 : sal_uInt8 WW8Export::GetNumId( sal_uInt16 eNumType )
666 : {
667 310 : sal_uInt8 nRet = 0;
668 310 : switch( eNumType )
669 : {
670 : case SVX_NUM_CHARS_UPPER_LETTER:
671 0 : case SVX_NUM_CHARS_UPPER_LETTER_N: nRet = 3; break;
672 : case SVX_NUM_CHARS_LOWER_LETTER:
673 0 : case SVX_NUM_CHARS_LOWER_LETTER_N: nRet = 4; break;
674 0 : case SVX_NUM_ROMAN_UPPER: nRet = 1; break;
675 34 : case SVX_NUM_ROMAN_LOWER: nRet = 2; break;
676 :
677 : case SVX_NUM_BITMAP:
678 4 : case SVX_NUM_CHAR_SPECIAL: nRet = 23; break;
679 :
680 : // nix, macht WW undokumentiert auch so
681 150 : case SVX_NUM_NUMBER_NONE: nRet = 0xff; break;
682 : }
683 310 : return nRet;
684 : }
685 :
686 10 : void WW8AttributeOutput::OutlineNumbering( sal_uInt8 nLvl, const SwNumFmt &rNFmt, const SwFmt &rFmt )
687 : {
688 10 : if ( nLvl >= WW8ListManager::nMaxLevel )
689 0 : nLvl = WW8ListManager::nMaxLevel-1;
690 :
691 10 : if ( m_rWW8Export.bWrtWW8 )
692 : {
693 : // write sprmPOutLvl sprmPIlvl and sprmPIlfo
694 10 : SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_POutLvl );
695 10 : m_rWW8Export.pO->push_back( nLvl );
696 10 : SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_PIlvl );
697 10 : m_rWW8Export.pO->push_back( nLvl );
698 10 : SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_PIlfo );
699 : SwWW8Writer::InsUInt16( *m_rWW8Export.pO,
700 10 : 1 + m_rWW8Export.GetId( *m_rWW8Export.pDoc->GetOutlineNumRule() ) );
701 : }
702 : else
703 : {
704 0 : m_rWW8Export.Out_SwNumLvl( nLvl );
705 0 : if ( rNFmt.GetPositionAndSpaceMode() ==
706 0 : SvxNumberFormat::LABEL_WIDTH_AND_POSITION &&
707 0 : rNFmt.GetAbsLSpace() )
708 : {
709 0 : SwNumFmt aNumFmt( rNFmt );
710 : const SvxLRSpaceItem& rLR =
711 0 : ItemGet<SvxLRSpaceItem>( rFmt, RES_LR_SPACE );
712 :
713 : aNumFmt.SetAbsLSpace( writer_cast<short>(
714 0 : aNumFmt.GetAbsLSpace() + rLR.GetLeft() ) );
715 : m_rWW8Export.Out_NumRuleAnld(
716 0 : *m_rWW8Export.pDoc->GetOutlineNumRule(),
717 0 : aNumFmt, nLvl );
718 : }
719 : else
720 : m_rWW8Export.Out_NumRuleAnld(
721 0 : *m_rWW8Export.pDoc->GetOutlineNumRule(),
722 0 : rNFmt, nLvl );
723 : }
724 10 : }
725 :
726 : // #i77805#
727 358 : bool WW8Export::DisallowInheritingOutlineNumbering(const SwFmt &rFmt)
728 : {
729 358 : bool bRet( false );
730 :
731 : //If there is no numbering on this fmt, but its parent was outline
732 : //numbered, then in writer this is no inheritied, but in word it would
733 : //be, so we must export "no numbering" and "body level" to make word
734 : //behave like writer (see #i25755)
735 358 : if (SfxItemState::SET != rFmt.GetItemState(RES_PARATR_NUMRULE, false))
736 : {
737 340 : if (const SwFmt *pParent = rFmt.DerivedFrom())
738 : {
739 340 : if (((const SwTxtFmtColl*)pParent)->IsAssignedToListLevelOfOutlineStyle())
740 : {
741 0 : if (bWrtWW8)
742 : {
743 0 : SwWW8Writer::InsUInt16(*pO, NS_sprm::LN_POutLvl);
744 0 : pO->push_back(sal_uInt8(9));
745 0 : SwWW8Writer::InsUInt16(*pO, NS_sprm::LN_PIlfo);
746 0 : SwWW8Writer::InsUInt16(*pO, 0);
747 :
748 0 : bRet = true;
749 : }
750 : /*whats the winword 6 way to do this ?*/
751 : }
752 : }
753 : }
754 :
755 358 : return bRet;
756 : }
757 :
758 36248 : void MSWordExportBase::OutputFormat( const SwFmt& rFmt, bool bPapFmt, bool bChpFmt, bool bFlyFmt )
759 : {
760 36248 : bool bCallOutSet = true;
761 36248 : const SwModify* pOldMod = pOutFmtNode;
762 36248 : pOutFmtNode = &rFmt;
763 :
764 36248 : switch( rFmt.Which() )
765 : {
766 : case RES_CONDTXTFMTCOLL:
767 : case RES_TXTFMTCOLL:
768 28912 : if( bPapFmt )
769 : {
770 14456 : int nLvl = MAXLEVEL;
771 :
772 14456 : if (((const SwTxtFmtColl&)rFmt).IsAssignedToListLevelOfOutlineStyle())
773 194 : nLvl = ((const SwTxtFmtColl&)rFmt).GetAssignedOutlineStyleLevel();
774 :
775 14456 : if (nLvl >= 0 && nLvl < MAXLEVEL)
776 : {
777 : //if outline numbered
778 : // if Write StyleDefinition then write the OutlineRule
779 194 : const SwNumFmt& rNFmt = pDoc->GetOutlineNumRule()->Get( static_cast<sal_uInt16>( nLvl ) );
780 194 : if ( bStyDef )
781 194 : AttrOutput().OutlineNumbering( static_cast< sal_uInt8 >( nLvl ), rNFmt, rFmt );
782 :
783 388 : if ( rNFmt.GetPositionAndSpaceMode() ==
784 214 : SvxNumberFormat::LABEL_WIDTH_AND_POSITION &&
785 20 : rNFmt.GetAbsLSpace() )
786 : {
787 4 : SfxItemSet aSet( rFmt.GetAttrSet() );
788 : SvxLRSpaceItem aLR(
789 8 : ItemGet<SvxLRSpaceItem>(aSet, RES_LR_SPACE));
790 :
791 4 : aLR.SetTxtLeft( aLR.GetTxtLeft() + rNFmt.GetAbsLSpace() );
792 4 : aLR.SetTxtFirstLineOfst( GetWordFirstLineOffset(rNFmt));
793 :
794 4 : aSet.Put( aLR );
795 4 : CorrectTabStopInSet( aSet, rNFmt.GetAbsLSpace() );
796 : OutputItemSet( aSet, bPapFmt, bChpFmt,
797 4 : i18n::ScriptType::LATIN, mbExportModeRTF);
798 8 : bCallOutSet = false;
799 194 : }
800 : }
801 : else
802 : {
803 : //otherwise we might have to remove outline numbering from
804 : //what gets exported if the parent style was outline numbered
805 : // #i77805#
806 : // If inherited outline numbering is suppress, the left/right
807 : // margins has to be exported explicitly.
808 14262 : if ( bStyDef && DisallowInheritingOutlineNumbering(rFmt) )
809 : {
810 0 : SfxItemSet aSet( rFmt.GetAttrSet() );
811 : SvxLRSpaceItem aLR(
812 0 : ItemGet<SvxLRSpaceItem>(aSet, RES_LR_SPACE));
813 0 : aSet.Put( aLR );
814 : OutputItemSet( aSet, bPapFmt, bChpFmt,
815 0 : com::sun::star::i18n::ScriptType::LATIN, mbExportModeRTF);
816 0 : bCallOutSet = false;
817 : }
818 : }
819 : }
820 28912 : break;
821 :
822 : case RES_CHRFMT:
823 6590 : break;
824 : case RES_FLYFRMFMT:
825 426 : if (bFlyFmt)
826 : {
827 : OSL_ENSURE(mpParentFrame, "No parent frame, all broken");
828 :
829 426 : if (mpParentFrame)
830 : {
831 426 : const SwFrmFmt &rFrmFmt = mpParentFrame->GetFrmFmt();
832 :
833 426 : SfxItemSet aSet(pDoc->GetAttrPool(), RES_FRMATR_BEGIN,
834 : RES_FRMATR_END-1,
835 : XATTR_FILL_FIRST, XATTR_FILL_LAST,
836 426 : 0);
837 426 : aSet.Set(rFrmFmt.GetAttrSet());
838 :
839 : // Fly als Zeichen werden bei uns zu Absatz-gebundenen
840 : // jetzt den Abstand vom Absatz-Rand setzen
841 426 : if (pFlyOffset)
842 : {
843 0 : aSet.Put(SwFmtHoriOrient(pFlyOffset->X()));
844 0 : aSet.Put(SwFmtVertOrient(pFlyOffset->Y()));
845 0 : SwFmtAnchor aAnchor(rFrmFmt.GetAnchor());
846 0 : aAnchor.SetType(eNewAnchorType);
847 0 : aSet.Put(aAnchor);
848 : }
849 :
850 426 : if (SfxItemState::SET != aSet.GetItemState(RES_SURROUND))
851 0 : aSet.Put(SwFmtSurround(SURROUND_NONE));
852 :
853 426 : const XFillStyleItem* pXFillStyleItem(static_cast< const XFillStyleItem* >(rFrmFmt.GetAttrSet().GetItem(XATTR_FILLSTYLE)));
854 426 : if (pXFillStyleItem)
855 : {
856 426 : switch (pXFillStyleItem->GetValue())
857 : {
858 : case drawing::FillStyle_NONE:
859 318 : break;
860 : case drawing::FillStyle_SOLID:
861 : {
862 : // Construct an SvxBrushItem, as expected by the exporters.
863 92 : aSet.Put(getSvxBrushItemFromSourceSet(rFrmFmt.GetAttrSet(), RES_BACKGROUND));
864 92 : break;
865 : }
866 : default:
867 16 : break;
868 : }
869 : }
870 :
871 426 : bOutFlyFrmAttrs = true;
872 : //script doesn't matter if not exporting chp
873 : OutputItemSet(aSet, true, false,
874 426 : i18n::ScriptType::LATIN, mbExportModeRTF);
875 426 : bOutFlyFrmAttrs = false;
876 :
877 426 : bCallOutSet = false;
878 : }
879 : }
880 426 : break;
881 : case RES_FRMFMT:
882 320 : break;
883 : default:
884 : OSL_ENSURE( false, "Which format is exported here?" );
885 0 : break;
886 : }
887 :
888 36248 : if( bCallOutSet )
889 35818 : OutputItemSet( rFmt.GetAttrSet(), bPapFmt, bChpFmt,
890 71636 : i18n::ScriptType::LATIN, mbExportModeRTF);
891 36248 : pOutFmtNode = pOldMod;
892 36248 : }
893 :
894 26 : bool MSWordExportBase::HasRefToObject( sal_uInt16 nTyp, const OUString* pName, sal_uInt16 nSeqNo )
895 : {
896 : const SwTxtNode* pNd;
897 :
898 26 : SwFieldType* pType = pDoc->getIDocumentFieldsAccess().GetSysFldType( RES_GETREFFLD );
899 26 : SwIterator<SwFmtFld, SwFieldType> aFmtFlds( *pType );
900 26 : for ( SwFmtFld* pFmtFld = aFmtFlds.First(); pFmtFld; pFmtFld = aFmtFlds.Next() )
901 : {
902 0 : if ( pFmtFld->GetTxtFld() && nTyp == pFmtFld->GetField()->GetSubType() &&
903 0 : 0 != ( pNd = pFmtFld->GetTxtFld()->GetpTxtNode() ) &&
904 0 : pNd->GetNodes().IsDocNodes() )
905 : {
906 0 : const SwGetRefField& rRFld = *static_cast< SwGetRefField* >( pFmtFld->GetField() );
907 0 : switch ( nTyp )
908 : {
909 : case REF_BOOKMARK:
910 : case REF_SETREFATTR:
911 0 : if ( pName && *pName == rRFld.GetSetRefName() )
912 0 : return true;
913 0 : break;
914 : case REF_FOOTNOTE:
915 : case REF_ENDNOTE:
916 0 : if ( nSeqNo == rRFld.GetSeqNo() )
917 0 : return true;
918 0 : break;
919 : case REF_SEQUENCEFLD:
920 0 : break; // ???
921 : case REF_OUTLINE:
922 0 : break; // ???
923 : }
924 : }
925 : }
926 :
927 26 : return false;
928 : }
929 :
930 6 : OUString MSWordExportBase::GetBookmarkName( sal_uInt16 nTyp, const OUString* pName, sal_uInt16 nSeqNo )
931 : {
932 6 : OUString sRet;
933 6 : switch ( nTyp )
934 : {
935 : case REF_SETREFATTR:
936 0 : if ( pName )
937 : {
938 0 : sRet += "Ref_";
939 0 : sRet += *pName;
940 : }
941 0 : break;
942 : case REF_SEQUENCEFLD:
943 0 : break; // ???
944 : case REF_BOOKMARK:
945 6 : if ( pName )
946 6 : sRet = *pName;
947 6 : break;
948 : case REF_OUTLINE:
949 0 : break; // ???
950 : case REF_FOOTNOTE:
951 0 : sRet += "_RefF";
952 0 : sRet += OUString::number( nSeqNo );
953 0 : break;
954 : case REF_ENDNOTE:
955 0 : sRet += "_RefE";
956 0 : sRet += OUString::number( nSeqNo );
957 0 : break;
958 : }
959 6 : return BookmarkToWord( sRet ); // #i43956# - encode bookmark accordingly
960 : }
961 :
962 : /* File CHRATR.HXX: */
963 790 : void WW8AttributeOutput::RTLAndCJKState( bool bIsRTL, sal_uInt16 nScript )
964 : {
965 790 : if ( m_rWW8Export.bWrtWW8 && bIsRTL )
966 : {
967 0 : if( m_rWW8Export.pDoc->GetDocumentType() != SwDoc::DOCTYPE_MSWORD )
968 : {
969 0 : m_rWW8Export.InsUInt16( NS_sprm::LN_CFBiDi );
970 0 : m_rWW8Export.pO->push_back( (sal_uInt8)1 );
971 : }
972 : }
973 :
974 : // #i46087# patch from james_clark; complex texts needs the undocumented SPRM CComplexScript with param 0x81.
975 790 : if ( m_rWW8Export.bWrtWW8 && nScript == i18n::ScriptType::COMPLEX && !bIsRTL )
976 : {
977 0 : m_rWW8Export.InsUInt16( NS_sprm::LN_CComplexScript );
978 0 : m_rWW8Export.pO->push_back( (sal_uInt8)0x81 );
979 0 : m_rWW8Export.pDop->bUseThaiLineBreakingRules = true;
980 : }
981 790 : }
982 :
983 684 : void WW8AttributeOutput::EndParagraph( ww8::WW8TableNodeInfoInner::Pointer_t pTextNodeInfoInner )
984 : {
985 684 : m_rWW8Export.pPapPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell() - (mbOnTOXEnding?2:0), m_rWW8Export.pO->size(), m_rWW8Export.pO->data() );
986 684 : mbOnTOXEnding = false;
987 684 : m_rWW8Export.pO->clear();
988 :
989 684 : if ( pTextNodeInfoInner.get() != NULL )
990 : {
991 486 : if ( pTextNodeInfoInner->isEndOfLine() )
992 : {
993 72 : TableRowEnd( pTextNodeInfoInner->getDepth() );
994 :
995 : SVBT16 nSty;
996 72 : ShortToSVBT16( 0, nSty );
997 72 : m_rWW8Export.pO->insert( m_rWW8Export.pO->end(), (sal_uInt8*)&nSty, (sal_uInt8*)&nSty+2 ); // Style #
998 72 : TableInfoRow( pTextNodeInfoInner );
999 72 : m_rWW8Export.pPapPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), m_rWW8Export.pO->size(), m_rWW8Export.pO->data());
1000 72 : m_rWW8Export.pO->clear();
1001 : //For Bug 119650, should break the properties of CHP PLC after a paragraph end.
1002 72 : m_rWW8Export.pChpPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), m_rWW8Export.pO->size(), m_rWW8Export.pO->data());
1003 : }
1004 : }
1005 684 : }
1006 :
1007 790 : void WW8AttributeOutput::StartRunProperties()
1008 : {
1009 790 : WW8_WrPlcFld* pCurrentFields = m_rWW8Export.CurrentFieldPlc();
1010 790 : m_nFieldResults = pCurrentFields ? pCurrentFields->ResultCount() : 0;
1011 790 : }
1012 :
1013 802 : void WW8AttributeOutput::StartRun( const SwRedlineData* pRedlineData, bool /*bSingleEmptyRun*/ )
1014 : {
1015 802 : if (pRedlineData)
1016 : {
1017 6 : const OUString &rComment = pRedlineData->GetComment();
1018 : //Only possible to export to main text
1019 6 : if (!rComment.isEmpty() && (m_rWW8Export.nTxtTyp == TXT_MAINTEXT))
1020 : {
1021 0 : if (m_rWW8Export.pAtn->IsNewRedlineComment(pRedlineData))
1022 : {
1023 0 : m_rWW8Export.pAtn->Append( m_rWW8Export.Fc2Cp( m_rWW8Export.Strm().Tell() ), pRedlineData );
1024 0 : m_rWW8Export.WritePostItBegin( m_rWW8Export.pO );
1025 : }
1026 : }
1027 : }
1028 802 : }
1029 :
1030 0 : void WW8AttributeOutput::OnTOXEnding()
1031 : {
1032 0 : mbOnTOXEnding = true;
1033 0 : }
1034 :
1035 790 : void WW8AttributeOutput::EndRunProperties( const SwRedlineData* pRedlineData )
1036 : {
1037 790 : Redline( pRedlineData );
1038 :
1039 790 : WW8_WrPlcFld* pCurrentFields = m_rWW8Export.CurrentFieldPlc();
1040 790 : sal_uInt16 nNewFieldResults = pCurrentFields ? pCurrentFields->ResultCount() : 0;
1041 :
1042 790 : bool bExportedFieldResult = ( m_nFieldResults != nNewFieldResults );
1043 :
1044 : // If we have exported a field result, then we will have been forced to
1045 : // split up the text into a 0x13, 0x14, <result> 0x15 sequence with the
1046 : // properties forced out at the end of the result, so the 0x15 itself
1047 : // should remain clean of all other attributes to avoid #iXXXXX#
1048 790 : if ( !bExportedFieldResult )
1049 : {
1050 782 : m_rWW8Export.pChpPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(),
1051 1564 : m_rWW8Export.pO->size(), m_rWW8Export.pO->data() );
1052 : }
1053 790 : m_rWW8Export.pO->clear();
1054 790 : }
1055 :
1056 420 : void WW8AttributeOutput::RunText( const OUString& rText, rtl_TextEncoding eCharSet )
1057 : {
1058 420 : RawText( rText, m_rWW8Export.bWrtWW8, eCharSet );
1059 420 : }
1060 :
1061 420 : void WW8AttributeOutput::RawText( const OUString& rText, bool bForceUnicode, rtl_TextEncoding eCharSet )
1062 : {
1063 420 : m_rWW8Export.OutSwString( rText, 0, rText.getLength(), bForceUnicode, eCharSet );
1064 420 : }
1065 :
1066 694 : void WW8AttributeOutput::OutputFKP(bool bForce)
1067 : {
1068 694 : if (!m_rWW8Export.pO->empty() || bForce)
1069 : {
1070 10 : m_rWW8Export.pChpPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(),
1071 20 : m_rWW8Export.pO->size(), m_rWW8Export.pO->data() );
1072 10 : m_rWW8Export.pO->clear();
1073 : }
1074 694 : }
1075 :
1076 684 : void WW8AttributeOutput::ParagraphStyle( sal_uInt16 nStyle )
1077 : {
1078 : OSL_ENSURE( m_rWW8Export.pO->empty(), " pO ist am ZeilenEnde nicht leer" );
1079 :
1080 : SVBT16 nSty;
1081 684 : ShortToSVBT16( nStyle, nSty );
1082 684 : m_rWW8Export.pO->insert( m_rWW8Export.pO->end(), (sal_uInt8*)&nSty, (sal_uInt8*)&nSty+2 ); // Style #
1083 684 : }
1084 :
1085 260 : void WW8AttributeOutput::OutputWW8Attribute( sal_uInt8 nId, bool bVal )
1086 : {
1087 260 : if ( m_rWW8Export.bWrtWW8 )
1088 260 : m_rWW8Export.InsUInt16( 8 == nId ? NS_sprm::LN_CFDStrike : NS_sprm::LN_CFBold + nId );
1089 0 : else if (8 == nId )
1090 260 : return; // no such attribute in WW6
1091 : else
1092 0 : m_rWW8Export.pO->push_back( 85 + nId );
1093 :
1094 260 : m_rWW8Export.pO->push_back( bVal ? 1 : 0 );
1095 : }
1096 :
1097 96 : void WW8AttributeOutput::OutputWW8AttributeCTL( sal_uInt8 nId, bool bVal )
1098 : {
1099 : OSL_ENSURE( nId <= 1, "out of range" );
1100 96 : if ( !m_rWW8Export.bWrtWW8 || nId > 1 )
1101 96 : return;
1102 :
1103 96 : m_rWW8Export.InsUInt16( NS_sprm::LN_CFBoldBi + nId );
1104 96 : m_rWW8Export.pO->push_back( bVal ? 1 : 0 );
1105 : }
1106 :
1107 818 : void WW8AttributeOutput::CharFont( const SvxFontItem& rFont )
1108 : {
1109 818 : sal_uInt16 nFontID = m_rWW8Export.GetId( rFont );
1110 :
1111 818 : if ( m_rWW8Export.bWrtWW8 )
1112 : {
1113 818 : m_rWW8Export.InsUInt16( NS_sprm::LN_CRgFtc0 );
1114 818 : m_rWW8Export.InsUInt16( nFontID );
1115 818 : m_rWW8Export.InsUInt16( NS_sprm::LN_CRgFtc2 );
1116 : }
1117 : else
1118 0 : m_rWW8Export.pO->push_back( 93 );
1119 :
1120 818 : m_rWW8Export.InsUInt16( nFontID );
1121 818 : }
1122 :
1123 904 : void WW8AttributeOutput::CharFontCTL( const SvxFontItem& rFont )
1124 : {
1125 : //Can only export in 8+, in 7- export as normal variant and expect that
1126 : //upperlevel code has blocked exporting clobbering attributes
1127 904 : sal_uInt16 nFontID = m_rWW8Export.GetId( rFont );
1128 904 : if ( m_rWW8Export.bWrtWW8 )
1129 904 : m_rWW8Export.InsUInt16( NS_sprm::LN_CFtcBi );
1130 : else
1131 0 : m_rWW8Export.pO->push_back( 93 );
1132 904 : m_rWW8Export.InsUInt16( nFontID );
1133 904 : }
1134 :
1135 122 : void WW8AttributeOutput::CharFontCJK( const SvxFontItem& rFont )
1136 : {
1137 : //Can only export in 8+, in 7- export as normal variant and expect that
1138 : //upperlevel code has blocked exporting clobbering attributes
1139 122 : sal_uInt16 nFontID = m_rWW8Export.GetId( rFont );
1140 122 : if ( m_rWW8Export.bWrtWW8 )
1141 122 : m_rWW8Export.InsUInt16( NS_sprm::LN_CRgFtc1 );
1142 : else
1143 0 : m_rWW8Export.pO->push_back( 93 );
1144 122 : m_rWW8Export.InsUInt16( nFontID );
1145 122 : }
1146 :
1147 46 : void WW8AttributeOutput::CharWeightCTL( const SvxWeightItem& rWeight )
1148 : {
1149 : //Can only export in 8+, in 7- export as normal variant and expect that
1150 : //upperlevel code has blocked exporting clobbering attributes
1151 46 : if (m_rWW8Export.bWrtWW8)
1152 : {
1153 46 : OutputWW8AttributeCTL( 0, WEIGHT_BOLD == rWeight.GetWeight());
1154 : }
1155 : else
1156 : {
1157 0 : OutputWW8Attribute( 0, WEIGHT_BOLD == rWeight.GetWeight());
1158 : }
1159 46 : }
1160 :
1161 50 : void WW8AttributeOutput::CharPostureCTL( const SvxPostureItem& rPosture )
1162 : {
1163 : // Can only export in 8+, in 7- export as normal variant and expect that
1164 : // upperlevel code has blocked exporting clobbering attributes
1165 50 : if (m_rWW8Export.bWrtWW8)
1166 : {
1167 50 : OutputWW8AttributeCTL( 1, ITALIC_NONE != rPosture.GetPosture() );
1168 : }
1169 : else
1170 : {
1171 0 : OutputWW8Attribute( 1, ITALIC_NONE != rPosture.GetPosture() );
1172 : }
1173 50 : }
1174 :
1175 74 : void WW8AttributeOutput::CharPosture( const SvxPostureItem& rPosture )
1176 : {
1177 74 : OutputWW8Attribute( 1, ITALIC_NONE != rPosture.GetPosture() );
1178 74 : }
1179 :
1180 156 : void WW8AttributeOutput::CharWeight( const SvxWeightItem& rWeight )
1181 : {
1182 156 : OutputWW8Attribute( 0, WEIGHT_BOLD == rWeight.GetWeight() );
1183 156 : }
1184 :
1185 : // Shadowed und Contour are not in WW-UI. JP: ??
1186 2 : void WW8AttributeOutput::CharContour( const SvxContourItem& rContour )
1187 : {
1188 2 : OutputWW8Attribute( 3, rContour.GetValue() ? true : false);
1189 2 : }
1190 :
1191 2 : void WW8AttributeOutput::CharShadow( const SvxShadowedItem& rShadow )
1192 : {
1193 2 : OutputWW8Attribute( 4, rShadow.GetValue() ? true : false);
1194 2 : }
1195 :
1196 10 : void WW8AttributeOutput::CharKerning( const SvxKerningItem& rKerning )
1197 : {
1198 10 : if ( m_rWW8Export.bWrtWW8 )
1199 10 : m_rWW8Export.InsUInt16( NS_sprm::LN_CDxaSpace );
1200 : else
1201 0 : m_rWW8Export.pO->push_back( 96 );
1202 :
1203 10 : m_rWW8Export.InsUInt16( rKerning.GetValue() );
1204 10 : }
1205 :
1206 46 : void WW8AttributeOutput::CharAutoKern( const SvxAutoKernItem& rAutoKern )
1207 : {
1208 46 : if ( m_rWW8Export.bWrtWW8 )
1209 46 : m_rWW8Export.InsUInt16( NS_sprm::LN_CHpsKern );
1210 : else
1211 0 : m_rWW8Export.pO->push_back( 107 );
1212 :
1213 46 : m_rWW8Export.InsUInt16( rAutoKern.GetValue() ? 1 : 0 );
1214 46 : }
1215 :
1216 0 : void WW8AttributeOutput::CharAnimatedText( const SvxBlinkItem& rBlink )
1217 : {
1218 0 : if ( m_rWW8Export.bWrtWW8 )
1219 : {
1220 0 : m_rWW8Export.InsUInt16( NS_sprm::LN_CSfxText );
1221 : // At the moment the only animated text effect we support is blinking
1222 0 : m_rWW8Export.InsUInt16( rBlink.GetValue() ? 2 : 0 );
1223 : }
1224 0 : }
1225 :
1226 2 : void WW8AttributeOutput::CharCrossedOut( const SvxCrossedOutItem& rCrossed )
1227 : {
1228 2 : FontStrikeout eSt = rCrossed.GetStrikeout();
1229 2 : if ( STRIKEOUT_DOUBLE == eSt )
1230 : {
1231 0 : OutputWW8Attribute( 8, true );
1232 0 : return;
1233 : }
1234 2 : if ( STRIKEOUT_NONE != eSt )
1235 : {
1236 0 : OutputWW8Attribute( 2, true );
1237 0 : return;
1238 : }
1239 :
1240 : // otherwise both off
1241 2 : OutputWW8Attribute( 8, false );
1242 2 : OutputWW8Attribute( 2, false );
1243 : }
1244 :
1245 8 : void WW8AttributeOutput::CharCaseMap( const SvxCaseMapItem& rCaseMap )
1246 : {
1247 8 : sal_uInt16 eSt = rCaseMap.GetValue();
1248 8 : switch ( eSt )
1249 : {
1250 : case SVX_CASEMAP_KAPITAELCHEN:
1251 0 : OutputWW8Attribute( 5, true );
1252 0 : return;
1253 : case SVX_CASEMAP_VERSALIEN:
1254 8 : OutputWW8Attribute( 6, true );
1255 8 : return;
1256 : case SVX_CASEMAP_TITEL:
1257 : // no such feature in word
1258 0 : break;
1259 : default:
1260 : // otherwise both off
1261 0 : OutputWW8Attribute( 5, false );
1262 0 : OutputWW8Attribute( 6, false );
1263 0 : return;
1264 : }
1265 : }
1266 :
1267 14 : void WW8AttributeOutput::CharHidden( const SvxCharHiddenItem& rHidden )
1268 : {
1269 14 : OutputWW8Attribute( 7, rHidden.GetValue() );
1270 14 : }
1271 :
1272 8 : void WW8AttributeOutput::CharBorder( const SvxBorderLine* pAllBorder, const sal_uInt16 /*nDist*/, const bool bShadow )
1273 : {
1274 8 : m_rWW8Export.Out_BorderLine( *m_rWW8Export.pO, pAllBorder, 0, NS_sprm::LN_CBrc80, NS_sprm::LN_CBrc, bShadow );
1275 8 : }
1276 :
1277 92 : void WW8AttributeOutput::CharUnderline( const SvxUnderlineItem& rUnderline )
1278 : {
1279 92 : if ( m_rWW8Export.bWrtWW8 )
1280 92 : m_rWW8Export.InsUInt16( NS_sprm::LN_CKul );
1281 : else
1282 0 : m_rWW8Export.pO->push_back( 94 );
1283 :
1284 92 : const SfxPoolItem* pItem = m_rWW8Export.HasItem( RES_CHRATR_WORDLINEMODE );
1285 92 : bool bWord = false;
1286 92 : if (pItem)
1287 0 : bWord = ((const SvxWordLineModeItem*)pItem)->GetValue() ? true : false;
1288 :
1289 : // WW95 - parameters: 0 = none, 1 = single, 2 = by Word,
1290 : // 3 = double, 4 = dotted, 5 = hidden
1291 : // WW97 - additional parameters:
1292 : // 6 = thick, 7 = dash, 8 = dot(not used)
1293 : // 9 = dotdash 10 = dotdotdash, 11 = wave
1294 92 : sal_uInt8 b = 0;
1295 92 : switch ( rUnderline.GetLineStyle() )
1296 : {
1297 : case UNDERLINE_SINGLE:
1298 46 : b = ( bWord ) ? 2 : 1;
1299 46 : break;
1300 : case UNDERLINE_BOLD:
1301 0 : b = m_rWW8Export.bWrtWW8 ? 6 : 1;
1302 0 : break;
1303 : case UNDERLINE_DOUBLE:
1304 0 : b = 3;
1305 0 : break;
1306 : case UNDERLINE_DOTTED:
1307 0 : b = 4;
1308 0 : break;
1309 : case UNDERLINE_DASH:
1310 0 : b = m_rWW8Export.bWrtWW8 ? 7 : 4;
1311 0 : break;
1312 : case UNDERLINE_DASHDOT:
1313 0 : b = m_rWW8Export.bWrtWW8 ? 9 : 4;
1314 0 : break;
1315 : case UNDERLINE_DASHDOTDOT:
1316 0 : b = m_rWW8Export.bWrtWW8 ? 10 : 4;
1317 0 : break;
1318 : case UNDERLINE_WAVE:
1319 0 : b = m_rWW8Export.bWrtWW8 ? 11 : 3;
1320 0 : break;
1321 : // new in WW2000
1322 : case UNDERLINE_BOLDDOTTED:
1323 0 : b = m_rWW8Export.bWrtWW8 ? 20 : 4;
1324 0 : break;
1325 : case UNDERLINE_BOLDDASH:
1326 0 : b = m_rWW8Export.bWrtWW8 ? 23 : 4;
1327 0 : break;
1328 : case UNDERLINE_LONGDASH:
1329 0 : b = m_rWW8Export.bWrtWW8 ? 39 : 4;
1330 0 : break;
1331 : case UNDERLINE_BOLDLONGDASH:
1332 0 : b = m_rWW8Export.bWrtWW8 ? 55 : 4;
1333 0 : break;
1334 : case UNDERLINE_BOLDDASHDOT:
1335 0 : b = m_rWW8Export.bWrtWW8 ? 25 : 4;
1336 0 : break;
1337 : case UNDERLINE_BOLDDASHDOTDOT:
1338 0 : b = m_rWW8Export.bWrtWW8 ? 26 : 4;
1339 0 : break;
1340 : case UNDERLINE_BOLDWAVE:
1341 0 : b = m_rWW8Export.bWrtWW8 ? 27 : 3;
1342 0 : break;
1343 : case UNDERLINE_DOUBLEWAVE:
1344 0 : b = m_rWW8Export.bWrtWW8 ? 43 : 3;
1345 0 : break;
1346 : case UNDERLINE_NONE:
1347 46 : b = 0;
1348 46 : break;
1349 : default:
1350 : OSL_ENSURE( rUnderline.GetLineStyle() == UNDERLINE_NONE, "Unhandled underline type" );
1351 0 : break;
1352 : }
1353 :
1354 92 : m_rWW8Export.pO->push_back( b );
1355 92 : Color aColor = rUnderline.GetColor();
1356 92 : if( aColor != COL_TRANSPARENT )
1357 : {
1358 0 : if( m_rWW8Export.bWrtWW8 )
1359 : {
1360 0 : m_rWW8Export.InsUInt16( 0x6877 );
1361 :
1362 0 : m_rWW8Export.InsUInt32( wwUtility::RGBToBGR( aColor.GetColor() ) );
1363 : }
1364 : }
1365 92 : }
1366 :
1367 298 : void WW8AttributeOutput::CharLanguage( const SvxLanguageItem& rLanguage )
1368 : {
1369 298 : sal_uInt16 nId = 0;
1370 298 : if ( m_rWW8Export.bWrtWW8 )
1371 : {
1372 298 : switch ( rLanguage.Which() )
1373 : {
1374 : case RES_CHRATR_LANGUAGE:
1375 142 : nId = NS_sprm::LN_CRgLid0_80;
1376 142 : break;
1377 : case RES_CHRATR_CJK_LANGUAGE:
1378 86 : nId = NS_sprm::LN_CRgLid1_80;
1379 86 : break;
1380 : case RES_CHRATR_CTL_LANGUAGE:
1381 70 : nId = NS_sprm::LN_CLidBi;
1382 70 : break;
1383 : }
1384 : }
1385 : else
1386 0 : nId = 97;
1387 :
1388 298 : if ( nId )
1389 : {
1390 298 : if ( m_rWW8Export.bWrtWW8 ) // use sprmCRgLid0_80 rather than sprmCLid
1391 298 : m_rWW8Export.InsUInt16( nId );
1392 : else
1393 0 : m_rWW8Export.pO->push_back( static_cast<sal_uInt8>(nId) );
1394 298 : m_rWW8Export.InsUInt16( rLanguage.GetLanguage() );
1395 :
1396 : // Word 2000 and above apparently require both old and new versions of
1397 : // these sprms to be set, without it spellchecking doesn't work
1398 298 : if ( nId == NS_sprm::LN_CRgLid0_80 )
1399 : {
1400 142 : m_rWW8Export.InsUInt16( NS_sprm::LN_CRgLid0 );
1401 142 : m_rWW8Export.InsUInt16( rLanguage.GetLanguage() );
1402 : }
1403 156 : else if ( nId == NS_sprm::LN_CRgLid1_80 )
1404 : {
1405 86 : m_rWW8Export.InsUInt16( NS_sprm::LN_CRgLid1 );
1406 86 : m_rWW8Export.InsUInt16( rLanguage.GetLanguage() );
1407 : }
1408 : }
1409 298 : }
1410 :
1411 10 : void WW8AttributeOutput::CharEscapement( const SvxEscapementItem& rEscapement )
1412 : {
1413 10 : sal_uInt8 b = 0xFF;
1414 10 : short nEsc = rEscapement.GetEsc(), nProp = rEscapement.GetProp();
1415 10 : if ( !nEsc )
1416 : {
1417 2 : b = 0;
1418 2 : nEsc = 0;
1419 2 : nProp = 100;
1420 : }
1421 8 : else if ( DFLT_ESC_PROP == nProp )
1422 : {
1423 8 : if ( DFLT_ESC_SUB == nEsc || DFLT_ESC_AUTO_SUB == nEsc )
1424 0 : b = 2;
1425 8 : else if ( DFLT_ESC_SUPER == nEsc || DFLT_ESC_AUTO_SUPER == nEsc )
1426 8 : b = 1;
1427 : }
1428 :
1429 10 : if ( 0xFF != b )
1430 : {
1431 10 : if ( m_rWW8Export.bWrtWW8 )
1432 10 : m_rWW8Export.InsUInt16( NS_sprm::LN_CIss );
1433 : else
1434 0 : m_rWW8Export.pO->push_back( 104 );
1435 :
1436 10 : m_rWW8Export.pO->push_back( b );
1437 : }
1438 :
1439 10 : if ( 0 == b || 0xFF == b )
1440 : {
1441 : long nHeight = ((SvxFontHeightItem&)m_rWW8Export.GetItem(
1442 2 : RES_CHRATR_FONTSIZE )).GetHeight();
1443 2 : if( m_rWW8Export.bWrtWW8 )
1444 2 : m_rWW8Export.InsUInt16( NS_sprm::LN_CHpsPos );
1445 : else
1446 0 : m_rWW8Export.pO->push_back( 101 );
1447 :
1448 2 : m_rWW8Export.InsUInt16( (short)(( nHeight * nEsc + 500 ) / 1000 ));
1449 :
1450 2 : if( 100 != nProp || !b )
1451 : {
1452 2 : if( m_rWW8Export.bWrtWW8 )
1453 2 : m_rWW8Export.InsUInt16( NS_sprm::LN_CHps );
1454 : else
1455 0 : m_rWW8Export.pO->push_back( 99 );
1456 :
1457 : m_rWW8Export.InsUInt16(
1458 2 : msword_cast<sal_uInt16>((nHeight * nProp + 500 ) / 1000));
1459 : }
1460 : }
1461 10 : }
1462 :
1463 1092 : void WW8AttributeOutput::CharFontSize( const SvxFontHeightItem& rHeight )
1464 : {
1465 1092 : sal_uInt16 nId = 0;
1466 1092 : if ( m_rWW8Export.bWrtWW8 )
1467 : {
1468 1092 : switch ( rHeight.Which() )
1469 : {
1470 : case RES_CHRATR_FONTSIZE:
1471 : case RES_CHRATR_CJK_FONTSIZE:
1472 702 : nId = NS_sprm::LN_CHps;
1473 702 : break;
1474 : case RES_CHRATR_CTL_FONTSIZE:
1475 390 : nId = NS_sprm::LN_CHpsBi;
1476 390 : break;
1477 : }
1478 : }
1479 : else
1480 0 : nId = 99;
1481 :
1482 1092 : if ( nId )
1483 : {
1484 1092 : if ( m_rWW8Export.bWrtWW8 )
1485 1092 : m_rWW8Export.InsUInt16( nId );
1486 : else
1487 0 : m_rWW8Export.pO->push_back( static_cast<sal_uInt8>(nId) );
1488 :
1489 1092 : m_rWW8Export.InsUInt16( (sal_uInt16)(( rHeight.GetHeight() + 5 ) / 10 ) );
1490 : }
1491 1092 : }
1492 :
1493 2 : void WW8AttributeOutput::CharScaleWidth( const SvxCharScaleWidthItem& rScaleWidth )
1494 : {
1495 2 : if ( m_rWW8Export.bWrtWW8 )
1496 : {
1497 2 : m_rWW8Export.InsUInt16( NS_sprm::LN_CCharScale );
1498 2 : m_rWW8Export.InsUInt16( rScaleWidth.GetValue() );
1499 : }
1500 2 : }
1501 :
1502 0 : void WW8AttributeOutput::CharRelief( const SvxCharReliefItem& rRelief )
1503 : {
1504 0 : if ( m_rWW8Export.bWrtWW8 )
1505 : {
1506 : sal_uInt16 nId;
1507 0 : switch ( rRelief.GetValue() )
1508 : {
1509 0 : case RELIEF_EMBOSSED: nId = NS_sprm::LN_CFEmboss; break;
1510 0 : case RELIEF_ENGRAVED: nId = NS_sprm::LN_CFImprint; break;
1511 0 : default: nId = 0; break;
1512 : }
1513 :
1514 0 : if( nId )
1515 : {
1516 0 : m_rWW8Export.InsUInt16( nId );
1517 0 : m_rWW8Export.pO->push_back( (sal_uInt8)0x81 );
1518 : }
1519 : else
1520 : {
1521 : // switch both flags off
1522 0 : m_rWW8Export.InsUInt16( NS_sprm::LN_CFEmboss );
1523 0 : m_rWW8Export.pO->push_back( (sal_uInt8)0x0 );
1524 0 : m_rWW8Export.InsUInt16( NS_sprm::LN_CFImprint );
1525 0 : m_rWW8Export.pO->push_back( (sal_uInt8)0x0 );
1526 : }
1527 : }
1528 0 : }
1529 :
1530 0 : void WW8AttributeOutput::CharBidiRTL( const SfxPoolItem& rHt )
1531 : {
1532 0 : const SfxInt16Item& rAttr = (const SfxInt16Item&)rHt;
1533 0 : if( rAttr.GetValue() == 1 )
1534 : {
1535 0 : m_rWW8Export.InsUInt16(0x85a);
1536 0 : m_rWW8Export.pO->push_back((sal_uInt8)(1));
1537 : }
1538 0 : }
1539 :
1540 0 : void WW8AttributeOutput::CharIdctHint( const SfxPoolItem& rHt )
1541 : {
1542 0 : const SfxInt16Item& rAttr = (const SfxInt16Item&)rHt;
1543 0 : m_rWW8Export.InsUInt16(0x286F);
1544 0 : m_rWW8Export.pO->push_back((sal_uInt8)(rAttr.GetValue()));
1545 0 : }
1546 :
1547 0 : void WW8AttributeOutput::CharRotate( const SvxCharRotateItem& rRotate )
1548 : {
1549 : // #i28331# - check that a Value is set
1550 0 : if ( !rRotate.GetValue() )
1551 0 : return;
1552 :
1553 0 : if ( m_rWW8Export.bWrtWW8 && !m_rWW8Export.IsInTable() )
1554 : {
1555 : // #i36867 In word the text in a table is rotated via the TC or NS_sprm::LN_TTextFlow
1556 : // This means you can only rotate all or none of the text adding NS_sprm::LN_CFELayout
1557 : // here corrupts the table, hence !m_rWW8Export.bIsInTable
1558 :
1559 0 : m_rWW8Export.InsUInt16( NS_sprm::LN_CFELayout );
1560 0 : m_rWW8Export.pO->push_back( (sal_uInt8)0x06 ); //len 6
1561 0 : m_rWW8Export.pO->push_back( (sal_uInt8)0x01 );
1562 :
1563 0 : m_rWW8Export.InsUInt16( rRotate.IsFitToLine() ? 1 : 0 );
1564 : static const sal_uInt8 aZeroArr[ 3 ] = { 0, 0, 0 };
1565 0 : m_rWW8Export.pO->insert( m_rWW8Export.pO->end(), aZeroArr, aZeroArr+3);
1566 : }
1567 : }
1568 :
1569 2 : void WW8AttributeOutput::CharEmphasisMark( const SvxEmphasisMarkItem& rEmphasisMark )
1570 : {
1571 2 : if ( m_rWW8Export.bWrtWW8 )
1572 : {
1573 : sal_uInt8 nVal;
1574 2 : switch ( rEmphasisMark.GetValue() )
1575 : {
1576 2 : case EMPHASISMARK_NONE: nVal = 0; break;
1577 0 : case EMPHASISMARK_SIDE_DOTS: nVal = 2; break;
1578 0 : case EMPHASISMARK_CIRCLE_ABOVE: nVal = 3; break;
1579 0 : case EMPHASISMARK_DOTS_BELOW: nVal = 4; break;
1580 : // case 1:
1581 0 : default: nVal = 1; break;
1582 : }
1583 :
1584 2 : m_rWW8Export.InsUInt16( NS_sprm::LN_CKcd );
1585 2 : m_rWW8Export.pO->push_back( nVal );
1586 : }
1587 2 : }
1588 :
1589 : // TransCol uebersetzt SW-Farben in WW. Heraus kommt die bei WW fuer
1590 : // Text- und Hintergrundfarbe benutzte Codierung.
1591 : // Gibt es keine direkte Entsprechung, dann wird versucht, eine moeglichst
1592 : // aehnliche WW-Farbe zu finden.
1593 : // return: 5-Bit-Wert ( 0..16 )
1594 682 : sal_uInt8 WW8Export::TransCol( const Color& rCol )
1595 : {
1596 682 : sal_uInt8 nCol = 0; // ->Auto
1597 682 : switch( rCol.GetColor() )
1598 : {
1599 428 : case COL_BLACK: nCol = 1; break;
1600 10 : case COL_BLUE: nCol = 9; break;
1601 0 : case COL_GREEN: nCol = 11; break;
1602 0 : case COL_CYAN: nCol = 10; break;
1603 0 : case COL_RED: nCol = 13; break;
1604 0 : case COL_MAGENTA: nCol = 12; break;
1605 0 : case COL_BROWN: nCol = 14; break;
1606 0 : case COL_GRAY: nCol = 15; break;
1607 0 : case COL_LIGHTGRAY: nCol = 16; break;
1608 2 : case COL_LIGHTBLUE: nCol = 2; break;
1609 0 : case COL_LIGHTGREEN: nCol = 4; break;
1610 0 : case COL_LIGHTCYAN: nCol = 3; break;
1611 2 : case COL_LIGHTRED: nCol = 6; break;
1612 0 : case COL_LIGHTMAGENTA: nCol = 5; break;
1613 0 : case COL_YELLOW: nCol = 7; break;
1614 30 : case COL_WHITE: nCol = 8; break;
1615 64 : case COL_AUTO: nCol = 0; break;
1616 :
1617 : default:
1618 146 : if( !pBmpPal )
1619 : {
1620 16 : pBmpPal = new BitmapPalette( 16 );
1621 : static const ColorData aColArr[ 16 ] = {
1622 : COL_BLACK, COL_LIGHTBLUE, COL_LIGHTCYAN, COL_LIGHTGREEN,
1623 : COL_LIGHTMAGENTA,COL_LIGHTRED, COL_YELLOW, COL_WHITE,
1624 : COL_BLUE, COL_CYAN, COL_GREEN, COL_MAGENTA,
1625 : COL_RED, COL_BROWN, COL_GRAY, COL_LIGHTGRAY
1626 : };
1627 :
1628 272 : for( sal_uInt16 i = 0; i < 16; ++i )
1629 256 : pBmpPal->operator[]( i ) = Color( aColArr[ i ] );
1630 : }
1631 146 : nCol = static_cast< sal_uInt8 >(pBmpPal->GetBestIndex( rCol ) + 1);
1632 146 : break;
1633 : }
1634 682 : return nCol;
1635 : }
1636 :
1637 : // TransBrush uebersetzt SW-Brushes in WW. Heraus kommt WW8_SHD.
1638 : // Nicht-Standardfarben des SW werden noch nicht in die
1639 : // Misch-Werte ( 0 .. 95% ) vom WW uebersetzt.
1640 : // Return: Echte Brush ( nicht transparent )
1641 : // auch bei Transparent wird z.B. fuer Tabellen eine transparente Brush
1642 : // geliefert
1643 280 : bool WW8Export::TransBrush(const Color& rCol, WW8_SHD& rShd)
1644 : {
1645 280 : if( rCol.GetTransparency() )
1646 222 : rShd = WW8_SHD(); // alles Nullen : transparent
1647 : else
1648 : {
1649 58 : rShd.SetFore( 0);
1650 58 : rShd.SetBack( TransCol( rCol ) );
1651 58 : rShd.SetStyle( bWrtWW8, 0 );
1652 : }
1653 280 : return !rCol.GetTransparency();
1654 : }
1655 :
1656 12 : sal_uInt32 SuitableBGColor(sal_uInt32 nIn)
1657 : {
1658 12 : if (nIn == COL_AUTO)
1659 0 : return 0xFF000000;
1660 12 : return wwUtility::RGBToBGR(nIn);
1661 : }
1662 :
1663 200 : void WW8AttributeOutput::CharColor( const SvxColorItem& rColor )
1664 : {
1665 200 : if ( m_rWW8Export.bWrtWW8 )
1666 200 : m_rWW8Export.InsUInt16( NS_sprm::LN_CIco );
1667 : else
1668 0 : m_rWW8Export.pO->push_back( 98 );
1669 :
1670 200 : sal_uInt8 nColor = m_rWW8Export.TransCol( rColor.GetValue() );
1671 200 : m_rWW8Export.pO->push_back( nColor );
1672 :
1673 200 : if ( m_rWW8Export.bWrtWW8 && nColor )
1674 : {
1675 136 : m_rWW8Export.InsUInt16( NS_sprm::LN_CCv );
1676 136 : m_rWW8Export.InsUInt32( wwUtility::RGBToBGR( rColor.GetValue().GetColor() ) );
1677 : }
1678 200 : }
1679 :
1680 8 : void WW8AttributeOutput::CharBackground( const SvxBrushItem& rBrush )
1681 : {
1682 8 : if( m_rWW8Export.bWrtWW8 ) // nur WW8 kann ZeichenHintergrund
1683 : {
1684 8 : WW8_SHD aSHD;
1685 :
1686 8 : m_rWW8Export.TransBrush( rBrush.GetColor(), aSHD );
1687 : // sprmCShd80
1688 8 : m_rWW8Export.InsUInt16( NS_sprm::LN_CShd80 );
1689 8 : m_rWW8Export.InsUInt16( aSHD.GetValue() );
1690 :
1691 : //Quite a few unknowns, some might be transparency or something
1692 : //of that nature...
1693 8 : m_rWW8Export.InsUInt16( NS_sprm::LN_CShd );
1694 8 : m_rWW8Export.pO->push_back( 10 );
1695 8 : m_rWW8Export.InsUInt32( 0xFF000000 );
1696 8 : m_rWW8Export.InsUInt32( SuitableBGColor( rBrush.GetColor().GetColor() ) );
1697 8 : m_rWW8Export.InsUInt16( 0x0000);
1698 : }
1699 8 : }
1700 :
1701 0 : void WW8AttributeOutput::TextINetFormat( const SwFmtINetFmt& rINet )
1702 : {
1703 0 : if ( !rINet.GetValue().isEmpty() )
1704 : {
1705 0 : const sal_uInt16 nId = rINet.GetINetFmtId();
1706 0 : const OUString& rStr = rINet.GetINetFmt();
1707 0 : if (rStr.isEmpty())
1708 : {
1709 : OSL_ENSURE( false, "WW8AttributeOutput::TextINetFormat(..) - missing unvisited character format at hyperlink attribute" );
1710 : }
1711 :
1712 0 : const SwCharFmt* pFmt = IsPoolUserFmt( nId )
1713 0 : ? m_rWW8Export.pDoc->FindCharFmtByName( rStr )
1714 0 : : m_rWW8Export.pDoc->getIDocumentStylePoolAccess().GetCharFmtFromPool( nId );
1715 :
1716 0 : if ( m_rWW8Export.bWrtWW8 )
1717 0 : m_rWW8Export.InsUInt16( NS_sprm::LN_CIstd );
1718 : else
1719 0 : m_rWW8Export.pO->push_back( 80 );
1720 :
1721 0 : m_rWW8Export.InsUInt16( m_rWW8Export.GetId( pFmt ) );
1722 : }
1723 0 : }
1724 :
1725 : // #i43956# - add optional parameter <pLinkStr>
1726 : // It's needed to write the hyperlink data for a certain cross-reference
1727 : // - it contains the name of the link target, which is a bookmark.
1728 : // add optional parameter <bIncludeEmptyPicLocation>
1729 : // It is needed to write an empty picture location for page number field separators
1730 38 : static void InsertSpecialChar( WW8Export& rWrt, sal_uInt8 c,
1731 : OUString* pLinkStr = 0L,
1732 : bool bIncludeEmptyPicLocation = false )
1733 : {
1734 38 : ww::bytes aItems;
1735 38 : rWrt.GetCurrentItems(aItems);
1736 :
1737 38 : if (c == 0x13)
1738 12 : rWrt.pChpPlc->AppendFkpEntry(rWrt.Strm().Tell());
1739 : else
1740 26 : rWrt.pChpPlc->AppendFkpEntry(rWrt.Strm().Tell(), aItems.size(), aItems.data());
1741 :
1742 38 : rWrt.WriteChar(c);
1743 :
1744 : // store empty sprmCPicLocation for field separator
1745 38 : if ( bIncludeEmptyPicLocation &&
1746 4 : ( c == 0x13 || c == 0x14 || c == 0x15 ) )
1747 : {
1748 6 : SwWW8Writer::InsUInt16( aItems, NS_sprm::LN_CPicLocation );
1749 6 : SwWW8Writer::InsUInt32( aItems, 0x00000000 );
1750 : }
1751 :
1752 : // #i43956# - write hyperlink data and attributes
1753 38 : if ( rWrt.bWrtWW8 && c == 0x01 && pLinkStr )
1754 : {
1755 : // write hyperlink data to data stream
1756 2 : SvStream& rStrm = *rWrt.pDataStrm;
1757 : // position of hyperlink data
1758 2 : const sal_uInt32 nLinkPosInDataStrm = rStrm.Tell();
1759 : // write empty header
1760 2 : const sal_uInt16 nEmptyHdrLen = 0x44;
1761 2 : sal_uInt8 aEmptyHeader[ nEmptyHdrLen ] = { 0 };
1762 2 : aEmptyHeader[ 4 ] = 0x44;
1763 2 : rStrm.Write( aEmptyHeader, nEmptyHdrLen );
1764 : // writer fixed header
1765 2 : const sal_uInt16 nFixHdrLen = 0x19;
1766 : sal_uInt8 aFixHeader[ nFixHdrLen ] =
1767 : {
1768 : 0x08, 0xD0, 0xC9, 0xEA, 0x79, 0xF9, 0xBA, 0xCE,
1769 : 0x11, 0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9,
1770 : 0x0B, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
1771 : 0x00,
1772 2 : };
1773 2 : rStrm.Write( aFixHeader, nFixHdrLen );
1774 : // write reference string including length+1
1775 2 : sal_uInt32 nStrLen( pLinkStr->getLength() + 1 );
1776 2 : SwWW8Writer::WriteLong( rStrm, nStrLen );
1777 2 : SwWW8Writer::WriteString16( rStrm, *(pLinkStr), false );
1778 : // write additional two NULL Bytes
1779 2 : SwWW8Writer::WriteLong( rStrm, 0 );
1780 : // write length of hyperlink data
1781 2 : const sal_uInt32 nCurrPos = rStrm.Tell();
1782 2 : rStrm.Seek( nLinkPosInDataStrm );
1783 : SVBT32 nLen;
1784 2 : UInt32ToSVBT32( nCurrPos - nLinkPosInDataStrm, nLen );
1785 2 : rStrm.Write( nLen, 4 );
1786 2 : rStrm.Seek( nCurrPos );
1787 :
1788 : // write attributes of hyperlink character 0x01
1789 2 : SwWW8Writer::InsUInt16( aItems, NS_sprm::LN_CFFldVanish );
1790 2 : aItems.push_back( (sal_uInt8)0x81 );
1791 2 : SwWW8Writer::InsUInt16( aItems, NS_sprm::LN_CPicLocation );
1792 2 : SwWW8Writer::InsUInt32( aItems, nLinkPosInDataStrm );
1793 2 : SwWW8Writer::InsUInt16( aItems, NS_sprm::LN_CFData );
1794 2 : aItems.push_back( (sal_uInt8)0x01 );
1795 : }
1796 :
1797 : //Technically we should probably Remove all attribs
1798 : //here for the 0x13, 0x14, 0x15, but our import
1799 : //is slightly lacking
1800 : //aItems.Remove(0, aItems.Count());
1801 : // fSpec-Attribute true
1802 38 : if( rWrt.bWrtWW8 )
1803 : {
1804 38 : SwWW8Writer::InsUInt16( aItems, NS_sprm::LN_CFSpec );
1805 38 : aItems.push_back( 1 );
1806 : }
1807 : else
1808 : {
1809 0 : aItems.push_back( 117 ); //sprmCFSpec
1810 0 : aItems.push_back( 1 );
1811 : }
1812 :
1813 38 : rWrt.pChpPlc->AppendFkpEntry(rWrt.Strm().Tell(), aItems.size(), aItems.data());
1814 38 : }
1815 :
1816 10 : static OUString lcl_GetExpandedField(const SwField &rFld)
1817 : {
1818 10 : OUString sRet(rFld.ExpandField(true));
1819 :
1820 : //replace LF 0x0A with VT 0x0B
1821 10 : return sRet.replace(0x0A, 0x0B);
1822 : }
1823 :
1824 1598 : WW8_WrPlcFld* WW8Export::CurrentFieldPlc() const
1825 : {
1826 1598 : WW8_WrPlcFld* pFldP = NULL;
1827 1598 : switch (nTxtTyp)
1828 : {
1829 : case TXT_MAINTEXT:
1830 1306 : pFldP = pFldMain;
1831 1306 : break;
1832 : case TXT_HDFT:
1833 228 : pFldP = pFldHdFt;
1834 228 : break;
1835 : case TXT_FTN:
1836 4 : pFldP = pFldFtn;
1837 4 : break;
1838 : case TXT_EDN:
1839 0 : pFldP = pFldEdn;
1840 0 : break;
1841 : case TXT_ATN:
1842 0 : pFldP = pFldAtn;
1843 0 : break;
1844 : case TXT_TXTBOX:
1845 60 : pFldP = pFldTxtBxs;
1846 60 : break;
1847 : case TXT_HFTXTBOX:
1848 0 : pFldP = pFldHFTxtBxs;
1849 0 : break;
1850 : default:
1851 : OSL_ENSURE( false, "was ist das fuer ein SubDoc-Type?" );
1852 : }
1853 1598 : return pFldP;
1854 : }
1855 :
1856 18 : void WW8Export::OutputField( const SwField* pFld, ww::eField eFldType,
1857 : const OUString& rFldCmd, sal_uInt8 nMode )
1858 : {
1859 18 : bool bUnicode = IsUnicode();
1860 18 : WW8_WrPlcFld* pFldP = CurrentFieldPlc();
1861 :
1862 18 : const bool bIncludeEmptyPicLocation = ( eFldType == ww::ePAGE );
1863 18 : if (WRITEFIELD_START & nMode)
1864 : {
1865 12 : sal_uInt8 aFld13[2] = { 0x13, 0x00 }; // will change
1866 : //#i3958#, Needed to make this field work correctly in Word 2000
1867 12 : if (eFldType == ww::eSHAPE)
1868 0 : aFld13[0] |= 0x80;
1869 12 : aFld13[1] = static_cast< sal_uInt8 >(eFldType); // Typ nachtragen
1870 12 : pFldP->Append( Fc2Cp( Strm().Tell() ), aFld13 );
1871 12 : InsertSpecialChar( *this, 0x13, 0, bIncludeEmptyPicLocation );
1872 : }
1873 18 : if (WRITEFIELD_CMD_START & nMode)
1874 : {
1875 12 : if (bUnicode)
1876 12 : SwWW8Writer::WriteString16(Strm(), rFldCmd, false);
1877 : else
1878 : {
1879 0 : SwWW8Writer::WriteString8(Strm(), rFldCmd, false,
1880 0 : RTL_TEXTENCODING_MS_1252);
1881 : }
1882 : // #i43956# - write hyperlink character including
1883 : // attributes and corresponding binary data for certain reference fields.
1884 12 : bool bHandleBookmark = false;
1885 :
1886 12 : if (pFld)
1887 : {
1888 10 : if (pFld->GetTyp()->Which() == RES_GETREFFLD &&
1889 0 : ( eFldType == ww::ePAGEREF || eFldType == ww::eREF ||
1890 0 : eFldType == ww::eNOTEREF || eFldType == ww::eFOOTREF ))
1891 2 : bHandleBookmark = true;
1892 : }
1893 :
1894 12 : if ( bHandleBookmark )
1895 : {
1896 : // retrieve reference destination - the name of the bookmark
1897 2 : OUString aLinkStr;
1898 2 : const sal_uInt16 nSubType = pFld->GetSubType();
1899 2 : const SwGetRefField& rRFld = *(static_cast<const SwGetRefField*>(pFld));
1900 2 : if ( nSubType == REF_SETREFATTR ||
1901 : nSubType == REF_BOOKMARK )
1902 : {
1903 2 : const OUString aRefName(rRFld.GetSetRefName());
1904 2 : aLinkStr = GetBookmarkName( nSubType, &aRefName, 0 );
1905 : }
1906 0 : else if ( nSubType == REF_FOOTNOTE ||
1907 : nSubType == REF_ENDNOTE )
1908 : {
1909 0 : aLinkStr = GetBookmarkName( nSubType, 0, rRFld.GetSeqNo() );
1910 : }
1911 0 : else if ( nSubType == REF_SEQUENCEFLD )
1912 : {
1913 0 : aLinkStr = pFld->GetPar2();
1914 : }
1915 : // insert hyperlink character including attributes and data.
1916 2 : InsertSpecialChar( *this, 0x01, &aLinkStr );
1917 : }
1918 : }
1919 18 : if (WRITEFIELD_CMD_END & nMode)
1920 : {
1921 : static const sal_uInt8 aFld14[2] = { 0x14, 0xff };
1922 12 : pFldP->Append( Fc2Cp( Strm().Tell() ), aFld14 );
1923 12 : pFldP->ResultAdded();
1924 12 : InsertSpecialChar( *this, 0x14, 0, bIncludeEmptyPicLocation );
1925 : }
1926 18 : if (WRITEFIELD_END & nMode)
1927 : {
1928 10 : OUString sOut;
1929 10 : if( pFld )
1930 8 : sOut = lcl_GetExpandedField(*pFld);
1931 : else
1932 2 : sOut = rFldCmd;
1933 10 : if( !sOut.isEmpty() )
1934 : {
1935 8 : if( bUnicode )
1936 8 : SwWW8Writer::WriteString16(Strm(), sOut, false);
1937 : else
1938 : {
1939 0 : SwWW8Writer::WriteString8(Strm(), sOut, false,
1940 0 : RTL_TEXTENCODING_MS_1252);
1941 : }
1942 :
1943 8 : if (pFld)
1944 : {
1945 8 : if (pFld->GetTyp()->Which() == RES_INPUTFLD &&
1946 : eFldType == ww::eFORMTEXT)
1947 : {
1948 : sal_uInt8 aArr[12];
1949 0 : sal_uInt8 *pArr = aArr;
1950 :
1951 0 : if ( bWrtWW8 )
1952 : {
1953 0 : Set_UInt16( pArr, NS_sprm::LN_CPicLocation );
1954 0 : Set_UInt32( pArr, 0x0 );
1955 :
1956 0 : Set_UInt16( pArr, NS_sprm::LN_CFSpec );
1957 0 : Set_UInt8( pArr, 1 );
1958 :
1959 0 : Set_UInt16( pArr, NS_sprm::LN_CFNoProof );
1960 0 : Set_UInt8( pArr, 1 );
1961 : }
1962 : else
1963 : {
1964 0 : Set_UInt8(pArr, 0x68); //sprmCPicLocation
1965 0 : Set_UInt32(pArr, 0x0);
1966 :
1967 0 : Set_UInt8( pArr, 117 ); //sprmCFSpec
1968 0 : Set_UInt8( pArr, 1 );
1969 : }
1970 0 : pChpPlc->AppendFkpEntry( Strm().Tell(), static_cast< short >(pArr - aArr), aArr );
1971 : }
1972 : }
1973 10 : }
1974 : }
1975 18 : if (WRITEFIELD_CLOSE & nMode)
1976 : {
1977 12 : sal_uInt8 aFld15[2] = { 0x15, 0x80 };
1978 :
1979 12 : if (pFld)
1980 : {
1981 8 : if (pFld->GetTyp()->Which() == RES_INPUTFLD &&
1982 : eFldType == ww::eFORMTEXT)
1983 : {
1984 0 : sal_uInt16 nSubType = pFld->GetSubType();
1985 :
1986 0 : if (nSubType == REF_SEQUENCEFLD)
1987 0 : aFld15[0] |= (0x4 << 5);
1988 : }
1989 : }
1990 :
1991 12 : pFldP->Append( Fc2Cp( Strm().Tell() ), aFld15 );
1992 12 : InsertSpecialChar( *this, 0x15, 0, bIncludeEmptyPicLocation );
1993 : }
1994 18 : }
1995 :
1996 0 : void WW8Export::StartCommentOutput(const OUString& rName)
1997 : {
1998 0 : OUString sStr(FieldString(ww::eQUOTE));
1999 0 : sStr += "[" + rName + "] ";
2000 0 : OutputField(0, ww::eQUOTE, sStr, WRITEFIELD_START | WRITEFIELD_CMD_START);
2001 0 : }
2002 :
2003 0 : void WW8Export::EndCommentOutput(const OUString& rName)
2004 : {
2005 0 : OUString sStr(" [");
2006 0 : sStr += rName + "] ";
2007 : OutputField(0, ww::eQUOTE, sStr, WRITEFIELD_CMD_END | WRITEFIELD_END |
2008 0 : WRITEFIELD_CLOSE);
2009 0 : }
2010 :
2011 0 : sal_uInt16 MSWordExportBase::GetId( const SwTOXType& rTOXType )
2012 : {
2013 : std::vector<const SwTOXType*>::iterator it
2014 0 : = std::find( aTOXArr.begin(), aTOXArr.end(), &rTOXType );
2015 0 : if ( it != aTOXArr.end() )
2016 : {
2017 0 : return it - aTOXArr.begin();
2018 : }
2019 0 : aTOXArr.push_back( &rTOXType );
2020 0 : return aTOXArr.size() - 1;
2021 : }
2022 :
2023 : // return values: 1 - no PageNum,
2024 : // 2 - TabStop before PageNum,
2025 : // 3 - Text before PageNum - rTxt hold the text
2026 : // 4 - no Text and no TabStop before PageNum
2027 176 : static int lcl_CheckForm( const SwForm& rForm, sal_uInt8 nLvl, OUString& rText )
2028 : {
2029 176 : int nRet = 4;
2030 176 : rText = "";
2031 :
2032 : // #i21237#
2033 176 : SwFormTokens aPattern = rForm.GetPattern(nLvl);
2034 176 : SwFormTokens::iterator aIt = aPattern.begin();
2035 176 : bool bPgNumFnd = false;
2036 : FormTokenType eTType;
2037 :
2038 : // #i61362#
2039 176 : if (! aPattern.empty())
2040 : {
2041 : // #i21237#
2042 1030 : while( ++aIt != aPattern.end() && !bPgNumFnd )
2043 : {
2044 678 : eTType = aIt->eTokenType;
2045 :
2046 678 : switch( eTType )
2047 : {
2048 : case TOKEN_PAGE_NUMS:
2049 164 : bPgNumFnd = true;
2050 164 : break;
2051 :
2052 : case TOKEN_TAB_STOP:
2053 164 : nRet = 2;
2054 164 : break;
2055 : case TOKEN_TEXT:
2056 0 : nRet = 3;
2057 0 : rText = aIt->sText.copy( 0, 5 ); // #i21237#
2058 0 : break;
2059 :
2060 : case TOKEN_LINK_START:
2061 : case TOKEN_LINK_END:
2062 96 : break;
2063 :
2064 : default:
2065 254 : nRet = 4;
2066 254 : break;
2067 : }
2068 : }
2069 :
2070 176 : if( !bPgNumFnd )
2071 12 : nRet = 1;
2072 : }
2073 :
2074 176 : return nRet;
2075 : }
2076 :
2077 32 : static bool lcl_IsHyperlinked(const SwForm& rForm, sal_uInt16 nTOXLvl)
2078 : {
2079 32 : bool bRes = false;
2080 136 : for (sal_uInt16 nI = 1; nI < nTOXLvl; ++nI)
2081 : {
2082 : // #i21237#
2083 104 : SwFormTokens aPattern = rForm.GetPattern(nI);
2084 :
2085 104 : if ( !aPattern.empty() )
2086 : {
2087 104 : SwFormTokens::iterator aIt = aPattern.begin();
2088 :
2089 : FormTokenType eTType;
2090 :
2091 : // #i21237#
2092 828 : while ( ++aIt != aPattern.end() )
2093 : {
2094 620 : eTType = aIt->eTokenType;
2095 620 : switch (eTType)
2096 : {
2097 : case TOKEN_LINK_START:
2098 : case TOKEN_LINK_END:
2099 222 : bRes = true;
2100 222 : break;
2101 : default:
2102 : ;
2103 : }
2104 : }
2105 : }
2106 104 : }
2107 32 : return bRes;
2108 : }
2109 :
2110 58 : void AttributeOutputBase::StartTOX( const SwSection& rSect )
2111 : {
2112 58 : if ( const SwTOXBase* pTOX = rSect.GetTOXBase() )
2113 : {
2114 : static const sal_Char sEntryEnd[] = "\" ";
2115 :
2116 58 : ww::eField eCode = ww::eTOC;
2117 58 : OUString sStr = pTOX ->GetMSTOCExpression();
2118 58 : if ( sStr.isEmpty() )
2119 : {
2120 58 : switch (pTOX->GetType())
2121 : {
2122 : case TOX_INDEX:
2123 12 : eCode = ww::eINDEX;
2124 12 : sStr = FieldString(eCode);
2125 :
2126 : {
2127 12 : const SwFmtCol& rCol = (const SwFmtCol&)( rSect.GetFmt()->GetFmtAttr( RES_COL ) );
2128 12 : const SwColumns& rColumns = rCol.GetColumns();
2129 12 : sal_Int32 nCol = rColumns.size();
2130 :
2131 12 : if ( 0 < nCol )
2132 : {
2133 : // Add a continuous section break
2134 6 : if( GetExport().AddSectionBreaksForTOX() )
2135 : {
2136 6 : sal_uLong nRstLnNum = 0;
2137 6 : SwSection *pParent = rSect.GetParent();
2138 6 : WW8_SepInfo rInfo(&GetExport( ).pDoc->GetPageDesc(0),
2139 12 : pParent ? pParent->GetFmt() : NULL, nRstLnNum);
2140 6 : GetExport( ).AttrOutput().SectionBreak( msword::PageBreak, &rInfo );
2141 : }
2142 :
2143 6 : sStr += "\\c \"" + OUString::number( nCol ) + "\"";
2144 : }
2145 : }
2146 :
2147 12 : if (pTOX->GetTOXForm().IsCommaSeparated())
2148 0 : sStr += "\\r ";
2149 :
2150 12 : if (nsSwTOIOptions::TOI_ALPHA_DELIMITTER & pTOX->GetOptions())
2151 2 : sStr += "\\h \"A\" ";
2152 :
2153 12 : if(nsSwTOXElement::TOX_INDEX_ENTRY_TYPE & pTOX->GetCreateType())
2154 : {
2155 2 : sStr += "\\f ";
2156 2 : OUString sName = pTOX->GetEntryTypeName();
2157 2 : if(!sName.isEmpty())
2158 : {
2159 2 : sStr += sName;
2160 2 : sStr += sEntryEnd;
2161 2 : }
2162 : }
2163 :
2164 12 : if (!pTOX->GetTOXForm().IsCommaSeparated())
2165 : {
2166 : // In case of Run-in style no separators are added.
2167 12 : OUString aFillTxt;
2168 48 : for (sal_uInt8 n = 1; n <= 3; ++n)
2169 : {
2170 36 : OUString aTxt;
2171 36 : int nRet = ::lcl_CheckForm(pTOX->GetTOXForm(), n, aTxt);
2172 :
2173 36 : if( 3 == nRet )
2174 0 : aFillTxt = aTxt;
2175 36 : else if ((4 == nRet) || (2 == nRet)) //#109414#
2176 24 : aFillTxt = "\t";
2177 : else
2178 12 : aFillTxt = "";
2179 36 : }
2180 12 : sStr += "\\e \"";
2181 12 : sStr += aFillTxt;
2182 12 : sStr += sEntryEnd;
2183 : }
2184 12 : break;
2185 :
2186 : case TOX_ILLUSTRATIONS:
2187 : case TOX_OBJECTS:
2188 : case TOX_TABLES:
2189 4 : if (!pTOX->IsFromObjectNames())
2190 : {
2191 4 : sStr = FieldString(eCode);
2192 :
2193 4 : sStr += "\\c ";
2194 4 : OUString seqName = pTOX->GetSequenceName();
2195 4 : if(!seqName.isEmpty())
2196 : {
2197 2 : sStr += "\"";
2198 2 : sStr += seqName;
2199 2 : sStr += sEntryEnd;
2200 : }
2201 8 : OUString aTxt;
2202 4 : int nRet = ::lcl_CheckForm( pTOX->GetTOXForm(), 1, aTxt );
2203 4 : if (1 == nRet)
2204 0 : sStr += "\\n ";
2205 4 : else if( 3 == nRet || 4 == nRet )
2206 : {
2207 0 : sStr += "\\p \"";
2208 0 : sStr += aTxt;
2209 0 : sStr += sEntryEnd;
2210 4 : }
2211 : }
2212 4 : break;
2213 :
2214 : case TOX_AUTHORITIES:
2215 10 : eCode = ww::eBIBLIOGRPAHY;
2216 10 : sStr = FieldString(eCode);
2217 10 : break;
2218 : // case TOX_USER:
2219 : // case TOX_CONTENT:
2220 : default:
2221 : {
2222 32 : sStr = FieldString(eCode);
2223 :
2224 32 : OUString sTOption;
2225 32 : sal_uInt16 n, nTOXLvl = pTOX->GetLevel();
2226 32 : if( !nTOXLvl )
2227 0 : ++nTOXLvl;
2228 :
2229 32 : if(nsSwTOXElement::TOX_TABLEADER & pTOX->GetCreateType())
2230 : {
2231 26 : sStr +="\\z " ;
2232 26 : GetExport( ).bHideTabLeaderAndPageNumbers = true ;
2233 : }
2234 32 : if(nsSwTOXElement::TOX_TAB_IN_TOC & pTOX->GetCreateType())
2235 : {
2236 2 : sStr +="\\w " ;
2237 2 : GetExport( ).bTabInTOC = true ;
2238 : }
2239 32 : if(nsSwTOXElement::TOX_NEWLINE & pTOX->GetCreateType())
2240 : {
2241 2 : sStr +="\\x " ;
2242 : }
2243 32 : if( nsSwTOXElement::TOX_MARK & pTOX->GetCreateType() )
2244 : {
2245 8 : sStr += "\\f ";
2246 :
2247 8 : if( TOX_USER == pTOX->GetType() )
2248 : {
2249 0 : sStr += "\"";
2250 0 : sStr += OUString((sal_Char)( 'A' + GetExport( ).GetId( *pTOX->GetTOXType() ) ));
2251 0 : sStr += sEntryEnd;
2252 : }
2253 : }
2254 32 : if(nsSwTOXElement::TOX_BOOKMARK & pTOX->GetCreateType())
2255 : {
2256 2 : sStr += "\\b ";
2257 2 : OUString bName = pTOX->GetBookmarkName();
2258 2 : sStr += bName;
2259 2 : sStr += sEntryEnd;
2260 : }
2261 :
2262 32 : if( nsSwTOXElement::TOX_OUTLINELEVEL & pTOX->GetCreateType() )
2263 : {
2264 : // Take the TOC value of the max level to evaluate to as
2265 : // the starting point for the \o flag, but reduce it to the
2266 : // value of the highest outline level filled by a *standard*
2267 : // Heading 1 - 9 style because \o "Builds a table of
2268 : // contents from paragraphs formatted with built-in heading
2269 : // styles". And afterward fill in any outline styles left
2270 : // uncovered by that range to the \t flag
2271 :
2272 : // i.e. for
2273 : // Heading 1
2274 : // Heading 2
2275 : // custom-style
2276 : // Heading 4
2277 : // output
2278 : // \o 1-2 \tcustom-style,3,Heading 3,4
2279 :
2280 : // Search over all the outline styles used and figure out
2281 : // what is the minimum outline level (if any) filled by a
2282 : // non-standard style for that level, i.e. ignore headline
2283 : // styles 1-9 and find the lowest valid outline level
2284 32 : sal_uInt8 nPosOfLowestNonStandardLvl = MAXLEVEL;
2285 32 : const SwTxtFmtColls& rColls = *GetExport().pDoc->GetTxtFmtColls();
2286 912 : for( n = rColls.size(); n; )
2287 : {
2288 848 : const SwTxtFmtColl* pColl = rColls[ --n ];
2289 848 : sal_uInt16 nPoolId = pColl->GetPoolFmtId();
2290 848 : if (
2291 : //Is a Non-Standard Outline Style
2292 1490 : (RES_POOLCOLL_HEADLINE1 > nPoolId || RES_POOLCOLL_HEADLINE9 < nPoolId) &&
2293 : //Has a valid outline level
2294 1596 : (pColl->IsAssignedToListLevelOfOutlineStyle()) &&
2295 : // Is less than the lowest known non-standard level
2296 6 : (pColl->GetAssignedOutlineStyleLevel() < nPosOfLowestNonStandardLvl)
2297 : )
2298 : {
2299 6 : nPosOfLowestNonStandardLvl = ::sal::static_int_cast<sal_uInt8>(pColl->GetAssignedOutlineStyleLevel());
2300 : }
2301 : }
2302 :
2303 32 : sal_uInt8 nMaxMSAutoEvaluate = nPosOfLowestNonStandardLvl < nTOXLvl ? nPosOfLowestNonStandardLvl : (sal_uInt8)nTOXLvl;
2304 :
2305 : //output \o 1-X where X is the highest normal outline style to be included in the toc
2306 32 : if ( nMaxMSAutoEvaluate )
2307 : {
2308 32 : if (nMaxMSAutoEvaluate > WW8ListManager::nMaxLevel)
2309 2 : nMaxMSAutoEvaluate = WW8ListManager::nMaxLevel;
2310 :
2311 32 : sStr += "\\o \"1-";
2312 32 : sStr += OUString::number(nMaxMSAutoEvaluate);
2313 32 : sStr += sEntryEnd;
2314 : }
2315 :
2316 : //collect up any other styles in the writer TOC which will
2317 : //not already appear in the MS TOC and place then into the
2318 : //\t option
2319 32 : if( nMaxMSAutoEvaluate < nTOXLvl )
2320 : {
2321 : // collect this templates into the \t otion
2322 116 : for( n = rColls.size(); n;)
2323 : {
2324 108 : const SwTxtFmtColl* pColl = rColls[ --n ];
2325 108 : if (!pColl->IsAssignedToListLevelOfOutlineStyle())
2326 92 : continue;
2327 16 : sal_uInt8 nTestLvl = ::sal::static_int_cast<sal_uInt8>(pColl->GetAssignedOutlineStyleLevel());
2328 16 : if (nTestLvl < nTOXLvl && nTestLvl >= nMaxMSAutoEvaluate)
2329 : {
2330 16 : if (!sTOption.isEmpty())
2331 14 : sTOption += ",";
2332 16 : sTOption += pColl->GetName() + "," + OUString::number( nTestLvl + 1 );
2333 : }
2334 : }
2335 : }
2336 : }
2337 :
2338 32 : if( nsSwTOXElement::TOX_PARAGRAPH_OUTLINE_LEVEL & pTOX->GetCreateType() )
2339 : {
2340 22 : sStr +="\\u " ;
2341 : }
2342 :
2343 32 : if( nsSwTOXElement::TOX_TEMPLATE & pTOX->GetCreateType() )
2344 : {
2345 : // #i99641# - Consider additional styles regardless of TOX-outlinelevel
2346 0 : for( n = 0; n < MAXLEVEL; ++n )
2347 : {
2348 0 : const OUString& rStyles = pTOX->GetStyleNames( n );
2349 0 : if( !rStyles.isEmpty() )
2350 : {
2351 0 : sal_Int32 nPos = 0;
2352 0 : OUString sLvl = OUString(',');
2353 0 : sLvl += OUString::number( n + 1 );
2354 0 : do {
2355 0 : OUString sStyle( rStyles.getToken( 0, TOX_STYLE_DELIMITER, nPos ));
2356 0 : if( !sStyle.isEmpty() )
2357 : {
2358 0 : SwTxtFmtColl* pColl = GetExport().pDoc->FindTxtFmtCollByName(sStyle);
2359 0 : if (pColl)
2360 : {
2361 0 : if (!pColl->IsAssignedToListLevelOfOutlineStyle() || pColl->GetAssignedOutlineStyleLevel() < nTOXLvl)
2362 : {
2363 0 : if( !sTOption.isEmpty() )
2364 0 : sTOption += ",";
2365 0 : sTOption += sStyle + sLvl;
2366 : }
2367 : }
2368 0 : }
2369 0 : } while( -1 != nPos );
2370 : }
2371 0 : }
2372 : }
2373 :
2374 : // No 'else' branch; why the below snippet is a block I have no idea.
2375 : {
2376 32 : OUString aFillTxt;
2377 32 : sal_uInt8 nNoPgStt = MAXLEVEL, nNoPgEnd = MAXLEVEL;
2378 32 : bool bFirstFillTxt = true, bOnlyText = true;
2379 168 : for( n = 0; n < nTOXLvl; ++n )
2380 : {
2381 136 : OUString aTxt;
2382 136 : int nRet = ::lcl_CheckForm( pTOX->GetTOXForm(),
2383 272 : static_cast< sal_uInt8 >(n+1), aTxt );
2384 136 : if( 1 == nRet )
2385 : {
2386 0 : bOnlyText = false;
2387 0 : if( MAXLEVEL == nNoPgStt )
2388 0 : nNoPgStt = static_cast< sal_uInt8 >(n+1);
2389 : }
2390 : else
2391 : {
2392 136 : if( MAXLEVEL != nNoPgStt &&
2393 : MAXLEVEL == nNoPgEnd )
2394 0 : nNoPgEnd = sal_uInt8(n);
2395 :
2396 136 : bOnlyText = bOnlyText && 3 == nRet;
2397 136 : if( 3 == nRet || 4 == nRet )
2398 : {
2399 0 : if( bFirstFillTxt )
2400 0 : aFillTxt = aTxt;
2401 0 : else if( aFillTxt != aTxt )
2402 0 : aFillTxt = "";
2403 0 : bFirstFillTxt = false;
2404 : }
2405 : }
2406 136 : }
2407 32 : if( MAXLEVEL != nNoPgStt )
2408 : {
2409 0 : if (WW8ListManager::nMaxLevel < nNoPgEnd)
2410 0 : nNoPgEnd = WW8ListManager::nMaxLevel;
2411 0 : sStr += "\\n ";
2412 0 : sStr += OUString::number( nNoPgStt );
2413 0 : sStr += "-";
2414 0 : sStr += OUString::number( nNoPgEnd );
2415 0 : sStr += " ";
2416 : }
2417 32 : if( bOnlyText )
2418 : {
2419 0 : sStr += "\\p \"";
2420 0 : sStr += aFillTxt;
2421 0 : sStr += sEntryEnd;
2422 32 : }
2423 : }
2424 :
2425 32 : if( !sTOption.isEmpty() )
2426 : {
2427 2 : sStr += "\\t \"";
2428 2 : sStr += sTOption;
2429 2 : sStr += sEntryEnd;
2430 : }
2431 :
2432 32 : if (lcl_IsHyperlinked(pTOX->GetTOXForm(), nTOXLvl))
2433 30 : sStr += "\\h";
2434 32 : break;
2435 : }
2436 : }
2437 : }
2438 :
2439 58 : if (!sStr.isEmpty())
2440 : {
2441 58 : GetExport( ).bInWriteTOX = true;
2442 58 : GetExport( ).OutputField( 0, eCode, sStr, WRITEFIELD_START | WRITEFIELD_CMD_START |
2443 58 : WRITEFIELD_CMD_END );
2444 58 : }
2445 : }
2446 :
2447 58 : GetExport( ).bStartTOX = false;
2448 58 : }
2449 :
2450 58 : void AttributeOutputBase::EndTOX( const SwSection& rSect,bool bCareEnd )
2451 : {
2452 58 : const SwTOXBase* pTOX = rSect.GetTOXBase();
2453 58 : if ( pTOX )
2454 : {
2455 58 : ww::eField eCode = TOX_INDEX == pTOX->GetType() ? ww::eINDEX : ww::eTOC;
2456 58 : GetExport( ).OutputField( 0, eCode, OUString(), WRITEFIELD_CLOSE );
2457 :
2458 58 : if ( pTOX->GetType() == TOX_INDEX && GetExport().AddSectionBreaksForTOX() )
2459 : {
2460 12 : const SwFmtCol& rCol = (const SwFmtCol&)( rSect.GetFmt()->GetFmtAttr( RES_COL ) );
2461 12 : const SwColumns& rColumns = rCol.GetColumns();
2462 12 : sal_Int32 nCol = rColumns.size();
2463 :
2464 12 : if ( 0 < nCol )
2465 : {
2466 6 : sal_uLong nRstLnNum = 0;
2467 6 : WW8_SepInfo rInfo( &GetExport( ).pDoc->GetPageDesc( 0 ), rSect.GetFmt() , nRstLnNum );
2468 6 : GetExport( ).AttrOutput().SectionBreak( msword::PageBreak, &rInfo );
2469 : }
2470 : }
2471 : }
2472 58 : GetExport( ).bInWriteTOX = false;
2473 58 : if (bCareEnd)
2474 2 : OnTOXEnding();
2475 58 : }
2476 :
2477 4 : bool MSWordExportBase::GetNumberFmt(const SwField& rFld, OUString& rStr)
2478 : {
2479 : // Returns a date or time format string by using the US NfKeywordTable
2480 4 : bool bHasFmt = false;
2481 4 : SvNumberFormatter* pNFmtr = pDoc->GetNumberFormatter();
2482 4 : sal_uInt32 nFmtIdx = rFld.GetFormat();
2483 4 : const SvNumberformat* pNumFmt = pNFmtr->GetEntry( nFmtIdx );
2484 4 : if( pNumFmt )
2485 : {
2486 4 : sal_uInt16 nLng = rFld.GetLanguage();
2487 : LocaleDataWrapper aLocDat(pNFmtr->GetComponentContext(),
2488 4 : LanguageTag(nLng));
2489 :
2490 4 : OUString sFmt(pNumFmt->GetMappedFormatstring(GetNfKeywordTable(),
2491 8 : aLocDat));
2492 :
2493 4 : if (!sFmt.isEmpty())
2494 : {
2495 2 : sw::ms::SwapQuotesInField(sFmt);
2496 :
2497 2 : rStr = "\\@\"" + sFmt + "\" " ;
2498 2 : bHasFmt = true;
2499 4 : }
2500 : }
2501 4 : return bHasFmt;
2502 : }
2503 :
2504 210 : void AttributeOutputBase::GetNumberPara( OUString& rStr, const SwField& rFld )
2505 : {
2506 210 : switch(rFld.GetFormat())
2507 : {
2508 : case SVX_NUM_CHARS_UPPER_LETTER:
2509 : case SVX_NUM_CHARS_UPPER_LETTER_N:
2510 0 : rStr += "\\* ALPHABETIC ";
2511 0 : break;
2512 : case SVX_NUM_CHARS_LOWER_LETTER:
2513 : case SVX_NUM_CHARS_LOWER_LETTER_N:
2514 0 : rStr += "\\* alphabetic ";
2515 0 : break;
2516 : case SVX_NUM_ROMAN_UPPER:
2517 2 : rStr += "\\* ROMAN ";
2518 2 : break;
2519 : case SVX_NUM_ROMAN_LOWER:
2520 0 : rStr += "\\* roman ";
2521 0 : break;
2522 : default:
2523 : OSL_ENSURE(rFld.GetFormat() == SVX_NUM_ARABIC,
2524 : "Unknown numbering type exported as default of Arabic\n");
2525 : //fallthrough
2526 : case SVX_NUM_ARABIC:
2527 26 : rStr += "\\* ARABIC ";
2528 26 : break;
2529 : case SVX_NUM_PAGEDESC:
2530 : //Nothing, use word's default
2531 182 : break;
2532 : }
2533 210 : }
2534 :
2535 20 : void WW8Export::WritePostItBegin( ww::bytes* pOut )
2536 : {
2537 : sal_uInt8 aArr[ 3 ];
2538 20 : sal_uInt8* pArr = aArr;
2539 :
2540 : // sprmCFSpec true
2541 20 : if( bWrtWW8 )
2542 20 : Set_UInt16( pArr, NS_sprm::LN_CFSpec );
2543 : else
2544 0 : Set_UInt8( pArr, 117 ); //sprmCFSpec
2545 20 : Set_UInt8( pArr, 1 );
2546 :
2547 20 : pChpPlc->AppendFkpEntry( Strm().Tell() );
2548 20 : WriteChar( 0x05 ); // Annotation reference
2549 :
2550 20 : if( pOut )
2551 10 : pOut->insert( pOut->end(), aArr, pArr );
2552 : else
2553 10 : pChpPlc->AppendFkpEntry( Strm().Tell(), static_cast< short >(pArr - aArr), aArr );
2554 20 : }
2555 :
2556 542 : OUString FieldString(ww::eField eIndex)
2557 : {
2558 542 : if (const char *pField = ww::GetEnglishFieldName(eIndex))
2559 542 : return " " + OUString::createFromAscii(pField) + " ";
2560 0 : return OUString(" ");
2561 : }
2562 :
2563 0 : void WW8AttributeOutput::HiddenField( const SwField& rFld )
2564 : {
2565 0 : OUString sExpand(rFld.GetPar2());
2566 :
2567 : //replace LF 0x0A with VT 0x0B
2568 0 : sExpand = sExpand.replace(0x0A, 0x0B);
2569 0 : m_rWW8Export.pChpPlc->AppendFkpEntry(m_rWW8Export.Strm().Tell());
2570 0 : if (m_rWW8Export.IsUnicode())
2571 : {
2572 0 : SwWW8Writer::WriteString16(m_rWW8Export.Strm(), sExpand, false);
2573 : static sal_uInt8 aArr[] =
2574 : {
2575 : 0x3C, 0x08, 0x1
2576 : };
2577 0 : m_rWW8Export.pChpPlc->AppendFkpEntry(m_rWW8Export.Strm().Tell(), sizeof(aArr), aArr);
2578 : }
2579 : else
2580 : {
2581 0 : SwWW8Writer::WriteString8(m_rWW8Export.Strm(), sExpand, false,
2582 0 : RTL_TEXTENCODING_MS_1252);
2583 : static sal_uInt8 aArr[] =
2584 : {
2585 : 92, 0x1
2586 : };
2587 0 : m_rWW8Export.pChpPlc->AppendFkpEntry(m_rWW8Export.Strm().Tell(), sizeof(aArr), aArr);
2588 0 : }
2589 0 : }
2590 :
2591 0 : void WW8AttributeOutput::SetField( const SwField& rFld, ww::eField eType, const OUString& rCmd )
2592 : {
2593 0 : const SwSetExpField* pSet=(const SwSetExpField*)(&rFld);
2594 0 : const OUString &rVar = pSet->GetPar2();
2595 :
2596 0 : sal_uLong nFrom = m_rWW8Export.Fc2Cp(m_rWW8Export.Strm().Tell());
2597 :
2598 0 : GetExport().OutputField(&rFld, eType, rCmd, WRITEFIELD_START |
2599 0 : WRITEFIELD_CMD_START | WRITEFIELD_CMD_END);
2600 :
2601 : /*
2602 : Is there a bookmark at the start position of this field, if so
2603 : move it to the 0x14 of the result of the field. This is what word
2604 : does. MoveFieldMarks moves any bookmarks at this position to
2605 : the beginning of the field result, and marks the bookmark as a
2606 : fieldbookmark which is to be ended before the field end mark
2607 : instead of after it like a normal bookmark.
2608 : */
2609 0 : m_rWW8Export.MoveFieldMarks(nFrom,m_rWW8Export.Fc2Cp(m_rWW8Export.Strm().Tell()));
2610 :
2611 0 : if (!rVar.isEmpty())
2612 : {
2613 0 : if (m_rWW8Export.IsUnicode())
2614 0 : SwWW8Writer::WriteString16(m_rWW8Export.Strm(), rVar, false);
2615 : else
2616 : {
2617 0 : SwWW8Writer::WriteString8(m_rWW8Export.Strm(), rVar, false,
2618 0 : RTL_TEXTENCODING_MS_1252);
2619 : }
2620 : }
2621 0 : GetExport().OutputField(&rFld, eType, rCmd, WRITEFIELD_CLOSE);
2622 0 : }
2623 :
2624 10 : void WW8AttributeOutput::PostitField( const SwField* pFld )
2625 : {
2626 10 : const SwPostItField *pPFld = (const SwPostItField*)pFld;
2627 10 : m_rWW8Export.pAtn->Append( m_rWW8Export.Fc2Cp( m_rWW8Export.Strm().Tell() ), pPFld );
2628 10 : m_rWW8Export.WritePostItBegin( m_rWW8Export.pO );
2629 10 : }
2630 :
2631 0 : bool WW8AttributeOutput::DropdownField( const SwField* pFld )
2632 : {
2633 0 : bool bExpand = true;
2634 0 : if ( m_rWW8Export.bWrtWW8 )
2635 : {
2636 0 : const SwDropDownField& rFld2 = *(SwDropDownField*)pFld;
2637 : uno::Sequence<OUString> aItems =
2638 0 : rFld2.GetItemSequence();
2639 0 : GetExport().DoComboBox(rFld2.GetName(),
2640 0 : rFld2.GetHelp(),
2641 0 : rFld2.GetToolTip(),
2642 0 : rFld2.GetSelectedItem(), aItems);
2643 0 : bExpand = false;
2644 : }
2645 0 : return bExpand;
2646 : }
2647 :
2648 0 : bool WW8AttributeOutput::PlaceholderField( const SwField* )
2649 : {
2650 0 : return true; // expand to text?
2651 : }
2652 :
2653 0 : void WW8AttributeOutput::RefField( const SwField &rFld, const OUString &rRef)
2654 : {
2655 0 : OUString sStr( FieldString( ww::eREF ) );
2656 0 : sStr += "\"" + rRef + "\" ";
2657 : m_rWW8Export.OutputField( &rFld, ww::eREF, sStr, WRITEFIELD_START |
2658 0 : WRITEFIELD_CMD_START | WRITEFIELD_CMD_END );
2659 0 : OUString sVar = lcl_GetExpandedField( rFld );
2660 0 : if ( !sVar.isEmpty() )
2661 : {
2662 0 : if ( m_rWW8Export.IsUnicode() )
2663 0 : SwWW8Writer::WriteString16( m_rWW8Export.Strm(), sVar, false );
2664 : else
2665 : {
2666 0 : SwWW8Writer::WriteString8( m_rWW8Export.Strm(), sVar, false,
2667 0 : RTL_TEXTENCODING_MS_1252 );
2668 : }
2669 : }
2670 0 : m_rWW8Export.OutputField( &rFld, ww::eREF, sStr, WRITEFIELD_CLOSE );
2671 0 : }
2672 :
2673 0 : void WW8AttributeOutput::WriteExpand( const SwField* pFld )
2674 : {
2675 0 : OUString sExpand( lcl_GetExpandedField( *pFld ) );
2676 0 : if ( m_rWW8Export.IsUnicode() )
2677 0 : SwWW8Writer::WriteString16( m_rWW8Export.Strm(), sExpand, false );
2678 : else
2679 : {
2680 0 : SwWW8Writer::WriteString8( m_rWW8Export.Strm(), sExpand, false,
2681 0 : RTL_TEXTENCODING_MS_1252 );
2682 0 : }
2683 0 : }
2684 :
2685 308 : void AttributeOutputBase::TextField( const SwFmtFld& rField )
2686 : {
2687 308 : const SwField* pFld = rField.GetField();
2688 308 : bool bWriteExpand = false;
2689 308 : const sal_uInt16 nSubType = pFld->GetSubType();
2690 :
2691 308 : switch (pFld->GetTyp()->Which())
2692 : {
2693 : case RES_GETEXPFLD:
2694 0 : if (nSubType == nsSwGetSetExpType::GSE_STRING)
2695 : {
2696 0 : const SwGetExpField *pGet=(const SwGetExpField*)(pFld);
2697 0 : RefField( *pGet, pGet->GetFormula() );
2698 : }
2699 : else
2700 0 : bWriteExpand = true;
2701 0 : break;
2702 : case RES_SETEXPFLD:
2703 24 : if (nsSwGetSetExpType::GSE_SEQ == nSubType)
2704 : {
2705 22 : OUString sStr;
2706 22 : if (GetExport().FieldsQuoted())
2707 22 : sStr = FieldString(ww::eSEQ) + pFld->GetTyp()->GetName() + " ";
2708 : else
2709 0 : sStr = FieldString(ww::eSEQ) + "\"" + pFld->GetTyp()->GetName() +"\" ";
2710 22 : GetNumberPara( sStr, *pFld );
2711 22 : GetExport().OutputField(pFld, ww::eSEQ, sStr);
2712 : }
2713 2 : else if (nSubType & nsSwGetSetExpType::GSE_STRING)
2714 : {
2715 2 : bool bShowAsWell = false;
2716 : ww::eField eFieldNo;
2717 2 : const SwSetExpField *pSet=(const SwSetExpField*)(pFld);
2718 2 : const OUString sVar = pSet->GetPar2();
2719 4 : OUString sStr;
2720 2 : if (pSet->GetInputFlag())
2721 : {
2722 8 : sStr = FieldString(ww::eASK) + "\""
2723 8 : + pSet->GetPar1() + "\" "
2724 8 : + pSet->GetPromptText() + " \\d "
2725 6 : + sVar;
2726 2 : eFieldNo = ww::eASK;
2727 : }
2728 : else
2729 : {
2730 0 : sStr = FieldString(ww::eSET)
2731 0 : + pSet->GetPar1() + " \""
2732 0 : + sVar + "\" ";
2733 0 : eFieldNo = ww::eSET;
2734 0 : bShowAsWell = (nSubType & nsSwExtendedSubType::SUB_INVISIBLE) ? false : true;
2735 : }
2736 :
2737 2 : SetField( *pFld, eFieldNo, sStr );
2738 :
2739 2 : if (bShowAsWell)
2740 2 : RefField( *pSet, pSet->GetPar1() );
2741 : }
2742 : else
2743 0 : bWriteExpand = true;
2744 24 : break;
2745 : case RES_PAGENUMBERFLD:
2746 : {
2747 166 : OUString sStr = FieldString(ww::ePAGE);
2748 166 : GetNumberPara(sStr, *pFld);
2749 166 : GetExport().OutputField(pFld, ww::ePAGE, sStr);
2750 : }
2751 166 : break;
2752 : case RES_FILENAMEFLD:
2753 : {
2754 18 : OUString sStr = FieldString(ww::eFILENAME);
2755 18 : if (pFld->GetFormat() == FF_PATHNAME)
2756 4 : sStr += "\\p ";
2757 18 : GetExport().OutputField(pFld, ww::eFILENAME, sStr);
2758 : }
2759 18 : break;
2760 : case RES_DBNAMEFLD:
2761 : {
2762 0 : SwDBData aData = GetExport().pDoc->GetDBData();
2763 : const OUString sStr = FieldString(ww::eDATABASE)
2764 0 : + aData.sDataSource
2765 0 : + OUString(DB_DELIM)
2766 0 : + aData.sCommand;
2767 0 : GetExport().OutputField(pFld, ww::eDATABASE, sStr);
2768 : }
2769 0 : break;
2770 : case RES_AUTHORFLD:
2771 : {
2772 : ww::eField eFld =
2773 0 : (AF_SHORTCUT & pFld->GetFormat() ? ww::eUSERINITIALS : ww::eUSERNAME);
2774 0 : GetExport().OutputField(pFld, eFld, FieldString(eFld));
2775 : }
2776 0 : break;
2777 : case RES_TEMPLNAMEFLD:
2778 0 : GetExport().OutputField(pFld, ww::eTEMPLATE, FieldString(ww::eTEMPLATE));
2779 0 : break;
2780 : case RES_DOCINFOFLD: // Last printed, last edited,...
2781 18 : if( DI_SUB_FIXED & nSubType )
2782 0 : bWriteExpand = true;
2783 : else
2784 : {
2785 18 : OUString sStr;
2786 18 : ww::eField eFld(ww::eNONE);
2787 18 : switch (0xff & nSubType)
2788 : {
2789 : case DI_TITEL:
2790 12 : eFld = ww::eTITLE;
2791 12 : break;
2792 : case DI_THEMA:
2793 0 : eFld = ww::eSUBJECT;
2794 0 : break;
2795 : case DI_KEYS:
2796 0 : eFld = ww::eKEYWORDS;
2797 0 : break;
2798 : case DI_COMMENT:
2799 0 : eFld = ww::eCOMMENTS;
2800 0 : break;
2801 : case DI_DOCNO:
2802 2 : eFld = ww::eREVNUM;
2803 2 : break;
2804 : case DI_CREATE:
2805 0 : if (DI_SUB_AUTHOR == (nSubType & DI_SUB_MASK))
2806 0 : eFld = ww::eAUTHOR;
2807 0 : else if (GetExport().GetNumberFmt(*pFld, sStr))
2808 0 : eFld = ww::eCREATEDATE;
2809 0 : break;
2810 :
2811 : case DI_CHANGE:
2812 2 : if (DI_SUB_AUTHOR == (nSubType & DI_SUB_MASK))
2813 2 : eFld = ww::eLASTSAVEDBY;
2814 0 : else if (GetExport().GetNumberFmt(*pFld, sStr))
2815 0 : eFld = ww::eSAVEDATE;
2816 2 : break;
2817 :
2818 : case DI_PRINT:
2819 0 : if (DI_SUB_AUTHOR != (nSubType & DI_SUB_MASK) &&
2820 0 : GetExport().GetNumberFmt(*pFld, sStr))
2821 0 : eFld = ww::ePRINTDATE;
2822 0 : break;
2823 : case DI_EDIT:
2824 4 : if( DI_SUB_AUTHOR != (nSubType & DI_SUB_MASK ) &&
2825 2 : GetExport().GetNumberFmt( *pFld, sStr ))
2826 0 : eFld = ww::eSAVEDATE;
2827 : else
2828 2 : eFld = ww::eEDITTIME;
2829 2 : break;
2830 : case DI_CUSTOM:
2831 0 : eFld = ww::eDOCPROPERTY;
2832 : {
2833 0 : OUString sQuotes('\"');
2834 : const SwDocInfoField * pDocInfoField =
2835 0 : dynamic_cast<const SwDocInfoField *> (pFld);
2836 :
2837 0 : if (pDocInfoField != NULL)
2838 : {
2839 0 : OUString sFieldname = pDocInfoField->GetFieldName();
2840 0 : sal_Int32 nIndex = sFieldname.indexOf(':');
2841 :
2842 0 : if (nIndex != sFieldname.getLength())
2843 0 : sFieldname = sFieldname.copy(nIndex + 1);
2844 :
2845 0 : sStr = sQuotes + sFieldname + sQuotes;
2846 0 : }
2847 : }
2848 0 : break;
2849 : default:
2850 0 : break;
2851 : }
2852 :
2853 18 : if (eFld != ww::eNONE)
2854 : {
2855 18 : GetExport().OutputField(pFld, eFld, FieldString(eFld) + sStr);
2856 : }
2857 : else
2858 0 : bWriteExpand = true;
2859 : }
2860 18 : break;
2861 : case RES_DATETIMEFLD:
2862 : {
2863 2 : OUString sStr;
2864 2 : if (FIXEDFLD & nSubType || !GetExport().GetNumberFmt(*pFld, sStr))
2865 0 : bWriteExpand = true;
2866 : else
2867 : {
2868 2 : ww::eField eFld = (DATEFLD & nSubType) ? ww::eDATE : ww::eTIME;
2869 2 : GetExport().OutputField(pFld, eFld, FieldString(eFld) + sStr);
2870 2 : }
2871 : }
2872 2 : break;
2873 : case RES_DOCSTATFLD:
2874 : {
2875 22 : ww::eField eFld = ww::eNONE;
2876 :
2877 22 : switch (nSubType)
2878 : {
2879 : case DS_PAGE:
2880 22 : eFld = ww::eNUMPAGE;
2881 22 : break;
2882 : case DS_WORD:
2883 0 : eFld = ww::eNUMWORDS;
2884 0 : break;
2885 : case DS_CHAR:
2886 0 : eFld = ww::eNUMCHARS;
2887 0 : break;
2888 : }
2889 :
2890 22 : if (eFld != ww::eNONE)
2891 : {
2892 22 : OUString sStr = FieldString(eFld);
2893 22 : GetNumberPara(sStr, *pFld);
2894 22 : GetExport().OutputField(pFld, eFld, sStr);
2895 : }
2896 : else
2897 0 : bWriteExpand = true;
2898 : }
2899 22 : break;
2900 : case RES_EXTUSERFLD:
2901 : {
2902 0 : ww::eField eFld = ww::eNONE;
2903 0 : switch (0xFF & nSubType)
2904 : {
2905 : case EU_FIRSTNAME:
2906 : case EU_NAME:
2907 0 : eFld = ww::eUSERNAME;
2908 0 : break;
2909 : case EU_SHORTCUT:
2910 0 : eFld = ww::eUSERINITIALS;
2911 0 : break;
2912 : case EU_STREET:
2913 : case EU_COUNTRY:
2914 : case EU_ZIP:
2915 : case EU_CITY:
2916 0 : eFld = ww::eUSERADDRESS;
2917 0 : break;
2918 : }
2919 :
2920 0 : if (eFld != ww::eNONE)
2921 : {
2922 0 : GetExport().OutputField(pFld, eFld, FieldString(eFld));
2923 : }
2924 : else
2925 0 : bWriteExpand = true;
2926 : }
2927 0 : break;
2928 : case RES_AUTHORITY:
2929 : {
2930 14 : OUString sRet(pFld->ExpandCitation(AUTH_FIELD_IDENTIFIER));
2931 14 : GetExport().OutputField( pFld, ww::eCITATION, sRet );
2932 : }
2933 14 : break;
2934 : case RES_POSTITFLD:
2935 : //Sadly only possible for word in main document text
2936 34 : if (GetExport().nTxtTyp == TXT_MAINTEXT)
2937 : {
2938 34 : PostitField( pFld );
2939 : }
2940 34 : break;
2941 : case RES_INPUTFLD:
2942 : {
2943 0 : const SwInputField * pInputField = dynamic_cast<const SwInputField *>(pFld);
2944 :
2945 0 : if (pInputField && pInputField->isFormField())
2946 0 : GetExport().DoFormText(pInputField);
2947 : else
2948 : {
2949 0 : const OUString sStr = FieldString(ww::eFILLIN) + "\""
2950 0 : + pFld->GetPar2() + "\"";
2951 :
2952 0 : GetExport().OutputField(pFld, ww::eFILLIN, sStr);
2953 : }
2954 : }
2955 0 : break;
2956 : case RES_GETREFFLD:
2957 : {
2958 4 : ww::eField eFld = ww::eNONE;
2959 4 : OUString sStr;
2960 4 : const SwGetRefField& rRFld = *(SwGetRefField*)pFld;
2961 4 : switch (nSubType)
2962 : {
2963 : case REF_SETREFATTR:
2964 : case REF_BOOKMARK:
2965 4 : switch (pFld->GetFormat())
2966 : {
2967 : case REF_PAGE_PGDESC:
2968 : case REF_PAGE:
2969 4 : eFld = ww::ePAGEREF;
2970 4 : break;
2971 : default:
2972 0 : eFld = ww::eREF;
2973 0 : break;
2974 : }
2975 : {
2976 4 : const OUString aRefName(rRFld.GetSetRefName());
2977 8 : sStr = FieldString(eFld)
2978 12 : + GetExport().GetBookmarkName(nSubType, &aRefName, 0);
2979 : }
2980 4 : switch (pFld->GetFormat())
2981 : {
2982 : case REF_NUMBER:
2983 0 : sStr += " \\r";
2984 0 : break;
2985 : case REF_NUMBER_NO_CONTEXT:
2986 0 : sStr += " \\n";
2987 0 : break;
2988 : case REF_NUMBER_FULL_CONTEXT:
2989 0 : sStr += " \\w";
2990 0 : break;
2991 : }
2992 4 : break;
2993 : case REF_FOOTNOTE:
2994 : case REF_ENDNOTE:
2995 0 : switch (pFld->GetFormat())
2996 : {
2997 : case REF_PAGE_PGDESC:
2998 : case REF_PAGE:
2999 0 : eFld = ww::ePAGEREF;
3000 0 : break;
3001 : case REF_UPDOWN:
3002 0 : eFld = ww::eREF;
3003 0 : break;
3004 : default:
3005 : eFld =
3006 0 : REF_ENDNOTE == nSubType ? ww::eNOTEREF : ww::eFOOTREF;
3007 0 : break;
3008 : }
3009 0 : sStr = FieldString(eFld)
3010 0 : + GetExport().GetBookmarkName(nSubType, 0, rRFld.GetSeqNo());
3011 0 : break;
3012 : }
3013 :
3014 4 : if (eFld != ww::eNONE)
3015 : {
3016 4 : switch (pFld->GetFormat())
3017 : {
3018 : case REF_UPDOWN:
3019 0 : sStr += " \\p \\h "; // with hyperlink
3020 0 : break;
3021 : case REF_CHAPTER:
3022 0 : sStr += " \\n \\h "; // with hyperlink
3023 0 : break;
3024 : default:
3025 4 : sStr += " \\h "; // insert hyperlink
3026 4 : break;
3027 : }
3028 4 : GetExport().OutputField(pFld, eFld, sStr);
3029 : }
3030 : else
3031 0 : bWriteExpand = true;
3032 : }
3033 4 : break;
3034 : case RES_COMBINED_CHARS:
3035 : {
3036 : /*
3037 : We need a font size to fill in the defaults, if these are overridden
3038 : (as they generally are) by character properties then those properties
3039 : win.
3040 :
3041 : The fontsize that is used in MS for determing the defaults is always
3042 : the CJK fontsize even if the text is not in that language, in OOo the
3043 : largest fontsize used in the field is the one we should take, but
3044 : whatever we do, word will actually render using the fontsize set for
3045 : CJK text. Nevertheless we attempt to guess whether the script is in
3046 : asian or western text based up on the first character and use the
3047 : font size of that script as our default.
3048 : */
3049 : sal_uInt16 nScript;
3050 0 : if( g_pBreakIt->GetBreakIter().is() )
3051 0 : nScript = g_pBreakIt->GetBreakIter()->getScriptType( pFld->GetPar1(), 0);
3052 : else
3053 0 : nScript = i18n::ScriptType::ASIAN;
3054 :
3055 0 : long nHeight = ((SvxFontHeightItem&)(GetExport().GetItem(
3056 0 : GetWhichOfScript(RES_CHRATR_FONTSIZE,nScript)))).GetHeight();
3057 :
3058 0 : nHeight = (nHeight + 10) / 20; //Font Size in points;
3059 :
3060 : /*
3061 : Divide the combined char string into its up and down part. Get the
3062 : font size and fill in the defaults as up == half the font size and
3063 : down == a fifth the font size
3064 : */
3065 0 : const sal_Int32 nAbove = (pFld->GetPar1().getLength()+1)/2;
3066 : const OUString sStr = FieldString(ww::eEQ)
3067 0 : + "\\o (\\s\\up "
3068 0 : + OUString::number(nHeight/2)
3069 0 : + "("
3070 0 : + pFld->GetPar1().copy(0, nAbove)
3071 0 : + "), \\s\\do "
3072 0 : + OUString::number(nHeight/5)
3073 0 : + "("
3074 0 : + pFld->GetPar1().copy(nAbove)
3075 0 : + "))";
3076 0 : GetExport().OutputField(pFld, ww::eEQ, sStr);
3077 : }
3078 0 : break;
3079 : case RES_DROPDOWN:
3080 0 : bWriteExpand = DropdownField( pFld );
3081 0 : break;
3082 : case RES_CHAPTERFLD:
3083 0 : bWriteExpand = true;
3084 0 : if (GetExport().bOutKF && rField.GetTxtFld())
3085 : {
3086 0 : const SwTxtNode *pTxtNd = GetExport().GetHdFtPageRoot();
3087 0 : if (!pTxtNd)
3088 : {
3089 0 : pTxtNd = GetExport().pCurPam->GetNode().GetTxtNode();
3090 : }
3091 :
3092 0 : if (pTxtNd)
3093 : {
3094 0 : SwChapterField aCopy(*(const SwChapterField*)pFld);
3095 0 : aCopy.ChangeExpansion(*pTxtNd, false);
3096 0 : WriteExpand( &aCopy );
3097 0 : bWriteExpand = false;
3098 : }
3099 : }
3100 0 : break;
3101 : case RES_HIDDENTXTFLD:
3102 : {
3103 0 : OUString sExpand(pFld->GetPar2());
3104 0 : if (!sExpand.isEmpty())
3105 : {
3106 0 : HiddenField( *pFld );
3107 0 : }
3108 : }
3109 0 : break;
3110 : case RES_JUMPEDITFLD:
3111 2 : bWriteExpand = PlaceholderField( pFld );
3112 2 : break;
3113 : case RES_MACROFLD:
3114 : {
3115 : const OUString sStr = " MACROBUTTON"
3116 4 : + pFld->GetPar1().replaceFirst("StarOffice.Standard.Modul1.", " ")
3117 4 : + " "
3118 6 : + lcl_GetExpandedField(*pFld);
3119 2 : GetExport().OutputField( pFld, ww::eMACROBUTTON, sStr );
3120 : }
3121 2 : break;
3122 : default:
3123 2 : bWriteExpand = true;
3124 2 : break;
3125 : }
3126 :
3127 308 : if (bWriteExpand)
3128 2 : WriteExpand( pFld );
3129 308 : }
3130 :
3131 558 : void AttributeOutputBase::TextFlyContent( const SwFmtFlyCnt& rFlyContent )
3132 : {
3133 558 : if ( GetExport().pOutFmtNode && GetExport().pOutFmtNode->ISA( SwCntntNode ) )
3134 : {
3135 558 : SwTxtNode* pTxtNd = (SwTxtNode*)GetExport().pOutFmtNode;
3136 :
3137 558 : Point aLayPos;
3138 558 : aLayPos = pTxtNd->FindLayoutRect( false, &aLayPos ).Pos();
3139 :
3140 558 : SwPosition aPos( *pTxtNd );
3141 1116 : sw::Frame aFrm( *rFlyContent.GetFrmFmt(), aPos );
3142 :
3143 1116 : OutputFlyFrame_Impl( aFrm, aLayPos );
3144 : }
3145 558 : }
3146 :
3147 : // TOXMarks fehlen noch
3148 :
3149 : // Detaillierte Einstellungen zur Trennung erlaubt WW nur dokumentenweise.
3150 : // Man koennte folgende Mimik einbauen: Die Werte des Style "Standard" werden,
3151 : // falls vorhanden, in die Document Properties ( DOP ) gesetzt.
3152 :
3153 : // ACK. Dieser Vorschlag passt exakt zu unserer Implementierung des Import,
3154 : // daher setze ich das gleich mal um. (KHZ, 07/15/2000)
3155 48 : void WW8AttributeOutput::ParaHyphenZone( const SvxHyphenZoneItem& rHyphenZone )
3156 : {
3157 : // sprmPFNoAutoHyph
3158 48 : if( m_rWW8Export.bWrtWW8 )
3159 48 : m_rWW8Export.InsUInt16( NS_sprm::LN_PFNoAutoHyph );
3160 : else
3161 0 : m_rWW8Export.pO->push_back( 44 );
3162 :
3163 48 : m_rWW8Export.pO->push_back( rHyphenZone.IsHyphen() ? 0 : 1 );
3164 48 : }
3165 :
3166 38 : void WW8AttributeOutput::ParaScriptSpace( const SfxBoolItem& rScriptSpace )
3167 : {
3168 38 : if ( !m_rWW8Export.bWrtWW8 )
3169 38 : return;
3170 :
3171 38 : m_rWW8Export.InsUInt16( NS_sprm::LN_PFAutoSpaceDE );
3172 38 : m_rWW8Export.pO->push_back( rScriptSpace.GetValue() ? 1 : 0 );
3173 : }
3174 :
3175 30 : void WW8AttributeOutput::ParaHangingPunctuation( const SfxBoolItem& rItem )
3176 : {
3177 30 : if ( !m_rWW8Export.bWrtWW8 )
3178 30 : return;
3179 :
3180 30 : m_rWW8Export.InsUInt16( NS_sprm::LN_PFOverflowPunct );
3181 30 : m_rWW8Export.pO->push_back( rItem.GetValue() ? 1 : 0 );
3182 : }
3183 :
3184 30 : void WW8AttributeOutput::ParaForbiddenRules( const SfxBoolItem& rItem )
3185 : {
3186 30 : if ( !m_rWW8Export.bWrtWW8 )
3187 30 : return;
3188 :
3189 30 : m_rWW8Export.InsUInt16( NS_sprm::LN_PFKinsoku );
3190 30 : m_rWW8Export.pO->push_back( rItem.GetValue() ? 1 : 0 );
3191 : }
3192 :
3193 140 : void WW8AttributeOutput::ParaSnapToGrid( const SvxParaGridItem& rGrid )
3194 : {
3195 : // sprmPFUsePgsuSettings
3196 : // 97+ only
3197 140 : if ( !m_rWW8Export.bWrtWW8 )
3198 140 : return;
3199 :
3200 140 : m_rWW8Export.InsUInt16( NS_sprm::LN_PFUsePgsuSettings );
3201 140 : m_rWW8Export.pO->push_back( rGrid.GetValue() );
3202 : }
3203 :
3204 0 : void WW8AttributeOutput::ParaVerticalAlign( const SvxParaVertAlignItem& rAlign )
3205 : {
3206 : // sprmPWAlignFont
3207 : // 97+ only
3208 0 : if( !m_rWW8Export.bWrtWW8 )
3209 0 : return;
3210 :
3211 0 : m_rWW8Export.InsUInt16( NS_sprm::LN_PWAlignFont );
3212 :
3213 0 : sal_Int16 nVal = rAlign.GetValue();
3214 0 : switch ( nVal )
3215 : {
3216 : case SvxParaVertAlignItem::BASELINE:
3217 0 : nVal = 2;
3218 0 : break;
3219 : case SvxParaVertAlignItem::TOP:
3220 0 : nVal = 0;
3221 0 : break;
3222 : case SvxParaVertAlignItem::CENTER:
3223 0 : nVal = 1;
3224 0 : break;
3225 : case SvxParaVertAlignItem::BOTTOM:
3226 0 : nVal = 3;
3227 0 : break;
3228 : case SvxParaVertAlignItem::AUTOMATIC:
3229 0 : nVal = 4;
3230 0 : break;
3231 : default:
3232 0 : nVal = 4;
3233 : OSL_FAIL( "Unknown vert alignment" );
3234 0 : break;
3235 : }
3236 0 : m_rWW8Export.InsUInt16( nVal );
3237 : }
3238 :
3239 : // NoHyphen: ich habe keine Entsprechung in der SW-UI und WW-UI gefunden
3240 :
3241 : // RefMark, NoLineBreakHere fehlen noch
3242 :
3243 4 : void WW8Export::WriteFtnBegin( const SwFmtFtn& rFtn, ww::bytes* pOutArr )
3244 : {
3245 4 : ww::bytes aAttrArr;
3246 4 : const bool bAutoNum = rFtn.GetNumStr().isEmpty(); // Auto-Nummer
3247 4 : if( bAutoNum )
3248 : {
3249 4 : if( bWrtWW8 )
3250 : {
3251 : static const sal_uInt8 aSpec[] =
3252 : {
3253 : 0x03, 0x6a, 0, 0, 0, 0, // sprmCObjLocation
3254 : 0x55, 0x08, 1 // sprmCFSpec
3255 : };
3256 :
3257 4 : aAttrArr.insert(aAttrArr.end(), aSpec, aSpec+sizeof(aSpec));
3258 : }
3259 : else
3260 : {
3261 : static sal_uInt8 const aSpec[] =
3262 : {
3263 : 117, 1, // sprmCFSpec
3264 : 68, 4, 0, 0, 0, 0 // sprmCObjLocation
3265 : };
3266 :
3267 0 : aAttrArr.insert(aAttrArr.end(), aSpec, aSpec+sizeof(aSpec));
3268 : }
3269 : }
3270 :
3271 : // sprmCIstd
3272 : const SwEndNoteInfo* pInfo;
3273 4 : if( rFtn.IsEndNote() )
3274 0 : pInfo = &pDoc->GetEndNoteInfo();
3275 : else
3276 4 : pInfo = &pDoc->GetFtnInfo();
3277 : const SwCharFmt* pCFmt = pOutArr
3278 2 : ? pInfo->GetAnchorCharFmt( *pDoc )
3279 6 : : pInfo->GetCharFmt( *pDoc );
3280 4 : if( bWrtWW8 )
3281 4 : SwWW8Writer::InsUInt16( aAttrArr, NS_sprm::LN_CIstd );
3282 : else
3283 0 : aAttrArr.push_back( 80 );
3284 4 : SwWW8Writer::InsUInt16( aAttrArr, GetId( pCFmt ) );
3285 :
3286 : // fSpec-Attribut true
3287 : // Fuer Auto-Nummer muss ein Spezial-Zeichen
3288 : // in den Text und darum ein fSpec-Attribut
3289 4 : pChpPlc->AppendFkpEntry( Strm().Tell() );
3290 4 : if( bAutoNum )
3291 4 : WriteChar( 0x02 ); // Auto-Nummer-Zeichen
3292 : else
3293 : // User-Nummerierung
3294 : OutSwString( rFtn.GetNumStr(), 0, rFtn.GetNumStr().getLength(),
3295 0 : IsUnicode(), RTL_TEXTENCODING_MS_1252 );
3296 :
3297 4 : if( pOutArr )
3298 : {
3299 : // insert at start of array, so the "hard" attribute overrule the
3300 : // attributes of the character template
3301 2 : pOutArr->insert( pOutArr->begin(), aAttrArr.begin(), aAttrArr.end() );
3302 : }
3303 : else
3304 : {
3305 2 : ww::bytes aOutArr;
3306 :
3307 : // insert at start of array, so the "hard" attribute overrule the
3308 : // attributes of the character template
3309 2 : aOutArr.insert( aOutArr.begin(), aAttrArr.begin(), aAttrArr.end() );
3310 :
3311 : // write for the ftn number in the content, the font of the anchor
3312 2 : const SwTxtFtn* pTxtFtn = rFtn.GetTxtFtn();
3313 2 : if( pTxtFtn )
3314 : {
3315 2 : ww::bytes* pOld = pO;
3316 2 : pO = &aOutArr;
3317 2 : SfxItemSet aSet( pDoc->GetAttrPool(), RES_CHRATR_FONT,
3318 2 : RES_CHRATR_FONT );
3319 :
3320 2 : pCFmt = pInfo->GetCharFmt( *pDoc );
3321 2 : aSet.Set( pCFmt->GetAttrSet() );
3322 :
3323 4 : pTxtFtn->GetTxtNode().GetAttr( aSet, pTxtFtn->GetStart(),
3324 6 : (pTxtFtn->GetStart()) + 1 );
3325 2 : m_pAttrOutput->OutputItem( aSet.Get( RES_CHRATR_FONT ) );
3326 2 : pO = pOld;
3327 : }
3328 4 : pChpPlc->AppendFkpEntry( Strm().Tell(), aOutArr.size(),
3329 6 : aOutArr.data() );
3330 4 : }
3331 4 : }
3332 :
3333 20 : static bool lcl_IsAtTxtEnd(const SwFmtFtn& rFtn)
3334 : {
3335 20 : bool bRet = true;
3336 20 : if( rFtn.GetTxtFtn() )
3337 : {
3338 20 : sal_uInt16 nWh = static_cast< sal_uInt16 >(rFtn.IsEndNote() ? RES_END_AT_TXTEND
3339 20 : : RES_FTN_AT_TXTEND);
3340 20 : const SwSectionNode* pSectNd = rFtn.GetTxtFtn()->GetTxtNode().
3341 20 : FindSectionNode();
3342 48 : while( pSectNd && FTNEND_ATPGORDOCEND ==
3343 4 : ((const SwFmtFtnEndAtTxtEnd&)pSectNd->GetSection().GetFmt()->
3344 8 : GetFmtAttr( nWh, true)).GetValue() )
3345 4 : pSectNd = pSectNd->StartOfSectionNode()->FindSectionNode();
3346 :
3347 20 : if (!pSectNd)
3348 20 : bRet = false; // the is ftn/end collected at Page- or Doc-End
3349 : }
3350 20 : return bRet;
3351 : }
3352 :
3353 26 : void AttributeOutputBase::TextFootnote( const SwFmtFtn& rFtn )
3354 : {
3355 : sal_uInt16 nTyp;
3356 26 : if ( rFtn.IsEndNote() )
3357 : {
3358 6 : nTyp = REF_ENDNOTE;
3359 6 : if ( GetExport().bEndAtTxtEnd )
3360 4 : GetExport().bEndAtTxtEnd = lcl_IsAtTxtEnd( rFtn );
3361 : }
3362 : else
3363 : {
3364 20 : nTyp = REF_FOOTNOTE;
3365 20 : if ( GetExport().bFtnAtTxtEnd )
3366 16 : GetExport().bFtnAtTxtEnd = lcl_IsAtTxtEnd( rFtn );
3367 : }
3368 :
3369 : // if any reference to this footnote/endnote then insert an internal
3370 : // Bookmark.
3371 26 : OUString sBkmkNm;
3372 26 : if ( GetExport().HasRefToObject( nTyp, 0, rFtn.GetTxtFtn()->GetSeqRefNo() ))
3373 : {
3374 0 : sBkmkNm = GetExport().GetBookmarkName( nTyp, 0,
3375 0 : rFtn.GetTxtFtn()->GetSeqRefNo() );
3376 0 : GetExport().AppendBookmark( sBkmkNm );
3377 : }
3378 :
3379 26 : TextFootnote_Impl( rFtn );
3380 :
3381 26 : if ( !sBkmkNm.isEmpty() )
3382 0 : GetExport().AppendBookmark( sBkmkNm ); // FIXME: Why is it added twice? Shouldn't this one go to WW8AttributeOuput::TextFootnote_Impl()?
3383 26 : }
3384 :
3385 2 : void WW8AttributeOutput::TextFootnote_Impl( const SwFmtFtn& rFtn )
3386 : {
3387 : WW8_WrPlcFtnEdn* pFtnEnd;
3388 2 : if ( rFtn.IsEndNote() )
3389 0 : pFtnEnd = m_rWW8Export.pEdn;
3390 : else
3391 2 : pFtnEnd = m_rWW8Export.pFtn;
3392 :
3393 2 : pFtnEnd->Append( m_rWW8Export.Fc2Cp( m_rWW8Export.Strm().Tell() ), rFtn );
3394 2 : m_rWW8Export.WriteFtnBegin( rFtn, m_rWW8Export.pO );
3395 2 : }
3396 :
3397 2 : void WW8AttributeOutput::TextCharFormat( const SwFmtCharFmt& rCharFmt )
3398 : {
3399 2 : if( rCharFmt.GetCharFmt() )
3400 : {
3401 2 : if( m_rWW8Export.bWrtWW8 )
3402 2 : m_rWW8Export.InsUInt16( NS_sprm::LN_CIstd );
3403 : else
3404 0 : m_rWW8Export.pO->push_back( 80 );
3405 :
3406 2 : m_rWW8Export.InsUInt16( m_rWW8Export.GetId( rCharFmt.GetCharFmt() ) );
3407 : }
3408 2 : }
3409 :
3410 : /*
3411 : See ww8par6.cxx Read_DoubleLine for some more info
3412 : */
3413 0 : void WW8AttributeOutput::CharTwoLines( const SvxTwoLinesItem& rTwoLines )
3414 : {
3415 : // #i28331# - check that bOn is set
3416 0 : if ( rTwoLines.GetValue() )
3417 : {
3418 : //97+ only
3419 0 : if( !m_rWW8Export.bWrtWW8 )
3420 0 : return;
3421 :
3422 0 : m_rWW8Export.InsUInt16( NS_sprm::LN_CFELayout );
3423 0 : m_rWW8Export.pO->push_back( (sal_uInt8)0x06 ); //len 6
3424 0 : m_rWW8Export.pO->push_back( (sal_uInt8)0x02 );
3425 :
3426 0 : sal_Unicode cStart = rTwoLines.GetStartBracket();
3427 0 : sal_Unicode cEnd = rTwoLines.GetEndBracket();
3428 :
3429 : /*
3430 : As per usual we have problems. We can have separate left and right brackets
3431 : in OOo, it doesn't appear that you can in word. Also in word there appear
3432 : to only be a limited number of possibilities, we can use pretty much
3433 : anything.
3434 :
3435 : So if we have none, we export none, if either bracket is set to a known
3436 : word type we export both as that type (with the bracket winning out in
3437 : the case of a conflict simply being the order of test here.
3438 :
3439 : Upshot being a documented created in word will be reexported with no
3440 : ill effects.
3441 : */
3442 :
3443 : sal_uInt16 nType;
3444 0 : if (!cStart && !cEnd)
3445 0 : nType = 0;
3446 0 : else if ((cStart == '{') || (cEnd == '}'))
3447 0 : nType = 4;
3448 0 : else if ((cStart == '<') || (cEnd == '>'))
3449 0 : nType = 3;
3450 0 : else if ((cStart == '[') || (cEnd == ']'))
3451 0 : nType = 2;
3452 : else
3453 0 : nType = 1;
3454 0 : m_rWW8Export.InsUInt16( nType );
3455 : static const sal_uInt8 aZeroArr[ 3 ] = { 0, 0, 0 };
3456 0 : m_rWW8Export.pO->insert( m_rWW8Export.pO->end(), aZeroArr, aZeroArr+3);
3457 : }
3458 : }
3459 :
3460 1312 : void AttributeOutputBase::ParaNumRule( const SwNumRuleItem& rNumRule )
3461 : {
3462 1312 : const SwTxtNode* pTxtNd = 0;
3463 : sal_uInt16 nNumId;
3464 1312 : sal_uInt8 nLvl = 0;
3465 1312 : if (!rNumRule.GetValue().isEmpty())
3466 : {
3467 974 : const SwNumRule* pRule = GetExport().pDoc->FindNumRulePtr(
3468 1948 : rNumRule.GetValue() );
3469 974 : if ( pRule && USHRT_MAX != ( nNumId = GetExport().GetId( *pRule ) ) )
3470 : {
3471 974 : ++nNumId;
3472 974 : if ( GetExport().pOutFmtNode )
3473 : {
3474 974 : if ( GetExport().pOutFmtNode->ISA( SwCntntNode ) )
3475 : {
3476 748 : pTxtNd = (SwTxtNode*)GetExport().pOutFmtNode;
3477 :
3478 748 : if( pTxtNd->IsCountedInList())
3479 : {
3480 748 : int nLevel = pTxtNd->GetActualListLevel();
3481 :
3482 748 : if (nLevel < 0)
3483 0 : nLevel = 0;
3484 :
3485 748 : if (nLevel >= MAXLEVEL)
3486 0 : nLevel = MAXLEVEL - 1;
3487 :
3488 748 : nLvl = static_cast< sal_uInt8 >(nLevel);
3489 :
3490 748 : if ( pTxtNd->IsListRestart() )
3491 : {
3492 6 : sal_uInt16 nStartWith = static_cast< sal_uInt16 >( pTxtNd->GetActualListStartValue() );
3493 6 : nNumId = GetExport().DuplicateNumRule( pRule, nLvl, nStartWith );
3494 6 : if ( USHRT_MAX != nNumId )
3495 6 : ++nNumId;
3496 : }
3497 : }
3498 : else
3499 : {
3500 : // #i44815# adjust numbering for numbered paragraphs
3501 : // without number (NO_NUMLEVEL). These paragaphs
3502 : // will receive a list id 0, which WW interprets as
3503 : // 'no number'.
3504 0 : nNumId = 0;
3505 : }
3506 : }
3507 226 : else if ( GetExport().pOutFmtNode->ISA( SwTxtFmtColl ) )
3508 : {
3509 226 : const SwTxtFmtColl* pC = (SwTxtFmtColl*)GetExport().pOutFmtNode;
3510 226 : if ( pC && pC->IsAssignedToListLevelOfOutlineStyle() )
3511 194 : nLvl = static_cast< sal_uInt8 >( pC->GetAssignedOutlineStyleLevel() );
3512 : }
3513 : }
3514 : }
3515 : else
3516 0 : nNumId = USHRT_MAX;
3517 : }
3518 : else
3519 338 : nNumId = 0;
3520 :
3521 1312 : if ( USHRT_MAX != nNumId )
3522 : {
3523 1312 : if ( nLvl >= WW8ListManager::nMaxLevel )
3524 2 : nLvl = WW8ListManager::nMaxLevel - 1;
3525 :
3526 1312 : ParaNumRule_Impl( pTxtNd, nLvl, nNumId );
3527 : }
3528 1312 : }
3529 :
3530 58 : void WW8AttributeOutput::ParaNumRule_Impl( const SwTxtNode* pTxtNd, sal_Int32 nLvl, sal_Int32 nNumId )
3531 : {
3532 58 : if ( m_rWW8Export.bWrtWW8 )
3533 : {
3534 : // write sprmPIlvl and sprmPIlfo
3535 58 : SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_PIlvl );
3536 58 : m_rWW8Export.pO->push_back( ::sal::static_int_cast<sal_uInt8>(nLvl) );
3537 58 : SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_PIlfo );
3538 58 : SwWW8Writer::InsUInt16( *m_rWW8Export.pO, ::sal::static_int_cast<sal_uInt16>(nNumId) );
3539 : }
3540 0 : else if ( pTxtNd && m_rWW8Export.Out_SwNum( pTxtNd ) ) // NumRules
3541 0 : m_rWW8Export.pSepx->SetNum( pTxtNd );
3542 58 : }
3543 :
3544 : /* File FRMATR.HXX */
3545 :
3546 40 : void WW8AttributeOutput::FormatFrameSize( const SwFmtFrmSize& rSize )
3547 : {
3548 40 : if( m_rWW8Export.bOutFlyFrmAttrs ) // Flys
3549 : {
3550 0 : if( m_rWW8Export.bOutGrf )
3551 40 : return; // Fly um Grafik -> Auto-Groesse
3552 :
3553 : //???? was ist bei Prozentangaben ???
3554 0 : if ( rSize.GetWidth() && rSize.GetWidthSizeType() == ATT_FIX_SIZE)
3555 : {
3556 : //"sprmPDxaWidth"
3557 0 : if( m_rWW8Export.bWrtWW8 )
3558 0 : m_rWW8Export.InsUInt16( NS_sprm::LN_PDxaWidth );
3559 : else
3560 0 : m_rWW8Export.pO->push_back( 28 );
3561 0 : m_rWW8Export.InsUInt16( (sal_uInt16)rSize.GetWidth() );
3562 : }
3563 :
3564 0 : if ( rSize.GetHeight() )
3565 : {
3566 : // sprmPWHeightAbs
3567 0 : if( m_rWW8Export.bWrtWW8 )
3568 0 : m_rWW8Export.InsUInt16( NS_sprm::LN_PWHeightAbs );
3569 : else
3570 0 : m_rWW8Export.pO->push_back( 45 );
3571 :
3572 0 : sal_uInt16 nH = 0;
3573 0 : switch ( rSize.GetHeightSizeType() )
3574 : {
3575 0 : case ATT_VAR_SIZE: break;
3576 0 : case ATT_FIX_SIZE: nH = (sal_uInt16)rSize.GetHeight() & 0x7fff; break;
3577 0 : default: nH = (sal_uInt16)rSize.GetHeight() | 0x8000; break;
3578 : }
3579 0 : m_rWW8Export.InsUInt16( nH );
3580 : }
3581 : }
3582 40 : else if( m_rWW8Export.bOutPageDescs ) // PageDesc : Breite + Hoehe
3583 : {
3584 40 : if( m_rWW8Export.pAktPageDesc->GetLandscape() )
3585 : {
3586 : /*sprmSBOrientation*/
3587 4 : if( m_rWW8Export.bWrtWW8 )
3588 4 : m_rWW8Export.InsUInt16( NS_sprm::LN_SBOrientation );
3589 : else
3590 0 : m_rWW8Export.pO->push_back( 162 );
3591 4 : m_rWW8Export.pO->push_back( 2 );
3592 : }
3593 :
3594 : /*sprmSXaPage*/
3595 40 : if( m_rWW8Export.bWrtWW8 )
3596 40 : m_rWW8Export.InsUInt16( NS_sprm::LN_SXaPage );
3597 : else
3598 0 : m_rWW8Export.pO->push_back( 164 );
3599 : m_rWW8Export.InsUInt16(
3600 40 : msword_cast<sal_uInt16>(SvxPaperInfo::GetSloppyPaperDimension(rSize.GetWidth())));
3601 :
3602 : /*sprmSYaPage*/
3603 40 : if( m_rWW8Export.bWrtWW8 )
3604 40 : m_rWW8Export.InsUInt16( NS_sprm::LN_SYaPage );
3605 : else
3606 0 : m_rWW8Export.pO->push_back( 165 );
3607 : m_rWW8Export.InsUInt16(
3608 40 : msword_cast<sal_uInt16>(SvxPaperInfo::GetSloppyPaperDimension(rSize.GetHeight())));
3609 : }
3610 : }
3611 :
3612 : // FillOrder fehlt noch
3613 :
3614 : // ReplaceCr() wird fuer Pagebreaks und Pagedescs gebraucht. Es wird ein
3615 : // bereits geschriebenes CR durch ein Break-Zeichen ersetzt. Replace muss
3616 : // direkt nach Schreiben des CR gerufen werden.
3617 : // Rueckgabe: FilePos des ersetzten CRs + 1 oder 0 fuer nicht ersetzt
3618 :
3619 30 : sal_uLong WW8Export::ReplaceCr( sal_uInt8 nChar )
3620 : {
3621 : OSL_ENSURE( nChar, "gegen 0 ersetzt bringt WW97/95 zum Absturz" );
3622 :
3623 30 : bool bReplaced = false;
3624 30 : SvStream& rStrm = Strm();
3625 30 : sal_uLong nRetPos = 0, nPos = rStrm.Tell();
3626 : //If there is at least two characters already output
3627 30 : if (nPos - (IsUnicode() ? 2 : 1) >= sal_uLong(pFib->fcMin))
3628 : {
3629 6 : sal_uInt8 nBCode=0;
3630 6 : sal_uInt16 nUCode=0;
3631 :
3632 6 : rStrm.SeekRel(IsUnicode() ? -2 : -1);
3633 6 : if (IsUnicode())
3634 6 : rStrm.ReadUInt16( nUCode );
3635 : else
3636 : {
3637 0 : rStrm.ReadUChar( nBCode );
3638 0 : nUCode = nBCode;
3639 : }
3640 : //If the last char was a cr
3641 6 : if (nUCode == 0x0d) // CR ?
3642 : {
3643 8 : if ((nChar == 0x0c) &&
3644 4 : (nPos - (IsUnicode() ? 4 : 2) >= sal_uLong(pFib->fcMin)))
3645 : {
3646 4 : rStrm.SeekRel( IsUnicode() ? -4 : -2 );
3647 4 : if (IsUnicode())
3648 4 : rStrm.ReadUInt16( nUCode );
3649 : else
3650 : {
3651 0 : rStrm.ReadUInt16( nUCode );
3652 0 : nUCode = nBCode;
3653 : }
3654 : }
3655 : else
3656 : {
3657 0 : rStrm.SeekRel( IsUnicode() ? -2 : -1 );
3658 0 : nUCode = 0x0;
3659 : }
3660 : //And the para is not of len 0, then replace this cr with the mark
3661 : //#120140# If there is a cr before a column break, need replace the cr. So remove the "nChar==0x0e" check.
3662 4 : if( nUCode == 0x0d )
3663 0 : bReplaced = false;
3664 : else
3665 : {
3666 4 : bReplaced = true;
3667 4 : WriteChar(nChar);
3668 4 : nRetPos = nPos;
3669 : }
3670 : }
3671 2 : else if ((nUCode == 0x0c) && (nChar == 0x0e))
3672 : {
3673 : // a column break after a section has no effect in writer
3674 0 : bReplaced = true;
3675 : }
3676 6 : rStrm.Seek( nPos );
3677 : }
3678 : else
3679 24 : bReplaced = true;
3680 :
3681 30 : if (!bReplaced)
3682 : {
3683 : // then write as normal char
3684 2 : WriteChar(nChar);
3685 2 : pPiece->SetParaBreak();
3686 2 : pPapPlc->AppendFkpEntry(rStrm.Tell());
3687 2 : pChpPlc->AppendFkpEntry(rStrm.Tell());
3688 2 : nRetPos = rStrm.Tell();
3689 : }
3690 30 : return nRetPos;
3691 : }
3692 :
3693 72 : void WW8AttributeOutput::TableRowEnd(sal_uInt32 nDepth)
3694 : {
3695 72 : if ( nDepth == 1 )
3696 72 : m_rWW8Export.WriteChar( 0x07 );
3697 0 : else if ( nDepth > 1 )
3698 0 : m_rWW8Export.WriteChar( 0x0d );
3699 :
3700 : //Technically in a word document this is a different value for a row ends
3701 : //that are not row ends directly after a cell with a graphic. But it
3702 : //doesn't seem to make a difference
3703 : //pMagicTable->Append(Fc2Cp(Strm().Tell()),0x1B6);
3704 72 : }
3705 :
3706 966 : void AttributeOutputBase::FormatPageDescription( const SwFmtPageDesc& rPageDesc )
3707 : {
3708 966 : if ( GetExport().bStyDef && GetExport().pOutFmtNode && GetExport().pOutFmtNode->ISA( SwTxtFmtColl ) )
3709 : {
3710 20 : const SwTxtFmtColl* pC = (SwTxtFmtColl*)GetExport().pOutFmtNode;
3711 20 : if ( (SfxItemState::SET != pC->GetItemState( RES_BREAK, false ) ) && rPageDesc.KnowsPageDesc() )
3712 2 : FormatBreak( SvxFmtBreakItem( SVX_BREAK_PAGE_BEFORE, RES_BREAK ) );
3713 : }
3714 966 : }
3715 :
3716 10 : void WW8AttributeOutput::PageBreakBefore( bool bBreak )
3717 : {
3718 : // sprmPPageBreakBefore/sprmPFPageBreakBefore
3719 10 : if ( m_rWW8Export.bWrtWW8 )
3720 10 : m_rWW8Export.InsUInt16( NS_sprm::LN_PFPageBreakBefore );
3721 : else
3722 0 : m_rWW8Export.pO->push_back( 9 );
3723 :
3724 10 : m_rWW8Export.pO->push_back( bBreak ? 1 : 0 );
3725 10 : }
3726 :
3727 : // Breaks schreiben nichts in das Ausgabe-Feld rWrt.pO,
3728 : // sondern nur in den Text-Stream ( Bedingung dafuer, dass sie von Out_Break...
3729 : // gerufen werden duerfen )
3730 640 : void AttributeOutputBase::FormatBreak( const SvxFmtBreakItem& rBreak )
3731 : {
3732 640 : if ( GetExport().bStyDef )
3733 : {
3734 50 : switch ( rBreak.GetBreak() )
3735 : {
3736 : case SVX_BREAK_NONE:
3737 : case SVX_BREAK_PAGE_BEFORE:
3738 : case SVX_BREAK_PAGE_BOTH:
3739 50 : PageBreakBefore( rBreak.GetValue() );
3740 50 : break;
3741 : default:
3742 0 : break;
3743 : }
3744 : }
3745 590 : else if ( !GetExport().mpParentFrame )
3746 : {
3747 590 : sal_uInt8 nC = 0;
3748 590 : bool bBefore = false;
3749 : // #i76300# - Note: Can only be <true>, if <bBefore> equals <false>.
3750 590 : bool bCheckForFollowPageDesc = false;
3751 :
3752 590 : switch ( rBreak.GetBreak() )
3753 : {
3754 : case SVX_BREAK_NONE: // Ausgeschaltet
3755 2 : if ( !GetExport().bBreakBefore )
3756 2 : PageBreakBefore( false );
3757 642 : return;
3758 :
3759 : case SVX_BREAK_COLUMN_BEFORE: // ColumnBreak
3760 220 : bBefore = true;
3761 : // no break;
3762 : case SVX_BREAK_COLUMN_AFTER:
3763 : case SVX_BREAK_COLUMN_BOTH:
3764 220 : if ( GetExport().Sections().CurrentNumberOfColumns( *GetExport().pDoc ) > 1 || GetExport().SupportsOneColumnBreak() )
3765 : {
3766 214 : nC = msword::ColumnBreak;
3767 : }
3768 220 : break;
3769 :
3770 : case SVX_BREAK_PAGE_BEFORE: // PageBreak
3771 : // From now on(fix for #i77900#) we prefer to save a page break
3772 : // as paragraph attribute (if the exporter is OK with that),
3773 : // this has to be done after the export of the paragraph ( =>
3774 : // !GetExport().bBreakBefore )
3775 368 : if (GetExport().PreferPageBreakBefore())
3776 : {
3777 34 : if (!GetExport().bBreakBefore)
3778 18 : PageBreakBefore(true);
3779 34 : break;
3780 : }
3781 : case SVX_BREAK_PAGE_AFTER:
3782 : case SVX_BREAK_PAGE_BOTH:
3783 334 : nC = msword::PageBreak;
3784 : // #i76300# - check for follow page description,
3785 : // if current writing attributes of a paragraph.
3786 838 : if ( dynamic_cast< const SwTxtNode* >( GetExport().pOutFmtNode ) &&
3787 504 : GetExport().GetCurItemSet() )
3788 : {
3789 170 : bCheckForFollowPageDesc = true;
3790 : }
3791 334 : break;
3792 :
3793 : default:
3794 0 : break;
3795 : }
3796 :
3797 1284 : if ( (( bBefore != GetExport().bBreakBefore ) && ( nC == msword::PageBreak)) ||
3798 722 : (( bBefore == GetExport().bBreakBefore ) && ( nC == msword::ColumnBreak)) )
3799 : {
3800 : // #i76300#
3801 272 : bool bFollowPageDescWritten = false;
3802 272 : if ( bCheckForFollowPageDesc && !bBefore )
3803 : {
3804 : bFollowPageDescWritten =
3805 0 : GetExport().OutputFollowPageDesc( GetExport().GetCurItemSet(),
3806 0 : dynamic_cast<const SwTxtNode*>( GetExport().pOutFmtNode ) );
3807 : }
3808 272 : if ( !bFollowPageDescWritten )
3809 : {
3810 272 : SectionBreak( nC );
3811 : }
3812 : }
3813 : }
3814 : }
3815 :
3816 0 : void WW8AttributeOutput::SectionBreak( sal_uInt8 nC, const WW8_SepInfo* /*pSectionInfo*/ )
3817 : {
3818 0 : m_rWW8Export.ReplaceCr( nC );
3819 0 : }
3820 :
3821 928 : sal_uInt32 AttributeOutputBase::GridCharacterPitch( const SwTextGridItem& rGrid ) const
3822 : {
3823 928 : MSWordStyles * pStyles = GetExport().pStyles;
3824 928 : const SwFmt * pSwFmt = pStyles->GetSwFmt(0);
3825 :
3826 928 : sal_uInt32 nPageCharSize = 0;
3827 :
3828 928 : if (pSwFmt != NULL)
3829 : {
3830 : nPageCharSize = ItemGet<SvxFontHeightItem>
3831 928 : (*pSwFmt, RES_CHRATR_FONTSIZE).GetHeight();
3832 : }
3833 928 : sal_uInt16 nPitch = rGrid.IsSquaredMode() ? rGrid.GetBaseHeight() :
3834 928 : rGrid.GetBaseWidth( );
3835 :
3836 928 : sal_Int32 nCharWidth = nPitch - nPageCharSize;
3837 928 : sal_Int32 nFraction = nCharWidth % 20;
3838 928 : if ( nCharWidth < 0 )
3839 804 : nFraction = 20 + nFraction;
3840 928 : nFraction = ( nFraction * 0xFFF ) / 20;
3841 928 : nFraction = ( nFraction & 0x00000FFF );
3842 :
3843 928 : sal_Int32 nMain = nCharWidth / 20;
3844 928 : if ( nCharWidth < 0 )
3845 804 : nMain -= 1;
3846 928 : nMain = nMain * 0x1000;
3847 928 : nMain = ( nMain & 0xFFFFF000 );
3848 :
3849 928 : return sal_uInt32( nFraction + nMain );
3850 : }
3851 :
3852 66 : void WW8AttributeOutput::FormatTextGrid( const SwTextGridItem& rGrid )
3853 : {
3854 66 : if ( m_rWW8Export.bOutPageDescs && m_rWW8Export.bWrtWW8 )
3855 : {
3856 36 : sal_uInt16 nGridType = 0;
3857 36 : switch ( rGrid.GetGridType() )
3858 : {
3859 : default:
3860 : OSL_FAIL("Unknown grid type");
3861 : //fall-through
3862 : case GRID_NONE:
3863 36 : nGridType = 0;
3864 36 : break;
3865 : case GRID_LINES_ONLY:
3866 0 : nGridType = 2;
3867 0 : break;
3868 : case GRID_LINES_CHARS:
3869 0 : if ( rGrid.IsSnapToChars() )
3870 0 : nGridType = 3;
3871 : else
3872 0 : nGridType = 1;
3873 0 : break;
3874 : }
3875 36 : m_rWW8Export.InsUInt16( NS_sprm::LN_SClm );
3876 36 : m_rWW8Export.InsUInt16( nGridType );
3877 :
3878 36 : sal_uInt16 nHeight = rGrid.GetBaseHeight() + rGrid.GetRubyHeight();
3879 36 : m_rWW8Export.InsUInt16( NS_sprm::LN_SDyaLinePitch );
3880 36 : m_rWW8Export.InsUInt16( nHeight );
3881 :
3882 36 : m_rWW8Export.InsUInt16( NS_sprm::LN_SDxtCharSpace );
3883 36 : m_rWW8Export.InsUInt32( GridCharacterPitch( rGrid ) );
3884 : }
3885 66 : }
3886 :
3887 0 : void WW8AttributeOutput::FormatPaperBin( const SvxPaperBinItem& rPaperBin )
3888 : {
3889 0 : if ( m_rWW8Export.bOutPageDescs )
3890 : {
3891 : sal_uInt16 nVal;
3892 0 : switch ( rPaperBin.GetValue() )
3893 : {
3894 0 : case 0: nVal = 15; break; // Automatically select
3895 0 : case 1: nVal = 1; break; // Upper paper tray
3896 0 : case 2: nVal = 4; break; // Manual paper feed
3897 0 : default: nVal = 0; break;
3898 : }
3899 :
3900 0 : if ( nVal )
3901 : {
3902 0 : if( m_rWW8Export.bWrtWW8 )
3903 0 : m_rWW8Export.InsUInt16( m_rWW8Export.bOutFirstPage? NS_sprm::LN_SDmBinFirst: NS_sprm::LN_SDmBinOther );
3904 : else
3905 0 : m_rWW8Export.pO->push_back( m_rWW8Export.bOutFirstPage? 140: 141 );
3906 :
3907 0 : m_rWW8Export.InsUInt16( nVal );
3908 : }
3909 : }
3910 0 : }
3911 :
3912 128 : void WW8AttributeOutput::FormatLRSpace( const SvxLRSpaceItem& rLR )
3913 : {
3914 : // Flys fehlen noch ( siehe RTF )
3915 :
3916 128 : if ( m_rWW8Export.bOutFlyFrmAttrs ) // Flys
3917 : {
3918 : // sprmPDxaFromText10
3919 0 : if( m_rWW8Export.bWrtWW8 )
3920 0 : m_rWW8Export.InsUInt16( NS_sprm::LN_PDxaFromText10 );
3921 : else
3922 0 : m_rWW8Export.pO->push_back( 49 );
3923 : // Mittelwert nehmen, da WW nur 1 Wert kennt
3924 0 : m_rWW8Export.InsUInt16( (sal_uInt16) ( ( rLR.GetLeft() + rLR.GetRight() ) / 2 ) );
3925 : }
3926 128 : else if ( m_rWW8Export.bOutPageDescs ) // PageDescs
3927 : {
3928 : sal_uInt16 nLDist, nRDist;
3929 40 : const SfxPoolItem* pItem = m_rWW8Export.HasItem( RES_BOX );
3930 40 : if ( pItem )
3931 : {
3932 2 : nRDist = ((SvxBoxItem*)pItem)->CalcLineSpace( BOX_LINE_LEFT );
3933 2 : nLDist = ((SvxBoxItem*)pItem)->CalcLineSpace( BOX_LINE_RIGHT );
3934 : }
3935 : else
3936 38 : nLDist = nRDist = 0;
3937 40 : nLDist = nLDist + (sal_uInt16)rLR.GetLeft();
3938 40 : nRDist = nRDist + (sal_uInt16)rLR.GetRight();
3939 :
3940 : // sprmSDxaLeft
3941 40 : if( m_rWW8Export.bWrtWW8 )
3942 40 : m_rWW8Export.InsUInt16( NS_sprm::LN_SDxaLeft );
3943 : else
3944 0 : m_rWW8Export.pO->push_back( 166 );
3945 40 : m_rWW8Export.InsUInt16( nLDist );
3946 :
3947 : // sprmSDxaRight
3948 40 : if( m_rWW8Export.bWrtWW8 )
3949 40 : m_rWW8Export.InsUInt16( NS_sprm::LN_SDxaRight );
3950 : else
3951 0 : m_rWW8Export.pO->push_back( 167 );
3952 40 : m_rWW8Export.InsUInt16( nRDist );
3953 : }
3954 : else
3955 : { // normale Absaetze
3956 : // sprmPDxaLeft
3957 88 : if( m_rWW8Export.bWrtWW8 )
3958 : {
3959 88 : m_rWW8Export.InsUInt16( 0x845E ); //asian version ?
3960 88 : m_rWW8Export.InsUInt16( (sal_uInt16)rLR.GetTxtLeft() );
3961 : }
3962 : else
3963 : {
3964 0 : m_rWW8Export.pO->push_back( 17 );
3965 0 : m_rWW8Export.InsUInt16( (sal_uInt16)rLR.GetTxtLeft() );
3966 : }
3967 :
3968 : // sprmPDxaRight
3969 88 : if( m_rWW8Export.bWrtWW8 )
3970 : {
3971 88 : m_rWW8Export.InsUInt16( 0x845D ); //asian version ?
3972 88 : m_rWW8Export.InsUInt16( (sal_uInt16)rLR.GetRight() );
3973 : }
3974 : else
3975 : {
3976 0 : m_rWW8Export.pO->push_back( 16 );
3977 0 : m_rWW8Export.InsUInt16( (sal_uInt16)rLR.GetRight() );
3978 : }
3979 :
3980 : // sprmPDxaLeft1
3981 88 : if( m_rWW8Export.bWrtWW8 )
3982 : {
3983 88 : m_rWW8Export.InsUInt16( 0x8460 ); //asian version ?
3984 88 : m_rWW8Export.InsUInt16( rLR.GetTxtFirstLineOfst() );
3985 : }
3986 : else
3987 : {
3988 0 : m_rWW8Export.pO->push_back( 19 );
3989 0 : m_rWW8Export.InsUInt16( rLR.GetTxtFirstLineOfst() );
3990 : }
3991 : }
3992 128 : }
3993 :
3994 390 : void WW8AttributeOutput::FormatULSpace( const SvxULSpaceItem& rUL )
3995 : {
3996 : // Flys fehlen noch ( siehe RTF )
3997 :
3998 390 : if ( m_rWW8Export.bOutFlyFrmAttrs ) // Flys
3999 : {
4000 : // sprmPDyaFromText
4001 0 : if( m_rWW8Export.bWrtWW8 )
4002 0 : m_rWW8Export.InsUInt16( NS_sprm::LN_PDyaFromText );
4003 : else
4004 0 : m_rWW8Export.pO->push_back( 48 );
4005 : // Mittelwert nehmen, da WW nur 1 Wert kennt
4006 0 : m_rWW8Export.InsUInt16( (sal_uInt16) ( ( rUL.GetUpper() + rUL.GetLower() ) / 2 ) );
4007 : }
4008 390 : else if ( m_rWW8Export.bOutPageDescs ) // Page-UL
4009 : {
4010 : OSL_ENSURE( m_rWW8Export.GetCurItemSet(), "Impossible" );
4011 40 : if ( !m_rWW8Export.GetCurItemSet() )
4012 390 : return;
4013 :
4014 40 : HdFtDistanceGlue aDistances( *m_rWW8Export.GetCurItemSet() );
4015 :
4016 40 : if ( aDistances.HasHeader() )
4017 : {
4018 : //sprmSDyaHdrTop
4019 16 : if ( m_rWW8Export.bWrtWW8 )
4020 16 : m_rWW8Export.InsUInt16( NS_sprm::LN_SDyaHdrTop );
4021 : else
4022 0 : m_rWW8Export.pO->push_back( 156 );
4023 16 : m_rWW8Export.InsUInt16( aDistances.dyaHdrTop );
4024 : }
4025 :
4026 : // sprmSDyaTop
4027 40 : if ( m_rWW8Export.bWrtWW8 )
4028 40 : m_rWW8Export.InsUInt16( NS_sprm::LN_SDyaTop );
4029 : else
4030 0 : m_rWW8Export.pO->push_back( 168 );
4031 40 : m_rWW8Export.InsUInt16( aDistances.dyaTop );
4032 :
4033 40 : if ( aDistances.HasFooter() )
4034 : {
4035 : //sprmSDyaHdrBottom
4036 16 : if ( m_rWW8Export.bWrtWW8 )
4037 16 : m_rWW8Export.InsUInt16( NS_sprm::LN_SDyaHdrBottom );
4038 : else
4039 0 : m_rWW8Export.pO->push_back( 157 );
4040 16 : m_rWW8Export.InsUInt16( aDistances.dyaHdrBottom );
4041 : }
4042 :
4043 : //sprmSDyaBottom
4044 40 : if ( m_rWW8Export.bWrtWW8 )
4045 40 : m_rWW8Export.InsUInt16( NS_sprm::LN_SDyaBottom );
4046 : else
4047 0 : m_rWW8Export.pO->push_back( 169 );
4048 40 : m_rWW8Export.InsUInt16( aDistances.dyaBottom );
4049 : }
4050 : else
4051 : {
4052 : // sprmPDyaBefore
4053 350 : if ( m_rWW8Export.bWrtWW8 )
4054 350 : m_rWW8Export.InsUInt16( NS_sprm::LN_PDyaBefore );
4055 : else
4056 0 : m_rWW8Export.pO->push_back( 21 );
4057 350 : m_rWW8Export.InsUInt16( rUL.GetUpper() );
4058 : // sprmPDyaAfter
4059 350 : if( m_rWW8Export.bWrtWW8 )
4060 350 : m_rWW8Export.InsUInt16( NS_sprm::LN_PDyaAfter );
4061 : else
4062 0 : m_rWW8Export.pO->push_back( 22 );
4063 350 : m_rWW8Export.InsUInt16( rUL.GetLower() );
4064 : // sprmPFContextualSpacing
4065 350 : if (m_rWW8Export.bWrtWW8 && rUL.GetContext())
4066 : {
4067 0 : m_rWW8Export.InsUInt16(NS_sprm::LN_PContextualSpacing);
4068 0 : m_rWW8Export.pO->push_back( (sal_uInt8)rUL.GetContext() );
4069 : }
4070 : }
4071 : }
4072 :
4073 : // Print, Opaque, Protect fehlen noch
4074 :
4075 0 : void WW8AttributeOutput::FormatSurround( const SwFmtSurround& rSurround )
4076 : {
4077 0 : if ( m_rWW8Export.bOutFlyFrmAttrs )
4078 : {
4079 0 : if ( m_rWW8Export.bWrtWW8 )
4080 0 : m_rWW8Export.InsUInt16( NS_sprm::LN_PWr );
4081 : else
4082 0 : m_rWW8Export.pO->push_back( 37 );
4083 :
4084 : m_rWW8Export.pO->push_back(
4085 0 : ( SURROUND_NONE != rSurround.GetSurround() ) ? 2 : 1 );
4086 : }
4087 0 : }
4088 :
4089 0 : void WW8AttributeOutput::FormatVertOrientation( const SwFmtVertOrient& rFlyVert )
4090 : {
4091 : //!!!! Ankertyp und entsprechende Umrechnung fehlt noch
4092 :
4093 0 : if ( m_rWW8Export.bOutFlyFrmAttrs )
4094 : {
4095 : short nPos;
4096 0 : switch( rFlyVert.GetVertOrient() )
4097 : {
4098 : case text::VertOrientation::NONE:
4099 0 : nPos = (short)rFlyVert.GetPos();
4100 0 : break;
4101 : case text::VertOrientation::CENTER:
4102 : case text::VertOrientation::LINE_CENTER:
4103 0 : nPos = -8;
4104 0 : break;
4105 : case text::VertOrientation::BOTTOM:
4106 : case text::VertOrientation::LINE_BOTTOM:
4107 0 : nPos = -12;
4108 0 : break;
4109 : case text::VertOrientation::TOP:
4110 : case text::VertOrientation::LINE_TOP:
4111 : default:
4112 0 : nPos = -4;
4113 0 : break;
4114 : }
4115 :
4116 : // sprmPDyaAbs
4117 0 : if ( m_rWW8Export.bWrtWW8 )
4118 0 : m_rWW8Export.InsUInt16( NS_sprm::LN_PDyaAbs );
4119 : else
4120 0 : m_rWW8Export.pO->push_back( 27 );
4121 0 : m_rWW8Export.InsUInt16( nPos );
4122 : }
4123 0 : }
4124 :
4125 0 : void WW8AttributeOutput::FormatHorizOrientation( const SwFmtHoriOrient& rFlyHori )
4126 : {
4127 0 : if ( !m_rWW8Export.mpParentFrame )
4128 : {
4129 : OSL_ENSURE( m_rWW8Export.mpParentFrame, "HoriOrient without mpParentFrame !!" );
4130 0 : return;
4131 : }
4132 :
4133 : //!!!! Ankertyp und entsprechende Umrechnung fehlt noch
4134 0 : if ( m_rWW8Export.bOutFlyFrmAttrs )
4135 : {
4136 : short nPos;
4137 0 : switch( rFlyHori.GetHoriOrient() )
4138 : {
4139 : case text::HoriOrientation::NONE:
4140 0 : nPos = (short)rFlyHori.GetPos();
4141 0 : if( !nPos )
4142 0 : nPos = 1; // WW: 0 ist reserviert
4143 0 : break;
4144 : case text::HoriOrientation::LEFT:
4145 0 : nPos = rFlyHori.IsPosToggle() ? -12 : 0;
4146 0 : break;
4147 : case text::HoriOrientation::RIGHT:
4148 0 : nPos = rFlyHori.IsPosToggle() ? -16 : -8;
4149 0 : break;
4150 : case text::HoriOrientation::CENTER:
4151 : case text::HoriOrientation::FULL: // FULL nur fuer Tabellen
4152 : default:
4153 0 : nPos = -4;
4154 0 : break;
4155 : }
4156 :
4157 : // sprmPDxaAbs
4158 0 : if( m_rWW8Export.bWrtWW8 )
4159 0 : m_rWW8Export.InsUInt16( NS_sprm::LN_PDxaAbs );
4160 : else
4161 0 : m_rWW8Export.pO->push_back( 26 );
4162 0 : m_rWW8Export.InsUInt16( nPos );
4163 : }
4164 : }
4165 :
4166 0 : void WW8AttributeOutput::FormatAnchor( const SwFmtAnchor& rAnchor )
4167 : {
4168 : OSL_ENSURE( m_rWW8Export.mpParentFrame, "Anchor without mpParentFrame !!" );
4169 :
4170 0 : if ( m_rWW8Export.bOutFlyFrmAttrs )
4171 : {
4172 0 : sal_uInt8 nP = 0;
4173 0 : switch ( rAnchor.GetAnchorId() )
4174 : {
4175 : case FLY_AT_PAGE:
4176 : // Vert: Page | Horz: Page
4177 0 : nP |= (1 << 4) | (2 << 6);
4178 0 : break;
4179 : // Im Fall eine Flys als Zeichen: Absatz-gebunden setzen!!!
4180 : case FLY_AT_FLY:
4181 : case FLY_AT_CHAR:
4182 : case FLY_AT_PARA:
4183 : case FLY_AS_CHAR:
4184 : // Vert: Page | Horz: Page
4185 0 : nP |= (2 << 4) | (0 << 6);
4186 0 : break;
4187 : default:
4188 0 : break;
4189 : }
4190 :
4191 : // sprmPPc
4192 0 : if ( m_rWW8Export.bWrtWW8 )
4193 0 : m_rWW8Export.InsUInt16( NS_sprm::LN_PPc );
4194 : else
4195 0 : m_rWW8Export.pO->push_back( 29 );
4196 0 : m_rWW8Export.pO->push_back( nP );
4197 : }
4198 0 : }
4199 :
4200 4 : void WW8AttributeOutput::FormatBackground( const SvxBrushItem& rBrush )
4201 : {
4202 : // WW cannot have background in a section
4203 4 : if ( !m_rWW8Export.bOutPageDescs )
4204 : {
4205 4 : WW8_SHD aSHD;
4206 :
4207 4 : m_rWW8Export.TransBrush( rBrush.GetColor(), aSHD );
4208 : // sprmPShd
4209 4 : if ( m_rWW8Export.bWrtWW8 )
4210 4 : m_rWW8Export.InsUInt16( NS_sprm::LN_PShd );
4211 : else
4212 0 : m_rWW8Export.pO->push_back(47);
4213 4 : m_rWW8Export.InsUInt16( aSHD.GetValue() );
4214 :
4215 : // Quite a few unknowns, some might be transparency or something
4216 : // of that nature...
4217 4 : if ( m_rWW8Export.bWrtWW8 )
4218 : {
4219 4 : m_rWW8Export.InsUInt16( 0xC64D );
4220 4 : m_rWW8Export.pO->push_back( 10 );
4221 4 : m_rWW8Export.InsUInt32( 0xFF000000 );
4222 4 : m_rWW8Export.InsUInt32( SuitableBGColor( rBrush.GetColor().GetColor() ) );
4223 4 : m_rWW8Export.InsUInt16( 0x0000 );
4224 : }
4225 : }
4226 4 : }
4227 :
4228 54 : void WW8AttributeOutput::FormatFillStyle( const XFillStyleItem& /*rFillStyle*/ )
4229 : {
4230 54 : }
4231 :
4232 0 : void WW8AttributeOutput::FormatFillGradient( const XFillGradientItem& /*rFillGradient*/ )
4233 : {
4234 0 : }
4235 :
4236 756 : WW8_BRCVer9 WW8Export::TranslateBorderLine(const SvxBorderLine& rLine,
4237 : sal_uInt16 nDist, bool bShadow)
4238 : {
4239 : // M.M. This function writes out border lines to the word format similar to
4240 : // what SwRTFWriter::OutRTFBorder does in the RTF filter Eventually it
4241 : // would be nice if all this functionality was in the one place
4242 756 : sal_uInt32 nColBGR = 0;
4243 : sal_uInt16 nWidth = ::editeng::ConvertBorderWidthToWord(
4244 756 : rLine.GetBorderLineStyle(), rLine.GetWidth());
4245 756 : sal_uInt8 brcType = 0;
4246 :
4247 756 : if( nWidth ) // Linie ?
4248 : {
4249 : // BRC.brcType
4250 756 : bool bThick = !rLine.isDouble() && !bWrtWW8 && nWidth > 75;
4251 756 : if( bThick )
4252 0 : brcType = 2;
4253 : else
4254 : {
4255 756 : brcType = 0;
4256 756 : if ( bWrtWW8 )
4257 : {
4258 : // All the border types values are available on
4259 : // http://msdn.microsoft.com/en-us/library/dd908142%28v=office.12%29.aspx
4260 756 : switch (rLine.GetBorderLineStyle())
4261 : {
4262 : case table::BorderLineStyle::SOLID:
4263 : {
4264 634 : if ( rLine.GetWidth( ) == DEF_LINE_WIDTH_0 )
4265 0 : brcType = 5;
4266 : else
4267 634 : brcType = 1;
4268 : }
4269 634 : break;
4270 : case table::BorderLineStyle::DOTTED:
4271 50 : brcType = 6;
4272 50 : break;
4273 : case table::BorderLineStyle::DASHED:
4274 4 : brcType = 7;
4275 4 : break;
4276 : case table::BorderLineStyle::DOUBLE:
4277 26 : brcType = 3;
4278 26 : break;
4279 : case table::BorderLineStyle::THINTHICK_SMALLGAP:
4280 32 : brcType = 11;
4281 32 : break;
4282 : case table::BorderLineStyle::THINTHICK_MEDIUMGAP:
4283 0 : brcType = 14;
4284 0 : break;
4285 : case table::BorderLineStyle::THINTHICK_LARGEGAP:
4286 0 : brcType = 17;
4287 0 : break;
4288 : case table::BorderLineStyle::THICKTHIN_SMALLGAP:
4289 0 : brcType = 12;
4290 0 : break;
4291 : case table::BorderLineStyle::THICKTHIN_MEDIUMGAP:
4292 0 : brcType = 15;
4293 0 : break;
4294 : case table::BorderLineStyle::THICKTHIN_LARGEGAP:
4295 0 : brcType = 18;
4296 0 : break;
4297 : case table::BorderLineStyle::EMBOSSED:
4298 0 : brcType = 24;
4299 0 : break;
4300 : case table::BorderLineStyle::ENGRAVED:
4301 0 : brcType = 25;
4302 0 : break;
4303 : case table::BorderLineStyle::OUTSET:
4304 0 : brcType = 26;
4305 0 : break;
4306 : case table::BorderLineStyle::INSET:
4307 0 : brcType = 27;
4308 0 : break;
4309 : case table::BorderLineStyle::FINE_DASHED:
4310 10 : brcType = 22;
4311 10 : break;
4312 : case table::BorderLineStyle::DASH_DOT:
4313 0 : brcType = 8;
4314 0 : break;
4315 : case table::BorderLineStyle::DASH_DOT_DOT:
4316 0 : brcType = 9;
4317 0 : break;
4318 : default:
4319 0 : break;
4320 : }
4321 : }
4322 : }
4323 :
4324 : // BRC.dptLineWidth
4325 756 : if( bThick )
4326 0 : nWidth /= 2;
4327 :
4328 : // convert width from twips (1/20 pt) to eighths of a point
4329 756 : nWidth = (( nWidth * 8 ) + 10 ) / 20;
4330 756 : if( 0xff < nWidth )
4331 0 : nWidth = 0xff;
4332 :
4333 756 : if( 0 == nWidth ) // ganz duenne Linie
4334 0 : nWidth = 1; // nicht weglassen
4335 :
4336 : // BRC.cv
4337 756 : nColBGR = wwUtility::RGBToBGR(rLine.GetColor().GetRGBColor());
4338 : }
4339 :
4340 : // BRC.dptSpace
4341 756 : sal_uInt16 nLDist = nDist;
4342 756 : nLDist /= 20; // Masseinheit : pt
4343 756 : if( nLDist > 0x1f )
4344 8 : nLDist = 0x1f;
4345 :
4346 : return WW8_BRCVer9(nColBGR, sal_uInt8(nWidth), brcType, sal_uInt8(nLDist),
4347 756 : bShadow, false);
4348 : }
4349 :
4350 : // MakeBorderLine() bekommt einen WW8Bytes* uebergeben, um die Funktion
4351 : // auch fuer die Tabellen-Umrandungen zu benutzen.
4352 : // Wenn nSprmNo == 0, dann wird der Opcode nicht ausgegeben.
4353 : // bShadow darf bei Tabellenzellen *nicht* gesetzt sein !
4354 1128 : void WW8Export::Out_BorderLine(ww::bytes& rO, const SvxBorderLine* pLine,
4355 : sal_uInt16 nDist, sal_uInt16 nSprmNo, sal_uInt16 nSprmNoVer9, bool bShadow)
4356 : {
4357 : OSL_ENSURE( ( nSprmNo == 0 ) ||
4358 : ( nSprmNo >= 38 && nSprmNo <= 41 ) ||
4359 : ( nSprmNo >= NS_sprm::LN_PBrcTop80
4360 : && nSprmNo <= NS_sprm::LN_PBrcRight80 ) ||
4361 : ( nSprmNo >= NS_sprm::LN_SBrcTop80
4362 : && nSprmNo <= NS_sprm::LN_SBrcRight80 ),
4363 : "Sprm for border out is of range" );
4364 :
4365 1128 : WW8_BRCVer9 aBrcVer9;
4366 1128 : WW8_BRC aBrcVer8;
4367 :
4368 1128 : if( pLine && pLine->GetBorderLineStyle() != table::BorderLineStyle::NONE )
4369 : {
4370 416 : aBrcVer9 = TranslateBorderLine( *pLine, nDist, bShadow );
4371 416 : sal_uInt8 ico = TransCol( msfilter::util::BGRToRGB(aBrcVer9.cv()) );
4372 832 : aBrcVer8 = WW8_BRC( aBrcVer9.dptLineWidth(), aBrcVer9.brcType(), ico,
4373 1248 : aBrcVer9.dptSpace(), aBrcVer9.fShadow(), aBrcVer9.fFrame() );
4374 : }
4375 :
4376 1128 : if( bWrtWW8 )
4377 : {
4378 : // WW97-SprmIds
4379 1128 : if ( nSprmNo != 0 )
4380 56 : SwWW8Writer::InsUInt16( rO, nSprmNo );
4381 :
4382 1128 : rO.insert( rO.end(), aBrcVer8.aBits1, aBrcVer8.aBits2+2 );
4383 :
4384 1128 : if ( nSprmNoVer9 != 0 )
4385 : {
4386 56 : SwWW8Writer::InsUInt16( rO, nSprmNoVer9 );
4387 56 : rO.push_back(sizeof(WW8_BRCVer9));
4388 56 : rO.insert( rO.end(), aBrcVer9.aBits1, aBrcVer9.aBits2+4);
4389 : }
4390 : }
4391 : else
4392 : {
4393 0 : WW8_BRCVer6 aBrcVer6(aBrcVer8);
4394 : // WW95-SprmIds
4395 0 : if ( nSprmNo != 0 )
4396 0 : rO.push_back( static_cast<sal_uInt8>( nSprmNo ) );
4397 0 : rO.insert( rO.end(), aBrcVer6.aBits1, aBrcVer6.aBits1+2 );
4398 : }
4399 1128 : }
4400 :
4401 : // FormatBox1() ist fuer alle Boxen ausser in Tabellen.
4402 : // es wird pO des WW8Writers genommen
4403 12 : void WW8Export::Out_SwFmtBox(const SvxBoxItem& rBox, bool bShadow)
4404 : {
4405 12 : if ( bOutPageDescs && !bWrtWW8 )
4406 12 : return; // no page ouline in WW6
4407 :
4408 : static const sal_uInt16 aBorders[] =
4409 : {
4410 : BOX_LINE_TOP, BOX_LINE_LEFT, BOX_LINE_BOTTOM, BOX_LINE_RIGHT
4411 : };
4412 : static const sal_uInt16 aPBrc[] =
4413 : {
4414 : // WW8 SPRMs
4415 : NS_sprm::LN_PBrcTop80, NS_sprm::LN_PBrcLeft80,
4416 : NS_sprm::LN_PBrcBottom80, NS_sprm::LN_PBrcRight80,
4417 : // WW9 SPRMs
4418 : NS_sprm::LN_PBrcTop, NS_sprm::LN_PBrcLeft,
4419 : NS_sprm::LN_PBrcBottom, NS_sprm::LN_PBrcRight
4420 : };
4421 : static const sal_uInt16 aSBrc[] =
4422 : {
4423 : // WW8 SPRMs
4424 : NS_sprm::LN_SBrcTop80, NS_sprm::LN_SBrcLeft80,
4425 : NS_sprm::LN_SBrcBottom80, NS_sprm::LN_SBrcRight80,
4426 : // WW9 SPRMs
4427 : NS_sprm::LN_SBrcTop, NS_sprm::LN_SBrcLeft,
4428 : NS_sprm::LN_SBrcBottom, NS_sprm::LN_SBrcRight
4429 : };
4430 : static const sal_uInt16 aWW6PBrc[] =
4431 : {
4432 : 38, 39, 40, 41
4433 : };
4434 :
4435 12 : const sal_uInt16* pBrd = aBorders;
4436 60 : for( sal_uInt16 i = 0; i < 4; ++i, ++pBrd )
4437 : {
4438 48 : const SvxBorderLine* pLn = rBox.GetLine( *pBrd );
4439 :
4440 48 : sal_uInt16 nSprmNo, nSprmNoVer9 = 0;
4441 48 : if ( !bWrtWW8 )
4442 0 : nSprmNo = aWW6PBrc[i];
4443 48 : else if ( bOutPageDescs )
4444 : {
4445 8 : nSprmNo = aSBrc[i];
4446 8 : nSprmNoVer9 = aSBrc[i+4];
4447 : }
4448 : else
4449 : {
4450 40 : nSprmNo = aPBrc[i];
4451 40 : nSprmNoVer9 = aPBrc[i+4];
4452 : }
4453 :
4454 48 : Out_BorderLine( *pO, pLn, rBox.GetDistance( *pBrd ), nSprmNo,
4455 96 : nSprmNoVer9, bShadow );
4456 : }
4457 : }
4458 :
4459 : // FormatBox2() ist fuer TC-Strukturen in Tabellen. Der Sprm-Opcode
4460 : // wird nicht geschrieben, da es in der TC-Structur ohne Opcode gepackt ist.
4461 : // dxpSpace wird immer 0, da WW das in Tabellen so verlangt
4462 : // ( Tabellenumrandungen fransen sonst aus )
4463 : // Ein WW8Bytes-Ptr wird als Ausgabe-Parameter uebergeben
4464 :
4465 268 : void WW8Export::Out_SwFmtTableBox( ww::bytes& rO, const SvxBoxItem * pBox )
4466 : {
4467 : // moeglich und vielleicht besser waere 0xffff
4468 : static const sal_uInt16 aBorders[] =
4469 : {
4470 : BOX_LINE_TOP, BOX_LINE_LEFT, BOX_LINE_BOTTOM, BOX_LINE_RIGHT
4471 : };
4472 268 : static const SvxBorderLine aBorderLine;
4473 :
4474 268 : const sal_uInt16* pBrd = aBorders;
4475 1340 : for( int i = 0; i < 4; ++i, ++pBrd )
4476 : {
4477 : const SvxBorderLine* pLn;
4478 1072 : if (pBox != NULL)
4479 1072 : pLn = pBox->GetLine( *pBrd );
4480 : else
4481 0 : pLn = & aBorderLine;
4482 :
4483 1072 : Out_BorderLine(rO, pLn, 0, 0, 0, false);
4484 : }
4485 268 : }
4486 :
4487 184 : void WW8Export::Out_CellRangeBorders( const SvxBoxItem * pBox, sal_uInt8 nStart,
4488 : sal_uInt8 nLimit )
4489 : {
4490 : static const sal_uInt16 aBorders[] =
4491 : {
4492 : BOX_LINE_TOP, BOX_LINE_LEFT, BOX_LINE_BOTTOM, BOX_LINE_RIGHT
4493 : };
4494 :
4495 920 : for( int i = 0; i < 4; ++i )
4496 : {
4497 736 : const SvxBorderLine* pLn = 0;
4498 736 : if (pBox != NULL)
4499 736 : pLn = pBox->GetLine( aBorders[i] );
4500 736 : if (!pLn)
4501 404 : continue;
4502 :
4503 332 : InsUInt16( NS_sprm::LN_TSetBrc );
4504 332 : pO->push_back( 11 );
4505 332 : pO->push_back( nStart );
4506 332 : pO->push_back( nLimit );
4507 332 : pO->push_back( 1<<i );
4508 332 : WW8_BRCVer9 aBrcVer9 = TranslateBorderLine( *pLn, 0, false );
4509 332 : pO->insert( pO->end(), aBrcVer9.aBits1, aBrcVer9.aBits2+4 );
4510 : }
4511 184 : }
4512 :
4513 12 : void WW8AttributeOutput::FormatBox( const SvxBoxItem& rBox )
4514 : {
4515 : // Fly um Grafik-> keine Umrandung hier, da
4516 : // der GrafikHeader bereits die Umrandung hat
4517 12 : if ( !m_rWW8Export.bOutGrf )
4518 : {
4519 12 : bool bShadow = false;
4520 12 : const SfxPoolItem* pItem = m_rWW8Export.HasItem( RES_SHADOW );
4521 12 : if ( pItem )
4522 : {
4523 0 : const SvxShadowItem* p = (const SvxShadowItem*)pItem;
4524 0 : bShadow = ( p->GetLocation() != SVX_SHADOW_NONE )
4525 0 : && ( p->GetWidth() != 0 );
4526 : }
4527 :
4528 12 : m_rWW8Export.Out_SwFmtBox( rBox, bShadow );
4529 : }
4530 12 : }
4531 :
4532 0 : SwTwips WW8Export::CurrentPageWidth(SwTwips &rLeft, SwTwips &rRight) const
4533 : {
4534 0 : const SwFrmFmt* pFmt = pAktPageDesc ? &pAktPageDesc->GetMaster()
4535 0 : : &pDoc->GetPageDesc(0).GetMaster();
4536 :
4537 0 : const SvxLRSpaceItem& rLR = pFmt->GetLRSpace();
4538 0 : SwTwips nPageSize = pFmt->GetFrmSize().GetWidth();
4539 0 : rLeft = rLR.GetLeft();
4540 0 : rRight = rLR.GetRight();
4541 0 : return nPageSize;
4542 : }
4543 :
4544 0 : void WW8AttributeOutput::FormatColumns_Impl( sal_uInt16 nCols, const SwFmtCol & rCol, bool bEven, SwTwips nPageSize )
4545 : {
4546 : // CColumns
4547 0 : if ( m_rWW8Export.bWrtWW8 )
4548 0 : m_rWW8Export.InsUInt16( NS_sprm::LN_SCcolumns );
4549 : else
4550 0 : m_rWW8Export.pO->push_back( 144 );
4551 0 : m_rWW8Export.InsUInt16( nCols - 1 );
4552 :
4553 : // DxaColumns
4554 0 : if ( m_rWW8Export.bWrtWW8 )
4555 0 : m_rWW8Export.InsUInt16( NS_sprm::LN_SDxaColumns );
4556 : else
4557 0 : m_rWW8Export.pO->push_back( 145 );
4558 0 : m_rWW8Export.InsUInt16( rCol.GetGutterWidth( true ) );
4559 :
4560 : // LBetween
4561 0 : if ( m_rWW8Export.bWrtWW8 )
4562 0 : m_rWW8Export.InsUInt16( NS_sprm::LN_SLBetween );
4563 : else
4564 0 : m_rWW8Export.pO->push_back( 158 );
4565 0 : m_rWW8Export.pO->push_back( COLADJ_NONE == rCol.GetLineAdj( )? 0 : 1 );
4566 :
4567 0 : const SwColumns & rColumns = rCol.GetColumns( );
4568 :
4569 : // FEvenlySpaced
4570 0 : if ( m_rWW8Export.bWrtWW8 )
4571 0 : m_rWW8Export.InsUInt16( NS_sprm::LN_SFEvenlySpaced );
4572 : else
4573 0 : m_rWW8Export.pO->push_back( 138 );
4574 0 : m_rWW8Export.pO->push_back( bEven ? 1 : 0 );
4575 :
4576 0 : if ( !bEven )
4577 : {
4578 0 : for ( sal_uInt16 n = 0; n < nCols; ++n )
4579 : {
4580 : //sprmSDxaColWidth
4581 0 : if ( m_rWW8Export.bWrtWW8 )
4582 0 : m_rWW8Export.InsUInt16( NS_sprm::LN_SDxaColWidth );
4583 : else
4584 0 : m_rWW8Export.pO->push_back( 136 );
4585 0 : m_rWW8Export.pO->push_back( static_cast<sal_uInt8>(n) );
4586 : m_rWW8Export.InsUInt16( rCol.
4587 : CalcPrtColWidth( n,
4588 0 : ( sal_uInt16 ) nPageSize ) );
4589 :
4590 0 : if ( n + 1 != nCols )
4591 : {
4592 : //sprmSDxaColSpacing
4593 0 : if ( m_rWW8Export.bWrtWW8 )
4594 0 : m_rWW8Export.InsUInt16( NS_sprm::LN_SDxaColSpacing );
4595 : else
4596 0 : m_rWW8Export.pO->push_back( 137 );
4597 0 : m_rWW8Export.pO->push_back( static_cast<sal_uInt8>(n) );
4598 0 : m_rWW8Export.InsUInt16( rColumns[n].GetRight( ) +
4599 0 : rColumns[n + 1].GetLeft( ) );
4600 : }
4601 : }
4602 : }
4603 0 : }
4604 :
4605 68 : void AttributeOutputBase::FormatColumns( const SwFmtCol& rCol )
4606 : {
4607 68 : const SwColumns& rColumns = rCol.GetColumns();
4608 :
4609 68 : sal_uInt16 nCols = rColumns.size();
4610 68 : if ( 1 < nCols && !GetExport( ).bOutFlyFrmAttrs )
4611 : {
4612 : // dann besorge mal die Seitenbreite ohne Raender !!
4613 :
4614 40 : const SwFrmFmt* pFmt = GetExport( ).pAktPageDesc ? &GetExport( ).pAktPageDesc->GetMaster() : &const_cast<const SwDoc *>(GetExport( ).pDoc)->GetPageDesc(0).GetMaster();
4615 40 : const SvxFrameDirectionItem &frameDirection = pFmt->GetFrmDir();
4616 : SwTwips nPageSize;
4617 40 : if ( frameDirection.GetValue() == FRMDIR_VERT_TOP_RIGHT || frameDirection.GetValue() == FRMDIR_VERT_TOP_LEFT )
4618 : {
4619 0 : const SvxULSpaceItem &rUL = pFmt->GetULSpace();
4620 0 : nPageSize = pFmt->GetFrmSize().GetHeight();
4621 0 : nPageSize -= rUL.GetUpper() + rUL.GetLower();
4622 :
4623 0 : const SwFmtHeader *header = dynamic_cast<const SwFmtHeader *>(pFmt->GetAttrSet().GetItem(RES_HEADER));
4624 0 : if ( header )
4625 : {
4626 0 : const SwFrmFmt *headerFmt = header->GetHeaderFmt();
4627 0 : if (headerFmt)
4628 : {
4629 0 : nPageSize -= headerFmt->GetFrmSize().GetHeight();
4630 : }
4631 : }
4632 0 : const SwFmtFooter *footer = dynamic_cast<const SwFmtFooter *>(pFmt->GetAttrSet().GetItem(RES_FOOTER));
4633 0 : if ( footer )
4634 : {
4635 0 : const SwFrmFmt *footerFmt = footer->GetFooterFmt();
4636 0 : if ( footerFmt )
4637 : {
4638 0 : nPageSize -= footerFmt->GetFrmSize().GetHeight();
4639 : }
4640 : }
4641 : }
4642 : else
4643 : {
4644 40 : const SvxLRSpaceItem &rLR = pFmt->GetLRSpace();
4645 40 : nPageSize = pFmt->GetFrmSize().GetWidth();
4646 40 : nPageSize -= rLR.GetLeft() + rLR.GetRight();
4647 : //i120133: The Section width should consider page indent value.
4648 40 : nPageSize -= rCol.GetAdjustValue();
4649 :
4650 : }
4651 :
4652 : // Nachsehen, ob alle Spalten gleich sind
4653 40 : bool bEven = true;
4654 : sal_uInt16 n;
4655 40 : sal_uInt16 nColWidth = rCol.CalcPrtColWidth( 0, (sal_uInt16)nPageSize );
4656 68 : for ( n = 1; n < nCols; n++ )
4657 : {
4658 : short nDiff = nColWidth -
4659 40 : rCol.CalcPrtColWidth( n, (sal_uInt16)nPageSize );
4660 :
4661 40 : if ( nDiff > 10 || nDiff < -10 ) // Toleranz: 10 tw
4662 : {
4663 12 : bEven = false;
4664 12 : break;
4665 : }
4666 : }
4667 :
4668 40 : FormatColumns_Impl( nCols, rCol, bEven, nPageSize );
4669 : }
4670 68 : }
4671 :
4672 : // "Paragraphs together"
4673 58 : void WW8AttributeOutput::FormatKeep( const SvxFmtKeepItem& rKeep )
4674 : {
4675 : // sprmFKeepFollow
4676 58 : if ( m_rWW8Export.bWrtWW8 )
4677 58 : m_rWW8Export.InsUInt16( NS_sprm::LN_PFKeepFollow );
4678 : else
4679 0 : m_rWW8Export.pO->push_back( 8 );
4680 :
4681 58 : m_rWW8Export.pO->push_back( rKeep.GetValue() ? 1 : 0 );
4682 58 : }
4683 :
4684 : // exclude a paragraph from Line Numbering
4685 114 : void WW8AttributeOutput::FormatLineNumbering( const SwFmtLineNumber& rNumbering )
4686 : {
4687 : // sprmPFNoLineNumb
4688 114 : if( m_rWW8Export.bWrtWW8 )
4689 114 : m_rWW8Export.InsUInt16( NS_sprm::LN_PFNoLineNumb );
4690 : else
4691 0 : m_rWW8Export.pO->push_back( 14 );
4692 :
4693 114 : m_rWW8Export.pO->push_back( rNumbering.IsCount() ? 0 : 1 );
4694 114 : }
4695 :
4696 : /* File PARATR.HXX */
4697 :
4698 136 : void WW8AttributeOutput::ParaLineSpacing_Impl( short nSpace, short nMulti )
4699 : {
4700 : // sprmPDyaLine
4701 136 : if ( m_rWW8Export.bWrtWW8 )
4702 136 : m_rWW8Export.InsUInt16( NS_sprm::LN_PDyaLine );
4703 : else
4704 0 : m_rWW8Export.pO->push_back( 20 );
4705 :
4706 136 : m_rWW8Export.InsUInt16( nSpace );
4707 136 : m_rWW8Export.InsUInt16( nMulti );
4708 136 : }
4709 :
4710 7800 : void AttributeOutputBase::ParaLineSpacing( const SvxLineSpacingItem& rSpacing )
4711 : {
4712 7800 : short nSpace = 240, nMulti = 0;
4713 :
4714 7800 : switch ( rSpacing.GetLineSpaceRule() )
4715 : {
4716 : default:
4717 0 : break;
4718 : case SVX_LINE_SPACE_FIX: // Fix
4719 374 : nSpace = -(short)rSpacing.GetLineHeight();
4720 374 : break;
4721 : case SVX_LINE_SPACE_MIN: // At least
4722 612 : nSpace = (short)rSpacing.GetLineHeight();
4723 612 : break;
4724 : case SVX_LINE_SPACE_AUTO:
4725 : {
4726 6814 : if( rSpacing.GetInterLineSpaceRule() == SVX_INTER_LINE_SPACE_FIX ) // Leading
4727 : {
4728 : // gibt es aber nicht in WW - also wie kommt man an
4729 : // die MaxLineHeight heran?
4730 0 : nSpace = (short)rSpacing.GetInterLineSpace();
4731 : sal_uInt16 nScript =
4732 0 : i18n::ScriptType::LATIN;
4733 0 : const SwAttrSet *pSet = 0;
4734 0 : if ( GetExport().pOutFmtNode && GetExport().pOutFmtNode->ISA( SwFmt ) )
4735 : {
4736 0 : const SwFmt *pFmt = (const SwFmt*)( GetExport().pOutFmtNode );
4737 0 : pSet = &pFmt->GetAttrSet();
4738 : }
4739 0 : else if ( GetExport().pOutFmtNode && GetExport().pOutFmtNode->ISA( SwTxtNode ) )
4740 : {
4741 0 : const SwTxtNode* pNd = (const SwTxtNode*)GetExport().pOutFmtNode;
4742 0 : pSet = &pNd->GetSwAttrSet();
4743 0 : if ( g_pBreakIt->GetBreakIter().is() )
4744 : {
4745 0 : nScript = g_pBreakIt->GetBreakIter()->
4746 0 : getScriptType(pNd->GetTxt(), 0);
4747 : }
4748 : }
4749 : OSL_ENSURE( pSet, "No attrset for lineheight :-(" );
4750 0 : if ( pSet )
4751 : {
4752 0 : nSpace = nSpace + (short)( AttrSetToLineHeight( GetExport().pDoc->getIDocumentSettingAccess(),
4753 0 : *pSet, *Application::GetDefaultDevice(), nScript ) );
4754 : }
4755 : }
4756 : else // Proportional
4757 : {
4758 6814 : nSpace = (short)( ( 240L * rSpacing.GetPropLineSpace() ) / 100L );
4759 6814 : nMulti = 1;
4760 6814 : break;
4761 : }
4762 : }
4763 0 : break;
4764 : }
4765 : // if nSpace is negative, it is a fixed size in 1/20 of a point
4766 : // if nSpace is positive and nMulti is 1, it is 1/240 of a single line height
4767 : // otherwise, it is a minimum size in 1/20 of a point
4768 7800 : ParaLineSpacing_Impl( nSpace, nMulti );
4769 7800 : }
4770 :
4771 92 : void WW8AttributeOutput::ParaAdjust( const SvxAdjustItem& rAdjust )
4772 : {
4773 : // sprmPJc
4774 92 : sal_uInt8 nAdj = 255;
4775 92 : sal_uInt8 nAdjBiDi = 255;
4776 92 : switch ( rAdjust.GetAdjust() )
4777 : {
4778 : case SVX_ADJUST_LEFT:
4779 6 : nAdj = 0;
4780 6 : nAdjBiDi = 2;
4781 6 : break;
4782 : case SVX_ADJUST_RIGHT:
4783 10 : nAdj = 2;
4784 10 : nAdjBiDi = 0;
4785 10 : break;
4786 : case SVX_ADJUST_BLOCKLINE:
4787 : case SVX_ADJUST_BLOCK:
4788 14 : nAdj = nAdjBiDi = 3;
4789 14 : break;
4790 : case SVX_ADJUST_CENTER:
4791 62 : nAdj = nAdjBiDi = 1;
4792 62 : break;
4793 : default:
4794 92 : return; // not a supported Attribut
4795 : }
4796 :
4797 92 : if ( 255 != nAdj ) // supported Attribut?
4798 : {
4799 92 : if ( m_rWW8Export.bWrtWW8 )
4800 : {
4801 92 : m_rWW8Export.InsUInt16( NS_sprm::LN_PJc );
4802 92 : m_rWW8Export.pO->push_back( nAdj );
4803 :
4804 : /*
4805 : Sadly for left to right paragraphs both these values are the same,
4806 : for right to left paragraphs the bidi one is the reverse of the
4807 : normal one.
4808 : */
4809 92 : m_rWW8Export.InsUInt16( NS_sprm::LN_PJcExtra ); //bidi version ?
4810 92 : bool bBiDiSwap = false;
4811 92 : if ( m_rWW8Export.pOutFmtNode )
4812 : {
4813 90 : short nDirection = FRMDIR_HORI_LEFT_TOP;
4814 90 : if ( m_rWW8Export.pOutFmtNode->ISA( SwTxtNode ) )
4815 : {
4816 66 : SwPosition aPos(*(const SwCntntNode*)m_rWW8Export.pOutFmtNode);
4817 66 : nDirection = m_rWW8Export.pDoc->GetTextDirection(aPos);
4818 : }
4819 24 : else if ( m_rWW8Export.pOutFmtNode->ISA( SwTxtFmtColl ) )
4820 : {
4821 : const SwTxtFmtColl* pC =
4822 24 : (const SwTxtFmtColl*)m_rWW8Export.pOutFmtNode;
4823 : const SvxFrameDirectionItem &rItem =
4824 24 : ItemGet<SvxFrameDirectionItem>(*pC, RES_FRAMEDIR);
4825 24 : nDirection = rItem.GetValue();
4826 : }
4827 90 : if ( ( nDirection == FRMDIR_HORI_RIGHT_TOP ) ||
4828 0 : ( nDirection == FRMDIR_ENVIRONMENT && Application::GetSettings().GetLayoutRTL() ) )
4829 : {
4830 0 : bBiDiSwap = true;
4831 : }
4832 : }
4833 :
4834 92 : if ( bBiDiSwap )
4835 0 : m_rWW8Export.pO->push_back( nAdjBiDi );
4836 : else
4837 92 : m_rWW8Export.pO->push_back( nAdj );
4838 : }
4839 : else
4840 : {
4841 0 : m_rWW8Export.pO->push_back( 5 );
4842 0 : m_rWW8Export.pO->push_back( nAdj );
4843 : }
4844 : }
4845 : }
4846 :
4847 106 : void WW8AttributeOutput::FormatFrameDirection( const SvxFrameDirectionItem& rDirection )
4848 : {
4849 106 : if ( !m_rWW8Export.bWrtWW8 ) //8+ only
4850 106 : return;
4851 :
4852 106 : sal_uInt16 nTextFlow=0;
4853 106 : bool bBiDi = false;
4854 106 : short nDir = rDirection.GetValue();
4855 :
4856 106 : if ( nDir == FRMDIR_ENVIRONMENT )
4857 : {
4858 4 : if ( m_rWW8Export.bOutPageDescs )
4859 0 : nDir = m_rWW8Export.GetCurrentPageDirection();
4860 4 : else if ( m_rWW8Export.pOutFmtNode )
4861 : {
4862 4 : if ( m_rWW8Export.bOutFlyFrmAttrs ) //frame
4863 : {
4864 : nDir = m_rWW8Export.TrueFrameDirection(
4865 0 : *(const SwFrmFmt*)m_rWW8Export.pOutFmtNode );
4866 : }
4867 4 : else if ( m_rWW8Export.pOutFmtNode->ISA( SwCntntNode ) ) //pagagraph
4868 : {
4869 : const SwCntntNode* pNd =
4870 0 : (const SwCntntNode*)m_rWW8Export.pOutFmtNode;
4871 0 : SwPosition aPos( *pNd );
4872 0 : nDir = m_rWW8Export.pDoc->GetTextDirection( aPos );
4873 : }
4874 4 : else if ( m_rWW8Export.pOutFmtNode->ISA( SwTxtFmtColl ) )
4875 4 : nDir = FRMDIR_HORI_LEFT_TOP; //what else can we do :-(
4876 : }
4877 :
4878 4 : if ( nDir == FRMDIR_ENVIRONMENT )
4879 0 : nDir = FRMDIR_HORI_LEFT_TOP; //Set something
4880 : }
4881 :
4882 106 : switch ( nDir )
4883 : {
4884 : default:
4885 : //Can't get an unknown type here
4886 : OSL_FAIL("Unknown frame direction");
4887 : //fall-through
4888 : case FRMDIR_HORI_LEFT_TOP:
4889 106 : nTextFlow = 0;
4890 106 : break;
4891 : case FRMDIR_HORI_RIGHT_TOP:
4892 0 : nTextFlow = 0;
4893 0 : bBiDi = true;
4894 0 : break;
4895 : case FRMDIR_VERT_TOP_LEFT: //word doesn't have this
4896 : case FRMDIR_VERT_TOP_RIGHT:
4897 0 : nTextFlow = 1;
4898 0 : break;
4899 : }
4900 :
4901 106 : if ( m_rWW8Export.bOutPageDescs )
4902 : {
4903 40 : m_rWW8Export.InsUInt16( NS_sprm::LN_STextFlow );
4904 40 : m_rWW8Export.InsUInt16( nTextFlow );
4905 40 : m_rWW8Export.InsUInt16( NS_sprm::LN_SFBiDi );
4906 40 : m_rWW8Export.pO->push_back( bBiDi );
4907 : }
4908 66 : else if ( !m_rWW8Export.bOutFlyFrmAttrs ) //paragraph/style
4909 : {
4910 66 : m_rWW8Export.InsUInt16( NS_sprm::LN_PFBiDi );
4911 66 : m_rWW8Export.pO->push_back( bBiDi );
4912 : }
4913 : }
4914 :
4915 0 : void WW8AttributeOutput::ParaGrabBag(const SfxGrabBagItem& /*rItem*/)
4916 : {
4917 0 : }
4918 :
4919 0 : void WW8AttributeOutput::CharGrabBag(const SfxGrabBagItem& /*rItem*/)
4920 : {
4921 0 : }
4922 :
4923 26 : void WW8AttributeOutput::ParaOutlineLevel(const SfxUInt16Item& /*rItem*/)
4924 : {
4925 26 : }
4926 :
4927 : // "Separate paragraphs"
4928 6 : void WW8AttributeOutput::ParaSplit( const SvxFmtSplitItem& rSplit )
4929 : {
4930 : // sprmPFKeep
4931 6 : if ( m_rWW8Export.bWrtWW8 )
4932 6 : m_rWW8Export.InsUInt16( NS_sprm::LN_PFKeep );
4933 : else
4934 0 : m_rWW8Export.pO->push_back( 7 );
4935 6 : m_rWW8Export.pO->push_back( rSplit.GetValue() ? 0 : 1 );
4936 6 : }
4937 :
4938 : // Es wird nur das Item "SvxWidowItem" und nicht die Orphans uebersetzt,
4939 : // da es fuer beides im WW nur ein Attribut "Absatzkontrolle" gibt und
4940 : // im SW wahrscheinlich vom Anwender immer Beide oder keiner gesetzt werden.
4941 64 : void WW8AttributeOutput::ParaWidows( const SvxWidowsItem& rWidows )
4942 : {
4943 : // sprmPFWidowControl
4944 64 : if( m_rWW8Export.bWrtWW8 )
4945 64 : m_rWW8Export.InsUInt16( NS_sprm::LN_PFWidowControl );
4946 : else
4947 0 : m_rWW8Export.pO->push_back( 51 );
4948 64 : m_rWW8Export.pO->push_back( rWidows.GetValue() ? 1 : 0 );
4949 64 : }
4950 :
4951 : class SwWW8WrTabu
4952 : {
4953 : sal_uInt8* pDel; // DelArray
4954 : sal_uInt8* pAddPos; // AddPos-Array
4955 : sal_uInt8* pAddTyp; // AddTyp-Array
4956 : sal_uInt16 nAdd; // so viele Tabs kommen hinzu
4957 : sal_uInt16 nDel; // so viele Tabs fallen weg
4958 : public:
4959 : SwWW8WrTabu(sal_uInt16 nDelMax, sal_uInt16 nAddMax);
4960 : ~SwWW8WrTabu();
4961 :
4962 : void Add(const SvxTabStop &rTS, long nAdjustment);
4963 : void Del(const SvxTabStop &rTS, long nAdjustment);
4964 : void PutAll(WW8Export& rWW8Wrt);
4965 : };
4966 :
4967 94 : SwWW8WrTabu::SwWW8WrTabu(sal_uInt16 nDelMax, sal_uInt16 nAddMax)
4968 94 : : nAdd(0), nDel(0)
4969 : {
4970 94 : pDel = nDelMax ? new sal_uInt8[nDelMax * 2] : 0;
4971 94 : pAddPos = new sal_uInt8[nAddMax * 2];
4972 94 : pAddTyp = new sal_uInt8[nAddMax];
4973 94 : }
4974 :
4975 94 : SwWW8WrTabu::~SwWW8WrTabu()
4976 : {
4977 94 : delete[] pAddTyp;
4978 94 : delete[] pAddPos;
4979 94 : delete[] pDel;
4980 94 : }
4981 :
4982 : // Add( const SvxTabStop & rTS ) fuegt einen Tab in die WW-Struktur ein
4983 66 : void SwWW8WrTabu::Add(const SvxTabStop & rTS, long nAdjustment)
4984 : {
4985 : // Tab-Position eintragen
4986 66 : ShortToSVBT16(msword_cast<sal_Int16>(rTS.GetTabPos() + nAdjustment),
4987 132 : pAddPos + (nAdd * 2));
4988 :
4989 : // Tab-Typ eintragen
4990 66 : sal_uInt8 nPara = 0;
4991 66 : switch (rTS.GetAdjustment())
4992 : {
4993 : case SVX_TAB_ADJUST_RIGHT:
4994 32 : nPara = 2;
4995 32 : break;
4996 : case SVX_TAB_ADJUST_CENTER:
4997 24 : nPara = 1;
4998 24 : break;
4999 : case SVX_TAB_ADJUST_DECIMAL:
5000 : /*
5001 : Theres nothing we can do btw the decimal separator has been
5002 : customized, but if you think different remember that different
5003 : locales have different separators, i.e. german is a , while english
5004 : is a .
5005 : */
5006 0 : nPara = 3;
5007 0 : break;
5008 : default:
5009 10 : break;
5010 : }
5011 :
5012 66 : switch( rTS.GetFill() )
5013 : {
5014 : case '.': // dotted leader
5015 6 : nPara |= 1 << 3;
5016 6 : break;
5017 : case '_': // Single line leader
5018 0 : nPara |= 3 << 3;
5019 0 : break;
5020 : case '-': // hyphenated leader
5021 0 : nPara |= 2 << 3;
5022 0 : break;
5023 : case '=': // heavy line leader
5024 0 : nPara |= 4 << 3;
5025 0 : break;
5026 : }
5027 :
5028 66 : pAddTyp[nAdd] = nPara;
5029 66 : ++nAdd;
5030 66 : }
5031 :
5032 : // Del( const SvxTabStop & rTS ) fuegt einen zu loeschenden Tab
5033 : // in die WW-Struktur ein
5034 26 : void SwWW8WrTabu::Del(const SvxTabStop &rTS, long nAdjustment)
5035 : {
5036 : // Tab-Position eintragen
5037 26 : ShortToSVBT16(msword_cast<sal_Int16>(rTS.GetTabPos() + nAdjustment),
5038 52 : pDel + (nDel * 2));
5039 26 : ++nDel;
5040 26 : }
5041 :
5042 : // PutAll( WW8Export& rWW8Wrt ) schreibt das Attribut nach rWrt.pO
5043 94 : void SwWW8WrTabu::PutAll(WW8Export& rWrt)
5044 : {
5045 94 : if (!nAdd && !nDel) //It it's a no-op
5046 138 : return;
5047 : OSL_ENSURE(nAdd <= 255, "more than 255 added tabstops ?");
5048 : OSL_ENSURE(nDel <= 255, "more than 244 removed tabstops ?");
5049 50 : if (nAdd > 255)
5050 0 : nAdd = 255;
5051 50 : if (nDel > 255)
5052 0 : nDel = 255;
5053 :
5054 50 : sal_uInt16 nSiz = 2 * nDel + 3 * nAdd + 2;
5055 50 : if (nSiz > 255)
5056 0 : nSiz = 255;
5057 :
5058 50 : if (rWrt.bWrtWW8)
5059 50 : rWrt.InsUInt16(NS_sprm::LN_PChgTabsPapx);
5060 : else
5061 0 : rWrt.pO->push_back(15);
5062 : // cch eintragen
5063 50 : rWrt.pO->push_back(msword_cast<sal_uInt8>(nSiz));
5064 : // DelArr schreiben
5065 50 : rWrt.pO->push_back(msword_cast<sal_uInt8>(nDel));
5066 50 : rWrt.OutSprmBytes(pDel, nDel * 2);
5067 : // InsArr schreiben
5068 50 : rWrt.pO->push_back(msword_cast<sal_uInt8>(nAdd));
5069 50 : rWrt.OutSprmBytes(pAddPos, 2 * nAdd); // AddPosArray
5070 50 : rWrt.OutSprmBytes(pAddTyp, nAdd); // AddTypArray
5071 : }
5072 :
5073 42 : static void ParaTabStopAdd( WW8Export& rWrt,
5074 : const SvxTabStopItem& rTStops,
5075 : const long nLParaMgn )
5076 : {
5077 42 : SwWW8WrTabu aTab( 0, rTStops.Count());
5078 :
5079 84 : for( sal_uInt16 n = 0; n < rTStops.Count(); n++ )
5080 : {
5081 42 : const SvxTabStop& rTS = rTStops[n];
5082 : // Def-Tabs ignorieren
5083 42 : if (SVX_TAB_ADJUST_DEFAULT != rTS.GetAdjustment())
5084 0 : aTab.Add(rTS, nLParaMgn);
5085 : }
5086 42 : aTab.PutAll( rWrt );
5087 42 : }
5088 :
5089 2 : static bool lcl_IsEqual(long nOneLeft, const SvxTabStop &rOne,
5090 : long nTwoLeft, const SvxTabStop &rTwo)
5091 : {
5092 : return(
5093 2 : nOneLeft == nTwoLeft &&
5094 4 : rOne.GetAdjustment() == rTwo.GetAdjustment() &&
5095 6 : rOne.GetDecimal() == rTwo.GetDecimal() &&
5096 2 : rOne.GetFill() == rTwo.GetFill()
5097 2 : );
5098 : }
5099 :
5100 52 : static void ParaTabStopDelAdd( WW8Export& rWrt,
5101 : const SvxTabStopItem& rTStyle,
5102 : const long nLStypeMgn,
5103 : const SvxTabStopItem& rTNew,
5104 : const long nLParaMgn )
5105 : {
5106 52 : SwWW8WrTabu aTab(rTStyle.Count(), rTNew.Count());
5107 :
5108 52 : sal_uInt16 nO = 0; // rTStyle Index
5109 52 : sal_uInt16 nN = 0; // rTNew Index
5110 :
5111 : do {
5112 : const SvxTabStop* pTO;
5113 : long nOP;
5114 184 : if( nO < rTStyle.Count() ) // alt noch nicht am Ende ?
5115 : {
5116 68 : pTO = &rTStyle[ nO ];
5117 68 : nOP = pTO->GetTabPos() + nLStypeMgn;
5118 68 : if( SVX_TAB_ADJUST_DEFAULT == pTO->GetAdjustment() )
5119 : {
5120 38 : nO++; // Default-Tab ignorieren
5121 38 : continue;
5122 : }
5123 : }
5124 : else
5125 : {
5126 116 : pTO = 0;
5127 116 : nOP = LONG_MAX;
5128 : }
5129 :
5130 : const SvxTabStop* pTN;
5131 : long nNP;
5132 146 : if( nN < rTNew.Count() ) // neu noch nicht am Ende
5133 : {
5134 74 : pTN = &rTNew[ nN ];
5135 74 : nNP = pTN->GetTabPos() + nLParaMgn;
5136 74 : if( SVX_TAB_ADJUST_DEFAULT == pTN->GetAdjustment() )
5137 : {
5138 0 : nN++; // Default-Tab ignorieren
5139 0 : continue;
5140 : }
5141 : }
5142 : else
5143 : {
5144 72 : pTN = 0;
5145 72 : nNP = LONG_MAX;
5146 : }
5147 :
5148 146 : if( nOP == LONG_MAX && nNP == LONG_MAX )
5149 52 : break; // alles fertig
5150 :
5151 94 : if( nOP < nNP ) // naechster Tab ist alt
5152 : {
5153 26 : aTab.Del(*pTO, nLStypeMgn); // muss geloescht werden
5154 26 : nO++;
5155 : }
5156 68 : else if( nNP < nOP ) // naechster Tab ist neu
5157 : {
5158 66 : aTab.Add(*pTN, nLParaMgn); // muss eigefuegt werden
5159 66 : nN++;
5160 : }
5161 2 : else if (lcl_IsEqual(nOP, *pTO, nNP, *pTN)) // Tabs sind gleich:
5162 : {
5163 2 : nO++; // nichts zu tun
5164 2 : nN++;
5165 : }
5166 : else // Tabs selbe Pos, diff Typ
5167 : {
5168 0 : aTab.Del(*pTO, nLStypeMgn); // alten loeschen
5169 0 : aTab.Add(*pTN, nLParaMgn); // neuen einfuegen
5170 0 : nO++;
5171 0 : nN++;
5172 : }
5173 : } while( true );
5174 :
5175 52 : aTab.PutAll( rWrt );
5176 52 : }
5177 :
5178 94 : void WW8AttributeOutput::ParaTabStop( const SvxTabStopItem& rTabStops )
5179 : {
5180 94 : const bool bTabsRelativeToIndex = m_rWW8Export.pCurPam->GetDoc()->getIDocumentSettingAccess().get( IDocumentSettingAccess::TABS_RELATIVE_TO_INDENT );
5181 :
5182 94 : long nCurrentLeft = 0;
5183 94 : if ( bTabsRelativeToIndex )
5184 : {
5185 8 : const SfxPoolItem* pLR = m_rWW8Export.HasItem( RES_LR_SPACE );
5186 :
5187 8 : if ( pLR != NULL )
5188 0 : nCurrentLeft = static_cast<const SvxLRSpaceItem*>(pLR)->GetTxtLeft();
5189 : }
5190 :
5191 : // #i100264#
5192 168 : if ( m_rWW8Export.bStyDef &&
5193 126 : m_rWW8Export.pCurrentStyle != NULL &&
5194 32 : m_rWW8Export.pCurrentStyle->DerivedFrom() != NULL )
5195 : {
5196 32 : SvxTabStopItem aParentTabs( 0, 0, SVX_TAB_ADJUST_DEFAULT, RES_PARATR_TABSTOP );
5197 32 : const SwFmt *pParentStyle = m_rWW8Export.pCurrentStyle->DerivedFrom();
5198 : {
5199 32 : const SvxTabStopItem* pParentTabs = HasItem<SvxTabStopItem>( pParentStyle->GetAttrSet(), RES_PARATR_TABSTOP );
5200 32 : if ( pParentTabs )
5201 : {
5202 32 : aParentTabs.Insert( pParentTabs );
5203 : }
5204 : }
5205 :
5206 : // #i120938# - consider left indentation of style and its parent style
5207 32 : long nParentLeft = 0;
5208 32 : if ( bTabsRelativeToIndex )
5209 : {
5210 2 : const SvxLRSpaceItem &rStyleLR = ItemGet<SvxLRSpaceItem>( pParentStyle->GetAttrSet(), RES_LR_SPACE );
5211 2 : nParentLeft = rStyleLR.GetTxtLeft();
5212 : }
5213 :
5214 32 : ParaTabStopDelAdd( m_rWW8Export, aParentTabs, nParentLeft, rTabStops, nCurrentLeft );
5215 126 : return;
5216 : }
5217 :
5218 62 : const SvxTabStopItem* pStyleTabs = 0;
5219 62 : if ( !m_rWW8Export.bStyDef && m_rWW8Export.pStyAttr )
5220 : {
5221 20 : pStyleTabs = HasItem<SvxTabStopItem>( *m_rWW8Export.pStyAttr, RES_PARATR_TABSTOP );
5222 : }
5223 :
5224 62 : if ( !pStyleTabs )
5225 : {
5226 42 : ParaTabStopAdd(m_rWW8Export, rTabStops, nCurrentLeft);
5227 : }
5228 : else
5229 : {
5230 20 : long nStyleLeft = 0;
5231 20 : if ( bTabsRelativeToIndex )
5232 : {
5233 0 : const SvxLRSpaceItem &rStyleLR = ItemGet<SvxLRSpaceItem>(*m_rWW8Export.pStyAttr, RES_LR_SPACE);
5234 0 : nStyleLeft = rStyleLR.GetTxtLeft();
5235 : }
5236 :
5237 : ParaTabStopDelAdd( m_rWW8Export,
5238 : *pStyleTabs, nStyleLeft,
5239 20 : rTabStops, nCurrentLeft);
5240 : }
5241 : }
5242 :
5243 263710 : void AttributeOutputBase::OutputItem( const SfxPoolItem& rHt )
5244 : {
5245 : // FIXME maybe use 'item_cast', like 'item_cast<SvxCharHiddenItem>( rHt )'?
5246 263710 : switch ( rHt.Which() )
5247 : {
5248 : case RES_CHRATR_CASEMAP:
5249 648 : CharCaseMap( static_cast< const SvxCaseMapItem& >( rHt ) );
5250 648 : break;
5251 : case RES_CHRATR_COLOR:
5252 10292 : CharColor( static_cast< const SvxColorItem& >( rHt ) );
5253 10292 : break;
5254 : case RES_CHRATR_CONTOUR:
5255 22 : CharContour( static_cast< const SvxContourItem& >( rHt ) );
5256 22 : break;
5257 : case RES_CHRATR_CROSSEDOUT:
5258 210 : CharCrossedOut( static_cast< const SvxCrossedOutItem& >( rHt ) );
5259 210 : break;
5260 : case RES_CHRATR_ESCAPEMENT:
5261 524 : CharEscapement( static_cast< const SvxEscapementItem& >( rHt ) );
5262 524 : break;
5263 : case RES_CHRATR_FONT:
5264 16148 : CharFont( static_cast< const SvxFontItem& >( rHt ) );
5265 16148 : break;
5266 : case RES_CHRATR_FONTSIZE:
5267 20004 : CharFontSize( static_cast< const SvxFontHeightItem& >( rHt ) );
5268 20004 : break;
5269 : case RES_CHRATR_KERNING:
5270 762 : CharKerning( static_cast< const SvxKerningItem& >( rHt ) );
5271 762 : break;
5272 : case RES_CHRATR_LANGUAGE:
5273 5868 : CharLanguage( static_cast< const SvxLanguageItem& >( rHt ) );
5274 5868 : break;
5275 : case RES_CHRATR_POSTURE:
5276 3690 : CharPosture( static_cast< const SvxPostureItem& >( rHt ) );
5277 3690 : break;
5278 : case RES_CHRATR_SHADOWED:
5279 8 : CharShadow( static_cast< const SvxShadowedItem& >( rHt ) );
5280 8 : break;
5281 : case RES_CHRATR_UNDERLINE:
5282 1336 : CharUnderline( static_cast< const SvxUnderlineItem& >( rHt ) );
5283 1336 : break;
5284 : case RES_CHRATR_WEIGHT:
5285 8860 : CharWeight( static_cast< const SvxWeightItem& >( rHt ) );
5286 8860 : break;
5287 : case RES_CHRATR_AUTOKERN:
5288 3460 : CharAutoKern( static_cast< const SvxAutoKernItem& >( rHt ) );
5289 3460 : break;
5290 : case RES_CHRATR_BLINK:
5291 16 : CharAnimatedText( static_cast< const SvxBlinkItem& >( rHt ) );
5292 16 : break;
5293 : case RES_CHRATR_BACKGROUND:
5294 450 : CharBackground( static_cast< const SvxBrushItem& >( rHt ) );
5295 450 : break;
5296 :
5297 : case RES_CHRATR_CJK_FONT:
5298 8114 : CharFontCJK( static_cast< const SvxFontItem& >( rHt ) );
5299 8114 : break;
5300 : case RES_CHRATR_CJK_FONTSIZE:
5301 8 : CharFontSizeCJK( static_cast< const SvxFontHeightItem& >( rHt ) );
5302 8 : break;
5303 : case RES_CHRATR_CJK_LANGUAGE:
5304 4350 : CharLanguageCJK( static_cast< const SvxLanguageItem& >( rHt ) );
5305 4350 : break;
5306 : case RES_CHRATR_CJK_POSTURE:
5307 536 : CharPostureCJK( static_cast< const SvxPostureItem& >( rHt ) );
5308 536 : break;
5309 : case RES_CHRATR_CJK_WEIGHT:
5310 2462 : CharWeightCJK( static_cast< const SvxWeightItem& >( rHt ) );
5311 2462 : break;
5312 :
5313 : case RES_CHRATR_CTL_FONT:
5314 13950 : CharFontCTL( static_cast< const SvxFontItem& >( rHt ) );
5315 13950 : break;
5316 : case RES_CHRATR_CTL_FONTSIZE:
5317 17900 : CharFontSizeCTL( static_cast< const SvxFontHeightItem& >( rHt ) );
5318 17900 : break;
5319 : case RES_CHRATR_CTL_LANGUAGE:
5320 3760 : CharLanguageCTL( static_cast< const SvxLanguageItem& >( rHt ) );
5321 3760 : break;
5322 : case RES_CHRATR_CTL_POSTURE:
5323 2330 : CharPostureCTL( static_cast< const SvxPostureItem& >( rHt ) );
5324 2330 : break;
5325 : case RES_CHRATR_CTL_WEIGHT:
5326 3576 : CharWeightCTL( static_cast< const SvxWeightItem& >( rHt ) );
5327 3576 : break;
5328 :
5329 : case RES_CHRATR_ROTATE:
5330 36 : CharRotate( static_cast< const SvxCharRotateItem& >( rHt ) );
5331 36 : break;
5332 : case RES_CHRATR_EMPHASIS_MARK:
5333 30 : CharEmphasisMark( static_cast< const SvxEmphasisMarkItem& >( rHt ) );
5334 30 : break;
5335 : case RES_CHRATR_TWO_LINES:
5336 0 : CharTwoLines( static_cast< const SvxTwoLinesItem& >( rHt ) );
5337 0 : break;
5338 : case RES_CHRATR_SCALEW:
5339 22 : CharScaleWidth( static_cast< const SvxCharScaleWidthItem& >( rHt ) );
5340 22 : break;
5341 : case RES_CHRATR_RELIEF:
5342 20 : CharRelief( static_cast< const SvxCharReliefItem& >( rHt ) );
5343 20 : break;
5344 : case RES_CHRATR_HIDDEN:
5345 298 : CharHidden( static_cast< const SvxCharHiddenItem& >( rHt ) );
5346 298 : break;
5347 : case RES_CHRATR_BOX:
5348 158 : FormatCharBorder( static_cast< const SvxBoxItem& >( rHt ) );
5349 158 : break;
5350 : case RES_CHRATR_HIGHLIGHT:
5351 0 : CharHighlight( static_cast< const SvxBrushItem& >( rHt ) );
5352 0 : break;
5353 : case RES_CHRATR_BIDIRTL:
5354 860 : CharBidiRTL( static_cast< const SfxPoolItem& >( rHt ) );
5355 860 : break;
5356 : case RES_CHRATR_IDCTHINT:
5357 914 : CharIdctHint( static_cast< const SfxPoolItem& >( rHt ) );
5358 914 : break;
5359 : case RES_TXTATR_INETFMT:
5360 596 : TextINetFormat( static_cast< const SwFmtINetFmt& >( rHt ) );
5361 596 : break;
5362 : case RES_TXTATR_CHARFMT:
5363 2708 : TextCharFormat( static_cast< const SwFmtCharFmt& >( rHt ) );
5364 2708 : break;
5365 :
5366 : case RES_TXTATR_FIELD:
5367 : case RES_TXTATR_ANNOTATION:
5368 : case RES_TXTATR_INPUTFIELD:
5369 308 : TextField( static_cast< const SwFmtFld& >( rHt ) );
5370 308 : break;
5371 :
5372 : case RES_TXTATR_FLYCNT:
5373 558 : TextFlyContent( static_cast< const SwFmtFlyCnt& >( rHt ) );
5374 558 : break;
5375 : case RES_TXTATR_FTN:
5376 26 : TextFootnote( static_cast< const SwFmtFtn& >( rHt ) );
5377 26 : break;
5378 :
5379 : case RES_PARATR_LINESPACING:
5380 7800 : ParaLineSpacing( static_cast< const SvxLineSpacingItem& >( rHt ) );
5381 7800 : break;
5382 : case RES_PARATR_ADJUST:
5383 6448 : ParaAdjust( static_cast< const SvxAdjustItem& >( rHt ) );
5384 6448 : break;
5385 : case RES_PARATR_SPLIT:
5386 498 : ParaSplit( static_cast< const SvxFmtSplitItem& >( rHt ) );
5387 498 : break;
5388 : case RES_PARATR_WIDOWS:
5389 2060 : ParaWidows( static_cast< const SvxWidowsItem& >( rHt ) );
5390 2060 : break;
5391 : case RES_PARATR_TABSTOP:
5392 4994 : ParaTabStop( static_cast< const SvxTabStopItem& >( rHt ) );
5393 4994 : break;
5394 : case RES_PARATR_HYPHENZONE:
5395 1828 : ParaHyphenZone( static_cast< const SvxHyphenZoneItem& >( rHt ) );
5396 1828 : break;
5397 : case RES_PARATR_NUMRULE:
5398 1312 : ParaNumRule( static_cast< const SwNumRuleItem& >( rHt ) );
5399 1312 : break;
5400 : case RES_PARATR_SCRIPTSPACE:
5401 112 : ParaScriptSpace( static_cast< const SfxBoolItem& >( rHt ) );
5402 112 : break;
5403 : case RES_PARATR_HANGINGPUNCTUATION:
5404 328 : ParaHangingPunctuation( static_cast< const SfxBoolItem& >( rHt ) );
5405 328 : break;
5406 : case RES_PARATR_FORBIDDEN_RULES:
5407 104 : ParaForbiddenRules( static_cast< const SfxBoolItem& >( rHt ) );
5408 104 : break;
5409 : case RES_PARATR_VERTALIGN:
5410 176 : ParaVerticalAlign( static_cast< const SvxParaVertAlignItem& >( rHt ) );
5411 176 : break;
5412 : case RES_PARATR_SNAPTOGRID:
5413 140 : ParaSnapToGrid( static_cast< const SvxParaGridItem& >( rHt ) );
5414 140 : break;
5415 :
5416 : case RES_FRM_SIZE:
5417 1726 : FormatFrameSize( static_cast< const SwFmtFrmSize& >( rHt ) );
5418 1726 : break;
5419 : case RES_PAPER_BIN:
5420 2 : FormatPaperBin( static_cast< const SvxPaperBinItem& >( rHt ) );
5421 2 : break;
5422 : case RES_LR_SPACE:
5423 6318 : FormatLRSpace( static_cast< const SvxLRSpaceItem& >( rHt ) );
5424 6318 : break;
5425 : case RES_UL_SPACE:
5426 13908 : FormatULSpace( static_cast< const SvxULSpaceItem& >( rHt ) );
5427 13908 : break;
5428 : case RES_PAGEDESC:
5429 966 : FormatPageDescription( static_cast< const SwFmtPageDesc& >( rHt ) );
5430 966 : break;
5431 : case RES_BREAK:
5432 638 : FormatBreak( static_cast< const SvxFmtBreakItem& >( rHt ) );
5433 638 : break;
5434 : case RES_SURROUND:
5435 426 : FormatSurround( static_cast< const SwFmtSurround& >( rHt ) );
5436 426 : break;
5437 : case RES_VERT_ORIENT:
5438 426 : FormatVertOrientation( static_cast< const SwFmtVertOrient& >( rHt ) );
5439 426 : break;
5440 : case RES_HORI_ORIENT:
5441 426 : FormatHorizOrientation( static_cast< const SwFmtHoriOrient& >( rHt ) );
5442 426 : break;
5443 : case RES_ANCHOR:
5444 426 : FormatAnchor( static_cast< const SwFmtAnchor& >( rHt ) );
5445 426 : break;
5446 : case RES_BACKGROUND:
5447 154 : FormatBackground( static_cast< const SvxBrushItem& >( rHt ) );
5448 154 : break;
5449 : case XATTR_FILLSTYLE:
5450 2914 : FormatFillStyle( static_cast< const XFillStyleItem& >( rHt ) );
5451 2914 : break;
5452 : case XATTR_FILLGRADIENT:
5453 16 : FormatFillGradient( static_cast< const XFillGradientItem& >( rHt ) );
5454 16 : break;
5455 : case RES_BOX:
5456 830 : FormatBox( static_cast< const SvxBoxItem& >( rHt ) );
5457 830 : break;
5458 : case RES_COL:
5459 68 : FormatColumns( static_cast< const SwFmtCol& >( rHt ) );
5460 68 : break;
5461 : case RES_KEEP:
5462 2148 : FormatKeep( static_cast< const SvxFmtKeepItem& >( rHt ) );
5463 2148 : break;
5464 : case RES_TEXTGRID:
5465 1286 : FormatTextGrid( static_cast< const SwTextGridItem& >( rHt ) );
5466 1286 : break;
5467 : case RES_LINENUMBER:
5468 2250 : FormatLineNumbering( static_cast< const SwFmtLineNumber& >( rHt ) );
5469 2250 : break;
5470 : case RES_FRAMEDIR:
5471 3090 : FormatFrameDirection( static_cast< const SvxFrameDirectionItem& >( rHt ) );
5472 3090 : break;
5473 : case RES_PARATR_GRABBAG:
5474 1802 : ParaGrabBag(static_cast<const SfxGrabBagItem&>(rHt));
5475 1802 : break;
5476 : case RES_PARATR_OUTLINELEVEL:
5477 10284 : ParaOutlineLevel(static_cast<const SfxUInt16Item&>(rHt));
5478 10284 : break;
5479 : case RES_CHRATR_GRABBAG:
5480 10920 : CharGrabBag(static_cast<const SfxGrabBagItem&>(rHt));
5481 10920 : break;
5482 :
5483 : default:
5484 : SAL_INFO("sw.ww8", "Unhandled SfxPoolItem with id " << rHt.Which() );
5485 41068 : break;
5486 : }
5487 263710 : }
5488 :
5489 980 : void AttributeOutputBase::OutputStyleItemSet( const SfxItemSet& rSet, bool bDeep, bool bTestForDefault )
5490 : {
5491 : // based on OutputItemSet() from wrt_fn.cxx
5492 :
5493 980 : const SfxItemPool& rPool = *rSet.GetPool();
5494 980 : const SfxItemSet* pSet = &rSet;
5495 980 : if ( !pSet->Count() )
5496 : {
5497 0 : if ( !bDeep )
5498 0 : return;
5499 :
5500 0 : while ( 0 != ( pSet = pSet->GetParent() ) && !pSet->Count() )
5501 : ;
5502 :
5503 0 : if ( !pSet )
5504 0 : return;
5505 : }
5506 :
5507 : const SfxPoolItem* pItem;
5508 980 : if ( !bDeep || !pSet->GetParent() )
5509 : {
5510 : OSL_ENSURE( rSet.Count(), "Wurde doch schon behandelt oder?" );
5511 0 : SfxItemIter aIter( *pSet );
5512 0 : pItem = aIter.GetCurItem();
5513 0 : do {
5514 0 : OutputItem( *pItem );
5515 0 : } while ( !aIter.IsAtEnd() && 0 != ( pItem = aIter.NextItem() ) );
5516 : }
5517 : else
5518 : {
5519 980 : SfxWhichIter aIter( *pSet );
5520 980 : sal_uInt16 nWhich = aIter.FirstWhich();
5521 64680 : while ( nWhich )
5522 : {
5523 78528 : if ( SfxItemState::SET == pSet->GetItemState( nWhich, bDeep, &pItem ) &&
5524 8148 : ( !bTestForDefault ||
5525 272 : *pItem != rPool.GetDefaultItem( nWhich ) ||
5526 112 : ( pSet->GetParent() && *pItem != pSet->GetParent()->Get( nWhich ) ) ) )
5527 : {
5528 7876 : OutputItem( *pItem );
5529 : }
5530 62720 : nWhich = aIter.NextWhich();
5531 980 : }
5532 : }
5533 : }
5534 :
5535 158 : void AttributeOutputBase::FormatCharBorder( const SvxBoxItem& rBox )
5536 : {
5537 : // Get one of the borders (if there is any border then in docx also will be)
5538 158 : const SvxBorderLine* pBorderLine = 0;
5539 158 : sal_uInt16 nDist = 0;
5540 158 : if( rBox.GetTop() )
5541 : {
5542 24 : pBorderLine = rBox.GetTop();
5543 24 : nDist = rBox.GetDistance( BOX_LINE_TOP );
5544 : }
5545 134 : else if( rBox.GetLeft() )
5546 : {
5547 12 : pBorderLine = rBox.GetLeft();
5548 12 : nDist = rBox.GetDistance( BOX_LINE_LEFT );
5549 : }
5550 122 : else if( rBox.GetBottom() )
5551 : {
5552 0 : pBorderLine = rBox.GetBottom();
5553 0 : nDist = rBox.GetDistance( BOX_LINE_BOTTOM );
5554 : }
5555 122 : else if( rBox.GetRight() )
5556 : {
5557 0 : pBorderLine = rBox.GetRight();
5558 0 : nDist = rBox.GetDistance( BOX_LINE_RIGHT );
5559 : }
5560 :
5561 158 : if( pBorderLine )
5562 : {
5563 36 : const SfxPoolItem* pItem = GetExport().HasItem( RES_CHRATR_SHADOW );
5564 36 : const SvxShadowItem* pShadowItem = static_cast<const SvxShadowItem*>(pItem);
5565 : const bool bShadow =
5566 50 : pShadowItem && pShadowItem->GetLocation() != SVX_SHADOW_NONE &&
5567 50 : pShadowItem->GetWidth() > 0;
5568 :
5569 36 : CharBorder( pBorderLine, nDist, bShadow );
5570 : }
5571 158 : }
5572 :
5573 : /*
5574 : * This function is used to check if the current SwTxtNode (paragraph) has a redline object
5575 : * that is attached to the paragraph marker.
5576 : * This is done by checking if the range (SwPaM) of the redline is :
5577 : * - Start = the last character of the current paragraph
5578 : * - End = the first character of the next paragraph
5579 : */
5580 28680 : const SwRedlineData* AttributeOutputBase::GetParagraphMarkerRedline( const SwTxtNode& rNode, RedlineType_t aRedlineType)
5581 : {
5582 : // ToDo : this is not the most ideal ... should start maybe from 'nCurRedlinePos'
5583 29480 : for( sal_uInt16 nRedlinePos = 0; nRedlinePos < GetExport().pDoc->getIDocumentRedlineAccess().GetRedlineTbl().size(); ++nRedlinePos )
5584 : {
5585 808 : const SwRangeRedline* pRedl = GetExport().pDoc->getIDocumentRedlineAccess().GetRedlineTbl()[ nRedlinePos ];
5586 :
5587 : // Only check redlines that are of type 'Delete'
5588 808 : if ( pRedl->GetRedlineData().GetType() != aRedlineType )
5589 614 : continue;
5590 :
5591 194 : const SwPosition* pCheckedStt = pRedl->Start();
5592 194 : const SwPosition* pCheckedEnd = pRedl->End();
5593 :
5594 194 : if( pCheckedStt->nNode == rNode )
5595 : {
5596 36 : if ( !pCheckedEnd )
5597 0 : continue;
5598 :
5599 36 : sal_uLong uStartNodeIndex = pCheckedStt->nNode.GetIndex();
5600 36 : sal_uLong uStartCharIndex = pCheckedStt->nContent.GetIndex();
5601 36 : sal_uLong uEndNodeIndex = pCheckedEnd->nNode.GetIndex();
5602 36 : sal_uLong uEndCharIndex = pCheckedEnd->nContent.GetIndex();
5603 :
5604 : // Maybe add here a check that also the start & end of the redline is the entire paragraph
5605 82 : if ( ( uStartNodeIndex == uEndNodeIndex - 1 ) &&
5606 46 : ( uStartCharIndex == (sal_uLong)rNode.Len() ) &&
5607 : ( uEndCharIndex == 0)
5608 : )
5609 : {
5610 8 : return &( pRedl->GetRedlineData() );
5611 : }
5612 : }
5613 : }
5614 28672 : return NULL;
5615 102 : }
5616 :
5617 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|