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