merge the formfield patch from ooo-build
[ooovba.git] / sw / source / filter / ww8 / ww8atr.cxx
blobe379e44a65d6b1347992fc04f4641e7586265a7e
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: ww8atr.cxx,v $
10 * $Revision: 1.113.40.3 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
33 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
36 * This file contains methods for the WW8 output
37 * (nodes, attributes, formats und chars).
40 #include <hintids.hxx>
42 #include <vcl/svapp.hxx>
43 #include <vcl/salbtype.hxx>
44 #include <svtools/zformat.hxx>
45 #include <svtools/itemiter.hxx>
46 #include <svtools/whiter.hxx>
47 #include <svx/fontitem.hxx>
48 #include <svx/tstpitem.hxx>
49 #include <svx/adjitem.hxx>
50 #include <svx/spltitem.hxx>
51 #include <svx/widwitem.hxx>
52 #include <svx/lspcitem.hxx>
53 #include <svx/keepitem.hxx>
54 #include <svx/shaditem.hxx>
55 #include <svx/brshitem.hxx>
56 #include <svx/postitem.hxx>
57 #include <svx/wghtitem.hxx>
58 #include <svx/kernitem.hxx>
59 #include <svx/crsditem.hxx>
60 #include <svx/cmapitem.hxx>
61 #include <svx/wrlmitem.hxx>
62 #include <svx/udlnitem.hxx>
63 #include <svx/langitem.hxx>
64 #include <svx/escpitem.hxx>
65 #include <svx/fhgtitem.hxx>
66 #include <svx/colritem.hxx>
67 #include <svx/hyznitem.hxx>
68 #include <svx/brkitem.hxx>
69 #include <svx/lrspitem.hxx>
70 #include <svx/ulspitem.hxx>
71 #include <svx/boxitem.hxx>
72 #include <svx/cntritem.hxx>
73 #include <svx/shdditem.hxx>
74 #include <svx/akrnitem.hxx>
75 #include <svx/pbinitem.hxx>
76 #include <svx/emphitem.hxx>
77 #include <svx/twolinesitem.hxx>
78 #include <svx/charscaleitem.hxx>
79 #include <svx/charrotateitem.hxx>
80 #include <svx/charreliefitem.hxx>
81 #include <svx/paravertalignitem.hxx>
82 #include <svx/pgrditem.hxx>
83 #include <svx/frmdiritem.hxx>
84 #include <svx/blnkitem.hxx>
85 #include <svx/charhiddenitem.hxx>
86 #include <svx/paperinf.hxx>
87 #include <fmtfld.hxx>
88 #include <fchrfmt.hxx>
89 #include <fmtfsize.hxx>
90 #include <fmtpdsc.hxx>
91 #include <fmtornt.hxx>
92 #include <fmtanchr.hxx>
93 #include <fmtclds.hxx>
94 #include <fmtsrnd.hxx>
95 #include <fmtftn.hxx>
96 #include <fmtflcnt.hxx>
97 #include <frmatr.hxx>
98 #include <swtable.hxx>
99 #include <fmtinfmt.hxx>
100 #include <txtfld.hxx>
101 #include <txtftn.hxx>
102 #include <poolfmt.hxx>
103 #include <doc.hxx> // Doc for footnotes
104 #include <pam.hxx>
105 #include <paratr.hxx>
106 #include <fldbas.hxx> // for SwField
107 #include <docufld.hxx> // for SwField
108 #include <expfld.hxx>
109 #include <pagedesc.hxx> // for SwPageDesc
110 #include <flddat.hxx> // for Date fields
111 #include <ndtxt.hxx> // for Numrules
112 #include <swrect.hxx>
113 #include <reffld.hxx>
114 #include <ftninfo.hxx>
115 #include <charfmt.hxx>
116 #include <section.hxx>
117 #include <lineinfo.hxx>
118 #include <fmtline.hxx>
119 #include <tox.hxx>
120 #include <fmtftntx.hxx>
121 #include <breakit.hxx>
122 #include <com/sun/star/i18n/ScriptType.hdl>
123 #include <unotools/localedatawrapper.hxx>
124 #include <tgrditem.hxx>
125 #include <flddropdown.hxx>
126 #include <chpfld.hxx>
127 #include <fmthdft.hxx>
129 #include <writerfilter/doctok/sprmids.hxx>
131 #if OSL_DEBUG_LEVEL > 1
132 # include <fmtcntnt.hxx>
133 #endif
134 #include "writerhelper.hxx"
135 #include "writerwordglue.hxx"
136 #include "wrtww8.hxx"
137 #include "ww8par.hxx"
138 #include "ww8attributeoutput.hxx"
139 #include "fields.hxx"
140 #include <vcl/outdev.hxx>
141 #include <i18npool/mslangid.hxx>
143 using namespace ::com::sun::star;
144 using namespace nsFieldFlags;
145 using namespace nsSwDocInfoSubType;
148 * um nicht immer wieder nach einem Update festzustellen, das irgendwelche
149 * Hint-Ids dazugekommen sind, wird hier definiert, die Groesse der Tabelle
150 * definiert und mit der akt. verglichen. Bei unterschieden wird der
151 * Compiler schon meckern.
153 * diese Section und die dazugeherigen Tabellen muessen in folgenden Files
154 * gepflegt werden: rtf\rtfatr.cxx, sw6\sw6atr.cxx, w4w\w4watr.cxx
157 #if !defined(MSC) && !defined(UNX) && !defined(PPC) && !defined(CSET) && !defined(__MWERKS__) && !defined(WTC) && !defined(__MINGW32__) && !defined(OS2)
159 #define ATTRFNTAB_SIZE 130
160 #if ATTRFNTAB_SIZE != POOLATTR_END - POOLATTR_BEGIN
161 # error "Attribut-Tabelle ist ungueltigt. Wurden neue Hint-ID's zugefuegt ??"
162 #endif
164 #define NODETAB_SIZE 3
165 #if NODETAB_SIZE != RES_NODE_END - RES_NODE_BEGIN
166 # error "Node-Tabelle ist ungueltigt. Wurden neue Hint-ID's zugefuegt ??"
167 #endif
169 #endif
171 using namespace sw::util;
172 using namespace sw::types;
174 bool WW8Export::CollapseScriptsforWordOk( USHORT nScript, USHORT nWhich )
176 bool bRet = true;
177 if ( nScript == i18n::ScriptType::ASIAN )
179 //for asian in ww8, there is only one fontsize
180 //and one fontstyle (posture/weight) for ww6
181 //there is the additional problem that there
182 //is only one font setting for all three scripts
183 switch ( nWhich )
185 case RES_CHRATR_FONTSIZE:
186 case RES_CHRATR_POSTURE:
187 case RES_CHRATR_WEIGHT:
188 bRet = false;
189 break;
190 case RES_CHRATR_LANGUAGE:
191 case RES_CHRATR_CTL_FONT:
192 case RES_CHRATR_CTL_FONTSIZE:
193 case RES_CHRATR_CTL_LANGUAGE:
194 case RES_CHRATR_CTL_POSTURE:
195 case RES_CHRATR_CTL_WEIGHT:
196 if (bWrtWW8 == 0)
197 bRet = false;
198 default:
199 break;
202 else if ( nScript == i18n::ScriptType::COMPLEX )
204 //Complex is ok in ww8, but for ww6 there is only
205 //one font, one fontsize, one fontsize (weight/posture)
206 //and only one language
207 if ( bWrtWW8 == 0 )
209 switch ( nWhich )
211 case RES_CHRATR_CJK_FONT:
212 case RES_CHRATR_CJK_FONTSIZE:
213 case RES_CHRATR_CJK_POSTURE:
214 case RES_CHRATR_CJK_WEIGHT:
215 case RES_CHRATR_CJK_LANGUAGE:
216 case RES_CHRATR_FONT:
217 case RES_CHRATR_FONTSIZE:
218 case RES_CHRATR_POSTURE:
219 case RES_CHRATR_WEIGHT:
220 case RES_CHRATR_LANGUAGE:
221 bRet = false;
222 break;
223 default:
224 break;
228 else
230 //for western in ww8, there is only one fontsize
231 //and one fontstyle (posture/weight) for ww6
232 //there is the additional problem that there
233 //is only one font setting for all three scripts
234 switch ( nWhich )
236 case RES_CHRATR_CJK_FONTSIZE:
237 case RES_CHRATR_CJK_POSTURE:
238 case RES_CHRATR_CJK_WEIGHT:
239 bRet = false;
240 break;
241 case RES_CHRATR_CJK_LANGUAGE:
242 case RES_CHRATR_CTL_FONT:
243 case RES_CHRATR_CTL_FONTSIZE:
244 case RES_CHRATR_CTL_LANGUAGE:
245 case RES_CHRATR_CTL_POSTURE:
246 case RES_CHRATR_CTL_WEIGHT:
247 if ( bWrtWW8 == 0 )
248 bRet = false;
249 default:
250 break;
253 return bRet;
256 //------------------------------------------------------------
257 // Hilfsroutinen fuer Styles
258 //------------------------------------------------------------
260 void MSWordExportBase::ExportPoolItemsToCHP( sw::PoolItems &rItems, USHORT nScript )
262 sw::cPoolItemIter aEnd = rItems.end();
263 for ( sw::cPoolItemIter aI = rItems.begin(); aI != aEnd; ++aI )
265 const SfxPoolItem *pItem = aI->second;
266 USHORT nWhich = pItem->Which();
267 if ( ( isCHRATR( nWhich ) || isTXTATR( nWhich ) ) && CollapseScriptsforWordOk( nScript, nWhich ) )
269 AttrOutput().OutputItem( *pItem );
275 * Format wie folgt ausgeben:
276 * - gebe die Attribute aus; ohne Parents!
279 void MSWordExportBase::OutputItemSet( const SfxItemSet& rSet, bool bPapFmt, bool bChpFmt, USHORT nScript )
281 if ( rSet.Count() )
283 const SfxPoolItem* pItem;
284 pISet = &rSet; // fuer Doppel-Attribute
286 // If frame dir is set, but not adjust, then force adjust as well
287 if ( bPapFmt && SFX_ITEM_SET == rSet.GetItemState( RES_FRAMEDIR, false ) )
289 // No explicit adjust set ?
290 if ( SFX_ITEM_SET != rSet.GetItemState( RES_PARATR_ADJUST, false ) )
292 if ( 0 != ( pItem = rSet.GetItem( RES_PARATR_ADJUST ) ) )
294 // then set the adjust used by the parent format
295 AttrOutput().OutputItem( *pItem );
300 if ( bPapFmt && SFX_ITEM_SET == rSet.GetItemState( RES_PARATR_NUMRULE, false, &pItem ) )
302 AttrOutput().OutputItem( *pItem );
304 // switch off the numerbering?
305 if ( !( (SwNumRuleItem*)pItem )->GetValue().Len() &&
306 SFX_ITEM_SET != rSet.GetItemState( RES_LR_SPACE, false) &&
307 SFX_ITEM_SET == rSet.GetItemState( RES_LR_SPACE, true, &pItem ) )
309 // the set the LR-Space of the parentformat!
310 AttrOutput().OutputItem( *pItem );
314 sw::PoolItems aItems;
315 GetPoolItems( rSet, aItems );
316 if ( bChpFmt )
317 ExportPoolItemsToCHP(aItems, nScript);
319 if ( bPapFmt )
321 sw::cPoolItemIter aEnd = aItems.end();
322 for ( sw::cPoolItemIter aI = aItems.begin(); aI != aEnd; ++aI )
324 pItem = aI->second;
325 USHORT nWhich = pItem->Which();
326 if ( nWhich >= RES_PARATR_BEGIN && nWhich < RES_FRMATR_END && nWhich != RES_PARATR_NUMRULE)
327 AttrOutput().OutputItem( *pItem );
330 pISet = 0; // fuer Doppel-Attribute
334 void MSWordExportBase::GatherChapterFields()
336 //If the header/footer contains a chapter field
337 SwClientIter aIter(*pDoc->GetSysFldType(RES_CHAPTERFLD));
338 const SwClient *pField = aIter.First(TYPE(SwFmtFld));
339 while (pField)
341 const SwFmtFld* pFld = (const SwFmtFld*)(pField);
342 if (const SwTxtFld *pTxtFld = pFld->GetTxtFld())
344 const SwTxtNode &rTxtNode = pTxtFld->GetTxtNode();
345 maChapterFieldLocs.push_back(rTxtNode.GetIndex());
347 pField = aIter.Next();
351 bool MSWordExportBase::CntntContainsChapterField(const SwFmtCntnt &rCntnt) const
353 bool bRet = false;
354 if ( const SwNodeIndex* pSttIdx = rCntnt.GetCntntIdx() )
356 SwNodeIndex aIdx( *pSttIdx, 1 );
357 SwNodeIndex aEnd( *pSttIdx->GetNode().EndOfSectionNode() );
358 ULONG nStart = aIdx.GetIndex();
359 ULONG nEnd = aEnd.GetIndex();
360 //If the header/footer contains a chapter field
361 mycCFIter aIEnd = maChapterFieldLocs.end();
362 for ( mycCFIter aI = maChapterFieldLocs.begin(); aI != aIEnd; ++aI )
364 if ( ( nStart <= *aI ) && ( *aI <= nEnd ) )
366 bRet = true;
367 break;
371 return bRet;
374 bool MSWordExportBase::FmtHdFtContainsChapterField(const SwFrmFmt &rFmt) const
376 if ( maChapterFieldLocs.empty() )
377 return false;
379 const SwFrmFmt *pFmt = 0;
381 pFmt = rFmt.GetHeader().GetHeaderFmt();
382 if ( pFmt && CntntContainsChapterField( pFmt->GetCntnt() ) )
383 return true;
385 pFmt = rFmt.GetFooter().GetFooterFmt();
386 if ( pFmt && CntntContainsChapterField( pFmt->GetCntnt() ) )
387 return true;
389 return false;
392 bool MSWordExportBase::SetAktPageDescFromNode(const SwNode &rNd)
394 bool bNewPageDesc = false;
395 const SwPageDesc* pCurrent = SwPageDesc::GetPageDescOfNode(rNd);
396 ASSERT(pCurrent && pAktPageDesc, "Not possible surely");
397 if (pAktPageDesc && pCurrent)
399 if (pCurrent != pAktPageDesc)
401 if (pAktPageDesc->GetFollow() != pCurrent)
402 bNewPageDesc = true;
403 else
405 const SwFrmFmt& rTitleFmt = pAktPageDesc->GetMaster();
406 const SwFrmFmt& rFollowFmt = pCurrent->GetMaster();
408 bNewPageDesc = !IsPlausableSingleWordSection(rTitleFmt,
409 rFollowFmt);
411 pAktPageDesc = pCurrent;
413 else
415 const SwFrmFmt &rFmt = pCurrent->GetMaster();
416 bNewPageDesc = FmtHdFtContainsChapterField(rFmt);
419 return bNewPageDesc;
422 // Da WW nur Break-After ( Pagebreak und Sectionbreaks ) kennt, im SW aber
423 // Bagebreaks "vor" und "nach" und Pagedescs nur "vor" existieren, werden
424 // die Breaks 2* durchgeklimpert, naemlich vor und hinter jeder Zeile.
425 // Je nach BreakTyp werden sie vor oder nach der Zeile gesetzt.
426 // Es duerfen nur Funktionen gerufen werden, die nicht in den
427 // Ausgabebereich pO schreiben, da dieser nur einmal fuer CHP und PAP existiert
428 // und damit im falschen landen wuerden.
429 void MSWordExportBase::OutputSectionBreaks( const SfxItemSet *pSet, const SwNode& rNd )
431 if ( bStyDef || bOutKF || bInWriteEscher || bOutPageDescs )
432 return;
434 bBreakBefore = true;
436 bool bNewPageDesc = false;
437 const SfxPoolItem* pItem=0;
438 const SwFmtPageDesc *pPgDesc=0;
440 //Output a sectionbreak if theres a new pagedesciptor. otherwise output a
441 //pagebreak if there is a pagebreak here, unless the new page (follow
442 //style) is different to the current one, in which case plump for a
443 //section.
444 bool bBreakSet = false;
446 if ( pSet && pSet->Count() )
448 if ( SFX_ITEM_SET == pSet->GetItemState( RES_PAGEDESC, false, &pItem )
449 && ( (SwFmtPageDesc*)pItem )->GetRegisteredIn() )
451 bBreakSet = true;
452 bNewPageDesc = true;
453 pPgDesc = (const SwFmtPageDesc*)pItem;
454 pAktPageDesc = pPgDesc->GetPageDesc();
456 else if ( SFX_ITEM_SET == pSet->GetItemState( RES_BREAK, false, &pItem ) )
458 // --> FME 2007-05-30 #146867# Word does not like hard break attributes in some table cells
459 bool bRemoveHardBreakInsideTable = false;
460 if ( bOutTable )
462 const SwTableNode* pTableNode = rNd.FindTableNode();
463 if ( pTableNode )
465 const SwTableBox* pBox = rNd.GetTblBox();
466 const SwTableLine* pLine = pBox ? pBox->GetUpper() : 0;
467 // but only for non-complex tables
468 if ( pLine && !pLine->GetUpper() )
470 // check if box is not first in that line:
471 if ( 0 < pLine->GetTabBoxes().GetPos( pBox ) && pBox->GetSttNd() )
473 bRemoveHardBreakInsideTable = true;
478 // <--
480 bBreakSet = true;
482 if ( !bRemoveHardBreakInsideTable )
484 ASSERT(pAktPageDesc, "should not be possible");
486 If because of this pagebreak the page desc following the page
487 break is the follow style of the current page desc then output a
488 section break using that style instead. At least in those cases
489 we end up with the same style in word and writer, nothing can be
490 done when it happens when we get a new pagedesc because we
491 overflow from the first page style.
493 if ( pAktPageDesc )
495 // --> OD 2007-05-30 #i76301#
496 // assure that there is a page break before set at the node.
497 const SvxFmtBreakItem* pBreak = dynamic_cast<const SvxFmtBreakItem*>(pItem);
498 if ( pBreak &&
499 pBreak->GetBreak() == SVX_BREAK_PAGE_BEFORE )
501 bNewPageDesc = SetAktPageDescFromNode( rNd );
503 // <--
505 if ( !bNewPageDesc )
506 AttrOutput().OutputItem( *pItem );
512 #i9301#
513 No explicit page break, lets see if the style had one and we've moved to a
514 new page style because of it, if we have to then we take the opportunity to
515 set the equivalent word section here. We *could* do it for every paragraph
516 that moves onto a new page because of layout, but that would be insane.
518 bool bHackInBreak = false;
519 if ( !bBreakSet )
521 if ( const SwCntntNode *pNd = rNd.GetCntntNode() )
523 const SvxFmtBreakItem &rBreak =
524 ItemGet<SvxFmtBreakItem>( *pNd, RES_BREAK );
525 if ( rBreak.GetBreak() == SVX_BREAK_PAGE_BEFORE )
526 bHackInBreak = true;
527 else
528 { // Even a pagedesc item is set, the break item can be set 'NONE',
529 // but a pagedesc item is an implicit page break before...
530 const SwFmtPageDesc &rPageDesc =
531 ItemGet<SwFmtPageDesc>( *pNd, RES_PAGEDESC );
532 if ( rPageDesc.GetRegisteredIn() )
533 bHackInBreak = true;
538 if ( bHackInBreak )
540 ASSERT( pAktPageDesc, "should not be possible" );
541 if ( pAktPageDesc )
542 bNewPageDesc = SetAktPageDescFromNode( rNd );
545 if ( bNewPageDesc && pAktPageDesc )
547 PrepareNewPageDesc( pSet, rNd, pPgDesc, pAktPageDesc );
549 bBreakBefore = false;
552 // --> OD 2007-05-29 #i76300#
553 bool MSWordExportBase::OutputFollowPageDesc( const SfxItemSet* pSet, const SwTxtNode* pNd )
555 bool bRet = false;
557 if ( pNd &&
558 pAktPageDesc &&
559 pAktPageDesc != pAktPageDesc->GetFollow() )
561 PrepareNewPageDesc( pSet, *pNd, 0, pAktPageDesc->GetFollow() );
562 bRet = true;
565 return bRet;
568 const SwSectionFmt* MSWordExportBase::GetSectionFormat( const SwNode& rNd ) const
570 const SwSectionFmt* pFmt = NULL;
571 const SwSectionNode* pSect = rNd.FindSectionNode();
572 if ( pSect &&
573 CONTENT_SECTION == pSect->GetSection().GetType() )
575 pFmt = pSect->GetSection().GetFmt();
578 return pFmt;
581 ULONG MSWordExportBase::GetSectionLineNo( const SfxItemSet* pSet, const SwNode& rNd ) const
583 const SwFmtLineNumber* pNItem = 0;
584 if ( pSet )
586 pNItem = &( ItemGet<SwFmtLineNumber>( *pSet, RES_LINENUMBER ) );
588 else if ( const SwCntntNode *pNd = rNd.GetCntntNode() )
590 pNItem = &( ItemGet<SwFmtLineNumber>( *pNd, RES_LINENUMBER ) );
593 return pNItem? pNItem->GetStartValue() : 0;
596 void WW8Export::PrepareNewPageDesc( const SfxItemSet*pSet,
597 const SwNode& rNd,
598 const SwFmtPageDesc* pNewPgDescFmt,
599 const SwPageDesc* pNewPgDesc )
601 // Die PageDescs werden beim Auftreten von PageDesc-Attributen nur in
602 // WW8Writer::pSepx mit der entsprechenden Position eingetragen. Das
603 // Aufbauen und die Ausgabe der am PageDesc haengenden Attribute und
604 // Kopf/Fusszeilen passiert nach dem Haupttext und seinen Attributen.
606 ULONG nFcPos = ReplaceCr( msword::PageBreak ); // Page/Section-Break
608 // tatsaechlich wird hier NOCH NICHTS ausgegeben, sondern
609 // nur die Merk-Arrays aCps, aSects entsprechend ergaenzt
610 if ( !nFcPos )
611 return;
613 const SwSectionFmt* pFmt = GetSectionFormat( rNd );
614 const ULONG nLnNm = GetSectionLineNo( pSet, rNd );
616 ASSERT( pNewPgDescFmt || pNewPgDesc, "Neither page desc format nor page desc provided." );
618 if ( pNewPgDescFmt )
620 pSepx->AppendSep( Fc2Cp( nFcPos ), *pNewPgDescFmt, rNd, pFmt, nLnNm );
622 else if ( pNewPgDesc )
624 pSepx->AppendSep( Fc2Cp( nFcPos ), pNewPgDesc, rNd, pFmt, nLnNm );
628 void MSWordExportBase::CorrectTabStopInSet( SfxItemSet& rSet, USHORT nAbsLeft )
630 const SvxTabStopItem *pItem =
631 sw::util::HasItem<SvxTabStopItem>( rSet, RES_PARATR_TABSTOP );
633 if ( pItem )
635 // dann muss das fuer die Ausgabe korrigiert werden
636 SvxTabStopItem aTStop(*pItem);
637 for ( USHORT nCnt = 0; nCnt < aTStop.Count(); ++nCnt )
639 SvxTabStop& rTab = (SvxTabStop&)aTStop[ nCnt ];
640 if ( SVX_TAB_ADJUST_DEFAULT != rTab.GetAdjustment() &&
641 rTab.GetTabPos() >= nAbsLeft )
643 rTab.GetTabPos() -= nAbsLeft;
645 else
647 aTStop.Remove( nCnt );
648 --nCnt;
651 rSet.Put( aTStop );
655 BYTE WW8Export::GetNumId( USHORT eNumType )
657 BYTE nRet = 0;
658 switch( eNumType )
660 case SVX_NUM_CHARS_UPPER_LETTER:
661 case SVX_NUM_CHARS_UPPER_LETTER_N: nRet = 3; break;
662 case SVX_NUM_CHARS_LOWER_LETTER:
663 case SVX_NUM_CHARS_LOWER_LETTER_N: nRet = 4; break;
664 case SVX_NUM_ROMAN_UPPER: nRet = 1; break;
665 case SVX_NUM_ROMAN_LOWER: nRet = 2; break;
667 case SVX_NUM_BITMAP:
668 case SVX_NUM_CHAR_SPECIAL: nRet = 23; break;
670 // nix, macht WW undokumentiert auch so
671 case SVX_NUM_NUMBER_NONE: nRet = 0xff; break;
673 return nRet;
676 void WW8AttributeOutput::OutlineNumbering( BYTE nLvl, const SwNumFmt &rNFmt, const SwFmt &rFmt )
678 if ( nLvl >= WW8ListManager::nMaxLevel )
679 nLvl = WW8ListManager::nMaxLevel-1;
681 if ( m_rWW8Export.bWrtWW8 )
683 // write sprmPOutLvl sprmPIlvl and sprmPIlfo
684 SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_POutLvl );
685 m_rWW8Export.pO->Insert( nLvl, m_rWW8Export.pO->Count() );
686 SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_PIlvl );
687 m_rWW8Export.pO->Insert( nLvl, m_rWW8Export.pO->Count() );
688 SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_PIlfo );
689 SwWW8Writer::InsUInt16( *m_rWW8Export.pO,
690 1 + m_rWW8Export.GetId( *m_rWW8Export.pDoc->GetOutlineNumRule() ) );
692 else
694 m_rWW8Export.Out_SwNumLvl( nLvl );
695 // --> OD 2008-06-03 #i86652#
696 // if (rNFmt.GetAbsLSpace())
697 if ( rNFmt.GetPositionAndSpaceMode() ==
698 SvxNumberFormat::LABEL_WIDTH_AND_POSITION &&
699 rNFmt.GetAbsLSpace() )
700 // <--
702 SwNumFmt aNumFmt( rNFmt );
703 const SvxLRSpaceItem& rLR =
704 ItemGet<SvxLRSpaceItem>( rFmt, RES_LR_SPACE );
706 aNumFmt.SetAbsLSpace( writer_cast<short>(
707 aNumFmt.GetAbsLSpace() + rLR.GetLeft() ) );
708 m_rWW8Export.Out_NumRuleAnld(
709 *m_rWW8Export.pDoc->GetOutlineNumRule(),
710 aNumFmt, nLvl );
712 else
713 m_rWW8Export.Out_NumRuleAnld(
714 *m_rWW8Export.pDoc->GetOutlineNumRule(),
715 rNFmt, nLvl );
719 // --> OD 2007-06-04 #i77805#
720 bool WW8Export::DisallowInheritingOutlineNumbering(const SwFmt &rFmt)
722 bool bRet( false );
724 //If there is no numbering on this fmt, but its parent was outline
725 //numbered, then in writer this is no inheritied, but in word it would
726 //be, so we must export "no numbering" and "body level" to make word
727 //behave like writer (see #i25755)
728 if (SFX_ITEM_SET != rFmt.GetItemState(RES_PARATR_NUMRULE, false))
730 if (const SwFmt *pParent = rFmt.DerivedFrom())
732 if (((const SwTxtFmtColl*)pParent)->IsAssignedToListLevelOfOutlineStyle())
734 if (bWrtWW8)
736 SwWW8Writer::InsUInt16(*pO, NS_sprm::LN_POutLvl);
737 pO->Insert(BYTE(9), pO->Count());
738 SwWW8Writer::InsUInt16(*pO, NS_sprm::LN_PIlfo);
739 SwWW8Writer::InsUInt16(*pO, 0);
741 bRet = true;
743 /*whats the winword 6 way to do this ?*/
748 return bRet;
750 // <--
752 void MSWordExportBase::OutputFormat( const SwFmt& rFmt, bool bPapFmt, bool bChpFmt, bool bFlyFmt )
754 bool bCallOutSet = true;
755 const SwModify* pOldMod = pOutFmtNode;
756 pOutFmtNode = &rFmt;
758 switch( rFmt.Which() )
760 case RES_CONDTXTFMTCOLL:
761 case RES_TXTFMTCOLL:
762 if( bPapFmt )
764 if (((const SwTxtFmtColl&)rFmt).IsAssignedToListLevelOfOutlineStyle())
766 int nLvl = ((const SwTxtFmtColl&)rFmt).GetAssignedOutlineStyleLevel();
768 //if outline numbered
769 // if Write StyleDefinition then write the OutlineRule
770 const SwNumFmt& rNFmt = pDoc->GetOutlineNumRule()->Get( static_cast<USHORT>( nLvl ) );
771 if ( bStyDef )
772 AttrOutput().OutlineNumbering( static_cast< BYTE >( nLvl ), rNFmt, rFmt );
774 // --> OD 2008-06-03 #i86652#
775 // if (rNFmt.GetAbsLSpace())
776 if ( rNFmt.GetPositionAndSpaceMode() ==
777 SvxNumberFormat::LABEL_WIDTH_AND_POSITION &&
778 rNFmt.GetAbsLSpace() )
779 // <--
781 SfxItemSet aSet( rFmt.GetAttrSet() );
782 SvxLRSpaceItem aLR(
783 ItemGet<SvxLRSpaceItem>(aSet, RES_LR_SPACE));
785 aLR.SetTxtLeft( aLR.GetTxtLeft() + rNFmt.GetAbsLSpace() );
786 aLR.SetTxtFirstLineOfst( GetWordFirstLineOffset(rNFmt));
788 aSet.Put( aLR );
789 CorrectTabStopInSet( aSet, rNFmt.GetAbsLSpace() );
790 OutputItemSet( aSet, bPapFmt, bChpFmt,
791 i18n::ScriptType::LATIN);
792 bCallOutSet = false;
795 else
797 //otherwise we might have to remove outline numbering from
798 //what gets exported if the parent style was outline numbered
799 // --> OD 2007-06-04 #i77805#
800 // If inherited outline numbering is suppress, the left/right
801 // margins has to be exported explicitly.
802 if ( bStyDef && DisallowInheritingOutlineNumbering(rFmt) )
804 SfxItemSet aSet( rFmt.GetAttrSet() );
805 SvxLRSpaceItem aLR(
806 ItemGet<SvxLRSpaceItem>(aSet, RES_LR_SPACE));
807 aSet.Put( aLR );
808 OutputItemSet( aSet, bPapFmt, bChpFmt,
809 com::sun::star::i18n::ScriptType::LATIN);
810 bCallOutSet = false;
812 // <--
815 break;
817 case RES_CHRFMT:
818 break;
819 case RES_FLYFRMFMT:
820 if (bFlyFmt)
822 ASSERT(mpParentFrame, "No parent frame, all broken");
824 if (mpParentFrame)
826 const SwFrmFmt &rFrmFmt = mpParentFrame->GetFrmFmt();
828 SfxItemSet aSet(pDoc->GetAttrPool(), RES_FRMATR_BEGIN,
829 RES_FRMATR_END-1);
830 aSet.Set(rFrmFmt.GetAttrSet());
832 // Fly als Zeichen werden bei uns zu Absatz-gebundenen
833 // jetzt den Abstand vom Absatz-Rand setzen
834 if (pFlyOffset)
836 aSet.Put(SwFmtHoriOrient(pFlyOffset->X()));
837 aSet.Put(SwFmtVertOrient(pFlyOffset->Y()));
838 SwFmtAnchor aAnchor(rFrmFmt.GetAnchor());
839 aAnchor.SetType(eNewAnchorType);
840 aSet.Put(aAnchor);
843 if (SFX_ITEM_SET != aSet.GetItemState(RES_SURROUND))
844 aSet.Put(SwFmtSurround(SURROUND_NONE));
846 bOutFlyFrmAttrs = true;
847 //script doesn't matter if not exporting chp
848 OutputItemSet(aSet, true, false,
849 i18n::ScriptType::LATIN);
850 bOutFlyFrmAttrs = false;
852 bCallOutSet = false;
855 break;
856 default:
857 ASSERT( !this, "Was wird hier ausgegeben ??? " );
858 break;
861 if( bCallOutSet )
862 OutputItemSet( rFmt.GetAttrSet(), bPapFmt, bChpFmt,
863 i18n::ScriptType::LATIN);
864 pOutFmtNode = pOldMod;
867 bool MSWordExportBase::HasRefToObject( USHORT nTyp, const String* pName, USHORT nSeqNo )
869 const SwTxtNode* pNd;
870 SwClientIter aIter( *pDoc->GetSysFldType( RES_GETREFFLD ) );
871 for ( SwFmtFld* pFld = static_cast< SwFmtFld* >( aIter.First( TYPE( SwFmtFld ) ) );
872 pFld;
873 pFld = static_cast< SwFmtFld* >( aIter.Next() ) )
875 if ( pFld->GetTxtFld() && nTyp == pFld->GetFld()->GetSubType() &&
876 0 != ( pNd = pFld->GetTxtFld()->GetpTxtNode() ) &&
877 pNd->GetNodes().IsDocNodes() )
879 const SwGetRefField& rRFld = *static_cast< SwGetRefField* >( pFld->GetFld() );
880 switch ( nTyp )
882 case REF_BOOKMARK:
883 case REF_SETREFATTR:
884 if ( pName && *pName == rRFld.GetSetRefName() )
885 return true;
886 break;
887 case REF_FOOTNOTE:
888 case REF_ENDNOTE:
889 if ( nSeqNo == rRFld.GetSeqNo() )
890 return true;
891 break;
892 case REF_SEQUENCEFLD:
893 break; // ???
894 case REF_OUTLINE:
895 break; // ???
900 return false;
903 String MSWordExportBase::GetBookmarkName( USHORT nTyp, const String* pName, USHORT nSeqNo )
905 String sRet;
906 switch ( nTyp )
908 case REF_SETREFATTR:
909 if ( pName )
911 sRet.APPEND_CONST_ASC( "Ref_" );
912 sRet += *pName;
914 break;
915 case REF_SEQUENCEFLD:
916 break; // ???
917 case REF_BOOKMARK:
918 if ( pName )
919 sRet = *pName;
920 break;
921 case REF_OUTLINE:
922 break; // ???
923 case REF_FOOTNOTE:
924 sRet.APPEND_CONST_ASC( "_RefF" );
925 sRet += String::CreateFromInt32( nSeqNo );
926 break;
927 case REF_ENDNOTE:
928 sRet.APPEND_CONST_ASC( "_RefE" );
929 sRet += String::CreateFromInt32( nSeqNo );
930 break;
932 // --> OD 2005-06-08 #i43956# - encode bookmark accordingly
933 return BookmarkToWord( sRet );
934 // <--
937 //-----------------------------------------------------------------------
938 /* \f */
939 /* File CHRATR.HXX: */
940 void WW8AttributeOutput::RTLAndCJKState( bool bIsRTL, sal_uInt16 nScript )
942 if ( m_rWW8Export.bWrtWW8 && bIsRTL )
944 m_rWW8Export.InsUInt16( NS_sprm::LN_CFBiDi );
945 m_rWW8Export.pO->Insert( (BYTE)1, m_rWW8Export.pO->Count() );
948 // #i46087# patch from james_clark; complex texts needs the undocumented SPRM CComplexScript with param 0x81.
949 if ( m_rWW8Export.bWrtWW8 && nScript == i18n::ScriptType::COMPLEX && !bIsRTL )
951 m_rWW8Export.InsUInt16( NS_sprm::LN_CComplexScript );
952 m_rWW8Export.pO->Insert( (BYTE)0x81, m_rWW8Export.pO->Count() );
953 m_rWW8Export.pDop->bUseThaiLineBreakingRules = true;
957 void WW8AttributeOutput::EndParagraph( ww8::WW8TableNodeInfoInner::Pointer_t pTextNodeInfoInner )
959 m_rWW8Export.pPapPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), m_rWW8Export.pO->Count(), m_rWW8Export.pO->GetData() );
960 m_rWW8Export.pO->Remove( 0, m_rWW8Export.pO->Count() ); // delete
962 if ( pTextNodeInfoInner.get() != NULL )
964 if ( pTextNodeInfoInner->isEndOfLine() )
966 TableRowEnd( pTextNodeInfoInner->getDepth() );
968 SVBT16 nSty;
969 ShortToSVBT16( m_rWW8Export.nStyleBeforeFly, nSty );
970 m_rWW8Export.pO->Insert( (BYTE*)&nSty, 2, m_rWW8Export.pO->Count() ); // Style #
971 TableInfoRow( pTextNodeInfoInner );
972 m_rWW8Export.pPapPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), m_rWW8Export.pO->Count(),
973 m_rWW8Export.pO->GetData() );
974 m_rWW8Export.pO->Remove( 0, m_rWW8Export.pO->Count() ); // delete
979 void WW8AttributeOutput::StartRunProperties()
981 WW8_WrPlcFld* pCurrentFields = m_rWW8Export.CurrentFieldPlc();
982 m_nFieldResults = pCurrentFields ? pCurrentFields->ResultCount() : 0;
985 void WW8AttributeOutput::EndRunProperties( const SwRedlineData* pRedlineData )
987 Redline( pRedlineData );
989 WW8_WrPlcFld* pCurrentFields = m_rWW8Export.CurrentFieldPlc();
990 USHORT nNewFieldResults = pCurrentFields ? pCurrentFields->ResultCount() : 0;
992 bool bExportedFieldResult = ( m_nFieldResults != nNewFieldResults );
994 // If we have exported a field result, then we will have been forced to
995 // split up the text into a 0x13, 0x14, <result> 0x15 sequence with the
996 // properties forced out at the end of the result, so the 0x15 itself
997 // should remain clean of all other attributes to avoid #iXXXXX#
998 if ( !bExportedFieldResult )
1000 m_rWW8Export.pChpPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(),
1001 m_rWW8Export.pO->Count(), m_rWW8Export.pO->GetData() );
1003 m_rWW8Export.pO->Remove( 0, m_rWW8Export.pO->Count() ); // delete
1006 void WW8AttributeOutput::RunText( const String& rText, rtl_TextEncoding eCharSet )
1008 RawText( rText, m_rWW8Export.bWrtWW8, eCharSet );
1011 void WW8AttributeOutput::RawText( const String& rText, bool bForceUnicode, rtl_TextEncoding eCharSet )
1013 m_rWW8Export.OutSwString( rText, 0, rText.Len(), bForceUnicode, eCharSet );
1016 void WW8AttributeOutput::OutputFKP()
1018 if ( m_rWW8Export.pO->Count() )
1020 m_rWW8Export.pChpPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(),
1021 m_rWW8Export.pO->Count(), m_rWW8Export.pO->GetData() );
1022 m_rWW8Export.pO->Remove( 0, m_rWW8Export.pO->Count() ); // delete
1026 void WW8AttributeOutput::ParagraphStyle( USHORT nStyle )
1028 ASSERT( !m_rWW8Export.pO->Count(), " pO ist am ZeilenEnde nicht leer" );
1030 SVBT16 nSty;
1031 ShortToSVBT16( nStyle, nSty );
1032 m_rWW8Export.pO->Insert( (BYTE*)&nSty, 2, m_rWW8Export.pO->Count() ); // Style #
1035 void WW8AttributeOutput::OutputWW8Attribute( BYTE nId, bool bVal )
1037 if ( m_rWW8Export.bWrtWW8 )
1038 m_rWW8Export.InsUInt16( 8 == nId ? NS_sprm::LN_CFDStrike : NS_sprm::LN_CFBold + nId );
1039 else if (8 == nId )
1040 return; // no such attribute in WW6
1041 else
1042 m_rWW8Export.pO->Insert( 85 + nId, m_rWW8Export.pO->Count() );
1044 m_rWW8Export.pO->Insert( bVal ? 1 : 0, m_rWW8Export.pO->Count() );
1047 void WW8AttributeOutput::OutputWW8AttributeCTL( BYTE nId, bool bVal )
1049 ASSERT( nId <= 1, "out of range" );
1050 if ( !m_rWW8Export.bWrtWW8 || nId > 1 )
1051 return;
1053 m_rWW8Export.InsUInt16( NS_sprm::LN_CFBoldBi + nId );
1054 m_rWW8Export.pO->Insert( bVal ? 1 : 0, m_rWW8Export.pO->Count() );
1057 void WW8AttributeOutput::CharFont( const SvxFontItem& rFont )
1059 USHORT nFontID = m_rWW8Export.GetId( rFont );
1061 if ( m_rWW8Export.bWrtWW8 )
1063 m_rWW8Export.InsUInt16( NS_sprm::LN_CRgFtc0 );
1064 m_rWW8Export.InsUInt16( nFontID );
1065 m_rWW8Export.InsUInt16( NS_sprm::LN_CRgFtc2 );
1067 else
1068 m_rWW8Export.pO->Insert( 93, m_rWW8Export.pO->Count() );
1070 m_rWW8Export.InsUInt16( nFontID );
1073 void WW8AttributeOutput::CharFontCTL( const SvxFontItem& rFont )
1075 if ( m_rWW8Export.bWrtWW8 )
1077 m_rWW8Export.InsUInt16( NS_sprm::LN_CFtcBi );
1078 m_rWW8Export.InsUInt16( m_rWW8Export.GetId( rFont ) );
1082 void WW8AttributeOutput::CharFontCJK( const SvxFontItem& rFont )
1084 if ( m_rWW8Export.bWrtWW8 )
1086 m_rWW8Export.InsUInt16( NS_sprm::LN_CRgFtc1 );
1087 m_rWW8Export.InsUInt16( m_rWW8Export.GetId( rFont ) );
1091 void WW8AttributeOutput::CharWeightCTL( const SvxWeightItem& rWeight )
1093 //Can only export in 8+, in 7- export as normal varient and expect that
1094 //upperlevel code has blocked exporting clobbering attributes
1095 if (m_rWW8Export.bWrtWW8)
1097 OutputWW8AttributeCTL( 0, WEIGHT_BOLD == rWeight.GetWeight());
1099 else
1101 OutputWW8Attribute( 0, WEIGHT_BOLD == rWeight.GetWeight());
1105 void WW8AttributeOutput::CharPostureCTL( const SvxPostureItem& rPosture )
1107 // Can only export in 8+, in 7- export as normal varient and expect that
1108 // upperlevel code has blocked exporting clobbering attributes
1109 if (m_rWW8Export.bWrtWW8)
1111 OutputWW8AttributeCTL( 1, ITALIC_NONE != rPosture.GetPosture() );
1113 else
1115 OutputWW8Attribute( 1, ITALIC_NONE != rPosture.GetPosture() );
1119 void WW8AttributeOutput::CharPosture( const SvxPostureItem& rPosture )
1121 OutputWW8Attribute( 1, ITALIC_NONE != rPosture.GetPosture() );
1124 void WW8AttributeOutput::CharWeight( const SvxWeightItem& rWeight )
1126 OutputWW8Attribute( 0, WEIGHT_BOLD == rWeight.GetWeight() );
1129 // Shadowed und Contour are not in WW-UI. JP: ??
1130 void WW8AttributeOutput::CharContour( const SvxContourItem& rContour )
1132 OutputWW8Attribute( 3, rContour.GetValue() ? true : false);
1135 void WW8AttributeOutput::CharShadow( const SvxShadowedItem& rShadow )
1137 OutputWW8Attribute( 4, rShadow.GetValue() ? true : false);
1140 void WW8AttributeOutput::CharKerning( const SvxKerningItem& rKerning )
1142 if ( m_rWW8Export.bWrtWW8 )
1143 m_rWW8Export.InsUInt16( NS_sprm::LN_CDxaSpace );
1144 else
1145 m_rWW8Export.pO->Insert( 96, m_rWW8Export.pO->Count() );
1147 m_rWW8Export.InsUInt16( rKerning.GetValue() );
1150 void WW8AttributeOutput::CharAutoKern( const SvxAutoKernItem& rAutoKern )
1152 if ( m_rWW8Export.bWrtWW8 )
1153 m_rWW8Export.InsUInt16( NS_sprm::LN_CHpsKern );
1154 else
1155 m_rWW8Export.pO->Insert( 107, m_rWW8Export.pO->Count() );
1157 m_rWW8Export.InsUInt16( rAutoKern.GetValue() ? 1 : 0 );
1160 void WW8AttributeOutput::CharAnimatedText( const SvxBlinkItem& rBlink )
1162 if ( m_rWW8Export.bWrtWW8 )
1164 m_rWW8Export.InsUInt16( NS_sprm::LN_CSfxText );
1165 // At the moment the only animated text effect we support is blinking
1166 m_rWW8Export.InsUInt16( rBlink.GetValue() ? 2 : 0 );
1170 void WW8AttributeOutput::CharCrossedOut( const SvxCrossedOutItem& rCrossed )
1172 FontStrikeout eSt = rCrossed.GetStrikeout();
1173 if ( STRIKEOUT_DOUBLE == eSt )
1175 OutputWW8Attribute( 8, true );
1176 return;
1178 if ( STRIKEOUT_NONE != eSt )
1180 OutputWW8Attribute( 2, true );
1181 return;
1184 // otherwise both off
1185 OutputWW8Attribute( 8, false );
1186 OutputWW8Attribute( 2, false );
1189 void WW8AttributeOutput::CharCaseMap( const SvxCaseMapItem& rCaseMap )
1191 USHORT eSt = rCaseMap.GetValue();
1192 switch ( eSt )
1194 case SVX_CASEMAP_KAPITAELCHEN:
1195 OutputWW8Attribute( 5, true );
1196 return;
1197 case SVX_CASEMAP_VERSALIEN:
1198 OutputWW8Attribute( 6, true );
1199 return;
1200 case SVX_CASEMAP_TITEL:
1201 // no such feature in word
1202 break;
1203 default:
1204 // otherwise both off
1205 OutputWW8Attribute( 5, false );
1206 OutputWW8Attribute( 6, false );
1207 return;
1211 void WW8AttributeOutput::CharHidden( const SvxCharHiddenItem& rHidden )
1213 OutputWW8Attribute( 7, rHidden.GetValue() );
1216 void WW8AttributeOutput::CharUnderline( const SvxUnderlineItem& rUnderline )
1218 if ( m_rWW8Export.bWrtWW8 )
1219 m_rWW8Export.InsUInt16( NS_sprm::LN_CKul );
1220 else
1221 m_rWW8Export.pO->Insert( 94, m_rWW8Export.pO->Count() );
1223 const SfxPoolItem* pItem = m_rWW8Export.HasItem( RES_CHRATR_WORDLINEMODE );
1224 bool bWord = false;
1225 if (pItem)
1226 bWord = ((const SvxWordLineModeItem*)pItem)->GetValue() ? true : false;
1228 // WW95 - parameters: 0 = none, 1 = single, 2 = by Word,
1229 // 3 = double, 4 = dotted, 5 = hidden
1230 // WW97 - additional parameters:
1231 // 6 = thick, 7 = dash, 8 = dot(not used)
1232 // 9 = dotdash 10 = dotdotdash, 11 = wave
1233 BYTE b = 0;
1234 switch ( rUnderline.GetLineStyle() )
1236 case UNDERLINE_SINGLE:
1237 b = ( bWord ) ? 2 : 1;
1238 break;
1239 case UNDERLINE_BOLD:
1240 b = m_rWW8Export.bWrtWW8 ? 6 : 1;
1241 break;
1242 case UNDERLINE_DOUBLE:
1243 b = 3;
1244 break;
1245 case UNDERLINE_DOTTED:
1246 b = 4;
1247 break;
1248 case UNDERLINE_DASH:
1249 b = m_rWW8Export.bWrtWW8 ? 7 : 4;
1250 break;
1251 case UNDERLINE_DASHDOT:
1252 b = m_rWW8Export.bWrtWW8 ? 9 : 4;
1253 break;
1254 case UNDERLINE_DASHDOTDOT:
1255 b = m_rWW8Export.bWrtWW8 ? 10 : 4;
1256 break;
1257 case UNDERLINE_WAVE:
1258 b = m_rWW8Export.bWrtWW8 ? 11 : 3;
1259 break;
1260 // ------------ new in WW2000 -------------------------------------
1261 case UNDERLINE_BOLDDOTTED:
1262 b = m_rWW8Export.bWrtWW8 ? 20 : 4;
1263 break;
1264 case UNDERLINE_BOLDDASH:
1265 b = m_rWW8Export.bWrtWW8 ? 23 : 4;
1266 break;
1267 case UNDERLINE_LONGDASH:
1268 b = m_rWW8Export.bWrtWW8 ? 39 : 4;
1269 break;
1270 case UNDERLINE_BOLDLONGDASH:
1271 b = m_rWW8Export.bWrtWW8 ? 55 : 4;
1272 break;
1273 case UNDERLINE_BOLDDASHDOT:
1274 b = m_rWW8Export.bWrtWW8 ? 25 : 4;
1275 break;
1276 case UNDERLINE_BOLDDASHDOTDOT:
1277 b = m_rWW8Export.bWrtWW8 ? 26 : 4;
1278 break;
1279 case UNDERLINE_BOLDWAVE:
1280 b = m_rWW8Export.bWrtWW8 ? 27 : 3;
1281 break;
1282 case UNDERLINE_DOUBLEWAVE:
1283 b = m_rWW8Export.bWrtWW8 ? 43 : 3;
1284 break;
1285 case UNDERLINE_NONE:
1286 b = 0;
1287 break;
1288 default:
1289 ASSERT( rUnderline.GetLineStyle() == UNDERLINE_NONE, "Unhandled underline type" );
1290 break;
1293 m_rWW8Export.pO->Insert( b, m_rWW8Export.pO->Count() );
1296 void WW8AttributeOutput::CharLanguage( const SvxLanguageItem& rLanguage )
1298 USHORT nId = 0;
1299 if ( m_rWW8Export.bWrtWW8 )
1301 switch ( rLanguage.Which() )
1303 case RES_CHRATR_LANGUAGE:
1304 nId = NS_sprm::LN_CRgLid0;
1305 break;
1306 case RES_CHRATR_CJK_LANGUAGE:
1307 nId = NS_sprm::LN_CRgLid1;
1308 break;
1309 case RES_CHRATR_CTL_LANGUAGE:
1310 nId = NS_sprm::LN_CLidBi;
1311 break;
1314 else
1315 nId = 97;
1317 if ( nId )
1319 if ( m_rWW8Export.bWrtWW8 ) // use sprmCRgLid0 rather than sprmCLid
1320 m_rWW8Export.InsUInt16( nId );
1321 else
1322 m_rWW8Export.pO->Insert( (BYTE)nId, m_rWW8Export.pO->Count() );
1323 m_rWW8Export.InsUInt16( rLanguage.GetLanguage() );
1325 // unknown as to exactly why, but this seems to shadow the other
1326 // paramater in word 2000 and without it spellchecking doesn't work
1327 if ( nId == NS_sprm::LN_CRgLid0 )
1329 m_rWW8Export.InsUInt16( 0x4873 );
1330 m_rWW8Export.InsUInt16( rLanguage.GetLanguage() );
1332 else if ( nId == NS_sprm::LN_CLidBi )
1334 m_rWW8Export.InsUInt16( 0x4874 );
1335 m_rWW8Export.InsUInt16( rLanguage.GetLanguage() );
1341 void WW8AttributeOutput::CharEscapement( const SvxEscapementItem& rEscapement )
1343 BYTE b = 0xFF;
1344 short nEsc = rEscapement.GetEsc(), nProp = rEscapement.GetProp();
1345 if ( !nEsc )
1347 b = 0;
1348 nEsc = 0;
1349 nProp = 100;
1351 else if ( DFLT_ESC_PROP == nProp )
1353 if ( DFLT_ESC_SUB == nEsc || DFLT_ESC_AUTO_SUB == nEsc )
1354 b = 2;
1355 else if ( DFLT_ESC_SUPER == nEsc || DFLT_ESC_AUTO_SUPER == nEsc )
1356 b = 1;
1359 if ( 0xFF != b )
1361 if ( m_rWW8Export.bWrtWW8 )
1362 m_rWW8Export.InsUInt16( NS_sprm::LN_CIss );
1363 else
1364 m_rWW8Export.pO->Insert( 104, m_rWW8Export.pO->Count() );
1366 m_rWW8Export.pO->Insert( b, m_rWW8Export.pO->Count() );
1369 if ( 0 == b || 0xFF == b )
1371 long nHeight = ((SvxFontHeightItem&)m_rWW8Export.GetItem(
1372 RES_CHRATR_FONTSIZE )).GetHeight();
1373 if( m_rWW8Export.bWrtWW8 )
1374 m_rWW8Export.InsUInt16( NS_sprm::LN_CHpsPos );
1375 else
1376 m_rWW8Export.pO->Insert( 101, m_rWW8Export.pO->Count() );
1378 m_rWW8Export.InsUInt16( (short)(( nHeight * nEsc + 500 ) / 1000 ));
1380 if( 100 != nProp || !b )
1382 if( m_rWW8Export.bWrtWW8 )
1383 m_rWW8Export.InsUInt16( NS_sprm::LN_CHps );
1384 else
1385 m_rWW8Export.pO->Insert( 99, m_rWW8Export.pO->Count() );
1387 m_rWW8Export.InsUInt16(
1388 msword_cast<sal_uInt16>((nHeight * nProp + 500 ) / 1000));
1393 void WW8AttributeOutput::CharFontSize( const SvxFontHeightItem& rHeight )
1395 USHORT nId = 0;
1396 if ( m_rWW8Export.bWrtWW8 )
1398 switch ( rHeight.Which() )
1400 case RES_CHRATR_FONTSIZE:
1401 case RES_CHRATR_CJK_FONTSIZE:
1402 nId = NS_sprm::LN_CHps;
1403 break;
1404 case RES_CHRATR_CTL_FONTSIZE:
1405 nId = NS_sprm::LN_CHpsBi;
1406 break;
1409 else
1410 nId = 99;
1412 if ( nId )
1414 if ( m_rWW8Export.bWrtWW8 )
1415 m_rWW8Export.InsUInt16( nId );
1416 else
1417 m_rWW8Export.pO->Insert( (BYTE)nId, m_rWW8Export.pO->Count() );
1419 m_rWW8Export.InsUInt16( (UINT16)(( rHeight.GetHeight() + 5 ) / 10 ) );
1423 void WW8AttributeOutput::CharScaleWidth( const SvxCharScaleWidthItem& rScaleWidth )
1425 if ( m_rWW8Export.bWrtWW8 )
1427 m_rWW8Export.InsUInt16( NS_sprm::LN_CCharScale );
1428 m_rWW8Export.InsUInt16( rScaleWidth.GetValue() );
1432 void WW8AttributeOutput::CharRelief( const SvxCharReliefItem& rRelief )
1434 if ( m_rWW8Export.bWrtWW8 )
1436 USHORT nId;
1437 switch ( rRelief.GetValue() )
1439 case RELIEF_EMBOSSED: nId = NS_sprm::LN_CFEmboss; break;
1440 case RELIEF_ENGRAVED: nId = NS_sprm::LN_CFImprint; break;
1441 default: nId = 0; break;
1444 if( nId )
1446 m_rWW8Export.InsUInt16( nId );
1447 m_rWW8Export.pO->Insert( (BYTE)0x81, m_rWW8Export.pO->Count() );
1449 else
1451 // switch both flags off
1452 m_rWW8Export.InsUInt16( NS_sprm::LN_CFEmboss );
1453 m_rWW8Export.pO->Insert( (BYTE)0x0, m_rWW8Export.pO->Count() );
1454 m_rWW8Export.InsUInt16( NS_sprm::LN_CFImprint );
1455 m_rWW8Export.pO->Insert( (BYTE)0x0, m_rWW8Export.pO->Count() );
1460 void WW8AttributeOutput::CharRotate( const SvxCharRotateItem& rRotate )
1462 // #i28331# - check that a Value is set
1463 if ( !rRotate.GetValue() )
1464 return;
1466 if ( m_rWW8Export.bWrtWW8 && !m_rWW8Export.bIsInTable )
1468 // #i36867 In word the text in a table is rotated via the TC or NS_sprm::LN_TTextFlow
1469 // This means you can only rotate all or none of the text adding NS_sprm::LN_CEastAsianLayout
1470 // here corrupts the table, hence !m_rWW8Export.bIsInTable
1472 m_rWW8Export.InsUInt16( NS_sprm::LN_CEastAsianLayout );
1473 m_rWW8Export.pO->Insert( (BYTE)0x06, m_rWW8Export.pO->Count() ); //len 6
1474 m_rWW8Export.pO->Insert( (BYTE)0x01, m_rWW8Export.pO->Count() );
1476 m_rWW8Export.InsUInt16( rRotate.IsFitToLine() ? 1 : 0 );
1477 static const BYTE aZeroArr[ 3 ] = { 0, 0, 0 };
1478 m_rWW8Export.pO->Insert( aZeroArr, 3, m_rWW8Export.pO->Count() );
1482 void WW8AttributeOutput::CharEmphasisMark( const SvxEmphasisMarkItem& rEmphasisMark )
1484 if ( m_rWW8Export.bWrtWW8 )
1486 BYTE nVal;
1487 switch ( rEmphasisMark.GetValue() )
1489 case EMPHASISMARK_NONE: nVal = 0; break;
1490 case EMPHASISMARK_SIDE_DOTS: nVal = 2; break;
1491 case EMPHASISMARK_CIRCLE_ABOVE: nVal = 3; break;
1492 case EMPHASISMARK_DOTS_BELOW: nVal = 4; break;
1493 // case 1:
1494 default: nVal = 1; break;
1497 m_rWW8Export.InsUInt16( NS_sprm::LN_CKcd );
1498 m_rWW8Export.pO->Insert( nVal, m_rWW8Export.pO->Count() );
1502 // TransCol uebersetzt SW-Farben in WW. Heraus kommt die bei WW fuer
1503 // Text- und Hintergrundfarbe benutzte Codierung.
1504 // Gibt es keine direkte Entsprechung, dann wird versucht, eine moeglichst
1505 // aehnliche WW-Farbe zu finden.
1506 // return: 5-Bit-Wert ( 0..16 )
1507 BYTE WW8Export::TransCol( const Color& rCol )
1509 BYTE nCol = 0; // ->Auto
1510 switch( rCol.GetColor() )
1512 case COL_BLACK: nCol = 1; break;
1513 case COL_BLUE: nCol = 9; break;
1514 case COL_GREEN: nCol = 11; break;
1515 case COL_CYAN: nCol = 10; break;
1516 case COL_RED: nCol = 13; break;
1517 case COL_MAGENTA: nCol = 12; break;
1518 case COL_BROWN: nCol = 14; break;
1519 case COL_GRAY: nCol = 15; break;
1520 case COL_LIGHTGRAY: nCol = 16; break;
1521 case COL_LIGHTBLUE: nCol = 2; break;
1522 case COL_LIGHTGREEN: nCol = 4; break;
1523 case COL_LIGHTCYAN: nCol = 3; break;
1524 case COL_LIGHTRED: nCol = 6; break;
1525 case COL_LIGHTMAGENTA: nCol = 5; break;
1526 case COL_YELLOW: nCol = 7; break;
1527 case COL_WHITE: nCol = 8; break;
1528 case COL_AUTO: nCol = 0; break;
1530 default:
1531 if( !pBmpPal )
1533 pBmpPal = new BitmapPalette( 16 );
1534 static const ColorData aColArr[ 16 ] = {
1535 COL_BLACK, COL_LIGHTBLUE, COL_LIGHTCYAN, COL_LIGHTGREEN,
1536 COL_LIGHTMAGENTA,COL_LIGHTRED, COL_YELLOW, COL_WHITE,
1537 COL_BLUE, COL_CYAN, COL_GREEN, COL_MAGENTA,
1538 COL_RED, COL_BROWN, COL_GRAY, COL_LIGHTGRAY
1541 for( USHORT i = 0; i < 16; ++i )
1542 pBmpPal->operator[]( i ) = Color( aColArr[ i ] );
1544 nCol = static_cast< BYTE >(pBmpPal->GetBestIndex( rCol ) + 1);
1545 break;
1547 return nCol;
1550 // TransBrush uebersetzt SW-Brushes in WW. Heraus kommt WW8_SHD.
1551 // Nicht-Standardfarben des SW werden noch nicht in die
1552 // Misch-Werte ( 0 .. 95% ) vom WW uebersetzt.
1553 // Return: Echte Brush ( nicht transparent )
1554 // auch bei Transparent wird z.B. fuer Tabellen eine transparente Brush
1555 // geliefert
1556 bool WW8Export::TransBrush(const Color& rCol, WW8_SHD& rShd)
1558 if( rCol.GetTransparency() )
1559 rShd = WW8_SHD(); // alles Nullen : transparent
1560 else
1562 rShd.SetFore( 8);
1563 rShd.SetBack( TransCol( rCol ) );
1564 rShd.SetStyle( bWrtWW8, 0 );
1566 return !rCol.GetTransparency();
1569 sal_uInt32 SuitableBGColor(sal_uInt32 nIn)
1571 if (nIn == COL_AUTO)
1572 return 0xFF000000;
1573 return wwUtility::RGBToBGR(nIn);
1576 void WW8AttributeOutput::CharColor( const SvxColorItem& rColor )
1578 if ( m_rWW8Export.bWrtWW8 )
1579 m_rWW8Export.InsUInt16( NS_sprm::LN_CIco );
1580 else
1581 m_rWW8Export.pO->Insert( 98, m_rWW8Export.pO->Count() );
1583 BYTE nColor = m_rWW8Export.TransCol( rColor.GetValue() );
1584 m_rWW8Export.pO->Insert( nColor, m_rWW8Export.pO->Count() );
1586 if ( m_rWW8Export.bWrtWW8 && nColor )
1588 m_rWW8Export.InsUInt16( 0x6870 );
1589 m_rWW8Export.InsUInt32( wwUtility::RGBToBGR( rColor.GetValue().GetColor() ) );
1593 void WW8AttributeOutput::CharBackground( const SvxBrushItem& rBrush )
1595 if( m_rWW8Export.bWrtWW8 ) // nur WW8 kann ZeichenHintergrund
1597 WW8_SHD aSHD;
1599 m_rWW8Export.TransBrush( rBrush.GetColor(), aSHD );
1600 // sprmCShd
1601 m_rWW8Export.InsUInt16( NS_sprm::LN_CShd );
1602 m_rWW8Export.InsUInt16( aSHD.GetValue() );
1604 //Quite a few unknowns, some might be transparency or something
1605 //of that nature...
1606 m_rWW8Export.InsUInt16( 0xCA71 );
1607 m_rWW8Export.pO->Insert( 10, m_rWW8Export.pO->Count() );
1608 m_rWW8Export.InsUInt32( 0xFF000000 );
1609 m_rWW8Export.InsUInt32( SuitableBGColor( rBrush.GetColor().GetColor() ) );
1610 m_rWW8Export.InsUInt16( 0x0000);
1614 void WW8AttributeOutput::TextINetFormat( const SwFmtINetFmt& rINet )
1616 if ( rINet.GetValue().Len() )
1618 USHORT nId;
1619 const String& rStr = rINet.GetINetFmt();
1620 if ( rStr.Len() )
1621 nId = rINet.GetINetFmtId();
1622 else
1623 nId = RES_POOLCHR_INET_NORMAL;
1625 const SwCharFmt* pFmt = IsPoolUserFmt( nId )
1626 ? m_rWW8Export.pDoc->FindCharFmtByName( rStr )
1627 : m_rWW8Export.pDoc->GetCharFmtFromPool( nId );
1629 if ( m_rWW8Export.bWrtWW8 )
1630 m_rWW8Export.InsUInt16( NS_sprm::LN_CIstd );
1631 else
1632 m_rWW8Export.pO->Insert( 80, m_rWW8Export.pO->Count() );
1634 m_rWW8Export.InsUInt16( m_rWW8Export.GetId( *pFmt ) );
1638 // --> OD 2005-06-08 #i43956# - add optional parameter <pLinkStr>
1639 // It's needed to write the hyperlink data for a certain cross-reference
1640 // - it contains the name of the link target, which is a bookmark.
1641 // --> OD 2008-08-14 #158418# - add optional parameter <bIncludeEmptyPicLocation>
1642 // It is needed to write an empty picture location for page number field separators
1643 static void InsertSpecialChar( WW8Export& rWrt, BYTE c,
1644 String* pLinkStr = 0L,
1645 bool bIncludeEmptyPicLocation = false )
1647 WW8Bytes aItems;
1648 rWrt.GetCurrentItems(aItems);
1650 if (c == 0x13)
1651 rWrt.pChpPlc->AppendFkpEntry(rWrt.Strm().Tell());
1652 else
1653 rWrt.pChpPlc->AppendFkpEntry(rWrt.Strm().Tell(), aItems.Count(),
1654 aItems.GetData());
1656 rWrt.WriteChar(c);
1658 // --> OD 2008-08-14 #158418#
1659 // store empty sprmCPicLocation for field separator
1660 if ( bIncludeEmptyPicLocation &&
1661 ( c == 0x13 || c == 0x14 || c == 0x15 ) )
1663 SwWW8Writer::InsUInt16( aItems, NS_sprm::LN_CPicLocation );
1664 SwWW8Writer::InsUInt32( aItems, 0x00000000 );
1666 // <--
1668 // --> OD 2005-06-08 #i43956# - write hyperlink data and attributes
1669 if ( rWrt.bWrtWW8 && c == 0x01 && pLinkStr )
1671 // write hyperlink data to data stream
1672 SvStream& rStrm = *rWrt.pDataStrm;
1673 // position of hyperlink data
1674 const UINT32 nLinkPosInDataStrm = rStrm.Tell();
1675 // write empty header
1676 const UINT16 nEmptyHdrLen = 0x44;
1677 BYTE aEmptyHeader[ nEmptyHdrLen ] = { 0 };
1678 aEmptyHeader[ 4 ] = 0x44;
1679 rStrm.Write( aEmptyHeader, nEmptyHdrLen );
1680 // writer fixed header
1681 const UINT16 nFixHdrLen = 0x19;
1682 BYTE aFixHeader[ nFixHdrLen ] =
1684 0x08, 0xD0, 0xC9, 0xEA, 0x79, 0xF9, 0xBA, 0xCE,
1685 0x11, 0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9,
1686 0x0B, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
1687 0x00,
1689 rStrm.Write( aFixHeader, nFixHdrLen );
1690 // write reference string including length+1
1691 UINT32 nStrLen( pLinkStr->Len() + 1 );
1692 SwWW8Writer::WriteLong( rStrm, nStrLen );
1693 SwWW8Writer::WriteString16( rStrm, *(pLinkStr), false );
1694 // write additional two NULL Bytes
1695 SwWW8Writer::WriteLong( rStrm, 0 );
1696 // write length of hyperlink data
1697 const UINT32 nCurrPos = rStrm.Tell();
1698 rStrm.Seek( nLinkPosInDataStrm );
1699 SVBT32 nLen;
1700 UInt32ToSVBT32( nCurrPos - nLinkPosInDataStrm, nLen );
1701 rStrm.Write( nLen, 4 );
1702 rStrm.Seek( nCurrPos );
1704 // write attributes of hyperlink character 0x01
1705 SwWW8Writer::InsUInt16( aItems, NS_sprm::LN_CFFldVanish );
1706 aItems.Insert( (BYTE)0x81, aItems.Count() );
1707 SwWW8Writer::InsUInt16( aItems, NS_sprm::LN_CPicLocation );
1708 SwWW8Writer::InsUInt32( aItems, nLinkPosInDataStrm );
1709 SwWW8Writer::InsUInt16( aItems, NS_sprm::LN_CFData );
1710 aItems.Insert( (BYTE)0x01, aItems.Count() );
1713 //Technically we should probably Remove all attribs
1714 //here for the 0x13, 0x14, 0x15, but our import
1715 //is slightly lacking
1716 //aItems.Remove(0, aItems.Count());
1717 // fSpec-Attribute true
1718 if( rWrt.bWrtWW8 )
1720 SwWW8Writer::InsUInt16( aItems, NS_sprm::LN_CFSpec );
1721 aItems.Insert( 1, aItems.Count() );
1723 else
1725 aItems.Insert( 117, aItems.Count() ); //sprmCFSpec
1726 aItems.Insert( 1, aItems.Count() );
1729 rWrt.pChpPlc->AppendFkpEntry(rWrt.Strm().Tell(), aItems.Count(),
1730 aItems.GetData());
1733 String lcl_GetExpandedField(const SwField &rFld)
1735 String sRet(rFld.Expand());
1737 //replace LF 0x0A with VT 0x0B
1738 sRet.SearchAndReplaceAll(0x0A, 0x0B);
1740 return sRet;
1743 WW8_WrPlcFld* WW8Export::CurrentFieldPlc() const
1745 WW8_WrPlcFld* pFldP = NULL;
1746 switch (nTxtTyp)
1748 case TXT_MAINTEXT:
1749 pFldP = pFldMain;
1750 break;
1751 case TXT_HDFT:
1752 pFldP = pFldHdFt;
1753 break;
1754 case TXT_FTN:
1755 pFldP = pFldFtn;
1756 break;
1757 case TXT_EDN:
1758 pFldP = pFldEdn;
1759 break;
1760 case TXT_ATN:
1761 pFldP = pFldAtn;
1762 break;
1763 case TXT_TXTBOX:
1764 pFldP = pFldTxtBxs;
1765 break;
1766 case TXT_HFTXTBOX:
1767 pFldP = pFldHFTxtBxs;
1768 break;
1769 default:
1770 ASSERT( !this, "was ist das fuer ein SubDoc-Type?" );
1772 return pFldP;
1775 void WW8Export::OutputField( const SwField* pFld, ww::eField eFldType,
1776 const String& rFldCmd, BYTE nMode )
1778 bool bUnicode = IsUnicode();
1779 WW8_WrPlcFld* pFldP = CurrentFieldPlc();
1781 // --> OD 2008-08-14 #158418#
1782 const bool bIncludeEmptyPicLocation = ( eFldType == ww::ePAGE );
1783 // <--
1784 if (WRITEFIELD_START & nMode)
1786 BYTE aFld13[2] = { 0x13, 0x00 }; // will change
1787 //#i3958#, Needed to make this field work correctly in Word 2000
1788 if (eFldType == ww::eSHAPE)
1789 aFld13[0] |= 0x80;
1790 aFld13[1] = static_cast< BYTE >(eFldType); // Typ nachtragen
1791 pFldP->Append( Fc2Cp( Strm().Tell() ), aFld13 );
1792 // --> OD 2008-08-14 #158418#
1793 InsertSpecialChar( *this, 0x13, 0, bIncludeEmptyPicLocation );
1794 // <--
1796 if (WRITEFIELD_CMD_START & nMode)
1798 if (bUnicode)
1799 SwWW8Writer::WriteString16(Strm(), rFldCmd, false);
1800 else
1802 SwWW8Writer::WriteString8(Strm(), rFldCmd, false,
1803 RTL_TEXTENCODING_MS_1252);
1805 // --> OD 2005-06-08 #i43956# - write hyperlink character including
1806 // attributes and corresponding binary data for certain reference fields.
1807 bool bHandleBookmark = false;
1809 if (pFld)
1811 if (pFld->GetTyp()->Which() == RES_GETREFFLD &&
1812 ( eFldType == ww::ePAGEREF || eFldType == ww::eREF ||
1813 eFldType == ww::eNOTEREF || eFldType == ww::eFOOTREF ))
1814 bHandleBookmark = true;
1816 #if 0
1817 if (pFld->GetTyp()->Which() == RES_INPUTFLD &&
1818 eFldType == ww::eFORMTEXT)
1819 bHandleBookmark = true;
1820 #endif
1823 if ( bHandleBookmark )
1825 // retrieve reference destionation - the name of the bookmark
1826 String aLinkStr;
1827 const USHORT nSubType = pFld->GetSubType();
1828 const SwGetRefField& rRFld = *(static_cast<const SwGetRefField*>(pFld));
1829 if ( nSubType == REF_SETREFATTR ||
1830 nSubType == REF_BOOKMARK )
1832 aLinkStr = GetBookmarkName( nSubType, &rRFld.GetSetRefName(), 0 );
1834 else if ( nSubType == REF_FOOTNOTE ||
1835 nSubType == REF_ENDNOTE )
1837 aLinkStr = GetBookmarkName( nSubType, 0, rRFld.GetSeqNo() );
1839 else if ( nSubType == REF_SEQUENCEFLD )
1841 aLinkStr = pFld->GetPar2();
1843 // insert hyperlink character including attributes and data.
1844 InsertSpecialChar( *this, 0x01, &aLinkStr );
1846 // <--
1848 if (WRITEFIELD_CMD_END & nMode)
1850 static const BYTE aFld14[2] = { 0x14, 0xff };
1851 pFldP->Append( Fc2Cp( Strm().Tell() ), aFld14 );
1852 pFldP->ResultAdded();
1853 // --> OD 2008-08-14 #158418#
1854 InsertSpecialChar( *this, 0x14, 0, bIncludeEmptyPicLocation );
1855 // <--
1857 if (WRITEFIELD_END & nMode)
1859 String sOut;
1860 if( pFld )
1861 sOut = lcl_GetExpandedField(*pFld);
1862 else
1863 sOut = rFldCmd;
1864 if( sOut.Len() )
1866 if( bUnicode )
1867 SwWW8Writer::WriteString16(Strm(), sOut, false);
1868 else
1870 SwWW8Writer::WriteString8(Strm(), sOut, false,
1871 RTL_TEXTENCODING_MS_1252);
1874 if (pFld)
1876 if (pFld->GetTyp()->Which() == RES_INPUTFLD &&
1877 eFldType == ww::eFORMTEXT)
1879 BYTE aArr[12];
1880 BYTE *pArr = aArr;
1882 if ( bWrtWW8 )
1884 Set_UInt16( pArr, NS_sprm::LN_CPicLocation );
1885 Set_UInt32( pArr, 0x0 );
1887 Set_UInt16( pArr, NS_sprm::LN_CFSpec );
1888 Set_UInt8( pArr, 1 );
1890 Set_UInt16( pArr, NS_sprm::LN_CFNoProof );
1891 Set_UInt8( pArr, 1 );
1893 else
1895 Set_UInt8(pArr, 0x68); //sprmCPicLocation
1896 Set_UInt32(pArr, 0x0);
1898 Set_UInt8( pArr, 117 ); //sprmCFSpec
1899 Set_UInt8( pArr, 1 );
1901 pChpPlc->AppendFkpEntry( Strm().Tell(), static_cast< short >(pArr - aArr), aArr );
1906 if (WRITEFIELD_CLOSE & nMode)
1908 BYTE aFld15[2] = { 0x15, 0x80 };
1910 if (pFld)
1912 if (pFld->GetTyp()->Which() == RES_INPUTFLD &&
1913 eFldType == ww::eFORMTEXT)
1915 USHORT nSubType = pFld->GetSubType();
1917 if (nSubType == REF_SEQUENCEFLD)
1918 aFld15[0] |= (0x4 << 5);
1922 pFldP->Append( Fc2Cp( Strm().Tell() ), aFld15 );
1923 // --> OD 2008-08-14 #158418#
1924 InsertSpecialChar( *this, 0x15, 0, bIncludeEmptyPicLocation );
1925 // <--
1929 void WW8Export::StartCommentOutput(const String& rName)
1931 String sStr(FieldString(ww::eQUOTE));
1932 sStr.APPEND_CONST_ASC("[");
1933 sStr += rName;
1934 sStr.APPEND_CONST_ASC("] ");
1935 OutputField(0, ww::eQUOTE, sStr, WRITEFIELD_START | WRITEFIELD_CMD_START);
1938 void WW8Export::EndCommentOutput(const String& rName)
1940 String sStr(CREATE_CONST_ASC(" ["));
1941 sStr += rName;
1942 sStr.APPEND_CONST_ASC("] ");
1943 OutputField(0, ww::eQUOTE, sStr, WRITEFIELD_CMD_END | WRITEFIELD_END |
1944 WRITEFIELD_CLOSE);
1947 USHORT MSWordExportBase::GetId( const SwTOXType& rTOXType )
1949 void* p = (void*)&rTOXType;
1950 USHORT nRet = aTOXArr.GetPos( p );
1951 if( USHRT_MAX == nRet )
1952 aTOXArr.Insert( p, nRet = aTOXArr.Count() );
1953 return nRet;
1956 // return values: 1 - no PageNum,
1957 // 2 - TabStop before PageNum,
1958 // 3 - Text before PageNum - rTxt hold the text
1959 // 4 - no Text and no TabStop before PageNum
1960 int lcl_CheckForm( const SwForm& rForm, BYTE nLvl, String& rText )
1962 int nRet = 4;
1963 rText.Erase();
1965 // #i21237#
1966 SwFormTokens aPattern = rForm.GetPattern(nLvl);
1967 SwFormTokens::iterator aIt = aPattern.begin();
1968 bool bPgNumFnd = false;
1969 FormTokenType eTType;
1971 // #i61362#
1972 if (! aPattern.empty())
1974 // #i21237#
1975 while( ++aIt != aPattern.end() && !bPgNumFnd )
1977 eTType = aIt->eTokenType;
1979 switch( eTType )
1981 case TOKEN_PAGE_NUMS:
1982 bPgNumFnd = true;
1983 break;
1985 case TOKEN_TAB_STOP:
1986 nRet = 2;
1987 break;
1988 case TOKEN_TEXT:
1989 nRet = 3;
1990 rText = aIt->sText.Copy( 0, 5 ); // #i21237#
1991 break;
1993 case TOKEN_LINK_START:
1994 case TOKEN_LINK_END:
1995 break;
1997 default:
1998 nRet = 4;
1999 break;
2003 if( !bPgNumFnd )
2004 nRet = 1;
2007 return nRet;
2010 bool lcl_IsHyperlinked(const SwForm& rForm, USHORT nTOXLvl)
2012 bool bRes = false;
2013 for (USHORT nI = 1; nI < nTOXLvl; ++nI)
2015 // #i21237#
2016 SwFormTokens aPattern = rForm.GetPattern(nI);
2018 if ( !aPattern.empty() )
2020 SwFormTokens::iterator aIt = aPattern.begin();
2022 FormTokenType eTType;
2024 // #i21237#
2025 while ( ++aIt != aPattern.end() )
2027 eTType = aIt->eTokenType;
2028 switch (eTType)
2030 case TOKEN_LINK_START:
2031 case TOKEN_LINK_END:
2032 bRes = true;
2033 break;
2034 default:
2040 return bRes;
2043 void AttributeOutputBase::StartTOX( const SwSection& rSect )
2045 if ( const SwTOXBase* pTOX = rSect.GetTOXBase() )
2047 static const sal_Char sEntryEnd[] = "\" ";
2049 ww::eField eCode = ww::eTOC;
2050 String sStr;
2051 switch (pTOX->GetType())
2053 case TOX_INDEX:
2054 eCode = ww::eINDEX;
2055 sStr = FieldString(eCode);
2057 if (pTOX->GetTOXForm().IsCommaSeparated())
2058 sStr.APPEND_CONST_ASC("\\r ");
2060 if (nsSwTOIOptions::TOI_ALPHA_DELIMITTER & pTOX->GetOptions())
2061 sStr.APPEND_CONST_ASC("\\h \"A\" ");
2064 String aFillTxt;
2065 for (BYTE n = 1; n <= 3; ++n)
2067 String aTxt;
2068 int nRet = ::lcl_CheckForm(pTOX->GetTOXForm(), n, aTxt);
2070 if( 3 == nRet )
2071 aFillTxt = aTxt;
2072 else if ((4 == nRet) || (2 == nRet)) //#109414#
2073 aFillTxt = '\t';
2074 else
2075 aFillTxt.Erase();
2077 sStr.APPEND_CONST_ASC("\\e \"");
2078 sStr += aFillTxt;
2079 sStr.AppendAscii(sEntryEnd);
2081 break;
2083 // case TOX_AUTHORITIES: eCode = eTOA; sStr = ???; break;
2085 case TOX_ILLUSTRATIONS:
2086 case TOX_OBJECTS:
2087 case TOX_TABLES:
2088 if (!pTOX->IsFromObjectNames())
2090 sStr = FieldString(eCode);
2092 sStr.APPEND_CONST_ASC("\\c \"");
2093 sStr += pTOX->GetSequenceName();
2094 sStr.AppendAscii(sEntryEnd);
2096 String aTxt;
2097 int nRet = ::lcl_CheckForm( pTOX->GetTOXForm(), 1, aTxt );
2098 if (1 == nRet)
2099 sStr.APPEND_CONST_ASC("\\n ");
2100 else if( 3 == nRet || 4 == nRet )
2102 sStr.APPEND_CONST_ASC("\\p \"");
2103 sStr += aTxt;
2104 sStr.AppendAscii(sEntryEnd);
2107 break;
2109 // case TOX_USER:
2110 // case TOX_CONTENT:
2111 default:
2113 sStr = FieldString(eCode);
2115 String sTOption;
2116 USHORT n, nTOXLvl = pTOX->GetLevel();
2117 if( !nTOXLvl )
2118 ++nTOXLvl;
2120 if( nsSwTOXElement::TOX_MARK & pTOX->GetCreateType() )
2122 sStr.APPEND_CONST_ASC( "\\f " );
2124 if( TOX_USER == pTOX->GetType() )
2126 sStr += '\"';
2127 sStr += (sal_Char)( 'A' + GetExport( ).GetId( *pTOX->GetTOXType() ) );
2128 sStr.AppendAscii( sEntryEnd );
2131 if( nsSwTOXElement::TOX_OUTLINELEVEL & pTOX->GetCreateType() )
2133 // --> OD 2009-02-27 #i99641#
2134 // The following code does not determine the minimum outline
2135 // level for the TOC
2136 // // Search over all the outline styles used and figure out
2137 // // what is the minimum outline level we need to display
2138 // // (ignoring headline styles 1-9)
2139 // //BYTE nLvl = 0, nMinLvl = 0; //#outline level, removed by zhaojianwei
2140 // int nLvl = 0, nMinLvl = 0; //<-end,add by zhaojianwei
2141 // const SwTxtFmtColls& rColls = *GetExport().pDoc->GetTxtFmtColls();
2142 // const SwTxtFmtColl* pColl;
2143 // for( n = rColls.Count(); n; )
2144 // {
2145 // pColl = rColls[ --n ];
2146 // //nLvl = pColl->GetOutlineLevel(); //#outline level,zhaojianwei
2147 // //USHORT nPoolId = pColl->GetPoolFmtId();
2148 // //if( MAXLEVEL > nLvl && nMinLvl < nLvl && //<-end, ->add by zhaojianwei
2149 // USHORT nPoolId = pColl->GetPoolFmtId();
2150 // if( pColl->IsAssignedToListLevelOfOutlineStyle() &&
2151 // nMinLvl < (nLvl = pColl->GetAssignedOutlineStyleLevel()) && //<-end,zhaojianwei
2152 // ( RES_POOLCOLL_HEADLINE1 > nPoolId ||
2153 // RES_POOLCOLL_HEADLINE9 < nPoolId ))
2154 // {
2155 // // If we are using the default heading styles then use nTOXLvl
2156 // if(!nMinLvl)
2157 // nLvl = nTOXLvl;
2158 // else
2159 // nLvl = nMinLvl < nTOXLvl ? nMinLvl : (BYTE)nTOXLvl;
2160 // nMinLvl = nLvl;
2161 // }
2162 // }
2163 const int nMinLvl = nTOXLvl;
2165 // if( nLvl )
2166 if ( nMinLvl > 0 )
2168 int nTmpLvl = nMinLvl;
2169 if (nTmpLvl > WW8ListManager::nMaxLevel)
2170 nTmpLvl = WW8ListManager::nMaxLevel;
2172 sStr.APPEND_CONST_ASC( "\\o \"1-" );
2173 sStr += String::CreateFromInt32( nTmpLvl );
2174 sStr.AppendAscii(sEntryEnd);
2177 // <--
2179 // --> OD 2009-02-27 #i99641#
2180 // not needed to additional export paragraph style with
2181 // an outline level to the /t option
2182 // if( nMinLvl > 0 )
2183 // // <--
2184 // {
2185 // // collect this templates into the \t otion
2186 // const SwTxtFmtColls& rColls = *pDoc->GetTxtFmtColls();
2187 // const SwTxtFmtColl* pColl;
2188 // int nLvl = 0;
2189 // for( n = rColls.Count(); n;)
2190 // {
2191 // pColl = rColls[--n];
2192 // //nLvl = pColl->GetOutlineLevel(); //#outline level, removed by zhaojianwei
2193 // //if (MAXLEVEL > nLvl && nMinLvl <= nLvl)
2194 // //{ //<-end, ->add by zhaojianwei
2195 // if( pColl->IsAssignedToListLevelOfOutlineStyle() &&
2196 // nMinLvl <= ( nLvl = pColl->GetAssignedOutlineStyleLevel()))
2197 // { //<-end,zhaojianwei
2198 // if( sTOption.Len() )
2199 // sTOption += ';';
2200 // (( sTOption += pColl->GetName() ) += ';' )
2201 // += String::CreateFromInt32( nLvl + 1 );
2202 // }
2203 // }
2204 // }
2209 if( nsSwTOXElement::TOX_OUTLINELEVEL & pTOX->GetCreateType() )
2211 // Take the TOC value of the max level to evaluate to as
2212 // the starting point for the \o flag, but reduce it to the
2213 // value of the highest outline level filled by a *standard*
2214 // Heading 1 - 9 style because \o "Builds a table of
2215 // contents from paragraphs formatted with built-in heading
2216 // styles". And afterward fill in any outline styles left
2217 // uncovered by that range to the \t flag
2219 // i.e. for
2220 // Heading 1
2221 // Heading 2
2222 // custom-style
2223 // Heading 4
2224 // output
2225 // \o 1-2 \tcustom-style,3,Heading 3,4
2227 // Search over all the outline styles used and figure out
2228 // what is the minimum outline level (if any) filled by a
2229 // non-standard style for that level, i.e. ignore headline
2230 // styles 1-9 and find the lowest valid outline level
2231 BYTE nPosOfLowestNonStandardLvl = MAXLEVEL;
2232 const SwTxtFmtColls& rColls = *GetExport().pDoc->GetTxtFmtColls();
2233 for( n = rColls.Count(); n; )
2235 const SwTxtFmtColl* pColl = rColls[ --n ];
2236 USHORT nPoolId = pColl->GetPoolFmtId();
2237 if (
2238 //Is a Non-Standard Outline Style
2239 (RES_POOLCOLL_HEADLINE1 > nPoolId || RES_POOLCOLL_HEADLINE9 < nPoolId) &&
2240 //Has a valid outline level
2241 (pColl->IsAssignedToListLevelOfOutlineStyle()) &&
2242 // Is less than the lowest known non-standard level
2243 (pColl->GetAssignedOutlineStyleLevel() < nPosOfLowestNonStandardLvl)
2246 nPosOfLowestNonStandardLvl = ::sal::static_int_cast<BYTE>(pColl->GetAssignedOutlineStyleLevel());
2250 BYTE nMaxMSAutoEvaluate = nPosOfLowestNonStandardLvl < nTOXLvl ? nPosOfLowestNonStandardLvl : (BYTE)nTOXLvl;
2252 //output \o 1-X where X is the highest normal outline style to be included in the toc
2253 if ( nMaxMSAutoEvaluate )
2255 if (nMaxMSAutoEvaluate > WW8ListManager::nMaxLevel)
2256 nMaxMSAutoEvaluate = WW8ListManager::nMaxLevel;
2258 sStr.APPEND_CONST_ASC( "\\o \"1-" );
2259 sStr += String::CreateFromInt32( nMaxMSAutoEvaluate );
2260 sStr.AppendAscii(sEntryEnd);
2263 //collect up any other styles in the writer TOC which will
2264 //not already appear in the MS TOC and place then into the
2265 //\t option
2266 if( nMaxMSAutoEvaluate < nTOXLvl )
2268 // collect this templates into the \t otion
2269 for( n = rColls.Count(); n;)
2271 const SwTxtFmtColl* pColl = rColls[ --n ];
2272 if (!pColl->IsAssignedToListLevelOfOutlineStyle())
2273 continue;
2274 BYTE nTestLvl = ::sal::static_int_cast<BYTE>(pColl->GetAssignedOutlineStyleLevel());
2275 if (nTestLvl < nTOXLvl && nTestLvl >= nMaxMSAutoEvaluate)
2277 if( sTOption.Len() )
2278 sTOption += ',';
2279 (( sTOption += pColl->GetName() ) += ',' )
2280 += String::CreateFromInt32( nTestLvl + 1 );
2286 if( nsSwTOXElement::TOX_TEMPLATE & pTOX->GetCreateType() )
2287 // --> OD 2009-02-27 #i99641#
2288 // Consider additional styles regardless of TOX-outlinelevel
2289 for( n = 0; n < MAXLEVEL; ++n )
2290 // <--
2292 const String& rStyles = pTOX->GetStyleNames( n );
2293 if( rStyles.Len() )
2295 xub_StrLen nPos = 0;
2296 String sLvl( ',' );
2297 sLvl += String::CreateFromInt32( n + 1 );
2298 do {
2299 String sStyle( rStyles.GetToken( 0,
2300 TOX_STYLE_DELIMITER, nPos ));
2301 if( sStyle.Len() )
2303 SwTxtFmtColl* pColl = GetExport().pDoc->FindTxtFmtCollByName(sStyle);
2304 if (!pColl->IsAssignedToListLevelOfOutlineStyle() || pColl->GetAssignedOutlineStyleLevel() < nTOXLvl)
2306 if( sTOption.Len() )
2307 sTOption += ',';
2308 ( sTOption += sStyle ) += sLvl;
2311 } while( STRING_NOTFOUND != nPos );
2316 String aFillTxt;
2317 BYTE nNoPgStt = MAXLEVEL, nNoPgEnd = MAXLEVEL;
2318 bool bFirstFillTxt = true, bOnlyText = true;
2319 for( n = 0; n < nTOXLvl; ++n )
2321 String aTxt;
2322 int nRet = ::lcl_CheckForm( pTOX->GetTOXForm(),
2323 static_cast< BYTE >(n+1), aTxt );
2324 if( 1 == nRet )
2326 bOnlyText = false;
2327 if( MAXLEVEL == nNoPgStt )
2328 nNoPgStt = static_cast< BYTE >(n+1);
2330 else
2332 if( MAXLEVEL != nNoPgStt &&
2333 MAXLEVEL == nNoPgEnd )
2334 nNoPgEnd = BYTE(n);
2336 bOnlyText = bOnlyText && 3 == nRet;
2337 if( 3 == nRet || 4 == nRet )
2339 if( bFirstFillTxt )
2340 aFillTxt = aTxt;
2341 else if( aFillTxt != aTxt )
2342 aFillTxt.Erase();
2343 bFirstFillTxt = false;
2347 if( MAXLEVEL != nNoPgStt )
2349 if (WW8ListManager::nMaxLevel < nNoPgEnd)
2350 nNoPgEnd = WW8ListManager::nMaxLevel;
2351 sStr.APPEND_CONST_ASC( "\\n " );
2352 sStr += String::CreateFromInt32( nNoPgStt );
2353 sStr += '-';
2354 sStr += String::CreateFromInt32( nNoPgEnd );
2355 sStr += ' ';
2357 if( bOnlyText )
2359 sStr.APPEND_CONST_ASC( "\\p \"" );
2360 sStr += aFillTxt;
2361 sStr.AppendAscii(sEntryEnd);
2365 if( sTOption.Len() )
2367 sStr.APPEND_CONST_ASC( "\\t \"" );
2368 sStr += sTOption;
2369 sStr.AppendAscii(sEntryEnd);
2372 if (lcl_IsHyperlinked(pTOX->GetTOXForm(), nTOXLvl))
2373 sStr.APPEND_CONST_ASC("\\h");
2375 break;
2379 if( sStr.Len() )
2381 GetExport( ).bInWriteTOX = true;
2382 GetExport( ).OutputField( 0, eCode, sStr, WRITEFIELD_START | WRITEFIELD_CMD_START |
2383 WRITEFIELD_CMD_END );
2387 GetExport( ).bStartTOX = false;
2390 void AttributeOutputBase::EndTOX( const SwSection& rSect )
2392 const SwTOXBase* pTOX = rSect.GetTOXBase();
2393 if ( pTOX )
2395 ww::eField eCode = TOX_INDEX == pTOX->GetType() ? ww::eINDEX : ww::eTOC;
2396 GetExport( ).OutputField( 0, eCode, aEmptyStr, WRITEFIELD_CLOSE );
2398 GetExport( ).bInWriteTOX = false;
2401 bool MSWordExportBase::GetNumberFmt(const SwField& rFld, String& rStr)
2403 // Returns a date or time format string by using the US NfKeywordTable
2404 bool bHasFmt = false;
2405 SvNumberFormatter* pNFmtr = pDoc->GetNumberFormatter();
2406 UINT32 nFmtIdx = rFld.GetFormat();
2407 const SvNumberformat* pNumFmt = pNFmtr->GetEntry( nFmtIdx );
2408 if( pNumFmt )
2410 //USHORT nLng = rFld.GetLanguage();
2411 LocaleDataWrapper aLocDat( pNFmtr->GetServiceManager(),
2412 MsLangId::convertLanguageToLocale( LANGUAGE_ENGLISH_US ) );
2414 if( !pKeyMap )
2416 pKeyMap = new NfKeywordTable;
2417 NfKeywordTable& rKeyMap = *(NfKeywordTable*)pKeyMap;
2418 pNFmtr->FillKeywordTable( rKeyMap, LANGUAGE_ENGLISH_US );
2421 String sFmt(pNumFmt->GetMappedFormatstring(*(NfKeywordTable*)pKeyMap,
2422 aLocDat));
2423 if (sFmt.Len())
2425 sw::ms::SwapQuotesInField(sFmt);
2427 rStr.APPEND_CONST_ASC( "\\@\"" );
2428 rStr += sFmt;
2429 rStr.APPEND_CONST_ASC( "\" " );
2430 bHasFmt = true;
2433 return bHasFmt;
2436 void AttributeOutputBase::GetNumberPara( String& rStr, const SwField& rFld )
2438 switch(rFld.GetFormat())
2440 case SVX_NUM_CHARS_UPPER_LETTER:
2441 case SVX_NUM_CHARS_UPPER_LETTER_N:
2442 rStr.APPEND_CONST_ASC( "\\*ALPHABETIC ");
2443 break;
2444 case SVX_NUM_CHARS_LOWER_LETTER:
2445 case SVX_NUM_CHARS_LOWER_LETTER_N:
2446 rStr.APPEND_CONST_ASC("\\*alphabetic ");
2447 break;
2448 case SVX_NUM_ROMAN_UPPER:
2449 rStr.APPEND_CONST_ASC("\\*ROMAN ");
2450 break;
2451 case SVX_NUM_ROMAN_LOWER:
2452 rStr.APPEND_CONST_ASC("\\*roman ");
2453 break;
2454 default:
2455 ASSERT(rFld.GetFormat() == SVX_NUM_ARABIC,
2456 "Unknown numbering type exported as default\n");
2457 case SVX_NUM_ARABIC:
2458 rStr.APPEND_CONST_ASC("\\*Arabic ");
2459 break;
2460 case SVX_NUM_PAGEDESC:
2461 //Nothing, use word's default
2462 break;
2466 void WW8Export::WritePostItBegin( WW8Bytes* pOut )
2468 BYTE aArr[ 3 ];
2469 BYTE* pArr = aArr;
2471 // sprmCFSpec true
2472 if( bWrtWW8 )
2473 Set_UInt16( pArr, NS_sprm::LN_CFSpec );
2474 else
2475 Set_UInt8( pArr, 117 ); //sprmCFSpec
2476 Set_UInt8( pArr, 1 );
2478 pChpPlc->AppendFkpEntry( Strm().Tell() );
2479 WriteChar( 0x05 ); // Annotation reference
2481 if( pOut )
2482 pOut->Insert( aArr, static_cast< USHORT >(pArr - aArr), pOut->Count() );
2483 else
2484 pChpPlc->AppendFkpEntry( Strm().Tell(), static_cast< short >(pArr - aArr), aArr );
2487 String FieldString(ww::eField eIndex)
2489 String sRet(CREATE_CONST_ASC(" "));
2490 if (const char *pField = ww::GetEnglishFieldName(eIndex))
2491 sRet.InsertAscii(pField, 1);
2492 return sRet;
2495 void WW8AttributeOutput::HiddenField( const SwField& rFld )
2497 String sExpand(rFld.GetPar2());
2499 //replace LF 0x0A with VT 0x0B
2500 sExpand.SearchAndReplaceAll(0x0A, 0x0B);
2501 m_rWW8Export.pChpPlc->AppendFkpEntry(m_rWW8Export.Strm().Tell());
2502 if (m_rWW8Export.IsUnicode())
2504 SwWW8Writer::WriteString16(m_rWW8Export.Strm(), sExpand, false);
2505 static BYTE aArr[] =
2507 0x3C, 0x08, 0x1
2509 m_rWW8Export.pChpPlc->AppendFkpEntry(m_rWW8Export.Strm().Tell(), sizeof(aArr), aArr);
2511 else
2513 SwWW8Writer::WriteString8(m_rWW8Export.Strm(), sExpand, false,
2514 RTL_TEXTENCODING_MS_1252);
2515 static BYTE aArr[] =
2517 92, 0x1
2519 m_rWW8Export.pChpPlc->AppendFkpEntry(m_rWW8Export.Strm().Tell(), sizeof(aArr), aArr);
2523 void WW8AttributeOutput::SetField( const SwField& rFld, ww::eField eType, const String& rCmd )
2525 const SwSetExpField* pSet=(const SwSetExpField*)(&rFld);
2526 const String &rVar = pSet->GetPar2();
2528 ULONG nFrom = m_rWW8Export.Fc2Cp(m_rWW8Export.Strm().Tell());
2530 GetExport().OutputField(&rFld, eType, rCmd, WRITEFIELD_START |
2531 WRITEFIELD_CMD_START | WRITEFIELD_CMD_END);
2534 Is there a bookmark at the start position of this field, if so
2535 move it to the 0x14 of the result of the field. This is what word
2536 does. MoveFieldMarks moves any bookmarks at this position to
2537 the beginning of the field result, and marks the bookmark as a
2538 fieldbookmark which is to be ended before the field end mark
2539 instead of after it like a normal bookmark.
2541 m_rWW8Export.MoveFieldMarks(nFrom,m_rWW8Export.Fc2Cp(m_rWW8Export.Strm().Tell()));
2543 if (rVar.Len())
2545 if (m_rWW8Export.IsUnicode())
2546 SwWW8Writer::WriteString16(m_rWW8Export.Strm(), rVar, false);
2547 else
2549 SwWW8Writer::WriteString8(m_rWW8Export.Strm(), rVar, false,
2550 RTL_TEXTENCODING_MS_1252);
2553 GetExport().OutputField(&rFld, eType, rCmd, WRITEFIELD_CLOSE);
2556 void WW8AttributeOutput::PostitField( const SwField* pFld )
2558 const SwPostItField& rPFld = *(SwPostItField*)pFld;
2559 m_rWW8Export.pAtn->Append( m_rWW8Export.Fc2Cp( m_rWW8Export.Strm().Tell() ), rPFld );
2560 m_rWW8Export.WritePostItBegin( m_rWW8Export.pO );
2563 bool WW8AttributeOutput::DropdownField( const SwField* pFld )
2565 bool bExpand = true;
2566 if ( m_rWW8Export.bWrtWW8 )
2568 const SwDropDownField& rFld2 = *(SwDropDownField*)pFld;
2569 uno::Sequence<rtl::OUString> aItems =
2570 rFld2.GetItemSequence();
2571 GetExport().DoComboBox(rFld2.GetName(),
2572 rFld2.GetHelp(),
2573 rFld2.GetToolTip(),
2574 rFld2.GetSelectedItem(), aItems);
2575 bExpand = false;
2577 return bExpand;
2580 void WW8AttributeOutput::RefField( const SwField &rFld, const String &rRef)
2582 String sStr( FieldString( ww::eREF ) );
2583 sStr.APPEND_CONST_ASC( "\"" );
2584 sStr += rRef;
2585 sStr.APPEND_CONST_ASC( "\" " );
2586 m_rWW8Export.OutputField( &rFld, ww::eREF, sStr, WRITEFIELD_START |
2587 WRITEFIELD_CMD_START | WRITEFIELD_CMD_END );
2588 String sVar = lcl_GetExpandedField( rFld );
2589 if ( sVar.Len() )
2591 if ( m_rWW8Export.IsUnicode() )
2592 SwWW8Writer::WriteString16( m_rWW8Export.Strm(), sVar, false );
2593 else
2595 SwWW8Writer::WriteString8( m_rWW8Export.Strm(), sVar, false,
2596 RTL_TEXTENCODING_MS_1252 );
2599 m_rWW8Export.OutputField( &rFld, ww::eREF, sStr, WRITEFIELD_CLOSE );
2602 void WW8AttributeOutput::WriteExpand( const SwField* pFld )
2604 String sExpand( lcl_GetExpandedField( *pFld ) );
2605 if ( m_rWW8Export.IsUnicode() )
2606 SwWW8Writer::WriteString16( m_rWW8Export.Strm(), sExpand, false );
2607 else
2609 SwWW8Writer::WriteString8( m_rWW8Export.Strm(), sExpand, false,
2610 RTL_TEXTENCODING_MS_1252 );
2614 void AttributeOutputBase::TextField( const SwFmtFld& rField )
2616 const SwField* pFld = rField.GetFld();
2617 String sStr; // fuer optionale Parameter
2618 bool bWriteExpand = false;
2619 USHORT nSubType = pFld->GetSubType();
2621 switch (pFld->GetTyp()->Which())
2623 case RES_GETEXPFLD:
2624 if (nSubType == nsSwGetSetExpType::GSE_STRING)
2626 const SwGetExpField *pGet=(const SwGetExpField*)(pFld);
2627 RefField( *pGet, pGet->GetFormula() );
2629 else
2630 bWriteExpand = true;
2631 break;
2632 case RES_SETEXPFLD:
2633 if (nsSwGetSetExpType::GSE_SEQ == nSubType)
2635 sStr = FieldString(ww::eSEQ);
2636 sStr.APPEND_CONST_ASC("\"");
2637 sStr += pFld->GetTyp()->GetName();
2638 sStr.APPEND_CONST_ASC( "\" " );
2640 GetNumberPara( sStr, *pFld );
2641 GetExport().OutputField(pFld, ww::eSEQ, sStr);
2643 else if (nSubType & nsSwGetSetExpType::GSE_STRING)
2645 bool bShowAsWell = false;
2646 ww::eField eFieldNo;
2647 const SwSetExpField *pSet=(const SwSetExpField*)(pFld);
2648 const String &rVar = pSet->GetPar2();
2649 if (pSet->GetInputFlag())
2651 sStr = FieldString(ww::eASK);
2652 sStr.APPEND_CONST_ASC("\"");
2653 sStr += pSet->GetPar1();
2654 sStr.APPEND_CONST_ASC( "\" " );
2655 sStr += pSet->GetPromptText();
2656 sStr.APPEND_CONST_ASC( " \\d " );
2657 sStr += rVar;
2658 eFieldNo = ww::eASK;
2660 else
2662 sStr = FieldString(ww::eSET);
2663 sStr += pSet->GetPar1();
2664 sStr.APPEND_CONST_ASC(" \"");
2665 sStr += rVar;
2666 sStr.APPEND_CONST_ASC("\" ");
2667 eFieldNo = ww::eSET;
2668 bShowAsWell = (nSubType & nsSwExtendedSubType::SUB_INVISIBLE) ? false : true;
2671 SetField( *pFld, eFieldNo, sStr );
2673 if (bShowAsWell)
2674 RefField( *pSet, pSet->GetPar1() );
2676 else
2677 bWriteExpand = true;
2678 break;
2679 case RES_PAGENUMBERFLD:
2680 sStr = FieldString(ww::ePAGE);
2681 GetNumberPara(sStr, *pFld);
2682 GetExport().OutputField(pFld, ww::ePAGE, sStr);
2683 break;
2684 case RES_FILENAMEFLD:
2685 sStr = FieldString(ww::eFILENAME);
2686 if (pFld->GetFormat() == FF_PATHNAME)
2687 sStr.APPEND_CONST_ASC("\\p ");
2688 GetExport().OutputField(pFld, ww::eFILENAME, sStr);
2689 break;
2690 case RES_DBNAMEFLD:
2692 sStr = FieldString(ww::eDATABASE);
2693 SwDBData aData = GetExport().pDoc->GetDBData();
2694 sStr += String(aData.sDataSource);
2695 sStr += DB_DELIM;
2696 sStr += String(aData.sCommand);
2697 GetExport().OutputField(pFld, ww::eDATABASE, sStr);
2699 break;
2700 case RES_AUTHORFLD:
2702 ww::eField eFld =
2703 (AF_SHORTCUT & nSubType ? ww::eUSERINITIALS : ww::eUSERNAME);
2704 GetExport().OutputField(pFld, eFld, FieldString(eFld));
2706 break;
2707 case RES_TEMPLNAMEFLD:
2708 GetExport().OutputField(pFld, ww::eTEMPLATE, FieldString(ww::eTEMPLATE));
2709 break;
2710 case RES_DOCINFOFLD: // Last printed, last edited,...
2711 if( DI_SUB_FIXED & nSubType )
2712 bWriteExpand = true;
2713 else
2715 ww::eField eFld(ww::eNONE);
2716 switch (0xff & nSubType)
2718 case DI_TITEL:
2719 eFld = ww::eTITLE;
2720 break;
2721 case DI_THEMA:
2722 eFld = ww::eSUBJECT;
2723 break;
2724 case DI_KEYS:
2725 eFld = ww::eKEYWORDS;
2726 break;
2727 case DI_COMMENT:
2728 eFld = ww::eCOMMENTS;
2729 break;
2730 case DI_DOCNO:
2731 eFld = ww::eREVNUM;
2732 break;
2733 case DI_CREATE:
2734 if (DI_SUB_AUTHOR == (nSubType & DI_SUB_MASK))
2735 eFld = ww::eAUTHOR;
2736 else if (GetExport().GetNumberFmt(*pFld, sStr))
2737 eFld = ww::eCREATEDATE;
2738 break;
2740 case DI_CHANGE:
2741 if (DI_SUB_AUTHOR == (nSubType & DI_SUB_MASK))
2742 eFld = ww::eLASTSAVEDBY;
2743 else if (GetExport().GetNumberFmt(*pFld, sStr))
2744 eFld = ww::eSAVEDATE;
2745 break;
2747 case DI_PRINT:
2748 if (DI_SUB_AUTHOR != (nSubType & DI_SUB_MASK) &&
2749 GetExport().GetNumberFmt(*pFld, sStr))
2750 eFld = ww::ePRINTDATE;
2751 break;
2752 case DI_EDIT:
2753 if( DI_SUB_AUTHOR != (nSubType & DI_SUB_MASK ) &&
2754 GetExport().GetNumberFmt( *pFld, sStr ))
2755 eFld = ww::eSAVEDATE;
2756 break;
2757 case DI_CUSTOM:
2758 eFld = ww::eDOCPROPERTY;
2760 static String sQuotes('\"');
2761 const SwDocInfoField * pDocInfoField =
2762 dynamic_cast<const SwDocInfoField *> (pFld);
2764 if (pDocInfoField != NULL)
2766 String sFieldname = pDocInfoField->GetCntnt(TRUE);
2767 xub_StrLen nIndex = sFieldname.Search(':');
2769 if (nIndex != sFieldname.Len())
2770 sFieldname = sFieldname.Copy(nIndex + 1);
2772 sStr.Insert(sQuotes);
2773 sStr.Insert(sFieldname);
2774 sStr.Insert(sQuotes);
2777 break;
2778 default:
2779 break;
2782 if (eFld != ww::eNONE)
2784 sStr.Insert(FieldString(eFld), 0);
2785 GetExport().OutputField(pFld, eFld, sStr);
2787 else
2788 bWriteExpand = true;
2790 break;
2791 case RES_DATETIMEFLD:
2792 if (FIXEDFLD & nSubType || !GetExport().GetNumberFmt(*pFld, sStr))
2793 bWriteExpand = true;
2794 else
2796 ww::eField eFld = (DATEFLD & nSubType) ? ww::eDATE : ww::eTIME;
2797 sStr.Insert(FieldString(eFld), 0);
2798 GetExport().OutputField(pFld, eFld, sStr);
2800 break;
2801 case RES_DOCSTATFLD:
2803 ww::eField eFld = ww::eNONE;
2805 switch (nSubType)
2807 case DS_PAGE:
2808 eFld = ww::eNUMPAGE;
2809 break;
2810 case DS_WORD:
2811 eFld = ww::eNUMWORDS;
2812 break;
2813 case DS_CHAR:
2814 eFld = ww::eNUMCHARS;
2815 break;
2818 if (eFld != ww::eNONE)
2820 sStr = FieldString(eFld);
2821 GetNumberPara(sStr, *pFld);
2822 GetExport().OutputField(pFld, eFld, sStr);
2824 else
2825 bWriteExpand = true;
2827 break;
2828 case RES_EXTUSERFLD:
2830 ww::eField eFld = ww::eNONE;
2831 switch (0xFF & nSubType)
2833 case EU_FIRSTNAME:
2834 case EU_NAME:
2835 eFld = ww::eUSERNAME;
2836 break;
2837 case EU_SHORTCUT:
2838 eFld = ww::eUSERINITIALS;
2839 break;
2840 case EU_STREET:
2841 case EU_COUNTRY:
2842 case EU_ZIP:
2843 case EU_CITY:
2844 eFld = ww::eUSERADDRESS;
2845 break;
2848 if (eFld != ww::eNONE)
2850 sStr = FieldString(eFld);
2851 GetExport().OutputField(pFld, eFld, sStr);
2853 else
2854 bWriteExpand = true;
2856 break;
2857 case RES_POSTITFLD:
2858 //Sadly only possible for word in main document text
2859 if (GetExport().nTxtTyp == TXT_MAINTEXT)
2861 PostitField( pFld );
2863 break;
2864 case RES_INPUTFLD:
2866 const SwInputField * pInputField =
2867 dynamic_cast<const SwInputField *>(pFld);
2869 if (pInputField->isFormField())
2870 GetExport().DoFormText(pInputField);
2871 else
2873 sStr = FieldString(ww::eFILLIN);
2875 sStr.APPEND_CONST_ASC("\"");
2876 sStr += pFld->GetPar2();
2877 sStr += '\"';
2879 GetExport().OutputField(pFld, ww::eFILLIN, sStr);
2882 break;
2883 case RES_GETREFFLD:
2885 ww::eField eFld = ww::eNONE;
2886 const SwGetRefField& rRFld = *(SwGetRefField*)pFld;
2887 switch (nSubType)
2889 case REF_SETREFATTR:
2890 case REF_BOOKMARK:
2891 switch (pFld->GetFormat())
2893 case REF_PAGE_PGDESC:
2894 case REF_PAGE:
2895 eFld = ww::ePAGEREF;
2896 break;
2897 default:
2898 eFld = ww::eREF;
2899 break;
2901 sStr = FieldString(eFld);
2902 sStr += GetExport().GetBookmarkName(nSubType,
2903 &rRFld.GetSetRefName(), 0);
2904 break;
2905 case REF_FOOTNOTE:
2906 case REF_ENDNOTE:
2907 switch (pFld->GetFormat())
2909 case REF_PAGE_PGDESC:
2910 case REF_PAGE:
2911 eFld = ww::ePAGEREF;
2912 break;
2913 case REF_UPDOWN:
2914 eFld = ww::eREF;
2915 break;
2916 default:
2917 eFld =
2918 REF_ENDNOTE == nSubType ? ww::eNOTEREF : ww::eFOOTREF;
2919 break;
2921 sStr = FieldString(eFld);
2922 sStr += GetExport().GetBookmarkName(nSubType, 0,
2923 rRFld.GetSeqNo());
2924 break;
2927 if (eFld != ww::eNONE)
2929 switch (pFld->GetFormat())
2931 case REF_UPDOWN:
2932 sStr.APPEND_CONST_ASC(" \\p");
2933 break;
2934 case REF_CHAPTER:
2935 sStr.APPEND_CONST_ASC(" \\n");
2936 break;
2937 default:
2938 break;
2940 sStr.APPEND_CONST_ASC(" \\h "); // insert hyperlink
2941 GetExport().OutputField(pFld, eFld, sStr);
2943 else
2944 bWriteExpand = true;
2946 break;
2947 case RES_COMBINED_CHARS:
2950 We need a font size to fill in the defaults, if these are overridden
2951 (as they generally are) by character properties then those properties
2952 win.
2954 The fontsize that is used in MS for determing the defaults is always
2955 the CJK fontsize even if the text is not in that language, in OOo the
2956 largest fontsize used in the field is the one we should take, but
2957 whatever we do, word will actually render using the fontsize set for
2958 CJK text. Nevertheless we attempt to guess whether the script is in
2959 asian or western text based up on the first character and use the
2960 font size of that script as our default.
2962 USHORT nScript;
2963 if( pBreakIt->GetBreakIter().is() )
2964 nScript = pBreakIt->GetBreakIter()->getScriptType( pFld->GetPar1(), 0);
2965 else
2966 nScript = i18n::ScriptType::ASIAN;
2968 long nHeight = ((SvxFontHeightItem&)(GetExport().GetItem(
2969 GetWhichOfScript(RES_CHRATR_FONTSIZE,nScript)))).GetHeight();;
2971 nHeight = (nHeight + 10) / 20; //Font Size in points;
2974 Divide the combined char string into its up and down part. Get the
2975 font size and fill in the defaults as up == half the font size and
2976 down == a fifth the font size
2978 xub_StrLen nAbove = (pFld->GetPar1().Len()+1)/2;
2979 sStr = FieldString(ww::eEQ);
2980 sStr.APPEND_CONST_ASC("\\o (\\s\\up ");
2981 sStr += String::CreateFromInt32(nHeight/2);
2983 sStr.Append('(');
2984 sStr += String(pFld->GetPar1(),0,nAbove);
2985 sStr.APPEND_CONST_ASC("), \\s\\do ");
2986 sStr += String::CreateFromInt32(nHeight/5);
2988 sStr.Append('(');
2989 sStr += String(pFld->GetPar1(),nAbove,pFld->GetPar1().Len()-nAbove);
2990 sStr.APPEND_CONST_ASC("))");
2991 GetExport().OutputField(pFld, ww::eEQ, sStr);
2993 break;
2994 case RES_DROPDOWN:
2995 bWriteExpand = DropdownField( pFld );
2996 break;
2997 case RES_CHAPTERFLD:
2998 bWriteExpand = true;
2999 if (GetExport().bOutKF && rField.GetTxtFld())
3001 const SwTxtNode *pTxtNd = GetExport().GetHdFtPageRoot();
3002 if (!pTxtNd)
3004 if (const SwNode *pNd = GetExport().pCurPam->GetNode())
3005 pTxtNd = pNd->GetTxtNode();
3008 if (pTxtNd)
3010 SwChapterField aCopy(*(const SwChapterField*)pFld);
3011 aCopy.ChangeExpansion(*pTxtNd, false);
3012 WriteExpand( &aCopy );
3013 bWriteExpand = false;
3016 break;
3017 case RES_HIDDENTXTFLD:
3019 String sExpand(pFld->GetPar2());
3020 if (sExpand.Len())
3022 HiddenField( *pFld );
3025 break;
3026 default:
3027 bWriteExpand = true;
3028 break;
3031 if (bWriteExpand)
3032 WriteExpand( pFld );
3035 void AttributeOutputBase::TextFlyContent( const SwFmtFlyCnt& rFlyContent )
3037 if ( GetExport().pOutFmtNode && GetExport().pOutFmtNode->ISA( SwCntntNode ) )
3039 SwTxtNode* pTxtNd = (SwTxtNode*)GetExport().pOutFmtNode;
3041 Point aLayPos;
3042 aLayPos = pTxtNd->FindLayoutRect( false, &aLayPos ).Pos();
3044 SwPosition aPos( *pTxtNd );
3045 sw::Frame aFrm( *rFlyContent.GetFrmFmt(), aPos );
3047 OutputFlyFrame_Impl( aFrm, aLayPos );
3051 // TOXMarks fehlen noch
3053 // Detaillierte Einstellungen zur Trennung erlaubt WW nur dokumentenweise.
3054 // Man koennte folgende Mimik einbauen: Die Werte des Style "Standard" werden,
3055 // falls vorhanden, in die Document Properties ( DOP ) gesetzt.
3056 // ---
3057 // ACK. Dieser Vorschlag passt exakt zu unserer Implementierung des Import,
3058 // daher setze ich das gleich mal um. (KHZ, 07/15/2000)
3059 void WW8AttributeOutput::ParaHyphenZone( const SvxHyphenZoneItem& rHyphenZone )
3061 // sprmPFNoAutoHyph
3062 if( m_rWW8Export.bWrtWW8 )
3063 m_rWW8Export.InsUInt16( NS_sprm::LN_PFNoAutoHyph );
3064 else
3065 m_rWW8Export.pO->Insert( 44, m_rWW8Export.pO->Count() );
3067 m_rWW8Export.pO->Insert( rHyphenZone.IsHyphen() ? 0 : 1, m_rWW8Export.pO->Count() );
3070 void WW8AttributeOutput::ParaScriptSpace( const SfxBoolItem& rScriptSpace )
3072 USHORT nId = 0;
3073 if ( m_rWW8Export.bWrtWW8 )
3074 switch ( rScriptSpace.Which() )
3076 case RES_PARATR_SCRIPTSPACE: nId = NS_sprm::LN_PFAutoSpaceDE; break;
3077 case RES_PARATR_HANGINGPUNCTUATION: nId = NS_sprm::LN_PFOverflowPunct; break;
3078 case RES_PARATR_FORBIDDEN_RULES: nId = NS_sprm::LN_PFKinsoku; break;
3081 if ( nId )
3083 if( m_rWW8Export.bWrtWW8 )
3084 m_rWW8Export.InsUInt16( nId );
3085 else
3086 m_rWW8Export.pO->Insert( (BYTE)nId, m_rWW8Export.pO->Count() );
3088 m_rWW8Export.pO->Insert( rScriptSpace.GetValue() ? 1 : 0,
3089 m_rWW8Export.pO->Count() );
3093 void WW8AttributeOutput::ParaSnapToGrid( const SvxParaGridItem& rGrid )
3095 // sprmPFUsePgsuSettings
3096 // 97+ only
3097 if ( !m_rWW8Export.bWrtWW8 )
3098 return;
3100 m_rWW8Export.InsUInt16( NS_sprm::LN_PFUsePgsuSettings );
3101 m_rWW8Export.pO->Insert( rGrid.GetValue(), m_rWW8Export.pO->Count() );
3104 void WW8AttributeOutput::ParaVerticalAlign( const SvxParaVertAlignItem& rAlign )
3106 // sprmPWAlignFont
3107 // 97+ only
3108 if( !m_rWW8Export.bWrtWW8 )
3109 return;
3111 m_rWW8Export.InsUInt16( NS_sprm::LN_PWAlignFont );
3113 INT16 nVal = rAlign.GetValue();
3114 switch ( nVal )
3116 case SvxParaVertAlignItem::BASELINE:
3117 nVal = 2;
3118 break;
3119 case SvxParaVertAlignItem::TOP:
3120 nVal = 0;
3121 break;
3122 case SvxParaVertAlignItem::CENTER:
3123 nVal = 1;
3124 break;
3125 case SvxParaVertAlignItem::BOTTOM:
3126 nVal = 3;
3127 break;
3128 case SvxParaVertAlignItem::AUTOMATIC:
3129 nVal = 4;
3130 break;
3131 default:
3132 nVal = 4;
3133 ASSERT( false, "Unknown vert alignment" );
3134 break;
3136 m_rWW8Export.InsUInt16( nVal );
3140 // NoHyphen: ich habe keine Entsprechung in der SW-UI und WW-UI gefunden
3143 // RefMark, NoLineBreakHere fehlen noch
3145 void WW8Export::WriteFtnBegin( const SwFmtFtn& rFtn, WW8Bytes* pOutArr )
3147 WW8Bytes aAttrArr;
3148 bool bAutoNum = !rFtn.GetNumStr().Len(); // Auto-Nummer
3149 if( bAutoNum )
3151 if( bWrtWW8 )
3153 static const BYTE aSpec[] =
3155 0x03, 0x6a, 0, 0, 0, 0, // sprmCObjLocation
3156 0x55, 0x08, 1 // sprmCFSpec
3159 aAttrArr.Insert(aSpec, sizeof(aSpec), aAttrArr.Count());
3161 else
3163 static BYTE const aSpec[] =
3165 117, 1, // sprmCFSpec
3166 68, 4, 0, 0, 0, 0 // sprmCObjLocation
3169 aAttrArr.Insert(aSpec, sizeof(aSpec), aAttrArr.Count());
3173 // sprmCIstd
3174 const SwEndNoteInfo* pInfo;
3175 if( rFtn.IsEndNote() )
3176 pInfo = &pDoc->GetEndNoteInfo();
3177 else
3178 pInfo = &pDoc->GetFtnInfo();
3179 const SwCharFmt* pCFmt = pOutArr
3180 ? pInfo->GetAnchorCharFmt( *pDoc )
3181 : pInfo->GetCharFmt( *pDoc );
3182 if( bWrtWW8 )
3183 SwWW8Writer::InsUInt16( aAttrArr, NS_sprm::LN_CIstd );
3184 else
3185 aAttrArr.Insert( 80, aAttrArr.Count() );
3186 SwWW8Writer::InsUInt16( aAttrArr, GetId( *pCFmt ) );
3188 // fSpec-Attribut true
3189 // Fuer Auto-Nummer muss ein Spezial-Zeichen
3190 // in den Text und darum ein fSpec-Attribut
3191 pChpPlc->AppendFkpEntry( Strm().Tell() );
3192 if( bAutoNum )
3193 WriteChar( 0x02 ); // Auto-Nummer-Zeichen
3194 else
3195 // User-Nummerierung
3196 OutSwString( rFtn.GetNumStr(), 0, rFtn.GetNumStr().Len(),
3197 IsUnicode(), RTL_TEXTENCODING_MS_1252 );
3199 if( pOutArr )
3201 // insert at start of array, so the "hard" attribute overrule the
3202 // attributes of the character template
3203 pOutArr->Insert( &aAttrArr, 0 );
3205 else
3207 WW8Bytes aOutArr;
3209 // insert at start of array, so the "hard" attribute overrule the
3210 // attributes of the character template
3211 aOutArr.Insert( &aAttrArr, 0 );
3213 // write for the ftn number in the content, the font of the anchor
3214 const SwTxtFtn* pTxtFtn = rFtn.GetTxtFtn();
3215 if( pTxtFtn )
3217 WW8Bytes* pOld = pO;
3218 pO = &aOutArr;
3219 SfxItemSet aSet( pDoc->GetAttrPool(), RES_CHRATR_FONT,
3220 RES_CHRATR_FONT );
3222 pCFmt = pInfo->GetCharFmt( *pDoc );
3223 aSet.Set( pCFmt->GetAttrSet() );
3225 pTxtFtn->GetTxtNode().GetAttr( aSet, *pTxtFtn->GetStart(),
3226 (*pTxtFtn->GetStart()) + 1 );
3227 m_pAttrOutput->OutputItem( aSet.Get( RES_CHRATR_FONT ) );
3228 pO = pOld;
3230 pChpPlc->AppendFkpEntry( Strm().Tell(), aOutArr.Count(),
3231 aOutArr.GetData() );
3235 static bool lcl_IsAtTxtEnd(const SwFmtFtn& rFtn)
3237 bool bRet = true;
3238 if( rFtn.GetTxtFtn() )
3240 USHORT nWh = static_cast< USHORT >(rFtn.IsEndNote() ? RES_END_AT_TXTEND
3241 : RES_FTN_AT_TXTEND);
3242 const SwSectionNode* pSectNd = rFtn.GetTxtFtn()->GetTxtNode().
3243 FindSectionNode();
3244 while( pSectNd && FTNEND_ATPGORDOCEND ==
3245 ((const SwFmtFtnAtTxtEnd&)pSectNd->GetSection().GetFmt()->
3246 GetFmtAttr( nWh, true)).GetValue() )
3247 pSectNd = pSectNd->StartOfSectionNode()->FindSectionNode();
3249 if (!pSectNd)
3250 bRet = false; // the is ftn/end collected at Page- or Doc-End
3252 return bRet;
3256 void AttributeOutputBase::TextFootnote( const SwFmtFtn& rFtn )
3258 USHORT nTyp;
3259 if ( rFtn.IsEndNote() )
3261 nTyp = REF_ENDNOTE;
3262 if ( GetExport().bEndAtTxtEnd )
3263 GetExport().bEndAtTxtEnd = lcl_IsAtTxtEnd( rFtn );
3265 else
3267 nTyp = REF_FOOTNOTE;
3268 if ( GetExport().bFtnAtTxtEnd )
3269 GetExport().bFtnAtTxtEnd = lcl_IsAtTxtEnd( rFtn );
3272 // if any reference to this footnote/endnote then insert an internal
3273 // Bookmark.
3274 String sBkmkNm;
3275 if ( GetExport().HasRefToObject( nTyp, 0, rFtn.GetTxtFtn()->GetSeqRefNo() ))
3277 sBkmkNm = GetExport().GetBookmarkName( nTyp, 0,
3278 rFtn.GetTxtFtn()->GetSeqRefNo() );
3279 GetExport().AppendBookmark( sBkmkNm );
3282 TextFootnote_Impl( rFtn );
3284 if ( sBkmkNm.Len() )
3285 GetExport().AppendBookmark( sBkmkNm ); // FIXME: Why is it added twice? Shouldn't this one go to WW8AttributeOuput::TextFootnote_Impl()?
3288 void WW8AttributeOutput::TextFootnote_Impl( const SwFmtFtn& rFtn )
3290 WW8_WrPlcFtnEdn* pFtnEnd;
3291 if ( rFtn.IsEndNote() )
3292 pFtnEnd = m_rWW8Export.pEdn;
3293 else
3294 pFtnEnd = m_rWW8Export.pFtn;
3296 pFtnEnd->Append( m_rWW8Export.Fc2Cp( m_rWW8Export.Strm().Tell() ), rFtn );
3297 m_rWW8Export.WriteFtnBegin( rFtn, m_rWW8Export.pO );
3300 void WW8AttributeOutput::TextCharFormat( const SwFmtCharFmt& rCharFmt )
3302 if( rCharFmt.GetCharFmt() )
3304 if( m_rWW8Export.bWrtWW8 )
3305 m_rWW8Export.InsUInt16( NS_sprm::LN_CIstd );
3306 else
3307 m_rWW8Export.pO->Insert( 80, m_rWW8Export.pO->Count() );
3309 m_rWW8Export.InsUInt16( m_rWW8Export.GetId( *rCharFmt.GetCharFmt() ) );
3314 See ww8par6.cxx Read_DoubleLine for some more info
3316 void WW8AttributeOutput::CharTwoLines( const SvxTwoLinesItem& rTwoLines )
3318 // #i28331# - check that bOn is set
3319 if ( rTwoLines.GetValue() )
3321 //97+ only
3322 if( !m_rWW8Export.bWrtWW8 )
3323 return;
3325 m_rWW8Export.InsUInt16( NS_sprm::LN_CEastAsianLayout );
3326 m_rWW8Export.pO->Insert( (BYTE)0x06, m_rWW8Export.pO->Count() ); //len 6
3327 m_rWW8Export.pO->Insert( (BYTE)0x02, m_rWW8Export.pO->Count() );
3329 sal_Unicode cStart = rTwoLines.GetStartBracket();
3330 sal_Unicode cEnd = rTwoLines.GetStartBracket();
3333 As per usual we have problems. We can have seperate left and right brackets
3334 in OOo, it doesn't appear that you can in word. Also in word there appear
3335 to only be a limited number of possibilities, we can use pretty much
3336 anything.
3338 So if we have none, we export none, if either bracket is set to a known
3339 word type we export both as that type (with the bracket winning out in
3340 the case of a conflict simply being the order of test here.
3342 Upshot being a documented created in word will be reexported with no
3343 ill effects.
3346 USHORT nType;
3347 if (!cStart && !cEnd)
3348 nType = 0;
3349 else if ((cStart == '{') || (cEnd == '}'))
3350 nType = 4;
3351 else if ((cStart == '<') || (cEnd == '>'))
3352 nType = 3;
3353 else if ((cStart == '[') || (cEnd == ']'))
3354 nType = 2;
3355 else
3356 nType = 1;
3357 m_rWW8Export.InsUInt16( nType );
3358 static const BYTE aZeroArr[ 3 ] = { 0, 0, 0 };
3359 m_rWW8Export.pO->Insert( aZeroArr, 3, m_rWW8Export.pO->Count() );
3363 void AttributeOutputBase::ParaNumRule( const SwNumRuleItem& rNumRule )
3365 const SwTxtNode* pTxtNd = 0;
3366 USHORT nNumId;
3367 BYTE nLvl = 0;
3368 if ( rNumRule.GetValue().Len() )
3370 const SwNumRule* pRule = GetExport().pDoc->FindNumRulePtr(
3371 rNumRule.GetValue() );
3372 if ( pRule && USHRT_MAX != ( nNumId = GetExport().GetId( *pRule ) ) )
3374 ++nNumId;
3375 if ( GetExport().pOutFmtNode )
3377 if ( GetExport().pOutFmtNode->ISA( SwCntntNode ) )
3379 pTxtNd = (SwTxtNode*)GetExport().pOutFmtNode;
3381 if( pTxtNd->IsCountedInList())
3383 nLvl = static_cast< BYTE >(pTxtNd->GetActualListLevel());
3385 if ( pTxtNd->IsListRestart() )
3387 USHORT nStartWith = static_cast< USHORT >( pTxtNd->GetActualListStartValue() );
3388 nNumId = GetExport().DuplicateNumRule( pRule, nLvl, nStartWith );
3389 if ( USHRT_MAX != nNumId )
3390 ++nNumId;
3393 else
3395 // #i44815# adjust numbering for numbered paragraphs
3396 // without number (NO_NUMLEVEL). These paragaphs
3397 // will receive a list id 0, which WW interprets as
3398 // 'no number'.
3399 nNumId = 0;
3402 else if ( GetExport().pOutFmtNode->ISA( SwTxtFmtColl ) )
3404 const SwTxtFmtColl* pC = (SwTxtFmtColl*)GetExport().pOutFmtNode;
3405 if ( pC && pC->IsAssignedToListLevelOfOutlineStyle() )
3406 nLvl = static_cast< BYTE >( pC->GetAssignedOutlineStyleLevel() ); //<-end,zhaojianwei
3410 else
3411 nNumId = USHRT_MAX;
3413 else
3414 nNumId = 0;
3416 if ( USHRT_MAX != nNumId )
3418 if ( nLvl >= WW8ListManager::nMaxLevel )
3419 nLvl = WW8ListManager::nMaxLevel - 1;
3421 ParaNumRule_Impl( pTxtNd, nLvl, nNumId );
3425 void WW8AttributeOutput::ParaNumRule_Impl( const SwTxtNode* pTxtNd, sal_Int32 nLvl, sal_Int32 nNumId )
3427 if ( m_rWW8Export.bWrtWW8 )
3429 // write sprmPIlvl and sprmPIlfo
3430 SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_PIlvl );
3431 m_rWW8Export.pO->Insert( ::sal::static_int_cast<BYTE>(nLvl), m_rWW8Export.pO->Count() );
3432 SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_PIlfo );
3433 SwWW8Writer::InsUInt16( *m_rWW8Export.pO, ::sal::static_int_cast<UINT16>(nNumId) );
3435 else if ( pTxtNd && m_rWW8Export.Out_SwNum( pTxtNd ) ) // NumRules
3436 m_rWW8Export.pSepx->SetNum( pTxtNd );
3439 /* File FRMATR.HXX */
3441 void WW8AttributeOutput::FormatFrameSize( const SwFmtFrmSize& rSize )
3443 if( m_rWW8Export.bOutFlyFrmAttrs ) // Flys
3445 if( m_rWW8Export.bOutGrf )
3446 return; // Fly um Grafik -> Auto-Groesse
3448 //???? was ist bei Prozentangaben ???
3449 if ( rSize.GetWidth() && rSize.GetWidthSizeType() == ATT_FIX_SIZE)
3451 //"sprmPDxaWidth"
3452 if( m_rWW8Export.bWrtWW8 )
3453 m_rWW8Export.InsUInt16( NS_sprm::LN_PDxaWidth );
3454 else
3455 m_rWW8Export.pO->Insert( 28, m_rWW8Export.pO->Count() );
3456 m_rWW8Export.InsUInt16( (USHORT)rSize.GetWidth() );
3459 if ( rSize.GetHeight() )
3461 // sprmPWHeightAbs
3462 if( m_rWW8Export.bWrtWW8 )
3463 m_rWW8Export.InsUInt16( NS_sprm::LN_PWHeightAbs );
3464 else
3465 m_rWW8Export.pO->Insert( 45, m_rWW8Export.pO->Count() );
3467 USHORT nH = 0;
3468 switch ( rSize.GetHeightSizeType() )
3470 case ATT_VAR_SIZE: break;
3471 case ATT_FIX_SIZE: nH = (USHORT)rSize.GetHeight() & 0x7fff; break;
3472 default: nH = (USHORT)rSize.GetHeight() | 0x8000; break;
3474 m_rWW8Export.InsUInt16( nH );
3477 else if( m_rWW8Export.bOutPageDescs ) // PageDesc : Breite + Hoehe
3479 if( m_rWW8Export.pAktPageDesc->GetLandscape() )
3481 /*sprmSBOrientation*/
3482 if( m_rWW8Export.bWrtWW8 )
3483 m_rWW8Export.InsUInt16( NS_sprm::LN_SBOrientation );
3484 else
3485 m_rWW8Export.pO->Insert( 162, m_rWW8Export.pO->Count() );
3486 m_rWW8Export.pO->Insert( 2, m_rWW8Export.pO->Count() );
3489 /*sprmSXaPage*/
3490 if( m_rWW8Export.bWrtWW8 )
3491 m_rWW8Export.InsUInt16( NS_sprm::LN_SXaPage );
3492 else
3493 m_rWW8Export.pO->Insert( 164, m_rWW8Export.pO->Count() );
3494 m_rWW8Export.InsUInt16(
3495 msword_cast<sal_uInt16>(SvxPaperInfo::GetSloppyPaperDimension(rSize.GetWidth())));
3497 /*sprmSYaPage*/
3498 if( m_rWW8Export.bWrtWW8 )
3499 m_rWW8Export.InsUInt16( NS_sprm::LN_SYaPage );
3500 else
3501 m_rWW8Export.pO->Insert( 165, m_rWW8Export.pO->Count() );
3502 m_rWW8Export.InsUInt16(
3503 msword_cast<sal_uInt16>(SvxPaperInfo::GetSloppyPaperDimension(rSize.GetHeight())));
3507 // FillOrder fehlt noch
3509 // ReplaceCr() wird fuer Pagebreaks und Pagedescs gebraucht. Es wird ein
3510 // bereits geschriebenes CR durch ein Break-Zeichen ersetzt. Replace muss
3511 // direkt nach Schreiben des CR gerufen werden.
3512 // Rueckgabe: FilePos des ersetzten CRs + 1 oder 0 fuer nicht ersetzt
3514 ULONG WW8Export::ReplaceCr( BYTE nChar )
3516 // Bug #49917#
3517 ASSERT( nChar, "gegen 0 ersetzt bringt WW97/95 zum Absturz" );
3519 bool bReplaced = false;
3520 SvStream& rStrm = Strm();
3521 ULONG nRetPos = 0, nPos = rStrm.Tell();
3522 BYTE nBCode=0;
3523 UINT16 nUCode=0;
3524 //If there is at least two characters already output
3525 if (nPos - (IsUnicode() ? 2 : 1) >= ULONG(pFib->fcMin))
3527 rStrm.SeekRel(IsUnicode() ? -2 : -1);
3528 if (IsUnicode())
3529 rStrm >> nUCode;
3530 else
3532 rStrm >> nBCode;
3533 nUCode = nBCode;
3535 //If the last char was a cr
3536 if (nUCode == 0x0d) // CR ?
3538 if ((nChar == 0x0c) &&
3539 (nPos - (IsUnicode() ? 4 : 2) >= ULONG(pFib->fcMin)))
3541 rStrm.SeekRel( IsUnicode() ? -4 : -2 );
3542 if (IsUnicode())
3543 rStrm >> nUCode;
3544 else
3546 rStrm >> nUCode;
3547 nUCode = nBCode;
3550 else
3552 rStrm.SeekRel( IsUnicode() ? -2 : -1 );
3553 nUCode = 0x0;
3555 //And the para is not of len 0, then replace this cr with the mark
3556 if( nChar == 0x0e || nUCode == 0x0d )
3557 bReplaced = false;
3558 else
3560 bReplaced = true;
3561 WriteChar(nChar);
3562 nRetPos = nPos;
3565 else if ((nUCode == 0x0c) && (nChar == 0x0e))
3567 //#108854# a column break after a section has
3568 //no effect in writer
3569 bReplaced = true;
3571 rStrm.Seek( nPos );
3573 else
3574 bReplaced = true;
3576 if (!bReplaced)
3578 // then write as normal char
3579 WriteChar(nChar);
3580 pPiece->SetParaBreak();
3581 pPapPlc->AppendFkpEntry(rStrm.Tell());
3582 pChpPlc->AppendFkpEntry(rStrm.Tell());
3583 nRetPos = rStrm.Tell();
3585 #ifdef PRODUCT
3586 else
3588 ASSERT( nRetPos || nPos == (ULONG)pFib->fcMin,
3589 "WW8_ReplaceCr an falscher FilePos gerufen" );
3591 #endif
3592 return nRetPos;
3595 void WW8AttributeOutput::TableRowEnd(sal_uInt32 nDepth)
3597 if ( nDepth == 1 )
3598 m_rWW8Export.WriteChar( (BYTE)0x07 );
3599 else if ( nDepth > 1 )
3600 m_rWW8Export.WriteChar( (BYTE)0x0d );
3602 //Technically in a word document this is a different value for a row ends
3603 //that are not row ends directly after a cell with a graphic. But it
3604 //doesn't seem to make a difference
3605 //pMagicTable->Append(Fc2Cp(Strm().Tell()),0x1B6);
3608 void AttributeOutputBase::FormatPageDescription( const SwFmtPageDesc& rPageDesc )
3610 if ( GetExport().bStyDef && GetExport().pOutFmtNode && GetExport().pOutFmtNode->ISA( SwTxtFmtColl ) )
3612 const SwTxtFmtColl* pC = (SwTxtFmtColl*)GetExport().pOutFmtNode;
3613 if ( (SFX_ITEM_SET != pC->GetItemState( RES_BREAK, false ) ) && rPageDesc.GetRegisteredIn() )
3614 FormatBreak( SvxFmtBreakItem( SVX_BREAK_PAGE_BEFORE, RES_BREAK ) );
3618 void WW8AttributeOutput::PageBreakBefore( bool bBreak )
3620 // sprmPPageBreakBefore/sprmPFPageBreakBefore
3621 if ( m_rWW8Export.bWrtWW8 )
3622 m_rWW8Export.InsUInt16( NS_sprm::LN_PFPageBreakBefore );
3623 else
3624 m_rWW8Export.pO->Insert( 9, m_rWW8Export.pO->Count() );
3626 m_rWW8Export.pO->Insert( bBreak ? 1 : 0, m_rWW8Export.pO->Count() );
3629 // Breaks schreiben nichts in das Ausgabe-Feld rWrt.pO,
3630 // sondern nur in den Text-Stream ( Bedingung dafuer, dass sie von Out_Break...
3631 // gerufen werden duerfen )
3632 void AttributeOutputBase::FormatBreak( const SvxFmtBreakItem& rBreak )
3634 if ( GetExport().bStyDef )
3636 switch ( rBreak.GetBreak() )
3638 // JP 21.06.99: column breaks never change to pagebreaks
3639 // case SVX_BREAK_COLUMN_BEFORE:
3640 // case SVX_BREAK_COLUMN_BOTH:
3641 case SVX_BREAK_NONE:
3642 case SVX_BREAK_PAGE_BEFORE:
3643 case SVX_BREAK_PAGE_BOTH:
3644 PageBreakBefore( rBreak.GetValue() );
3645 break;
3646 default:
3647 break;
3650 else if ( !GetExport().mpParentFrame )
3652 BYTE nC = 0;
3653 bool bBefore = false;
3654 // --> OD 2007-05-29 #i76300#
3655 // Note: Can only be <true>, if <bBefore> equals <false>.
3656 bool bCheckForFollowPageDesc = false;
3657 // <--
3659 switch ( rBreak.GetBreak() )
3661 case SVX_BREAK_NONE: // Ausgeschaltet
3662 if ( !GetExport().bBreakBefore )
3663 PageBreakBefore( false );
3664 return;
3666 case SVX_BREAK_COLUMN_BEFORE: // ColumnBreak
3667 bBefore = true;
3668 // no break;
3669 case SVX_BREAK_COLUMN_AFTER:
3670 case SVX_BREAK_COLUMN_BOTH:
3671 if ( GetExport().Sections().CurrentNumberOfColumns( *GetExport().pDoc ) > 1 )
3673 nC = msword::ColumnBreak;
3675 break;
3677 case SVX_BREAK_PAGE_BEFORE: // PageBreak
3678 // From now on(fix for #i77900#) we prefer to save a page break as
3679 // paragraph attribute, this has to be done after the export of the
3680 // paragraph ( => !GetExport().bBreakBefore )
3681 if ( !GetExport().bBreakBefore )
3682 PageBreakBefore( true );
3683 break;
3685 case SVX_BREAK_PAGE_AFTER:
3686 case SVX_BREAK_PAGE_BOTH:
3687 nC = msword::PageBreak;
3688 // --> OD 2007-05-29 #i76300#
3689 // check for follow page description, if current writing attributes
3690 // of a paragraph.
3691 if ( dynamic_cast< const SwTxtNode* >( GetExport().pOutFmtNode ) &&
3692 GetExport().GetCurItemSet() )
3694 bCheckForFollowPageDesc = true;
3696 // <--
3697 break;
3699 default:
3700 break;
3703 if ( ( bBefore == GetExport().bBreakBefore ) && nC ) // #49917#
3705 // --> OD 2007-05-29 #i76300#
3706 bool bFollowPageDescWritten = false;
3707 if ( bCheckForFollowPageDesc && !bBefore )
3709 bFollowPageDescWritten =
3710 GetExport().OutputFollowPageDesc( GetExport().GetCurItemSet(),
3711 dynamic_cast<const SwTxtNode*>( GetExport().pOutFmtNode ) );
3713 if ( !bFollowPageDescWritten )
3715 SectionBreak( nC );
3717 // <--
3722 void WW8AttributeOutput::SectionBreak( BYTE nC, const WW8_SepInfo* /*pSectionInfo*/ )
3724 m_rWW8Export.ReplaceCr( nC );
3727 void WW8AttributeOutput::FormatTextGrid( const SwTextGridItem& rGrid )
3729 if ( m_rWW8Export.bOutPageDescs && m_rWW8Export.bWrtWW8 )
3731 UINT16 nGridType = 0;
3732 switch ( rGrid.GetGridType() )
3734 default:
3735 ASSERT(false, "Unknown grid type");
3736 case GRID_NONE:
3737 nGridType = 0;
3738 break;
3739 case GRID_LINES_ONLY:
3740 nGridType = 2;
3741 break;
3742 case GRID_LINES_CHARS:
3743 if ( rGrid.IsSnapToChars() )
3744 nGridType = 3;
3745 else
3746 nGridType = 1;
3747 break;
3749 m_rWW8Export.InsUInt16( NS_sprm::LN_SClm );
3750 m_rWW8Export.InsUInt16( nGridType );
3752 UINT16 nHeight = rGrid.GetBaseHeight() + rGrid.GetRubyHeight();
3753 m_rWW8Export.InsUInt16( NS_sprm::LN_SDyaLinePitch );
3754 m_rWW8Export.InsUInt16( nHeight );
3756 MSWordStyles * pStyles = m_rWW8Export.pStyles;
3757 SwFmt * pSwFmt = pStyles->GetSwFmt();
3759 sal_uInt32 nPageCharSize = 0;
3761 if (pSwFmt != NULL)
3763 nPageCharSize = ItemGet<SvxFontHeightItem>
3764 (*pSwFmt, RES_CHRATR_CJK_FONTSIZE).GetHeight();
3767 INT32 nCharWidth = rGrid.GetBaseWidth() - nPageCharSize;
3768 INT32 nFraction = 0;
3769 nFraction = nCharWidth % 20;
3770 if ( nCharWidth < 0 )
3771 nFraction = 20 + nFraction;
3772 nFraction = ( nFraction * 0xFFF ) / 20;
3773 nFraction = ( nFraction & 0x00000FFF );
3775 INT32 nMain = 0;
3776 nMain = nCharWidth / 20;
3777 if ( nCharWidth < 0 )
3778 nMain -= 1;
3779 nMain = nMain * 0x1000;
3780 nMain = ( nMain & 0xFFFFF000 );
3782 UINT32 nCharSpace = nFraction + nMain;
3783 m_rWW8Export.InsUInt16( NS_sprm::LN_SDxtCharSpace );
3784 m_rWW8Export.InsUInt32( nCharSpace );
3788 void WW8AttributeOutput::FormatPaperBin( const SvxPaperBinItem& rPaperBin )
3790 if ( m_rWW8Export.bOutPageDescs )
3792 USHORT nVal;
3793 switch ( rPaperBin.GetValue() )
3795 case 0: nVal = 15; break; // Automatically select
3796 case 1: nVal = 1; break; // Upper paper tray
3797 case 2: nVal = 4; break; // Manual paper feed
3798 default: nVal = 0; break;
3801 if ( nVal )
3803 if( m_rWW8Export.bWrtWW8 )
3804 m_rWW8Export.InsUInt16( m_rWW8Export.bOutFirstPage? NS_sprm::LN_SDmBinFirst: NS_sprm::LN_SDmBinOther );
3805 else
3806 m_rWW8Export.pO->Insert( m_rWW8Export.bOutFirstPage? 140: 141, m_rWW8Export.pO->Count() );
3808 m_rWW8Export.InsUInt16( nVal );
3813 void WW8AttributeOutput::FormatLRSpace( const SvxLRSpaceItem& rLR )
3815 // Flys fehlen noch ( siehe RTF )
3817 if ( m_rWW8Export.bOutFlyFrmAttrs ) // Flys
3819 // sprmPDxaFromText10
3820 if( m_rWW8Export.bWrtWW8 )
3821 m_rWW8Export.InsUInt16( NS_sprm::LN_PDxaFromText10 );
3822 else
3823 m_rWW8Export.pO->Insert( 49, m_rWW8Export.pO->Count() );
3824 // Mittelwert nehmen, da WW nur 1 Wert kennt
3825 m_rWW8Export.InsUInt16( (USHORT) ( ( rLR.GetLeft() + rLR.GetRight() ) / 2 ) );
3827 else if ( m_rWW8Export.bOutPageDescs ) // PageDescs
3829 USHORT nLDist, nRDist;
3830 const SfxPoolItem* pItem = m_rWW8Export.HasItem( RES_BOX );
3831 if ( pItem )
3833 nRDist = ((SvxBoxItem*)pItem)->CalcLineSpace( BOX_LINE_LEFT );
3834 nLDist = ((SvxBoxItem*)pItem)->CalcLineSpace( BOX_LINE_RIGHT );
3836 else
3837 nLDist = nRDist = 0;
3838 nLDist = nLDist + (USHORT)rLR.GetLeft();
3839 nRDist = nRDist + (USHORT)rLR.GetRight();
3841 // sprmSDxaLeft
3842 if( m_rWW8Export.bWrtWW8 )
3843 m_rWW8Export.InsUInt16( NS_sprm::LN_SDxaLeft );
3844 else
3845 m_rWW8Export.pO->Insert( 166, m_rWW8Export.pO->Count() );
3846 m_rWW8Export.InsUInt16( nLDist );
3848 // sprmSDxaRight
3849 if( m_rWW8Export.bWrtWW8 )
3850 m_rWW8Export.InsUInt16( NS_sprm::LN_SDxaRight );
3851 else
3852 m_rWW8Export.pO->Insert( 167, m_rWW8Export.pO->Count() );
3853 m_rWW8Export.InsUInt16( nRDist );
3855 else
3856 { // normale Absaetze
3857 // sprmPDxaLeft
3858 if( m_rWW8Export.bWrtWW8 )
3860 m_rWW8Export.InsUInt16( 0x845E ); //asian version ?
3861 m_rWW8Export.InsUInt16( (USHORT)rLR.GetTxtLeft() );
3863 else
3865 m_rWW8Export.pO->Insert( 17, m_rWW8Export.pO->Count() );
3866 m_rWW8Export.InsUInt16( (USHORT)rLR.GetTxtLeft() );
3869 // sprmPDxaRight
3870 if( m_rWW8Export.bWrtWW8 )
3872 m_rWW8Export.InsUInt16( 0x845D ); //asian version ?
3873 m_rWW8Export.InsUInt16( (USHORT)rLR.GetRight() );
3875 else
3877 m_rWW8Export.pO->Insert( 16, m_rWW8Export.pO->Count() );
3878 m_rWW8Export.InsUInt16( (USHORT)rLR.GetRight() );
3881 // sprmPDxaLeft1
3882 if( m_rWW8Export.bWrtWW8 )
3884 m_rWW8Export.InsUInt16( 0x8460 ); //asian version ?
3885 m_rWW8Export.InsUInt16( rLR.GetTxtFirstLineOfst() );
3887 else
3889 m_rWW8Export.pO->Insert( 19, m_rWW8Export.pO->Count() );
3890 m_rWW8Export.InsUInt16( rLR.GetTxtFirstLineOfst() );
3895 void WW8AttributeOutput::FormatULSpace( const SvxULSpaceItem& rUL )
3897 // Flys fehlen noch ( siehe RTF )
3899 if ( m_rWW8Export.bOutFlyFrmAttrs ) // Flys
3901 // sprmPDyaFromText
3902 if( m_rWW8Export.bWrtWW8 )
3903 m_rWW8Export.InsUInt16( NS_sprm::LN_PDyaFromText );
3904 else
3905 m_rWW8Export.pO->Insert( 48, m_rWW8Export.pO->Count() );
3906 // Mittelwert nehmen, da WW nur 1 Wert kennt
3907 m_rWW8Export.InsUInt16( (USHORT) ( ( rUL.GetUpper() + rUL.GetLower() ) / 2 ) );
3909 else if ( m_rWW8Export.bOutPageDescs ) // Page-UL
3911 ASSERT( m_rWW8Export.GetCurItemSet(), "Impossible" );
3912 if ( !m_rWW8Export.GetCurItemSet() )
3913 return;
3915 HdFtDistanceGlue aDistances( *m_rWW8Export.GetCurItemSet() );
3917 if ( aDistances.HasHeader() )
3919 //sprmSDyaHdrTop
3920 if ( m_rWW8Export.bWrtWW8 )
3921 m_rWW8Export.InsUInt16( NS_sprm::LN_SDyaHdrTop );
3922 else
3923 m_rWW8Export.pO->Insert( 156, m_rWW8Export.pO->Count() );
3924 m_rWW8Export.InsUInt16( aDistances.dyaHdrTop );
3927 // sprmSDyaTop
3928 if ( m_rWW8Export.bWrtWW8 )
3929 m_rWW8Export.InsUInt16( NS_sprm::LN_SDyaTop );
3930 else
3931 m_rWW8Export.pO->Insert( 168, m_rWW8Export.pO->Count() );
3932 m_rWW8Export.InsUInt16( aDistances.dyaTop );
3934 if ( aDistances.HasFooter() )
3936 //sprmSDyaHdrBottom
3937 if ( m_rWW8Export.bWrtWW8 )
3938 m_rWW8Export.InsUInt16( NS_sprm::LN_SDyaHdrBottom );
3939 else
3940 m_rWW8Export.pO->Insert( 157, m_rWW8Export.pO->Count() );
3941 m_rWW8Export.InsUInt16( aDistances.dyaHdrBottom );
3944 //sprmSDyaBottom
3945 if ( m_rWW8Export.bWrtWW8 )
3946 m_rWW8Export.InsUInt16( NS_sprm::LN_SDyaBottom );
3947 else
3948 m_rWW8Export.pO->Insert( 169, m_rWW8Export.pO->Count() );
3949 m_rWW8Export.InsUInt16( aDistances.dyaBottom );
3951 else
3953 // sprmPDyaBefore
3954 if ( m_rWW8Export.bWrtWW8 )
3955 m_rWW8Export.InsUInt16( NS_sprm::LN_PDyaBefore );
3956 else
3957 m_rWW8Export.pO->Insert( 21, m_rWW8Export.pO->Count() );
3958 m_rWW8Export.InsUInt16( rUL.GetUpper() );
3959 // sprmPDyaAfter
3960 if( m_rWW8Export.bWrtWW8 )
3961 m_rWW8Export.InsUInt16( NS_sprm::LN_PDyaAfter );
3962 else
3963 m_rWW8Export.pO->Insert( 22, m_rWW8Export.pO->Count() );
3964 m_rWW8Export.InsUInt16( rUL.GetLower() );
3968 // Print, Opaque, Protect fehlen noch
3970 void WW8AttributeOutput::FormatSurround( const SwFmtSurround& rSurround )
3972 if ( m_rWW8Export.bOutFlyFrmAttrs )
3974 if ( m_rWW8Export.bWrtWW8 )
3975 m_rWW8Export.InsUInt16( NS_sprm::LN_PWr );
3976 else
3977 m_rWW8Export.pO->Insert( 37, m_rWW8Export.pO->Count() );
3979 m_rWW8Export.pO->Insert(
3980 ( SURROUND_NONE != rSurround.GetSurround() ) ? 2 : 1,
3981 m_rWW8Export.pO->Count() );
3985 void WW8AttributeOutput::FormatVertOrientation( const SwFmtVertOrient& rFlyVert )
3987 //!!!! Ankertyp und entsprechende Umrechnung fehlt noch
3989 if ( m_rWW8Export.bOutFlyFrmAttrs )
3991 short nPos;
3992 switch( rFlyVert.GetVertOrient() )
3994 case text::VertOrientation::NONE:
3995 nPos = (short)rFlyVert.GetPos();
3996 break;
3997 case text::VertOrientation::CENTER:
3998 case text::VertOrientation::LINE_CENTER:
3999 nPos = -8;
4000 break;
4001 case text::VertOrientation::BOTTOM:
4002 case text::VertOrientation::LINE_BOTTOM:
4003 nPos = -12;
4004 break;
4005 case text::VertOrientation::TOP:
4006 case text::VertOrientation::LINE_TOP:
4007 default:
4008 nPos = -4;
4009 break;
4012 // sprmPDyaAbs
4013 if ( m_rWW8Export.bWrtWW8 )
4014 m_rWW8Export.InsUInt16( NS_sprm::LN_PDyaAbs );
4015 else
4016 m_rWW8Export.pO->Insert( 27, m_rWW8Export.pO->Count() );
4017 m_rWW8Export.InsUInt16( nPos );
4022 void WW8AttributeOutput::FormatHorizOrientation( const SwFmtHoriOrient& rFlyHori )
4024 if ( !m_rWW8Export.mpParentFrame )
4026 ASSERT( m_rWW8Export.mpParentFrame, "HoriOrient without mpParentFrame !!" );
4027 return;
4030 //!!!! Ankertyp und entsprechende Umrechnung fehlt noch
4031 if ( m_rWW8Export.bOutFlyFrmAttrs )
4033 short nPos;
4034 switch( rFlyHori.GetHoriOrient() )
4036 case text::HoriOrientation::NONE:
4037 nPos = (short)rFlyHori.GetPos();
4038 if( !nPos )
4039 nPos = 1; // WW: 0 ist reserviert
4040 break;
4041 case text::HoriOrientation::LEFT:
4042 nPos = rFlyHori.IsPosToggle() ? -12 : 0;
4043 break;
4044 case text::HoriOrientation::RIGHT:
4045 nPos = rFlyHori.IsPosToggle() ? -16 : -8;
4046 break;
4047 case text::HoriOrientation::CENTER:
4048 case text::HoriOrientation::FULL: // FULL nur fuer Tabellen
4049 default:
4050 nPos = -4;
4051 break;
4054 // sprmPDxaAbs
4055 if( m_rWW8Export.bWrtWW8 )
4056 m_rWW8Export.InsUInt16( NS_sprm::LN_PDxaAbs );
4057 else
4058 m_rWW8Export.pO->Insert( 26, m_rWW8Export.pO->Count() );
4059 m_rWW8Export.InsUInt16( nPos );
4063 void WW8AttributeOutput::FormatAnchor( const SwFmtAnchor& rAnchor )
4065 ASSERT( m_rWW8Export.mpParentFrame, "Anchor without mpParentFrame !!" );
4067 if ( m_rWW8Export.bOutFlyFrmAttrs )
4069 BYTE nP = 0;
4070 switch ( rAnchor.GetAnchorId() )
4072 case FLY_PAGE:
4073 // Vert: Page | Horz: Page
4074 nP |= (1 << 4) | (2 << 6);
4075 break;
4076 // Im Fall eine Flys als Zeichen: Absatz-gebunden setzen!!!
4077 case FLY_AT_FLY:
4078 case FLY_AUTO_CNTNT:
4079 case FLY_AT_CNTNT:
4080 case FLY_IN_CNTNT:
4081 // Vert: Page | Horz: Page
4082 nP |= (2 << 4) | (0 << 6);
4083 break;
4084 default:
4085 break;
4088 // sprmPPc
4089 if ( m_rWW8Export.bWrtWW8 )
4090 m_rWW8Export.InsUInt16( NS_sprm::LN_PPc );
4091 else
4092 m_rWW8Export.pO->Insert( 29, m_rWW8Export.pO->Count() );
4093 m_rWW8Export.pO->Insert( nP, m_rWW8Export.pO->Count() );
4097 void WW8AttributeOutput::FormatBackground( const SvxBrushItem& rBrush )
4099 // WW cannot have background in a section
4100 if ( !m_rWW8Export.bOutPageDescs )
4102 WW8_SHD aSHD;
4104 m_rWW8Export.TransBrush( rBrush.GetColor(), aSHD );
4105 // sprmPShd
4106 if ( m_rWW8Export.bWrtWW8 )
4107 m_rWW8Export.InsUInt16( NS_sprm::LN_PShd );
4108 else
4109 m_rWW8Export.pO->Insert(47, m_rWW8Export.pO->Count());
4110 m_rWW8Export.InsUInt16( aSHD.GetValue() );
4112 // Quite a few unknowns, some might be transparency or something
4113 // of that nature...
4114 if ( m_rWW8Export.bWrtWW8 )
4116 m_rWW8Export.InsUInt16( 0xC64D );
4117 m_rWW8Export.pO->Insert( 10, m_rWW8Export.pO->Count() );
4118 m_rWW8Export.InsUInt32( 0xFF000000 );
4119 m_rWW8Export.InsUInt32( SuitableBGColor( rBrush.GetColor().GetColor() ) );
4120 m_rWW8Export.InsUInt16( 0x0000 );
4125 WW8_BRC WW8Export::TranslateBorderLine(const SvxBorderLine& rLine,
4126 USHORT nDist, bool bShadow)
4128 // M.M. This function writes out border lines to the word format similar to
4129 // what SwRTFWriter::OutRTFBorder does in the RTF filter Eventually it
4130 // would be nice if all this functionality was in the one place
4131 WW8_BRC aBrc;
4132 UINT16 nWidth = rLine.GetInWidth() + rLine.GetOutWidth();
4133 BYTE brcType = 0, nColCode = 0;
4135 if( nWidth ) // Linie ?
4137 // BRC.brcType
4138 bool bDouble = 0 != rLine.GetInWidth() && 0 != rLine.GetOutWidth();
4139 bool bThick = !bDouble && !bWrtWW8 && nWidth > 75;
4140 if( bDouble )
4141 brcType = 3;
4142 else if( bThick )
4143 brcType = 2;
4144 else
4145 brcType = 1;
4147 // BRC.dxpLineWidth
4148 if( bThick )
4149 nWidth /= 2;
4151 if( bWrtWW8 )
4153 // Angabe in 8tel Punkten, also durch 2.5, da 1 Punkt = 20 Twips
4154 nWidth = (( nWidth * 8 ) + 10 ) / 20;
4155 if( 0xff < nWidth )
4156 nWidth = 0xff;
4158 else
4160 // Angabe in 0.75 pt
4161 nWidth = ( nWidth + 7 ) / 15;
4162 if( nWidth > 5 )
4163 nWidth = 5;
4166 if( 0 == nWidth ) // ganz duenne Linie
4167 nWidth = 1; // nicht weglassen
4169 // BRC.ico
4170 nColCode = TransCol( rLine.GetColor() );
4173 // BRC.dxpSpace
4174 USHORT nLDist = nDist;
4175 nLDist /= 20; // Masseinheit : pt
4176 if( nLDist > 0x1f )
4177 nLDist = 0x1f;
4179 if( bWrtWW8 )
4181 aBrc.aBits1[0] = BYTE(nWidth);
4182 aBrc.aBits1[1] = brcType;
4183 aBrc.aBits2[0] = nColCode;
4184 aBrc.aBits2[1] = BYTE(nLDist);
4186 // fShadow, keine weiteren Einstellungen im WW moeglich
4187 if( bShadow )
4188 aBrc.aBits2[1] |= 0x20;
4190 else
4192 USHORT aBits = nWidth + ( brcType << 3 );
4193 aBits |= (nColCode & 0x1f) << 6;
4194 aBits |= nLDist << 11;
4195 // fShadow, keine weiteren Einstellungen im WW moeglich
4196 if( bShadow )
4197 aBits |= 0x20;
4198 ShortToSVBT16( aBits, aBrc.aBits1);
4201 return aBrc;
4204 // MakeBorderLine() bekommt einen WW8Bytes* uebergeben, um die Funktion
4205 // auch fuer die Tabellen-Umrandungen zu benutzen.
4206 // Wenn nSprmNo == 0, dann wird der Opcode nicht ausgegeben.
4207 // bShadow darf bei Tabellenzellen *nicht* gesetzt sein !
4208 void WW8Export::Out_BorderLine(WW8Bytes& rO, const SvxBorderLine* pLine,
4209 USHORT nDist, sal_uInt16 nSprmNo, bool bShadow)
4211 ASSERT( ( nSprmNo == 0 ) ||
4212 ( nSprmNo >= 38 && nSprmNo <= 41 ) ||
4213 ( nSprmNo >= NS_sprm::LN_PBrcTop && nSprmNo <= NS_sprm::LN_PBrcRight ) ||
4214 ( nSprmNo >= NS_sprm::LN_SBrcTop && nSprmNo <= NS_sprm::LN_SBrcRight ),
4215 "Sprm for border out is of range" );
4217 WW8_BRC aBrc;
4219 if (pLine)
4220 aBrc = TranslateBorderLine( *pLine, nDist, bShadow );
4222 if( bWrtWW8 )
4224 // WW97-SprmIds
4225 if ( nSprmNo != 0 )
4226 SwWW8Writer::InsUInt16( rO, nSprmNo );
4228 rO.Insert( aBrc.aBits1, 2, rO.Count() );
4229 rO.Insert( aBrc.aBits2, 2, rO.Count() );
4231 else
4233 // WW95-SprmIds
4234 if ( nSprmNo != 0 )
4235 rO.Insert( (BYTE)( nSprmNo ), rO.Count() );
4236 rO.Insert( aBrc.aBits1, 2, rO.Count() );
4240 // FormatBox1() ist fuer alle Boxen ausser in Tabellen.
4241 // es wird pO des WW8Writers genommen
4242 void WW8Export::Out_SwFmtBox(const SvxBoxItem& rBox, bool bShadow)
4244 if ( bOutPageDescs && !bWrtWW8 )
4245 return; // no page ouline in WW6
4247 static const USHORT aBorders[] =
4249 BOX_LINE_TOP, BOX_LINE_LEFT, BOX_LINE_BOTTOM, BOX_LINE_RIGHT
4251 static const sal_uInt16 aPBrc[] =
4253 NS_sprm::LN_PBrcTop, NS_sprm::LN_PBrcLeft, NS_sprm::LN_PBrcBottom, NS_sprm::LN_PBrcRight
4255 static const sal_uInt16 aSBrc[] =
4257 NS_sprm::LN_SBrcTop, NS_sprm::LN_SBrcLeft, NS_sprm::LN_SBrcBottom, NS_sprm::LN_SBrcRight
4259 static const sal_uInt16 aWW6PBrc[] =
4261 38, 39, 40, 41
4264 const USHORT* pBrd = aBorders;
4265 for( USHORT i = 0; i < 4; ++i, ++pBrd )
4267 const SvxBorderLine* pLn = rBox.GetLine( *pBrd );
4269 sal_uInt16 nSprmNo = 0;
4270 if ( !bWrtWW8 )
4271 nSprmNo = aWW6PBrc[i];
4272 else if ( bOutPageDescs )
4273 nSprmNo = aSBrc[i];
4274 else
4275 nSprmNo = aPBrc[i];
4277 Out_BorderLine( *pO, pLn, rBox.GetDistance( *pBrd ), nSprmNo, bShadow );
4281 // FormatBox2() ist fuer TC-Strukturen in Tabellen. Der Sprm-Opcode
4282 // wird nicht geschrieben, da es in der TC-Structur ohne Opcode gepackt ist.
4283 // dxpSpace wird immer 0, da WW das in Tabellen so verlangt
4284 // ( Tabellenumrandungen fransen sonst aus )
4285 // Ein WW8Bytes-Ptr wird als Ausgabe-Parameter uebergeben
4287 void WW8Export::Out_SwFmtTableBox( WW8Bytes& rO, const SvxBoxItem& rBox )
4289 // moeglich und vielleicht besser waere 0xffff
4290 static const USHORT aBorders[] =
4292 BOX_LINE_TOP, BOX_LINE_LEFT, BOX_LINE_BOTTOM, BOX_LINE_RIGHT
4294 const USHORT* pBrd = aBorders;
4295 for( int i = 0; i < 4; ++i, ++pBrd )
4297 const SvxBorderLine* pLn = rBox.GetLine( *pBrd );
4298 Out_BorderLine(rO, pLn, 0, 0, false);
4302 void WW8AttributeOutput::FormatBox( const SvxBoxItem& rBox )
4304 // Fly um Grafik-> keine Umrandung hier, da
4305 // der GrafikHeader bereits die Umrandung hat
4306 if ( !m_rWW8Export.bOutGrf )
4308 bool bShadow = false;
4309 const SfxPoolItem* pItem = m_rWW8Export.HasItem( RES_SHADOW );
4310 if ( pItem )
4312 const SvxShadowItem* p = (const SvxShadowItem*)pItem;
4313 bShadow = ( p->GetLocation() != SVX_SHADOW_NONE )
4314 && ( p->GetWidth() != 0 );
4317 m_rWW8Export.Out_SwFmtBox( rBox, bShadow );
4321 SwTwips WW8Export::CurrentPageWidth(SwTwips &rLeft, SwTwips &rRight) const
4323 const SwFrmFmt* pFmt = pAktPageDesc ? &pAktPageDesc->GetMaster()
4324 : &const_cast<const SwDoc *>(pDoc)->GetPageDesc(0).GetMaster();
4326 const SvxLRSpaceItem& rLR = pFmt->GetLRSpace();
4327 SwTwips nPageSize = pFmt->GetFrmSize().GetWidth();
4328 rLeft = rLR.GetLeft();
4329 rRight = rLR.GetRight();
4330 return nPageSize;
4333 void WW8AttributeOutput::FormatColumns_Impl( USHORT nCols, const SwFmtCol & rCol, bool bEven, SwTwips nPageSize )
4335 // CColumns
4336 if ( m_rWW8Export.bWrtWW8 )
4337 m_rWW8Export.InsUInt16( NS_sprm::LN_SCcolumns );
4338 else
4339 m_rWW8Export.pO->Insert( 144, m_rWW8Export.pO->Count( ) );
4340 m_rWW8Export.InsUInt16( nCols - 1 );
4342 // DxaColumns
4343 if ( m_rWW8Export.bWrtWW8 )
4344 m_rWW8Export.InsUInt16( NS_sprm::LN_SDxaColumns );
4345 else
4346 m_rWW8Export.pO->Insert( 145, m_rWW8Export.pO->Count( ) );
4347 m_rWW8Export.InsUInt16( rCol.GetGutterWidth( true ) );
4349 // LBetween
4350 if ( m_rWW8Export.bWrtWW8 )
4351 m_rWW8Export.InsUInt16( NS_sprm::LN_SLBetween );
4352 else
4353 m_rWW8Export.pO->Insert( 158, m_rWW8Export.pO->Count( ) );
4354 m_rWW8Export.pO->Insert( COLADJ_NONE == rCol.GetLineAdj( )? 0 : 1,
4355 m_rWW8Export.pO->Count( ) );
4357 const SwColumns & rColumns = rCol.GetColumns( );
4359 // FEvenlySpaced
4360 if ( m_rWW8Export.bWrtWW8 )
4361 m_rWW8Export.InsUInt16( NS_sprm::LN_SFEvenlySpaced );
4362 else
4363 m_rWW8Export.pO->Insert( 138, m_rWW8Export.pO->Count( ) );
4364 m_rWW8Export.pO->Insert( bEven ? 1 : 0, m_rWW8Export.pO->Count( ) );
4366 #if 0
4367 // FIXME what's the use of this code
4368 if ( bEven )
4370 USHORT nSpace = rColumns[0]->GetRight() + rColumns[1]->GetLeft();
4371 for ( n = 2; n < nCols; n++ )
4373 short nDiff = nSpace - ( rColumns[n - 1]->GetRight()
4374 + rColumns[n]->GetLeft() );
4375 if (nDiff > 10 || nDiff < -10)
4377 // Toleranz: 10 tw
4378 bEven = false;
4379 break;
4383 #endif
4385 if ( !bEven )
4387 for ( USHORT n = 0; n < nCols; ++n )
4389 //sprmSDxaColWidth
4390 if ( m_rWW8Export.bWrtWW8 )
4391 m_rWW8Export.InsUInt16( NS_sprm::LN_SDxaColWidth );
4392 else
4393 m_rWW8Export.pO->Insert( 136, m_rWW8Export.pO->Count( ) );
4394 m_rWW8Export.pO->Insert( ( BYTE ) n, m_rWW8Export.pO->Count( ) );
4395 m_rWW8Export.InsUInt16( rCol.
4396 CalcPrtColWidth( n,
4397 ( USHORT ) nPageSize ) );
4399 if ( n + 1 != nCols )
4401 //sprmSDxaColSpacing
4402 if ( m_rWW8Export.bWrtWW8 )
4403 m_rWW8Export.InsUInt16( NS_sprm::LN_SDxaColSpacing );
4404 else
4405 m_rWW8Export.pO->Insert( 137,
4406 m_rWW8Export.pO->Count( ) );
4407 m_rWW8Export.pO->Insert( ( BYTE ) n,
4408 m_rWW8Export.pO->Count( ) );
4409 m_rWW8Export.InsUInt16( rColumns[n]->GetRight( ) +
4410 rColumns[n + 1]->GetLeft( ) );
4416 void AttributeOutputBase::FormatColumns( const SwFmtCol& rCol )
4418 const SwColumns& rColumns = rCol.GetColumns();
4420 USHORT nCols = rColumns.Count();
4421 if ( 1 < nCols && !GetExport( ).bOutFlyFrmAttrs )
4423 // dann besorge mal die Seitenbreite ohne Raender !!
4425 const SwFrmFmt* pFmt = GetExport( ).pAktPageDesc ? &GetExport( ).pAktPageDesc->GetMaster() : &const_cast<const SwDoc *>(GetExport( ).pDoc)->GetPageDesc(0).GetMaster();
4426 const SvxFrameDirectionItem &frameDirection = pFmt->GetFrmDir();
4427 SwTwips nPageSize;
4428 if ( frameDirection.GetValue() == FRMDIR_VERT_TOP_RIGHT || frameDirection.GetValue() == FRMDIR_VERT_TOP_LEFT )
4430 const SvxULSpaceItem &rUL = pFmt->GetULSpace();
4431 nPageSize = pFmt->GetFrmSize().GetHeight();
4432 nPageSize -= rUL.GetUpper() + rUL.GetLower();
4434 const SwFmtHeader *header = dynamic_cast<const SwFmtHeader *>(pFmt->GetAttrSet().GetItem(RES_HEADER));
4435 if ( header )
4437 const SwFrmFmt *headerFmt = header->GetHeaderFmt();
4438 if (headerFmt)
4440 nPageSize -= headerFmt->GetFrmSize().GetHeight();
4443 const SwFmtFooter *footer = dynamic_cast<const SwFmtFooter *>(pFmt->GetAttrSet().GetItem(RES_FOOTER));
4444 if ( footer )
4446 const SwFrmFmt *footerFmt = footer->GetFooterFmt();
4447 if ( footerFmt )
4449 nPageSize -= footerFmt->GetFrmSize().GetHeight();
4453 else
4455 const SvxLRSpaceItem &rLR = pFmt->GetLRSpace();
4456 nPageSize = pFmt->GetFrmSize().GetWidth();
4457 nPageSize -= rLR.GetLeft() + rLR.GetRight();
4460 // Nachsehen, ob alle Spalten gleich sind
4461 bool bEven = true;
4462 USHORT n;
4463 USHORT nColWidth = rCol.CalcPrtColWidth( 0, (USHORT)nPageSize );
4464 for ( n = 1; n < nCols; n++ )
4466 short nDiff = nColWidth -
4467 rCol.CalcPrtColWidth( n, (USHORT)nPageSize );
4469 if ( nDiff > 10 || nDiff < -10 ) // Toleranz: 10 tw
4471 bEven = false;
4472 break;
4476 FormatColumns_Impl( nCols, rCol, bEven, nPageSize );
4480 // "Paragraphs together"
4481 void WW8AttributeOutput::FormatKeep( const SvxFmtKeepItem& rKeep )
4483 // sprmFKeepFollow
4484 if ( m_rWW8Export.bWrtWW8 )
4485 m_rWW8Export.InsUInt16( NS_sprm::LN_PFKeepFollow );
4486 else
4487 m_rWW8Export.pO->Insert( 8, m_rWW8Export.pO->Count() );
4489 m_rWW8Export.pO->Insert( rKeep.GetValue() ? 1 : 0, m_rWW8Export.pO->Count() );
4492 // exclude a paragraph from Line Numbering
4493 void WW8AttributeOutput::FormatLineNumbering( const SwFmtLineNumber& rNumbering )
4495 // sprmPFNoLineNumb
4496 if( m_rWW8Export.bWrtWW8 )
4497 m_rWW8Export.InsUInt16( NS_sprm::LN_PFNoLineNumb );
4498 else
4499 m_rWW8Export.pO->Insert( 14, m_rWW8Export.pO->Count() );
4501 m_rWW8Export.pO->Insert( rNumbering.IsCount() ? 0 : 1, m_rWW8Export.pO->Count() );
4505 /* File PARATR.HXX */
4507 void WW8AttributeOutput::ParaLineSpacing_Impl( short nSpace, short nMulti )
4509 // sprmPDyaLine
4510 if ( m_rWW8Export.bWrtWW8 )
4511 m_rWW8Export.InsUInt16( NS_sprm::LN_PDyaLine );
4512 else
4513 m_rWW8Export.pO->Insert( 20, m_rWW8Export.pO->Count() );
4515 m_rWW8Export.InsUInt16( nSpace );
4516 m_rWW8Export.InsUInt16( nMulti );
4519 void AttributeOutputBase::ParaLineSpacing( const SvxLineSpacingItem& rSpacing )
4521 short nSpace = 240, nMulti = 0;
4523 switch ( rSpacing.GetLineSpaceRule() )
4525 default:
4526 break;
4527 case SVX_LINE_SPACE_AUTO:
4528 case SVX_LINE_SPACE_FIX:
4529 case SVX_LINE_SPACE_MIN:
4531 switch ( rSpacing.GetInterLineSpaceRule() )
4533 case SVX_INTER_LINE_SPACE_FIX: // unser Durchschuss
4535 // gibt es aber nicht in WW - also wie kommt man an
4536 // die MaxLineHeight heran?
4537 nSpace = (short)rSpacing.GetInterLineSpace();
4538 sal_uInt16 nScript =
4539 i18n::ScriptType::LATIN;
4540 const SwAttrSet *pSet = 0;
4541 if ( GetExport().pOutFmtNode && GetExport().pOutFmtNode->ISA( SwFmt ) )
4543 const SwFmt *pFmt = (const SwFmt*)( GetExport().pOutFmtNode );
4544 pSet = &pFmt->GetAttrSet();
4546 else if ( GetExport().pOutFmtNode && GetExport().pOutFmtNode->ISA( SwTxtNode ) )
4548 const SwTxtNode* pNd = (const SwTxtNode*)GetExport().pOutFmtNode;
4549 pSet = &pNd->GetSwAttrSet();
4550 if ( pBreakIt->GetBreakIter().is() )
4552 nScript = pBreakIt->GetBreakIter()->
4553 getScriptType(pNd->GetTxt(), 0);
4556 ASSERT( pSet, "No attrset for lineheight :-(" );
4557 if ( pSet )
4559 nSpace = nSpace + (short)( AttrSetToLineHeight( *GetExport().pDoc,
4560 *pSet, *Application::GetDefaultDevice(), nScript ) );
4563 break;
4564 case SVX_INTER_LINE_SPACE_PROP:
4565 nSpace = (short)( ( 240L * rSpacing.GetPropLineSpace() ) / 100L );
4566 nMulti = 1;
4567 break;
4568 default: // z.B. Minimum oder FIX?
4569 if ( SVX_LINE_SPACE_FIX == rSpacing.GetLineSpaceRule() )
4570 nSpace = -(short)rSpacing.GetLineHeight();
4571 else
4572 nSpace = (short)rSpacing.GetLineHeight();
4573 break;
4576 break;
4579 ParaLineSpacing_Impl( nSpace, nMulti );
4582 void WW8AttributeOutput::ParaAdjust( const SvxAdjustItem& rAdjust )
4584 // sprmPJc
4585 BYTE nAdj = 255;
4586 BYTE nAdjBiDi = 255;
4587 switch ( rAdjust.GetAdjust() )
4589 case SVX_ADJUST_LEFT:
4590 nAdj = 0;
4591 nAdjBiDi = 2;
4592 break;
4593 case SVX_ADJUST_RIGHT:
4594 nAdj = 2;
4595 nAdjBiDi = 0;
4596 break;
4597 case SVX_ADJUST_BLOCKLINE:
4598 case SVX_ADJUST_BLOCK:
4599 nAdj = nAdjBiDi = 3;
4600 break;
4601 case SVX_ADJUST_CENTER:
4602 nAdj = nAdjBiDi = 1;
4603 break;
4604 default:
4605 return; // not a supported Attribut
4608 if ( 255 != nAdj ) // supported Attribut?
4610 if ( m_rWW8Export.bWrtWW8 )
4612 m_rWW8Export.InsUInt16( NS_sprm::LN_PJc );
4613 m_rWW8Export.pO->Insert( nAdj, m_rWW8Export.pO->Count() );
4616 Sadly for left to right paragraphs both these values are the same,
4617 for right to left paragraphs the bidi one is the reverse of the
4618 normal one.
4620 m_rWW8Export.InsUInt16( NS_sprm::LN_PJcExtra ); //bidi version ?
4621 bool bBiDiSwap = false;
4622 if ( m_rWW8Export.pOutFmtNode )
4624 short nDirection = FRMDIR_HORI_LEFT_TOP;
4625 if ( m_rWW8Export.pOutFmtNode->ISA( SwTxtNode ) )
4627 SwPosition aPos(*(const SwCntntNode*)m_rWW8Export.pOutFmtNode);
4628 nDirection = m_rWW8Export.pDoc->GetTextDirection(aPos);
4630 else if ( m_rWW8Export.pOutFmtNode->ISA( SwTxtFmtColl ) )
4632 const SwTxtFmtColl* pC =
4633 (const SwTxtFmtColl*)m_rWW8Export.pOutFmtNode;
4634 const SvxFrameDirectionItem &rItem =
4635 ItemGet<SvxFrameDirectionItem>(*pC, RES_FRAMEDIR);
4636 nDirection = rItem.GetValue();
4638 if ( ( nDirection == FRMDIR_HORI_RIGHT_TOP ) ||
4639 ( nDirection == FRMDIR_ENVIRONMENT && Application::GetSettings().GetLayoutRTL() ) )
4641 bBiDiSwap = true;
4645 if ( bBiDiSwap )
4646 m_rWW8Export.pO->Insert( nAdjBiDi, m_rWW8Export.pO->Count() );
4647 else
4648 m_rWW8Export.pO->Insert( nAdj, m_rWW8Export.pO->Count() );
4650 else
4652 m_rWW8Export.pO->Insert( 5, m_rWW8Export.pO->Count() );
4653 m_rWW8Export.pO->Insert( nAdj, m_rWW8Export.pO->Count() );
4658 void WW8AttributeOutput::FormatFrameDirection( const SvxFrameDirectionItem& rDirection )
4660 if ( !m_rWW8Export.bWrtWW8 ) //8+ only
4661 return;
4663 UINT16 nTextFlow=0;
4664 bool bBiDi = false;
4665 short nDir = rDirection.GetValue();
4667 if ( nDir == FRMDIR_ENVIRONMENT )
4669 if ( m_rWW8Export.bOutPageDescs )
4670 nDir = m_rWW8Export.GetCurrentPageDirection();
4671 else if ( m_rWW8Export.pOutFmtNode )
4673 if ( m_rWW8Export.bOutFlyFrmAttrs ) //frame
4675 nDir = m_rWW8Export.TrueFrameDirection(
4676 *(const SwFrmFmt*)m_rWW8Export.pOutFmtNode );
4678 else if ( m_rWW8Export.pOutFmtNode->ISA( SwCntntNode ) ) //pagagraph
4680 const SwCntntNode* pNd =
4681 (const SwCntntNode*)m_rWW8Export.pOutFmtNode;
4682 SwPosition aPos( *pNd );
4683 nDir = m_rWW8Export.pDoc->GetTextDirection( aPos );
4685 else if ( m_rWW8Export.pOutFmtNode->ISA( SwTxtFmtColl ) )
4686 nDir = FRMDIR_HORI_LEFT_TOP; //what else can we do :-(
4689 if ( nDir == FRMDIR_ENVIRONMENT )
4690 nDir = FRMDIR_HORI_LEFT_TOP; //Set something
4693 switch ( nDir )
4695 default:
4696 //Can't get an unknown type here
4697 ASSERT(false, "Unknown frame direction");
4698 case FRMDIR_HORI_LEFT_TOP:
4699 nTextFlow = 0;
4700 break;
4701 case FRMDIR_HORI_RIGHT_TOP:
4702 nTextFlow = 0;
4703 bBiDi = true;
4704 break;
4705 case FRMDIR_VERT_TOP_LEFT: //word doesn't have this
4706 case FRMDIR_VERT_TOP_RIGHT:
4707 nTextFlow = 1;
4708 break;
4711 if ( m_rWW8Export.bOutPageDescs )
4713 m_rWW8Export.InsUInt16( NS_sprm::LN_STextFlow );
4714 m_rWW8Export.InsUInt16( nTextFlow );
4715 m_rWW8Export.InsUInt16( NS_sprm::LN_SFBiDi );
4716 m_rWW8Export.pO->Insert( bBiDi, m_rWW8Export.pO->Count() );
4718 else if ( !m_rWW8Export.bOutFlyFrmAttrs ) //paragraph/style
4720 m_rWW8Export.InsUInt16( NS_sprm::LN_PFBiDi );
4721 m_rWW8Export.pO->Insert( bBiDi, m_rWW8Export.pO->Count() );
4725 // "Separate paragraphs"
4726 void WW8AttributeOutput::ParaSplit( const SvxFmtSplitItem& rSplit )
4728 // sprmPFKeep
4729 if ( m_rWW8Export.bWrtWW8 )
4730 m_rWW8Export.InsUInt16( NS_sprm::LN_PFKeep );
4731 else
4732 m_rWW8Export.pO->Insert( 7, m_rWW8Export.pO->Count() );
4733 m_rWW8Export.pO->Insert( rSplit.GetValue() ? 0 : 1, m_rWW8Export.pO->Count() );
4736 // Es wird nur das Item "SvxWidowItem" und nicht die Orphans uebersetzt,
4737 // da es fuer beides im WW nur ein Attribut "Absatzkontrolle" gibt und
4738 // im SW wahrscheinlich vom Anwender immer Beide oder keiner gesetzt werden.
4739 void WW8AttributeOutput::ParaWidows( const SvxWidowsItem& rWidows )
4741 // sprmPFWidowControl
4742 if( m_rWW8Export.bWrtWW8 )
4743 m_rWW8Export.InsUInt16( NS_sprm::LN_PFWidowControl );
4744 else
4745 m_rWW8Export.pO->Insert( 51, m_rWW8Export.pO->Count() );
4746 m_rWW8Export.pO->Insert( rWidows.GetValue() ? 1 : 0, m_rWW8Export.pO->Count() );
4750 class SwWW8WrTabu
4752 BYTE* pDel; // DelArray
4753 BYTE* pAddPos; // AddPos-Array
4754 BYTE* pAddTyp; // AddTyp-Array
4755 sal_uInt16 nAdd; // so viele Tabs kommen hinzu
4756 sal_uInt16 nDel; // so viele Tabs fallen weg
4757 public:
4758 SwWW8WrTabu(sal_uInt16 nDelMax, sal_uInt16 nAddMax);
4759 ~SwWW8WrTabu();
4761 void Add(const SvxTabStop &rTS, long nAdjustment);
4762 void Del(const SvxTabStop &rTS, long nAdjustment);
4763 void PutAll(WW8Export& rWW8Wrt);
4766 SwWW8WrTabu::SwWW8WrTabu(sal_uInt16 nDelMax, sal_uInt16 nAddMax)
4767 : nAdd(0), nDel(0)
4769 pDel = nDelMax ? new BYTE[nDelMax * 2] : 0;
4770 pAddPos = new BYTE[nAddMax * 2];
4771 pAddTyp = new BYTE[nAddMax];
4774 SwWW8WrTabu::~SwWW8WrTabu()
4776 delete[] pAddTyp;
4777 delete[] pAddPos;
4778 delete[] pDel;
4781 // Add( const SvxTabStop & rTS ) fuegt einen Tab in die WW-Struktur ein
4782 void SwWW8WrTabu::Add(const SvxTabStop & rTS, long nAdjustment)
4784 // Tab-Position eintragen
4785 ShortToSVBT16(msword_cast<sal_Int16>(rTS.GetTabPos() + nAdjustment),
4786 pAddPos + (nAdd * 2));
4788 // Tab-Typ eintragen
4789 BYTE nPara = 0;
4790 switch (rTS.GetAdjustment())
4792 case SVX_TAB_ADJUST_RIGHT:
4793 nPara = 2;
4794 break;
4795 case SVX_TAB_ADJUST_CENTER:
4796 nPara = 1;
4797 break;
4798 case SVX_TAB_ADJUST_DECIMAL:
4800 Theres nothing we can do btw the the decimal seperator has been
4801 customized, but if you think different remember that different
4802 locales have different seperators, i.e. german is a , while english
4803 is a .
4805 nPara = 3;
4806 break;
4807 default:
4808 break;
4811 switch( rTS.GetFill() )
4813 case '.': // dotted leader
4814 nPara |= 1 << 3;
4815 break;
4816 case '_': // Single line leader
4817 nPara |= 3 << 3;
4818 break;
4819 case '-': // hyphenated leader
4820 nPara |= 2 << 3;
4821 break;
4822 case '=': // heavy line leader
4823 nPara |= 4 << 3;
4824 break;
4827 ByteToSVBT8(nPara, pAddTyp + nAdd);
4828 ++nAdd;
4831 // Del( const SvxTabStop & rTS ) fuegt einen zu loeschenden Tab
4832 // in die WW-Struktur ein
4833 void SwWW8WrTabu::Del(const SvxTabStop &rTS, long nAdjustment)
4835 // Tab-Position eintragen
4836 ShortToSVBT16(msword_cast<sal_Int16>(rTS.GetTabPos() + nAdjustment),
4837 pDel + (nDel * 2));
4838 ++nDel;
4841 // PutAll( WW8Export& rWW8Wrt ) schreibt das Attribut nach rWrt.pO
4842 void SwWW8WrTabu::PutAll(WW8Export& rWrt)
4844 if (!nAdd && !nDel) //It its a no-op
4845 return;
4846 ASSERT(nAdd <= 255, "more than 255 added tabstops ?");
4847 ASSERT(nDel <= 255, "more than 244 removed tabstops ?");
4848 if (nAdd > 255)
4849 nAdd = 255;
4850 if (nDel > 255)
4851 nDel = 255;
4853 sal_uInt16 nSiz = 2 * nDel + 3 * nAdd + 2;
4854 if (nSiz > 255)
4855 nSiz = 255;
4857 if (rWrt.bWrtWW8)
4858 rWrt.InsUInt16(NS_sprm::LN_PChgTabsPapx);
4859 else
4860 rWrt.pO->Insert(15, rWrt.pO->Count());
4861 // cch eintragen
4862 rWrt.pO->Insert(msword_cast<sal_uInt8>(nSiz), rWrt.pO->Count());
4863 // DelArr schreiben
4864 rWrt.pO->Insert(msword_cast<sal_uInt8>(nDel), rWrt.pO->Count());
4865 rWrt.OutSprmBytes(pDel, nDel * 2);
4866 // InsArr schreiben
4867 rWrt.pO->Insert(msword_cast<sal_uInt8>(nAdd), rWrt.pO->Count());
4868 rWrt.OutSprmBytes(pAddPos, 2 * nAdd); // AddPosArray
4869 rWrt.OutSprmBytes(pAddTyp, nAdd); // AddTypArray
4873 static void ParaTabStopAdd( WW8Export& rWrt, const SvxTabStopItem& rTStops,
4874 long nLParaMgn )
4876 SwWW8WrTabu aTab( 0, rTStops.Count());
4878 for( USHORT n = 0; n < rTStops.Count(); n++ )
4880 const SvxTabStop& rTS = rTStops[n];
4881 // Def-Tabs ignorieren
4882 if (SVX_TAB_ADJUST_DEFAULT != rTS.GetAdjustment())
4883 aTab.Add(rTS, nLParaMgn);
4885 aTab.PutAll( rWrt );
4888 bool lcl_IsEqual(long nOneLeft, const SvxTabStop &rOne,
4889 long nTwoLeft, const SvxTabStop &rTwo)
4891 return(
4892 nOneLeft == nTwoLeft &&
4893 rOne.GetAdjustment() == rTwo.GetAdjustment() &&
4894 rOne.GetDecimal() == rTwo.GetDecimal() &&
4895 rOne.GetFill() == rTwo.GetFill()
4899 static void ParaTabStopDelAdd( WW8Export& rWrt, const SvxTabStopItem& rTStyle,
4900 long nLStypeMgn, const SvxTabStopItem& rTNew, long nLParaMgn )
4902 SwWW8WrTabu aTab(rTStyle.Count(), rTNew.Count());
4904 USHORT nO = 0; // rTStyle Index
4905 USHORT nN = 0; // rTNew Index
4907 do {
4908 const SvxTabStop* pTO;
4909 long nOP;
4910 if( nO < rTStyle.Count() ) // alt noch nicht am Ende ?
4912 pTO = &rTStyle[ nO ];
4913 nOP = pTO->GetTabPos() + nLStypeMgn;
4914 if( SVX_TAB_ADJUST_DEFAULT == pTO->GetAdjustment() )
4916 nO++; // Default-Tab ignorieren
4917 continue;
4920 else
4922 pTO = 0;
4923 nOP = LONG_MAX;
4926 const SvxTabStop* pTN;
4927 long nNP;
4928 if( nN < rTNew.Count() ) // neu noch nicht am Ende
4930 pTN = &rTNew[ nN ];
4931 nNP = pTN->GetTabPos() + nLParaMgn;
4932 if( SVX_TAB_ADJUST_DEFAULT == pTN->GetAdjustment() )
4934 nN++; // Default-Tab ignorieren
4935 continue;
4938 else
4940 pTN = 0;
4941 nNP = LONG_MAX;
4944 if( nOP == LONG_MAX && nNP == LONG_MAX )
4945 break; // alles fertig
4947 if( nOP < nNP ) // naechster Tab ist alt
4949 aTab.Del(*pTO, nLStypeMgn); // muss geloescht werden
4950 nO++;
4952 else if( nNP < nOP ) // naechster Tab ist neu
4954 aTab.Add(*pTN, nLParaMgn); // muss eigefuegt werden
4955 nN++;
4957 else if (lcl_IsEqual(nOP, *pTO, nNP, *pTN)) // Tabs sind gleich:
4959 nO++; // nichts zu tun
4960 nN++;
4962 else // Tabs selbe Pos, diff Typ
4964 aTab.Del(*pTO, nLStypeMgn); // alten loeschen
4965 aTab.Add(*pTN, nLParaMgn); // neuen einfuegen
4966 nO++;
4967 nN++;
4969 } while( 1 );
4971 aTab.PutAll( rWrt );
4974 void WW8AttributeOutput::ParaTabStop( const SvxTabStopItem& rTabStops )
4976 bool bTabsRelativeToIndex = m_rWW8Export.pCurPam->GetDoc()->get( IDocumentSettingAccess::TABS_RELATIVE_TO_INDENT );
4977 long nCurrentLeft = 0;
4979 if ( bTabsRelativeToIndex )
4981 const SfxPoolItem* pLR = m_rWW8Export.HasItem( RES_LR_SPACE );
4983 if ( pLR != NULL )
4984 nCurrentLeft = ((const SvxLRSpaceItem*)pLR)->GetTxtLeft();
4987 // --> FLR 2009-03-17 #i100264#
4988 if ( m_rWW8Export.bStyDef &&
4989 m_rWW8Export.pCurrentStyle != NULL &&
4990 m_rWW8Export.pCurrentStyle->DerivedFrom() != NULL )
4992 SvxTabStopItem aTabs( 0, 0, SVX_TAB_ADJUST_DEFAULT, RES_PARATR_TABSTOP );
4993 const SwFmt *pParentStyle = m_rWW8Export.pCurrentStyle->DerivedFrom();
4994 const SvxTabStopItem* pParentTabs = HasItem<SvxTabStopItem>( pParentStyle->GetAttrSet(), RES_PARATR_TABSTOP );
4995 if ( pParentTabs )
4997 aTabs.Insert( pParentTabs );
5000 ParaTabStopDelAdd( m_rWW8Export, aTabs, 0, rTabStops, 0 );
5001 return;
5003 // <--
5005 // StyleDef -> "einfach" eintragen || keine Style-Attrs -> dito
5006 const SvxTabStopItem* pStyleTabs = 0;
5007 if ( !m_rWW8Export.bStyDef && m_rWW8Export.pStyAttr )
5009 pStyleTabs =
5010 HasItem<SvxTabStopItem>( *m_rWW8Export.pStyAttr, RES_PARATR_TABSTOP );
5013 if ( !pStyleTabs )
5014 ParaTabStopAdd(m_rWW8Export, rTabStops, nCurrentLeft);
5015 else
5017 long nStyleLeft = 0;
5019 if (bTabsRelativeToIndex)
5021 const SvxLRSpaceItem &rStyleLR =
5022 ItemGet<SvxLRSpaceItem>(*m_rWW8Export.pStyAttr, RES_LR_SPACE);
5023 nStyleLeft = rStyleLR.GetTxtLeft();
5026 ParaTabStopDelAdd(m_rWW8Export, *pStyleTabs, nStyleLeft, rTabStops,
5027 nCurrentLeft);
5031 //-----------------------------------------------------------------------
5033 void AttributeOutputBase::OutputItem( const SfxPoolItem& rHt )
5035 // FIXME maybe use 'item_cast', like 'item_cast<SvxCharHiddenItem>( rHt )'?
5036 switch ( rHt.Which() )
5038 case RES_CHRATR_CASEMAP:
5039 CharCaseMap( static_cast< const SvxCaseMapItem& >( rHt ) );
5040 break;
5041 case RES_CHRATR_COLOR:
5042 CharColor( static_cast< const SvxColorItem& >( rHt ) );
5043 break;
5044 case RES_CHRATR_CONTOUR:
5045 CharContour( static_cast< const SvxContourItem& >( rHt ) );
5046 break;
5047 case RES_CHRATR_CROSSEDOUT:
5048 CharCrossedOut( static_cast< const SvxCrossedOutItem& >( rHt ) );
5049 break;
5050 case RES_CHRATR_ESCAPEMENT:
5051 CharEscapement( static_cast< const SvxEscapementItem& >( rHt ) );
5052 break;
5053 case RES_CHRATR_FONT:
5054 CharFont( static_cast< const SvxFontItem& >( rHt ) );
5055 break;
5056 case RES_CHRATR_FONTSIZE:
5057 CharFontSize( static_cast< const SvxFontHeightItem& >( rHt ) );
5058 break;
5059 case RES_CHRATR_KERNING:
5060 CharKerning( static_cast< const SvxKerningItem& >( rHt ) );
5061 break;
5062 case RES_CHRATR_LANGUAGE:
5063 CharLanguage( static_cast< const SvxLanguageItem& >( rHt ) );
5064 break;
5065 case RES_CHRATR_POSTURE:
5066 CharPosture( static_cast< const SvxPostureItem& >( rHt ) );
5067 break;
5068 case RES_CHRATR_SHADOWED:
5069 CharShadow( static_cast< const SvxShadowedItem& >( rHt ) );
5070 break;
5071 case RES_CHRATR_UNDERLINE:
5072 CharUnderline( static_cast< const SvxUnderlineItem& >( rHt ) );
5073 break;
5074 case RES_CHRATR_WEIGHT:
5075 CharWeight( static_cast< const SvxWeightItem& >( rHt ) );
5076 break;
5077 case RES_CHRATR_AUTOKERN:
5078 CharAutoKern( static_cast< const SvxAutoKernItem& >( rHt ) );
5079 break;
5080 case RES_CHRATR_BLINK:
5081 CharAnimatedText( static_cast< const SvxBlinkItem& >( rHt ) );
5082 break;
5083 case RES_CHRATR_BACKGROUND:
5084 CharBackground( static_cast< const SvxBrushItem& >( rHt ) );
5085 break;
5087 case RES_CHRATR_CJK_FONT:
5088 CharFontCJK( static_cast< const SvxFontItem& >( rHt ) );
5089 break;
5090 case RES_CHRATR_CJK_FONTSIZE:
5091 CharFontSizeCJK( static_cast< const SvxFontHeightItem& >( rHt ) );
5092 break;
5093 case RES_CHRATR_CJK_LANGUAGE:
5094 CharLanguageCJK( static_cast< const SvxLanguageItem& >( rHt ) );
5095 break;
5096 case RES_CHRATR_CJK_POSTURE:
5097 CharPostureCJK( static_cast< const SvxPostureItem& >( rHt ) );
5098 break;
5099 case RES_CHRATR_CJK_WEIGHT:
5100 CharWeightCJK( static_cast< const SvxWeightItem& >( rHt ) );
5101 break;
5103 case RES_CHRATR_CTL_FONT:
5104 CharFontCTL( static_cast< const SvxFontItem& >( rHt ) );
5105 break;
5106 case RES_CHRATR_CTL_FONTSIZE:
5107 CharFontSizeCTL( static_cast< const SvxFontHeightItem& >( rHt ) );
5108 break;
5109 case RES_CHRATR_CTL_LANGUAGE:
5110 CharLanguageCTL( static_cast< const SvxLanguageItem& >( rHt ) );
5111 break;
5112 case RES_CHRATR_CTL_POSTURE:
5113 CharPostureCTL( static_cast< const SvxPostureItem& >( rHt ) );
5114 break;
5115 case RES_CHRATR_CTL_WEIGHT:
5116 CharWeightCTL( static_cast< const SvxWeightItem& >( rHt ) );
5117 break;
5119 case RES_CHRATR_ROTATE:
5120 CharRotate( static_cast< const SvxCharRotateItem& >( rHt ) );
5121 break;
5122 case RES_CHRATR_EMPHASIS_MARK:
5123 CharEmphasisMark( static_cast< const SvxEmphasisMarkItem& >( rHt ) );
5124 break;
5125 case RES_CHRATR_TWO_LINES:
5126 CharTwoLines( static_cast< const SvxTwoLinesItem& >( rHt ) );
5127 break;
5128 case RES_CHRATR_SCALEW:
5129 CharScaleWidth( static_cast< const SvxCharScaleWidthItem& >( rHt ) );
5130 break;
5131 case RES_CHRATR_RELIEF:
5132 CharRelief( static_cast< const SvxCharReliefItem& >( rHt ) );
5133 break;
5134 case RES_CHRATR_HIDDEN:
5135 CharHidden( static_cast< const SvxCharHiddenItem& >( rHt ) );
5136 break;
5138 case RES_TXTATR_INETFMT:
5139 TextINetFormat( static_cast< const SwFmtINetFmt& >( rHt ) );
5140 break;
5141 case RES_TXTATR_CHARFMT:
5142 TextCharFormat( static_cast< const SwFmtCharFmt& >( rHt ) );
5143 break;
5144 case RES_TXTATR_FIELD:
5145 TextField( static_cast< const SwFmtFld& >( rHt ) );
5146 break;
5147 case RES_TXTATR_FLYCNT:
5148 TextFlyContent( static_cast< const SwFmtFlyCnt& >( rHt ) );
5149 break;
5150 case RES_TXTATR_FTN:
5151 TextFootnote( static_cast< const SwFmtFtn& >( rHt ) );
5152 break;
5154 case RES_PARATR_LINESPACING:
5155 ParaLineSpacing( static_cast< const SvxLineSpacingItem& >( rHt ) );
5156 break;
5157 case RES_PARATR_ADJUST:
5158 ParaAdjust( static_cast< const SvxAdjustItem& >( rHt ) );
5159 break;
5160 case RES_PARATR_SPLIT:
5161 ParaSplit( static_cast< const SvxFmtSplitItem& >( rHt ) );
5162 break;
5163 case RES_PARATR_WIDOWS:
5164 ParaWidows( static_cast< const SvxWidowsItem& >( rHt ) );
5165 break;
5166 case RES_PARATR_TABSTOP:
5167 ParaTabStop( static_cast< const SvxTabStopItem& >( rHt ) );
5168 break;
5169 case RES_PARATR_HYPHENZONE:
5170 ParaHyphenZone( static_cast< const SvxHyphenZoneItem& >( rHt ) );
5171 break;
5172 case RES_PARATR_NUMRULE:
5173 ParaNumRule( static_cast< const SwNumRuleItem& >( rHt ) );
5174 break;
5175 case RES_PARATR_SCRIPTSPACE:
5176 ParaScriptSpace( static_cast< const SfxBoolItem& >( rHt ) );
5177 break;
5178 case RES_PARATR_HANGINGPUNCTUATION:
5179 ParaHangingPunctuation( static_cast< const SfxBoolItem& >( rHt ) );
5180 break;
5181 case RES_PARATR_FORBIDDEN_RULES:
5182 ParaForbiddenRules( static_cast< const SfxBoolItem& >( rHt ) );
5183 break;
5184 case RES_PARATR_VERTALIGN:
5185 ParaVerticalAlign( static_cast< const SvxParaVertAlignItem& >( rHt ) );
5186 break;
5187 case RES_PARATR_SNAPTOGRID:
5188 ParaSnapToGrid( static_cast< const SvxParaGridItem& >( rHt ) );
5189 break;
5191 case RES_FRM_SIZE:
5192 FormatFrameSize( static_cast< const SwFmtFrmSize& >( rHt ) );
5193 break;
5194 case RES_PAPER_BIN:
5195 FormatPaperBin( static_cast< const SvxPaperBinItem& >( rHt ) );
5196 break;
5197 case RES_LR_SPACE:
5198 FormatLRSpace( static_cast< const SvxLRSpaceItem& >( rHt ) );
5199 break;
5200 case RES_UL_SPACE:
5201 FormatULSpace( static_cast< const SvxULSpaceItem& >( rHt ) );
5202 break;
5203 case RES_PAGEDESC:
5204 FormatPageDescription( static_cast< const SwFmtPageDesc& >( rHt ) );
5205 break;
5206 case RES_BREAK:
5207 FormatBreak( static_cast< const SvxFmtBreakItem& >( rHt ) );
5208 break;
5209 case RES_SURROUND:
5210 FormatSurround( static_cast< const SwFmtSurround& >( rHt ) );
5211 break;
5212 case RES_VERT_ORIENT:
5213 FormatVertOrientation( static_cast< const SwFmtVertOrient& >( rHt ) );
5214 break;
5215 case RES_HORI_ORIENT:
5216 FormatHorizOrientation( static_cast< const SwFmtHoriOrient& >( rHt ) );
5217 break;
5218 case RES_ANCHOR:
5219 FormatAnchor( static_cast< const SwFmtAnchor& >( rHt ) );
5220 break;
5221 case RES_BACKGROUND:
5222 FormatBackground( static_cast< const SvxBrushItem& >( rHt ) );
5223 break;
5224 case RES_BOX:
5225 FormatBox( static_cast< const SvxBoxItem& >( rHt ) );
5226 break;
5227 case RES_COL:
5228 FormatColumns( static_cast< const SwFmtCol& >( rHt ) );
5229 break;
5230 case RES_KEEP:
5231 FormatKeep( static_cast< const SvxFmtKeepItem& >( rHt ) );
5232 break;
5233 case RES_TEXTGRID:
5234 FormatTextGrid( static_cast< const SwTextGridItem& >( rHt ) );
5235 break;
5236 case RES_LINENUMBER:
5237 FormatLineNumbering( static_cast< const SwFmtLineNumber& >( rHt ) );
5238 break;
5239 case RES_FRAMEDIR:
5240 FormatFrameDirection( static_cast< const SvxFrameDirectionItem& >( rHt ) );
5241 break;
5243 default:
5244 #if OSL_DEBUG_LEVEL > 0
5245 fprintf( stderr, "Unhandled SfxPoolItem with id %d.\n", rHt.Which() );
5246 #endif
5247 break;
5251 void AttributeOutputBase::OutputStyleItemSet( const SfxItemSet& rSet, BOOL bDeep, BOOL bTestForDefault )
5253 // based on OutputItemSet() from wrt_fn.cxx
5255 const SfxItemPool& rPool = *rSet.GetPool();
5256 const SfxItemSet* pSet = &rSet;
5257 if ( !pSet->Count() )
5259 if ( !bDeep )
5260 return;
5262 while ( 0 != ( pSet = pSet->GetParent() ) && !pSet->Count() )
5265 if ( !pSet )
5266 return;
5269 const SfxPoolItem* pItem;
5270 if ( !bDeep || !pSet->GetParent() )
5272 ASSERT( rSet.Count(), "Wurde doch schon behandelt oder?" );
5273 SfxItemIter aIter( *pSet );
5274 pItem = aIter.GetCurItem();
5275 do {
5276 OutputItem( *pItem );
5277 } while ( !aIter.IsAtEnd() && 0 != ( pItem = aIter.NextItem() ) );
5279 else
5281 SfxWhichIter aIter( *pSet );
5282 USHORT nWhich = aIter.FirstWhich();
5283 while ( nWhich )
5285 if ( SFX_ITEM_SET == pSet->GetItemState( nWhich, bDeep, &pItem ) &&
5286 ( !bTestForDefault ||
5287 *pItem != rPool.GetDefaultItem( nWhich ) ||
5288 ( pSet->GetParent() && *pItem != pSet->GetParent()->Get( nWhich ) ) ) )
5290 OutputItem( *pItem );
5292 nWhich = aIter.NextWhich();
5297 /* vi:set tabstop=4 shiftwidth=4 expandtab: */