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