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 #include "docxattributeoutput.hxx"
25 #include "docxexport.hxx"
26 #include "docxfootnotes.hxx"
27 #include "writerwordglue.hxx"
28 #include "wrtww8.hxx"
29 #include "ww8par.hxx"
30
31 #include <oox/token/tokens.hxx>
32 #include <oox/export/drawingml.hxx>
33 #include <oox/export/utils.hxx>
34 #include <oox/export/vmlexport.hxx>
35
36 #include <i18npool/mslangid.hxx>
37
38 #include <hintids.hxx>
39
40 #include <svl/poolitem.hxx>
41
42 #include <editeng/fontitem.hxx>
43 #include <editeng/tstpitem.hxx>
44 #include <editeng/adjitem.hxx>
45 #include <editeng/spltitem.hxx>
46 #include <editeng/widwitem.hxx>
47 #include <editeng/lspcitem.hxx>
48 #include <editeng/keepitem.hxx>
49 #include <editeng/shaditem.hxx>
50 #include <editeng/brshitem.hxx>
51 #include <editeng/postitem.hxx>
52 #include <editeng/wghtitem.hxx>
53 #include <editeng/kernitem.hxx>
54 #include <editeng/crsditem.hxx>
55 #include <editeng/cmapitem.hxx>
56 #include <editeng/wrlmitem.hxx>
57 #include <editeng/udlnitem.hxx>
58 #include <editeng/langitem.hxx>
59 #include <editeng/escpitem.hxx>
60 #include <editeng/fhgtitem.hxx>
61 #include <editeng/colritem.hxx>
62 #include <editeng/hyznitem.hxx>
63 #include <editeng/brkitem.hxx>
64 #include <editeng/lrspitem.hxx>
65 #include <editeng/ulspitem.hxx>
66 #include <editeng/boxitem.hxx>
67 #include <editeng/cntritem.hxx>
68 #include <editeng/shdditem.hxx>
69 #include <editeng/akrnitem.hxx>
70 #include <editeng/pbinitem.hxx>
71 #include <editeng/emphitem.hxx>
72 #include <editeng/twolinesitem.hxx>
73 #include <editeng/charscaleitem.hxx>
74 #include <editeng/charrotateitem.hxx>
75 #include <editeng/charreliefitem.hxx>
76 #include <editeng/paravertalignitem.hxx>
77 #include <editeng/pgrditem.hxx>
78 #include <editeng/frmdiritem.hxx>
79 #include <editeng/blnkitem.hxx>
80 #include <editeng/charhiddenitem.hxx>
81 #include <svx/svdmodel.hxx>
82 #include <svx/svdobj.hxx>
83
84 #include <docufld.hxx>
85 #include <flddropdown.hxx>
86 #include <format.hxx>
87 #include <fmtclds.hxx>
88 #include <fmtinfmt.hxx>
89 #include <fmtfld.hxx>
90 #include <fmtfsize.hxx>
91 #include <fmtftn.hxx>
92 #include <fmtrowsplt.hxx>
93 #include <fmtline.hxx>
94 #include <frmfmt.hxx>
95 #include <frmatr.hxx>
96 #include <ftninfo.hxx>
97 #include <htmltbl.hxx>
98 #include <ndgrf.hxx>
99 #include <ndtxt.hxx>
100 #include <node.hxx>
101 #include <pagedesc.hxx>
102 #include <paratr.hxx>
103 #include <swmodule.hxx>
104 #include <swtable.hxx>
105 #include <txtftn.hxx>
106 #include <txtinet.hxx>
107 #include <numrule.hxx>
108
109 #include <rtl/strbuf.hxx>
110 #include <rtl/ustrbuf.hxx>
111 #include <rtl/ustring.hxx>
112
113 #include <tools/color.hxx>
114
115 #include <com/sun/star/i18n/ScriptType.hdl>
116
117 #if OSL_DEBUG_LEVEL > 0
118 #include <stdio.h>
119 #endif
120
121 using rtl::OString;
122 using rtl::OStringBuffer;
123 using rtl::OUString;
124 using rtl::OUStringBuffer;
125 using rtl::OUStringToOString;
126
127 using namespace oox;
128 using namespace docx;
129 using namespace sax_fastparser;
130 using namespace nsSwDocInfoSubType;
131 using namespace nsFieldFlags;
132 using namespace sw::util;
133
RTLAndCJKState(bool bIsRTL,sal_uInt16)134 void DocxAttributeOutput::RTLAndCJKState( bool bIsRTL, sal_uInt16 /*nScript*/ )
135 {
136 if (bIsRTL)
137 m_pSerializer->singleElementNS( XML_w, XML_rtl, FSNS( XML_w, XML_val ), "true", FSEND );
138 }
139
StartParagraph(ww8::WW8TableNodeInfo::Pointer_t pTextNodeInfo)140 void DocxAttributeOutput::StartParagraph( ww8::WW8TableNodeInfo::Pointer_t pTextNodeInfo )
141 {
142 if ( m_nColBreakStatus == COLBRK_POSTPONE )
143 m_nColBreakStatus = COLBRK_WRITE;
144
145 // Output table/table row/table cell starts if needed
146 if ( pTextNodeInfo.get() )
147 {
148 sal_uInt32 nRow = pTextNodeInfo->getRow();
149 sal_uInt32 nCell = pTextNodeInfo->getCell();
150
151 // New cell/row?
152 if ( m_nTableDepth > 0 && !m_bTableCellOpen )
153 {
154 ww8::WW8TableNodeInfoInner::Pointer_t pDeepInner( pTextNodeInfo->getInnerForDepth( m_nTableDepth ) );
155 if ( pDeepInner->getCell() == 0 )
156 StartTableRow( pDeepInner );
157
158 StartTableCell( pDeepInner );
159 }
160
161 if ( nRow == 0 && nCell == 0 )
162 {
163 // Do we have to start the table?
164 // [If we are at the rigth depth already, it means that we
165 // continue the table cell]
166 sal_uInt32 nCurrentDepth = pTextNodeInfo->getDepth();
167
168 if ( nCurrentDepth > m_nTableDepth )
169 {
170 // Start all the tables that begin here
171 for ( sal_uInt32 nDepth = m_nTableDepth + 1; nDepth <= pTextNodeInfo->getDepth(); ++nDepth )
172 {
173 ww8::WW8TableNodeInfoInner::Pointer_t pInner( pTextNodeInfo->getInnerForDepth( nDepth ) );
174
175 StartTable( pInner );
176 StartTableRow( pInner );
177 StartTableCell( pInner );
178 }
179
180 m_nTableDepth = nCurrentDepth;
181 }
182 }
183 }
184
185 m_pSerializer->startElementNS( XML_w, XML_p, FSEND );
186
187 // postpone the output of the run (we get it before the paragraph
188 // properties, but must write it after them)
189 m_pSerializer->mark();
190
191 // no section break in this paragraph yet; can be set in SectionBreak()
192 m_pSectionInfo = NULL;
193
194 m_bParagraphOpened = true;
195 }
196
EndParagraph(ww8::WW8TableNodeInfoInner::Pointer_t pTextNodeInfoInner)197 void DocxAttributeOutput::EndParagraph( ww8::WW8TableNodeInfoInner::Pointer_t pTextNodeInfoInner )
198 {
199 // write the paragraph properties + the run, already in the correct order
200 m_pSerializer->mergeTopMarks();
201 m_pSerializer->endElementNS( XML_w, XML_p );
202
203 // Check for end of cell, rows, tables here
204 FinishTableRowCell( pTextNodeInfoInner );
205
206 m_bParagraphOpened = false;
207 }
208
FinishTableRowCell(ww8::WW8TableNodeInfoInner::Pointer_t pInner,bool bForceEmptyParagraph)209 void DocxAttributeOutput::FinishTableRowCell( ww8::WW8TableNodeInfoInner::Pointer_t pInner, bool bForceEmptyParagraph )
210 {
211 if ( pInner.get() )
212 {
213 // Where are we in the table
214 sal_uInt32 nRow = pInner->getRow( );
215
216 const SwTable *pTable = pInner->getTable( );
217 const SwTableLines& rLines = pTable->GetTabLines( );
218 sal_uInt16 nLinesCount = rLines.Count( );
219
220 if ( pInner->isEndOfCell() )
221 {
222 if ( bForceEmptyParagraph )
223 m_pSerializer->singleElementNS( XML_w, XML_p, FSEND );
224
225 EndTableCell();
226 }
227
228 // This is a line end
229 if ( pInner->isEndOfLine() )
230 EndTableRow();
231
232 // This is the end of the table
233 if ( pInner->isEndOfLine( ) && ( nRow + 1 ) == nLinesCount )
234 EndTable();
235 }
236 }
237
EmptyParagraph()238 void DocxAttributeOutput::EmptyParagraph()
239 {
240 m_pSerializer->singleElementNS( XML_w, XML_p, FSEND );
241 }
242
StartParagraphProperties(const SwTxtNode & rNode)243 void DocxAttributeOutput::StartParagraphProperties( const SwTxtNode& rNode )
244 {
245 // output page/section breaks
246 // Writer can have them at the beginning of a paragraph, or at the end, but
247 // in docx, we have to output them in the paragraph properties of the last
248 // paragraph in a section. To get it right, we have to switch to the next
249 // paragraph, and detect the section breaks there.
250 SwNodeIndex aNextIndex( rNode, 1 );
251 if ( aNextIndex.GetNode().IsTxtNode() )
252 {
253 const SwTxtNode* pTxtNode = static_cast< SwTxtNode* >( &aNextIndex.GetNode() );
254 m_rExport.OutputSectionBreaks( pTxtNode->GetpSwAttrSet(), *pTxtNode );
255 }
256 else if ( aNextIndex.GetNode().IsTableNode() )
257 {
258 const SwTableNode* pTableNode = static_cast< SwTableNode* >( &aNextIndex.GetNode() );
259 const SwFrmFmt *pFmt = pTableNode->GetTable().GetFrmFmt();
260 m_rExport.OutputSectionBreaks( &(pFmt->GetAttrSet()), *pTableNode );
261 }
262
263 // postpone the output so that we can later [in EndParagraphProperties()]
264 // prepend the properties before the run
265 m_pSerializer->mark();
266
267 m_pSerializer->startElementNS( XML_w, XML_pPr, FSEND );
268
269 // and output the section break now (if it appeared)
270 if ( m_pSectionInfo )
271 {
272 m_rExport.SectionProperties( *m_pSectionInfo );
273 m_pSectionInfo = NULL;
274 }
275
276 InitCollectedParagraphProperties();
277 }
278
InitCollectedParagraphProperties()279 void DocxAttributeOutput::InitCollectedParagraphProperties()
280 {
281 m_pSpacingAttrList = NULL;
282 }
283
WriteCollectedParagraphProperties()284 void DocxAttributeOutput::WriteCollectedParagraphProperties()
285 {
286 if ( m_pSpacingAttrList )
287 {
288 XFastAttributeListRef xAttrList( m_pSpacingAttrList );
289 m_pSpacingAttrList = NULL;
290
291 m_pSerializer->singleElementNS( XML_w, XML_spacing, xAttrList );
292 }
293 }
294
EndParagraphProperties()295 void DocxAttributeOutput::EndParagraphProperties()
296 {
297 WriteCollectedParagraphProperties();
298
299 m_pSerializer->endElementNS( XML_w, XML_pPr );
300
301 if ( m_nColBreakStatus == COLBRK_WRITE )
302 {
303 m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
304 m_pSerializer->singleElementNS( XML_w, XML_br,
305 FSNS( XML_w, XML_type ), "column", FSEND );
306 m_pSerializer->endElementNS( XML_w, XML_r );
307
308 m_nColBreakStatus = COLBRK_NONE;
309 }
310
311 // merge the properties _before_ the run (strictly speaking, just
312 // after the start of the paragraph)
313 m_pSerializer->mergeTopMarks( sax_fastparser::MERGE_MARKS_PREPEND );
314 }
315
StartRun(const SwRedlineData * pRedlineData)316 void DocxAttributeOutput::StartRun( const SwRedlineData* pRedlineData )
317 {
318 // if there is some redlining in the document, output it
319 StartRedline( pRedlineData );
320
321 // postpone the output of the start of a run (there are elements that need
322 // to be written before the start of the run, but we learn which they are
323 // _inside_ of the run)
324 m_pSerializer->mark(); // let's call it "postponed run start"
325
326 // postpone the output of the text (we get it before the run properties,
327 // but must write it after them)
328 m_pSerializer->mark(); // let's call it "postponed text"
329 }
330
EndRun()331 void DocxAttributeOutput::EndRun()
332 {
333 // Write field starts
334 for ( std::vector<FieldInfos>::iterator pIt = m_Fields.begin(); pIt != m_Fields.end(); ++pIt )
335 {
336 // Add the fields starts for all but hyperlinks and TOCs
337 if ( pIt->bOpen && pIt->pField )
338 {
339 StartField_Impl( *pIt );
340
341 // Remove the field from the stack if only the start has to be written
342 // Unknown fields sould be removed too
343 if ( !pIt->bClose || ( pIt->eType == ww::eUNKNOWN ) )
344 {
345 m_Fields.erase( pIt );
346 --pIt;
347 }
348 }
349 }
350
351
352 // write the run properties + the text, already in the correct order
353 m_pSerializer->mergeTopMarks(); // merges with "postponed text", see above
354
355 // level down, to be able to prepend the actual run start attribute (just
356 // before "postponed run start")
357 m_pSerializer->mark(); // let's call it "actual run start"
358
359 // prepend the actual run start
360 if ( m_pHyperlinkAttrList )
361 {
362 XFastAttributeListRef xAttrList ( m_pHyperlinkAttrList );
363
364 m_pSerializer->startElementNS( XML_w, XML_hyperlink, xAttrList );
365 }
366
367 // Write the hyperlink and toc fields starts
368 for ( std::vector<FieldInfos>::iterator pIt = m_Fields.begin(); pIt != m_Fields.end(); ++pIt )
369 {
370 // Add the fields starts for hyperlinks, TOCs and index marks
371 if ( pIt->bOpen )
372 {
373 StartField_Impl( *pIt, sal_True );
374
375 // Remove the field if no end needs to be written
376 if ( !pIt->bClose ) {
377 m_Fields.erase( pIt );
378 --pIt;
379 }
380 }
381 }
382
383 DoWriteBookmarks( );
384 WriteCommentRanges();
385
386 m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
387 m_pSerializer->mergeTopMarks( sax_fastparser::MERGE_MARKS_PREPEND ); // merges with "postponed run start", see above
388
389 // write the run start + the run content
390 m_pSerializer->mergeTopMarks(); // merges the "actual run start"
391
392 // append the actual run end
393 m_pSerializer->endElementNS( XML_w, XML_r );
394
395 if ( m_pHyperlinkAttrList )
396 {
397 m_pSerializer->endElementNS( XML_w, XML_hyperlink );
398 m_pHyperlinkAttrList = NULL;
399 }
400
401 while ( m_Fields.begin() != m_Fields.end() )
402 {
403 EndField_Impl( m_Fields.front( ) );
404 m_Fields.erase( m_Fields.begin( ) );
405 }
406
407 // if there is some redlining in the document, output it
408 EndRedline();
409 }
410
WriteCommentRanges()411 void DocxAttributeOutput::WriteCommentRanges()
412 {
413 if (m_bPostitStart)
414 {
415 m_bPostitStart = false;
416 OString idstr = OString::valueOf( sal_Int32( m_postitFieldsMaxId ));
417 m_pSerializer->singleElementNS( XML_w, XML_commentRangeStart, FSNS( XML_w, XML_id ), idstr.getStr(), FSEND );
418 }
419 if (m_bPostitEnd)
420 {
421 m_bPostitEnd = false;
422 OString idstr = OString::valueOf( sal_Int32( m_postitFieldsMaxId ));
423 m_pSerializer->singleElementNS( XML_w, XML_commentRangeEnd, FSNS( XML_w, XML_id ), idstr.getStr(), FSEND );
424 }
425 }
426
WritePostitFieldStart()427 void DocxAttributeOutput::WritePostitFieldStart()
428 {
429 m_bPostitStart = true;
430 }
431
WritePostitFieldEnd()432 void DocxAttributeOutput::WritePostitFieldEnd()
433 {
434 m_bPostitEnd = true;
435 }
436
437
DoWriteBookmarks()438 void DocxAttributeOutput::DoWriteBookmarks()
439 {
440 // Write the start bookmarks
441 for ( std::vector< OString >::const_iterator it = m_rMarksStart.begin(), end = m_rMarksStart.end();
442 it < end; ++it )
443 {
444 const OString& rName = *it;
445
446 // Output the bookmark
447 sal_uInt16 nId = m_nNextMarkId++;
448 m_rOpenedMarksIds[rName] = nId;
449 m_pSerializer->singleElementNS( XML_w, XML_bookmarkStart,
450 FSNS( XML_w, XML_id ), OString::valueOf( sal_Int32( nId ) ).getStr( ),
451 FSNS( XML_w, XML_name ), rName.getStr(),
452 FSEND );
453 }
454 m_rMarksStart.clear();
455
456 // export the end bookmarks
457 for ( std::vector< OString >::const_iterator it = m_rMarksEnd.begin(), end = m_rMarksEnd.end();
458 it < end; ++it )
459 {
460 const OString& rName = *it;
461
462 // Get the id of the bookmark
463 std::map< OString, sal_uInt16 >::iterator pPos = m_rOpenedMarksIds.find( rName );
464 if ( pPos != m_rOpenedMarksIds.end( ) )
465 {
466 sal_uInt16 nId = ( *pPos ).second;
467 m_pSerializer->singleElementNS( XML_w, XML_bookmarkEnd,
468 FSNS( XML_w, XML_id ), OString::valueOf( sal_Int32( nId ) ).getStr( ),
469 FSEND );
470 m_rOpenedMarksIds.erase( rName );
471 }
472 }
473 m_rMarksEnd.clear();
474 }
475
StartField_Impl(FieldInfos & rInfos,sal_Bool bWriteRun)476 void DocxAttributeOutput::StartField_Impl( FieldInfos& rInfos, sal_Bool bWriteRun )
477 {
478 if ( rInfos.pField && rInfos.eType == ww::eUNKNOWN )
479 {
480 // Expand unsupported fields
481 RunText( rInfos.pField->Expand( ) );
482 }
483 else if ( rInfos.eType != ww::eNONE ) // HYPERLINK fields are just commands
484 {
485 if ( bWriteRun )
486 m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
487
488 if ( rInfos.eType == ww::eFORMDROPDOWN )
489 {
490 m_pSerializer->startElementNS( XML_w, XML_fldChar,
491 FSNS( XML_w, XML_fldCharType ), "begin",
492 FSEND );
493
494 const SwDropDownField& rFld2 = *(SwDropDownField*)rInfos.pField;
495 uno::Sequence<rtl::OUString> aItems =
496 rFld2.GetItemSequence();
497 GetExport().DoComboBox(rFld2.GetName(),
498 rFld2.GetHelp(),
499 rFld2.GetToolTip(),
500 rFld2.GetSelectedItem(), aItems);
501
502 m_pSerializer->endElementNS( XML_w, XML_fldChar );
503
504 if ( bWriteRun )
505 m_pSerializer->endElementNS( XML_w, XML_r );
506
507 }
508 else
509 {
510 // Write the field start
511 m_pSerializer->singleElementNS( XML_w, XML_fldChar,
512 FSNS( XML_w, XML_fldCharType ), "begin",
513 FSEND );
514
515 if ( bWriteRun )
516 m_pSerializer->endElementNS( XML_w, XML_r );
517
518 // The hyperlinks fields can't be expanded: the value is
519 // normally in the text run
520 if ( !rInfos.pField )
521 CmdField_Impl( rInfos );
522 }
523 }
524 }
525
DoWriteCmd(String & rCmd)526 void DocxAttributeOutput::DoWriteCmd( String& rCmd )
527 {
528 // Write the Field command
529 m_pSerializer->startElementNS( XML_w, XML_instrText, FSEND );
530 m_pSerializer->writeEscaped( OUString( rCmd ) );
531 m_pSerializer->endElementNS( XML_w, XML_instrText );
532
533 }
534
CmdField_Impl(FieldInfos & rInfos)535 void DocxAttributeOutput::CmdField_Impl( FieldInfos& rInfos )
536 {
537 m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
538 xub_StrLen nNbToken = rInfos.sCmd.GetTokenCount( '\t' );
539
540 for ( xub_StrLen i = 0; i < nNbToken; i++ )
541 {
542 String sToken = rInfos.sCmd.GetToken( i, '\t' );
543 // Write the Field command
544 DoWriteCmd( sToken );
545
546 // Replace tabs by </instrText><tab/><instrText>
547 if ( i < ( nNbToken - 1 ) )
548 RunText( String::CreateFromAscii( "\t" ) );
549 }
550
551 m_pSerializer->endElementNS( XML_w, XML_r );
552
553
554 // Write the Field separator
555 m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
556 m_pSerializer->singleElementNS( XML_w, XML_fldChar,
557 FSNS( XML_w, XML_fldCharType ), "separate",
558 FSEND );
559 m_pSerializer->endElementNS( XML_w, XML_r );
560 }
561
EndField_Impl(FieldInfos & rInfos)562 void DocxAttributeOutput::EndField_Impl( FieldInfos& rInfos )
563 {
564 // The command has to be written before for the hyperlinks
565 if ( rInfos.pField )
566 {
567 CmdField_Impl( rInfos );
568 }
569
570 // Write the bookmark start if any
571 OUString aBkmName( m_sFieldBkm );
572 if ( aBkmName.getLength( ) > 0 )
573 {
574 m_pSerializer->singleElementNS( XML_w, XML_bookmarkStart,
575 FSNS( XML_w, XML_id ), OString::valueOf( sal_Int32( m_nNextMarkId ) ).getStr( ),
576 FSNS( XML_w, XML_name ), OUStringToOString( aBkmName, RTL_TEXTENCODING_UTF8 ).getStr( ),
577 FSEND );
578 }
579
580 if (rInfos.pField ) // For hyperlinks and TOX
581 {
582 // Write the Field latest value
583 m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
584
585 // Find another way for hyperlinks
586 RunText( rInfos.pField->Expand( ) );
587 m_pSerializer->endElementNS( XML_w, XML_r );
588 }
589
590 // Write the bookmark end if any
591 if ( aBkmName.getLength( ) > 0 )
592 {
593 m_pSerializer->singleElementNS( XML_w, XML_bookmarkEnd,
594 FSNS( XML_w, XML_id ), OString::valueOf( sal_Int32( m_nNextMarkId ) ).getStr( ),
595 FSEND );
596
597 m_nNextMarkId++;
598 }
599
600 // Write the Field end
601 m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
602 m_pSerializer->singleElementNS( XML_w, XML_fldChar,
603 FSNS( XML_w, XML_fldCharType ), "end",
604 FSEND );
605 m_pSerializer->endElementNS( XML_w, XML_r );
606
607
608 // Write the ref field if a bookmark had to be set and the field
609 // should be visible
610 if ( rInfos.pField )
611 {
612 sal_uInt16 nSubType = rInfos.pField->GetSubType( );
613 bool bIsSetField = rInfos.pField->GetTyp( )->Which( ) == RES_SETEXPFLD;
614 bool bShowRef = ( !bIsSetField || ( nSubType & nsSwExtendedSubType::SUB_INVISIBLE ) ) ? false : true;
615
616 if ( ( m_sFieldBkm.Len( ) > 0 ) && bShowRef )
617 {
618 // Write the field beginning
619 m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
620 m_pSerializer->singleElementNS( XML_w, XML_fldChar,
621 FSNS( XML_w, XML_fldCharType ), "begin",
622 FSEND );
623 m_pSerializer->endElementNS( XML_w, XML_r );
624
625 rInfos.sCmd = FieldString( ww::eREF );
626 rInfos.sCmd.APPEND_CONST_ASC( "\"" );
627 rInfos.sCmd += m_sFieldBkm;
628 rInfos.sCmd.APPEND_CONST_ASC( "\" " );
629
630 // Clean the field bookmark data to avoid infinite loop
631 m_sFieldBkm = String( );
632
633 // Write the end of the field
634 EndField_Impl( rInfos );
635 }
636 }
637 }
638
StartRunProperties()639 void DocxAttributeOutput::StartRunProperties()
640 {
641 // postpone the output so that we can later [in EndRunProperties()]
642 // prepend the properties before the text
643 m_pSerializer->mark();
644
645 m_pSerializer->startElementNS( XML_w, XML_rPr, FSEND );
646
647 InitCollectedRunProperties();
648 }
649
InitCollectedRunProperties()650 void DocxAttributeOutput::InitCollectedRunProperties()
651 {
652 m_pFontsAttrList = NULL;
653 m_pEastAsianLayoutAttrList = NULL;
654 m_pCharLangAttrList = NULL;
655 }
656
WriteCollectedRunProperties()657 void DocxAttributeOutput::WriteCollectedRunProperties()
658 {
659 // Write all differed properties
660 if ( m_pFontsAttrList )
661 {
662 XFastAttributeListRef xAttrList( m_pFontsAttrList );
663 m_pFontsAttrList = NULL;
664
665 m_pSerializer->singleElementNS( XML_w, XML_rFonts, xAttrList );
666 }
667
668 if ( m_pEastAsianLayoutAttrList )
669 {
670 XFastAttributeListRef xAttrList( m_pEastAsianLayoutAttrList );
671 m_pEastAsianLayoutAttrList = NULL;
672
673 m_pSerializer->singleElementNS( XML_w, XML_eastAsianLayout, xAttrList );
674 }
675
676 if ( m_pCharLangAttrList )
677 {
678 XFastAttributeListRef xAttrList( m_pCharLangAttrList );
679 m_pCharLangAttrList = NULL;
680
681 m_pSerializer->singleElementNS( XML_w, XML_lang, xAttrList );
682 }
683 }
684
EndRunProperties(const SwRedlineData *)685 void DocxAttributeOutput::EndRunProperties( const SwRedlineData* /*pRedlineData*/ )
686 {
687 WriteCollectedRunProperties();
688
689 m_pSerializer->endElementNS( XML_w, XML_rPr );
690
691 // write footnotes/endnotes if we have any
692 FootnoteEndnoteReference();
693
694 // merge the properties _before_ the run text (strictly speaking, just
695 // after the start of the run)
696 m_pSerializer->mergeTopMarks( sax_fastparser::MERGE_MARKS_PREPEND );
697 }
698
699 /** Output sal_Unicode* as a run text (<t>the text</t>).
700
701 When bMove is true, update rBegin to point _after_ the end of the text +
702 1, meaning that it skips one character after the text. This is to make
703 the switch in DocxAttributeOutput::RunText() nicer ;-)
704 */
impl_WriteRunText(FSHelperPtr pSerializer,sal_Int32 nTextToken,const sal_Unicode * & rBegin,const sal_Unicode * pEnd,bool bMove=true)705 static void impl_WriteRunText( FSHelperPtr pSerializer, sal_Int32 nTextToken,
706 const sal_Unicode* &rBegin, const sal_Unicode* pEnd, bool bMove = true )
707 {
708 const sal_Unicode *pBegin = rBegin;
709
710 // skip one character after the end
711 if ( bMove )
712 rBegin = pEnd + 1;
713
714 if ( pBegin >= pEnd )
715 return; // we want to write at least one character
716
717 // we have to add 'preserve' when starting/ending with space
718 if ( *pBegin == sal_Unicode( ' ' ) || *( pEnd - 1 ) == sal_Unicode( ' ' ) )
719 {
720 pSerializer->startElementNS( XML_w, nTextToken, FSNS( XML_xml, XML_space ), "preserve", FSEND );
721 }
722 else
723 pSerializer->startElementNS( XML_w, nTextToken, FSEND );
724
725 pSerializer->writeEscaped( OUString( pBegin, pEnd - pBegin ) );
726
727 pSerializer->endElementNS( XML_w, nTextToken );
728 }
729
RunText(const String & rText,rtl_TextEncoding)730 void DocxAttributeOutput::RunText( const String& rText, rtl_TextEncoding /*eCharSet*/ )
731 {
732 OUString aText( rText );
733
734 // one text can be split into more <w:t>blah</w:t>'s by line breaks etc.
735 const sal_Unicode *pBegin = aText.getStr();
736 const sal_Unicode *pEnd = pBegin + aText.getLength();
737
738 // the text run is usually XML_t, with the exception of the deleted text
739 sal_Int32 nTextToken = XML_t;
740 if ( m_pRedlineData && m_pRedlineData->GetType() == nsRedlineType_t::REDLINE_DELETE )
741 nTextToken = XML_delText;
742
743 for ( const sal_Unicode *pIt = pBegin; pIt < pEnd; ++pIt )
744 {
745 switch ( *pIt )
746 {
747 case 0x09: // tab
748 impl_WriteRunText( m_pSerializer, nTextToken, pBegin, pIt );
749 m_pSerializer->singleElementNS( XML_w, XML_tab, FSEND );
750 break;
751 case 0x0b: // line break
752 impl_WriteRunText( m_pSerializer, nTextToken, pBegin, pIt );
753 m_pSerializer->singleElementNS( XML_w, XML_br, FSEND );
754 break;
755 default:
756 if ( *pIt < 0x0020 ) // filter out the control codes
757 {
758 impl_WriteRunText( m_pSerializer, nTextToken, pBegin, pIt );
759 OSL_TRACE( "Ignored control code %x in a text run.", *pIt );
760 }
761 break;
762 }
763 }
764
765 impl_WriteRunText( m_pSerializer, nTextToken, pBegin, pEnd, false );
766 }
767
RawText(const String &,bool,rtl_TextEncoding)768 void DocxAttributeOutput::RawText( const String& /*rText*/, bool /*bForceUnicode*/, rtl_TextEncoding /*eCharSet*/ )
769 {
770 OSL_TRACE("TODO DocxAttributeOutput::RawText( const String& rText, bool bForceUnicode, rtl_TextEncoding eCharSet )\n" );
771 }
772
StartRuby(const SwTxtNode &,const SwFmtRuby &)773 void DocxAttributeOutput::StartRuby( const SwTxtNode& /*rNode*/, const SwFmtRuby& /*rRuby*/ )
774 {
775 OSL_TRACE("TODO DocxAttributeOutput::StartRuby( const SwTxtNode& rNode, const SwFmtRuby& rRuby )\n" );
776 }
777
EndRuby()778 void DocxAttributeOutput::EndRuby()
779 {
780 OSL_TRACE( "TODO DocxAttributeOutput::EndRuby()\n" );
781 }
782
AnalyzeURL(const String & rUrl,const String & rTarget,String * pLinkURL,String * pMark)783 bool DocxAttributeOutput::AnalyzeURL( const String& rUrl, const String& rTarget, String* pLinkURL, String* pMark )
784 {
785 bool bBookMarkOnly = AttributeOutputBase::AnalyzeURL( rUrl, rTarget, pLinkURL, pMark );
786
787 String sURL = *pLinkURL;
788 String sMark = *pMark;
789
790 bool bOutputField = sMark.Len();
791
792 if ( bOutputField )
793 {
794 if ( bBookMarkOnly )
795 sURL = FieldString( ww::eHYPERLINK );
796 else
797 {
798 String sFld( FieldString( ww::eHYPERLINK ) );
799 sFld.APPEND_CONST_ASC( "\"" );
800 sURL.Insert( sFld, 0 );
801 sURL += '\"';
802 }
803
804 if ( sMark.Len() )
805 ( ( sURL.APPEND_CONST_ASC( " \\l \"" ) ) += sMark ) += '\"';
806
807 if ( rTarget.Len() )
808 ( sURL.APPEND_CONST_ASC( " \\n " ) ) += rTarget;
809 }
810
811 *pLinkURL = sURL;
812 *pMark = sMark;
813
814 return bBookMarkOnly;
815 }
816
StartURL(const String & rUrl,const String & rTarget)817 bool DocxAttributeOutput::StartURL( const String& rUrl, const String& rTarget )
818 {
819 String sMark;
820 String sUrl;
821
822 bool bBookmarkOnly = AnalyzeURL( rUrl, rTarget, &sUrl, &sMark );
823
824 if ( sMark.Len() && !bBookmarkOnly )
825 {
826 m_rExport.OutputField( NULL, ww::eHYPERLINK, sUrl );
827 }
828 else
829 {
830 // Output a hyperlink XML element
831
832 m_pHyperlinkAttrList = m_pSerializer->createAttrList();
833 if ( !bBookmarkOnly )
834 {
835 OUString osUrl( sUrl );
836
837 ::rtl::OString sId = m_rExport.AddRelation(
838 S( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink" ),
839 osUrl, S("External") );
840 m_pHyperlinkAttrList->add( FSNS( XML_r, XML_id), sId.getStr());
841 }
842 else
843 m_pHyperlinkAttrList->add( FSNS( XML_w, XML_anchor ),
844 OUStringToOString( OUString( sMark ), RTL_TEXTENCODING_UTF8 ).getStr( ) );
845
846 OUString sTarget( rTarget );
847 if ( sTarget.getLength( ) > 0 )
848 {
849 OString soTarget = OUStringToOString( sTarget, RTL_TEXTENCODING_UTF8 );
850 m_pHyperlinkAttrList->add(FSNS( XML_w, XML_tgtFrame ), soTarget.getStr());
851 }
852 }
853
854 return true;
855 }
856
EndURL()857 bool DocxAttributeOutput::EndURL()
858 {
859 return true;
860 }
861
FieldVanish(const String & rTxt,ww::eField eType)862 void DocxAttributeOutput::FieldVanish( const String& rTxt, ww::eField eType )
863 {
864 WriteField_Impl( NULL, eType, rTxt, WRITEFIELD_ALL );
865 }
866
Redline(const SwRedlineData *)867 void DocxAttributeOutput::Redline( const SwRedlineData* /*pRedline*/ )
868 {
869 OSL_TRACE( "TODO DocxAttributeOutput::Redline( const SwRedlineData* pRedline )\n" );
870 }
871
872 /// Append the number as 2-digit when less than 10.
impl_AppendTwoDigits(OStringBuffer & rBuffer,sal_Int32 nNum)873 static void impl_AppendTwoDigits( OStringBuffer &rBuffer, sal_Int32 nNum )
874 {
875 if ( nNum < 0 || nNum > 99 )
876 {
877 rBuffer.append( "00" );
878 return;
879 }
880
881 if ( nNum < 10 )
882 rBuffer.append( '0' );
883
884 rBuffer.append( nNum );
885 }
886
887 /** Convert DateTime to xsd::dateTime string.
888
889 I guess there must be an implementation of this somewhere in OOo, but I failed
890 to find it, unfortunately :-(
891 */
impl_DateTimeToOString(const DateTime & rDateTime)892 static OString impl_DateTimeToOString( const DateTime& rDateTime )
893 {
894 DateTime aInUTC( rDateTime );
895 aInUTC.ConvertToUTC();
896
897 OStringBuffer aBuffer( 25 );
898 aBuffer.append( sal_Int32( aInUTC.GetYear() ) );
899 aBuffer.append( '-' );
900
901 impl_AppendTwoDigits( aBuffer, aInUTC.GetMonth() );
902 aBuffer.append( '-' );
903
904 impl_AppendTwoDigits( aBuffer, aInUTC.GetDay() );
905 aBuffer.append( 'T' );
906
907 impl_AppendTwoDigits( aBuffer, aInUTC.GetHour() );
908 aBuffer.append( ':' );
909
910 impl_AppendTwoDigits( aBuffer, aInUTC.GetMin() );
911 aBuffer.append( ':' );
912
913 impl_AppendTwoDigits( aBuffer, aInUTC.GetSec() );
914 aBuffer.append( 'Z' ); // we are in UTC
915
916 return aBuffer.makeStringAndClear();
917 }
918
StartRedline(const SwRedlineData * pRedlineData)919 void DocxAttributeOutput::StartRedline( const SwRedlineData* pRedlineData )
920 {
921 m_pRedlineData = pRedlineData;
922
923 if ( !m_pRedlineData )
924 return;
925
926 // FIXME check if it's necessary to travel over the Next()'s in pRedlineData
927
928 OString aId( OString::valueOf( m_nRedlineId++ ) );
929
930 const String &rAuthor( SW_MOD()->GetRedlineAuthor( pRedlineData->GetAuthor() ) );
931 OString aAuthor( OUStringToOString( rAuthor, RTL_TEXTENCODING_UTF8 ) );
932
933 OString aDate( impl_DateTimeToOString( pRedlineData->GetTimeStamp() ) );
934
935 switch ( pRedlineData->GetType() )
936 {
937 case nsRedlineType_t::REDLINE_INSERT:
938 m_pSerializer->startElementNS( XML_w, XML_ins,
939 FSNS( XML_w, XML_id ), aId.getStr(),
940 FSNS( XML_w, XML_author ), aAuthor.getStr(),
941 FSNS( XML_w, XML_date ), aDate.getStr(),
942 FSEND );
943 break;
944
945 case nsRedlineType_t::REDLINE_DELETE:
946 m_pSerializer->startElementNS( XML_w, XML_del,
947 FSNS( XML_w, XML_id ), aId.getStr(),
948 FSNS( XML_w, XML_author ), aAuthor.getStr(),
949 FSNS( XML_w, XML_date ), aDate.getStr(),
950 FSEND );
951 break;
952
953 case nsRedlineType_t::REDLINE_FORMAT:
954 OSL_TRACE( "TODO DocxAttributeOutput::StartRedline()\n" );
955 default:
956 break;
957 }
958 }
959
EndRedline()960 void DocxAttributeOutput::EndRedline()
961 {
962 if ( !m_pRedlineData )
963 return;
964
965 switch ( m_pRedlineData->GetType() )
966 {
967 case nsRedlineType_t::REDLINE_INSERT:
968 m_pSerializer->endElementNS( XML_w, XML_ins );
969 break;
970
971 case nsRedlineType_t::REDLINE_DELETE:
972 m_pSerializer->endElementNS( XML_w, XML_del );
973 break;
974
975 case nsRedlineType_t::REDLINE_FORMAT:
976 OSL_TRACE( "TODO DocxAttributeOutput::EndRedline()\n" );
977 break;
978 default:
979 break;
980 }
981
982 m_pRedlineData = NULL;
983 }
984
FormatDrop(const SwTxtNode &,const SwFmtDrop &,sal_uInt16,ww8::WW8TableNodeInfo::Pointer_t,ww8::WW8TableNodeInfoInner::Pointer_t)985 void DocxAttributeOutput::FormatDrop( const SwTxtNode& /*rNode*/, const SwFmtDrop& /*rSwFmtDrop*/, sal_uInt16 /*nStyle*/, ww8::WW8TableNodeInfo::Pointer_t /*pTextNodeInfo*/, ww8::WW8TableNodeInfoInner::Pointer_t )
986 {
987 OSL_TRACE( "TODO DocxAttributeOutput::FormatDrop( const SwTxtNode& rNode, const SwFmtDrop& rSwFmtDrop, sal_uInt16 nStyle )\n" );
988 }
989
ParagraphStyle(sal_uInt16 nStyle)990 void DocxAttributeOutput::ParagraphStyle( sal_uInt16 nStyle )
991 {
992 OString aStyleId( "style" );
993 aStyleId += OString::valueOf( sal_Int32( nStyle ) );
994
995 m_pSerializer->singleElementNS( XML_w, XML_pStyle, FSNS( XML_w, XML_val ), aStyleId.getStr(), FSEND );
996 }
997
998 #if 0
999 void DocxAttributeOutput::InTable()
1000 {
1001 #if OSL_DEBUG_LEVEL > 0
1002 OSL_TRACE( "TODO DocxAttributeOutput::InTable()\n" );
1003 #endif
1004 }
1005
1006
1007 void DocxAttributeOutput::TableRowProperties( bool /*bHeader*/, long /*nCellHeight*/, bool /*bCannotSplit*/, bool /*bRightToLeft*/ )
1008 {
1009 #if OSL_DEBUG_LEVEL > 0
1010 OSL_TRACE( "TODO DocxAttributeOutput::TableRowProperties()\n" );
1011 #endif
1012 }
1013 #endif
1014
impl_ConvertColor(const Color & rColor)1015 static OString impl_ConvertColor( const Color &rColor )
1016 {
1017 OString color( "auto" );
1018 if ( rColor.GetColor() != COL_AUTO )
1019 {
1020 const char pHexDigits[] = "0123456789ABCDEF";
1021 char pBuffer[] = "000000";
1022
1023 pBuffer[0] = pHexDigits[ ( rColor.GetRed() >> 4 ) & 0x0F ];
1024 pBuffer[1] = pHexDigits[ rColor.GetRed() & 0x0F ];
1025 pBuffer[2] = pHexDigits[ ( rColor.GetGreen() >> 4 ) & 0x0F ];
1026 pBuffer[3] = pHexDigits[ rColor.GetGreen() & 0x0F ];
1027 pBuffer[4] = pHexDigits[ ( rColor.GetBlue() >> 4 ) & 0x0F ];
1028 pBuffer[5] = pHexDigits[ rColor.GetBlue() & 0x0F ];
1029
1030 color = OString( pBuffer );
1031 }
1032 return color;
1033 }
1034
impl_borderLine(FSHelperPtr pSerializer,sal_Int32 elementToken,const SvxBorderLine * pBorderLine,sal_uInt16 nDist)1035 static void impl_borderLine( FSHelperPtr pSerializer, sal_Int32 elementToken, const SvxBorderLine* pBorderLine, sal_uInt16 nDist )
1036 {
1037 FastAttributeList* pAttr = pSerializer->createAttrList();
1038
1039 sal_uInt16 inW = pBorderLine->GetInWidth();
1040 sal_uInt16 outW = pBorderLine->GetOutWidth();
1041 sal_uInt16 nWidth = inW + outW;
1042
1043 // Compute val attribute value
1044 // Can be one of:
1045 // single, double,
1046 // basicWideOutline, basicWideInline
1047 // OOXml also supports those types of borders, but we'll try to play with the first ones.
1048 // thickThinMediumGap, thickThinLargeGap, thickThinSmallGap
1049 // thinThickLargeGap, thinThickMediumGap, thinThickSmallGap
1050 const char* pVal = "single";
1051 if ( pBorderLine->isDouble() )
1052 {
1053 if ( inW == outW )
1054 pVal = ( sal_Char* )"double";
1055 else if ( inW > outW )
1056 {
1057 pVal = ( sal_Char* )"thinThickMediumGap";
1058 }
1059 else if ( inW < outW )
1060 {
1061 pVal = ( sal_Char* )"thickThinMediumGap";
1062 }
1063 }
1064
1065 pAttr->add( FSNS( XML_w, XML_val ), OString( pVal ) );
1066
1067 // Compute the sz attribute
1068
1069 // The unit is the 8th of point
1070 nWidth = sal_Int32( nWidth / 2.5 );
1071 sal_uInt16 nMinWidth = 2;
1072 sal_uInt16 nMaxWidth = 96;
1073
1074 if ( nWidth > nMaxWidth )
1075 nWidth = nMaxWidth;
1076 else if ( nWidth < nMinWidth )
1077 nWidth = nMinWidth;
1078
1079 pAttr->add( FSNS( XML_w, XML_sz ), OString::valueOf( sal_Int32( nWidth ) ) );
1080
1081 // Get the distance (in pt)
1082 pAttr->add( FSNS( XML_w, XML_space ), OString::valueOf( sal_Int32( nDist / 20 ) ) );
1083
1084 // Get the color code as an RRGGBB hex value
1085 OString sColor( impl_ConvertColor( pBorderLine->GetColor( ) ) );
1086 pAttr->add( FSNS( XML_w, XML_color ), sColor );
1087
1088 XFastAttributeListRef xAttrs( pAttr );
1089 pSerializer->singleElementNS( XML_w, elementToken, xAttrs );
1090 }
1091
impl_pageBorders(FSHelperPtr pSerializer,const SvxBoxItem & rBox)1092 static void impl_pageBorders( FSHelperPtr pSerializer, const SvxBoxItem& rBox )
1093 {
1094 static const sal_uInt16 aBorders[] =
1095 {
1096 BOX_LINE_TOP, BOX_LINE_LEFT, BOX_LINE_BOTTOM, BOX_LINE_RIGHT
1097 };
1098
1099 static const sal_uInt16 aXmlElements[] =
1100 {
1101 XML_top, XML_left, XML_bottom, XML_right
1102 };
1103 const sal_uInt16* pBrd = aBorders;
1104 for( int i = 0; i < 4; ++i, ++pBrd )
1105 {
1106 const SvxBorderLine* pLn = rBox.GetLine( *pBrd );
1107 if ( pLn )
1108 impl_borderLine( pSerializer, aXmlElements[i], pLn, 0 );
1109 }
1110 }
1111
TableCellProperties(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner)1112 void DocxAttributeOutput::TableCellProperties( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
1113 {
1114 m_pSerializer->startElementNS( XML_w, XML_tcPr, FSEND );
1115
1116 const SwTableBox *pTblBox = pTableTextNodeInfoInner->getTableBox( );
1117
1118 // The cell borders
1119 m_pSerializer->startElementNS( XML_w, XML_tcBorders, FSEND );
1120 SwFrmFmt *pFmt = pTblBox->GetFrmFmt( );
1121 impl_pageBorders( m_pSerializer, pFmt->GetBox( ) );
1122 m_pSerializer->endElementNS( XML_w, XML_tcBorders );
1123
1124 // Vertical merges
1125 long vSpan = pTblBox->getRowSpan( );
1126 if ( vSpan > 1 )
1127 {
1128 m_pSerializer->singleElementNS( XML_w, XML_vMerge,
1129 FSNS( XML_w, XML_val ), "restart",
1130 FSEND );
1131 }
1132 else if ( vSpan < 0 )
1133 {
1134 m_pSerializer->singleElementNS( XML_w, XML_vMerge,
1135 FSNS( XML_w, XML_val ), "continue",
1136 FSEND );
1137 }
1138
1139 // Horizontal spans
1140 const SwWriteTableRows& aRows = m_pTableWrt->GetRows( );
1141 SwWriteTableRow *pRow = aRows[ pTableTextNodeInfoInner->getRow( ) ];
1142 SwWriteTableCell *pCell = pRow->GetCells( )[ pTableTextNodeInfoInner->getCell( ) ];
1143
1144 sal_uInt16 nColSpan = pCell->GetColSpan();
1145 if ( nColSpan > 1 )
1146 m_pSerializer->singleElementNS( XML_w, XML_gridSpan,
1147 FSNS( XML_w, XML_val ), OString::valueOf( sal_Int32( nColSpan ) ).getStr(),
1148 FSEND );
1149
1150 TableBackgrounds( pTableTextNodeInfoInner );
1151
1152 // Cell prefered width
1153 SwTwips nWidth = GetGridCols( pTableTextNodeInfoInner )[ pTableTextNodeInfoInner->getCell() ];
1154 m_pSerializer->singleElementNS( XML_w, XML_tcW,
1155 FSNS( XML_w, XML_w ), OString::valueOf( sal_Int32( nWidth ) ).getStr( ),
1156 FSNS( XML_w, XML_type ), "dxa",
1157 FSEND );
1158
1159 // Cell margins
1160 m_pSerializer->startElementNS( XML_w, XML_tcMar, FSEND );
1161 const SvxBoxItem& rBox = pFmt->GetBox( );
1162 static const sal_uInt16 aBorders[] =
1163 {
1164 BOX_LINE_TOP, BOX_LINE_LEFT, BOX_LINE_BOTTOM, BOX_LINE_RIGHT
1165 };
1166
1167 static const sal_uInt16 aXmlElements[] =
1168 {
1169 XML_top, XML_left, XML_bottom, XML_right
1170 };
1171 const sal_uInt16* pBrd = aBorders;
1172 for( int i = 0; i < 4; ++i, ++pBrd )
1173 {
1174 sal_Int32 nDist = sal_Int32( rBox.GetDistance( *pBrd ) );
1175 m_pSerializer->singleElementNS( XML_w, aXmlElements[i],
1176 FSNS( XML_w, XML_w ), OString::valueOf( nDist ).getStr( ),
1177 FSNS( XML_w, XML_type ), "dxa",
1178 FSEND );
1179 }
1180
1181 m_pSerializer->endElementNS( XML_w, XML_tcMar );
1182
1183 TableVerticalCell( pTableTextNodeInfoInner );
1184
1185 m_pSerializer->endElementNS( XML_w, XML_tcPr );
1186 }
1187
InitTableHelper(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner)1188 void DocxAttributeOutput::InitTableHelper( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
1189 {
1190 sal_uInt32 nPageSize = 0;
1191 bool bRelBoxSize = false;
1192
1193 // Create the SwWriteTable instance to use col spans (and maybe other infos)
1194 GetTablePageSize( pTableTextNodeInfoInner, nPageSize, bRelBoxSize );
1195
1196 const SwTable* pTable = pTableTextNodeInfoInner->getTable( );
1197 const SwFrmFmt *pFmt = pTable->GetFrmFmt( );
1198 SwTwips nTblSz = pFmt->GetFrmSize( ).GetWidth( );
1199
1200 const SwHTMLTableLayout *pLayout = pTable->GetHTMLTableLayout();
1201 if( pLayout && pLayout->IsExportable() )
1202 m_pTableWrt = new SwWriteTable( pLayout );
1203 else
1204 m_pTableWrt = new SwWriteTable( pTable->GetTabLines(), (sal_uInt16)nPageSize,
1205 (sal_uInt16)nTblSz, false);
1206 }
1207
StartTable(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner)1208 void DocxAttributeOutput::StartTable( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
1209 {
1210 m_pSerializer->startElementNS( XML_w, XML_tbl, FSEND );
1211
1212 InitTableHelper( pTableTextNodeInfoInner );
1213 TableDefinition( pTableTextNodeInfoInner );
1214 }
1215
EndTable()1216 void DocxAttributeOutput::EndTable()
1217 {
1218 m_pSerializer->endElementNS( XML_w, XML_tbl );
1219
1220 if ( m_nTableDepth > 0 )
1221 --m_nTableDepth;
1222
1223 // We closed the table; if it is a nested table, the cell that contains it
1224 // still continues
1225 m_bTableCellOpen = true;
1226
1227 // Cleans the table helper
1228 delete m_pTableWrt, m_pTableWrt = NULL;
1229 }
1230
StartTableRow(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner)1231 void DocxAttributeOutput::StartTableRow( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
1232 {
1233 m_pSerializer->startElementNS( XML_w, XML_tr, FSEND );
1234
1235 // Output the row properties
1236 m_pSerializer->startElementNS( XML_w, XML_trPr, FSEND );
1237
1238 // Header row: tblHeader
1239 const SwTable *pTable = pTableTextNodeInfoInner->getTable( );
1240 if ( pTable->GetRowsToRepeat( ) > pTableTextNodeInfoInner->getRow( ) )
1241 m_pSerializer->singleElementNS( XML_w, XML_tblHeader,
1242 FSNS( XML_w, XML_val ), "true",
1243 FSEND );
1244
1245 TableHeight( pTableTextNodeInfoInner );
1246 TableCanSplit( pTableTextNodeInfoInner );
1247
1248 m_pSerializer->endElementNS( XML_w, XML_trPr );
1249 }
1250
EndTableRow()1251 void DocxAttributeOutput::EndTableRow( )
1252 {
1253 m_pSerializer->endElementNS( XML_w, XML_tr );
1254 }
1255
1256
StartTableCell(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner)1257 void DocxAttributeOutput::StartTableCell( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
1258 {
1259 if ( !m_pTableWrt )
1260 InitTableHelper( pTableTextNodeInfoInner );
1261
1262 m_pSerializer->startElementNS( XML_w, XML_tc, FSEND );
1263
1264 // Write the cell properties here
1265 TableCellProperties( pTableTextNodeInfoInner );
1266
1267 m_bTableCellOpen = true;
1268 }
1269
EndTableCell()1270 void DocxAttributeOutput::EndTableCell( )
1271 {
1272 m_pSerializer->endElementNS( XML_w, XML_tc );
1273
1274 m_bTableCellOpen = false;
1275 }
1276
TableInfoCell(ww8::WW8TableNodeInfoInner::Pointer_t)1277 void DocxAttributeOutput::TableInfoCell( ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner*/ )
1278 {
1279 }
1280
TableInfoRow(ww8::WW8TableNodeInfoInner::Pointer_t)1281 void DocxAttributeOutput::TableInfoRow( ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfo*/ )
1282 {
1283 }
1284
TableDefinition(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner)1285 void DocxAttributeOutput::TableDefinition( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
1286 {
1287 // Write the table properties
1288 m_pSerializer->startElementNS( XML_w, XML_tblPr, FSEND );
1289
1290 sal_uInt32 nPageSize = 0;
1291 bool bRelBoxSize = false;
1292
1293 // Create the SwWriteTable instance to use col spans (and maybe other infos)
1294 GetTablePageSize( pTableTextNodeInfoInner, nPageSize, bRelBoxSize );
1295
1296 // Output the table prefered width
1297 if ( nPageSize != 0 )
1298 m_pSerializer->singleElementNS( XML_w, XML_tblW,
1299 FSNS( XML_w, XML_w ), OString::valueOf( sal_Int32( nPageSize ) ).getStr( ),
1300 FSNS( XML_w, XML_type ), "dxa",
1301 FSEND );
1302
1303 // Output the table borders
1304 TableDefaultBorders( pTableTextNodeInfoInner );
1305 TableBidi( pTableTextNodeInfoInner );
1306
1307 // Output the table alignement
1308 const SwTable *pTable = pTableTextNodeInfoInner->getTable();
1309 SwFrmFmt *pTblFmt = pTable->GetFrmFmt( );
1310 const char* pJcVal;
1311 sal_Int32 nIndent = 0;
1312 switch ( pTblFmt->GetHoriOrient( ).GetHoriOrient( ) )
1313 {
1314 case text::HoriOrientation::CENTER:
1315 pJcVal = "center";
1316 break;
1317 case text::HoriOrientation::RIGHT:
1318 pJcVal = "right";
1319 break;
1320 default:
1321 case text::HoriOrientation::NONE:
1322 case text::HoriOrientation::LEFT_AND_WIDTH:
1323 {
1324 pJcVal = "left";
1325 nIndent = sal_Int32( pTblFmt->GetLRSpace( ).GetLeft( ) );
1326 break;
1327 }
1328 }
1329 m_pSerializer->singleElementNS( XML_w, XML_jc,
1330 FSNS( XML_w, XML_val ), pJcVal,
1331 FSEND );
1332
1333 // Table indent
1334 if ( nIndent != 0 )
1335 m_pSerializer->singleElementNS( XML_w, XML_tblInd,
1336 FSNS( XML_w, XML_w ), OString::valueOf( nIndent ).getStr( ),
1337 FSNS( XML_w, XML_type ), "dxa",
1338 FSEND );
1339
1340 m_pSerializer->endElementNS( XML_w, XML_tblPr );
1341
1342
1343 // Write the table grid infos
1344 m_pSerializer->startElementNS( XML_w, XML_tblGrid, FSEND );
1345
1346 std::vector<SwTwips> gridCols = GetGridCols( pTableTextNodeInfoInner );
1347 for ( std::vector<SwTwips>::const_iterator it = gridCols.begin(); it != gridCols.end(); ++it )
1348 m_pSerializer->singleElementNS( XML_w, XML_gridCol,
1349 FSNS( XML_w, XML_w ), OString::valueOf( sal_Int32( *it ) ).getStr( ),
1350 FSEND );
1351
1352 m_pSerializer->endElementNS( XML_w, XML_tblGrid );
1353 }
1354
TableDefaultBorders(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner)1355 void DocxAttributeOutput::TableDefaultBorders( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
1356 {
1357 const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
1358 const SwFrmFmt * pFrmFmt = pTabBox->GetFrmFmt();
1359
1360 // the defaults of the table are taken from the top-left cell
1361 m_pSerializer->startElementNS( XML_w, XML_tblBorders, FSEND );
1362 impl_pageBorders( m_pSerializer, pFrmFmt->GetBox( ) );
1363 m_pSerializer->endElementNS( XML_w, XML_tblBorders );
1364 }
1365
TableBackgrounds(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner)1366 void DocxAttributeOutput::TableBackgrounds( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
1367 {
1368 const SwTableBox *pTblBox = pTableTextNodeInfoInner->getTableBox( );
1369 const SwFrmFmt *pFmt = pTblBox->GetFrmFmt( );
1370 const SfxPoolItem *pI = NULL;
1371
1372 Color aColor;
1373 if ( SFX_ITEM_ON == pFmt->GetAttrSet().GetItemState( RES_BACKGROUND, false, &pI ) )
1374 aColor = dynamic_cast<const SvxBrushItem *>(pI)->GetColor();
1375 else
1376 aColor = COL_AUTO;
1377
1378 OString sColor = impl_ConvertColor( aColor );
1379 m_pSerializer->singleElementNS( XML_w, XML_shd,
1380 FSNS( XML_w, XML_fill ), sColor.getStr( ),
1381 FSEND );
1382 }
1383
TableHeight(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner)1384 void DocxAttributeOutput::TableHeight( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
1385 {
1386 const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
1387 const SwTableLine * pTabLine = pTabBox->GetUpper();
1388 const SwFrmFmt * pLineFmt = pTabLine->GetFrmFmt();
1389
1390 const SwFmtFrmSize& rLSz = pLineFmt->GetFrmSize();
1391 if ( ATT_VAR_SIZE != rLSz.GetHeightSizeType() && rLSz.GetHeight() )
1392 {
1393 sal_Int32 nHeight = rLSz.GetHeight();
1394 const char *pRule = NULL;
1395
1396 switch ( rLSz.GetHeightSizeType() )
1397 {
1398 case ATT_FIX_SIZE: pRule = "exact"; break;
1399 case ATT_MIN_SIZE: pRule = "atLeast"; break;
1400 default: break;
1401 }
1402
1403 if ( pRule )
1404 m_pSerializer->singleElementNS( XML_w, XML_trHeight,
1405 FSNS( XML_w, XML_val ), OString::valueOf( nHeight ).getStr( ),
1406 FSNS( XML_w, XML_hRule ), pRule,
1407 FSEND );
1408 }
1409 }
1410
TableCanSplit(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner)1411 void DocxAttributeOutput::TableCanSplit( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
1412 {
1413 const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
1414 const SwTableLine * pTabLine = pTabBox->GetUpper();
1415 const SwFrmFmt * pLineFmt = pTabLine->GetFrmFmt();
1416
1417 const SwFmtRowSplit& rSplittable = pLineFmt->GetRowSplit( );
1418 const char* pCantSplit = ( !rSplittable.GetValue( ) ) ? "on" : "off";
1419
1420 m_pSerializer->singleElementNS( XML_w, XML_cantSplit,
1421 FSNS( XML_w, XML_val ), pCantSplit,
1422 FSEND );
1423 }
1424
TableBidi(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner)1425 void DocxAttributeOutput::TableBidi( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
1426 {
1427 const SwTable * pTable = pTableTextNodeInfoInner->getTable();
1428 const SwFrmFmt * pFrmFmt = pTable->GetFrmFmt();
1429
1430 if ( m_rExport.TrueFrameDirection( *pFrmFmt ) == FRMDIR_HORI_RIGHT_TOP )
1431 {
1432 m_pSerializer->singleElementNS( XML_w, XML_bidiVisual,
1433 FSNS( XML_w, XML_val ), "on",
1434 FSEND );
1435 }
1436 }
1437
TableVerticalCell(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner)1438 void DocxAttributeOutput::TableVerticalCell( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
1439 {
1440 const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
1441 const SwFrmFmt *pFrmFmt = pTabBox->GetFrmFmt( );
1442
1443 if ( FRMDIR_VERT_TOP_RIGHT == m_rExport.TrueFrameDirection( *pFrmFmt ) )
1444 m_pSerializer->singleElementNS( XML_w, XML_textDirection,
1445 FSNS( XML_w, XML_val ), "tbRl",
1446 FSEND );
1447 }
1448
TableNodeInfo(ww8::WW8TableNodeInfo::Pointer_t)1449 void DocxAttributeOutput::TableNodeInfo( ww8::WW8TableNodeInfo::Pointer_t /*pNodeInfo*/ )
1450 {
1451 OSL_TRACE( "TODO: DocxAttributeOutput::TableNodeInfo( ww8::WW8TableNodeInfo::Pointer_t pNodeInfo )\n" );
1452 }
1453
TableNodeInfoInner(ww8::WW8TableNodeInfoInner::Pointer_t pNodeInfoInner)1454 void DocxAttributeOutput::TableNodeInfoInner( ww8::WW8TableNodeInfoInner::Pointer_t pNodeInfoInner )
1455 {
1456 // This is called when the nested table ends in a cell, and there's no
1457 // paragraph benhind that; so we must check for the ends of cell, rows,
1458 // tables
1459 // ['true' to write an empty paragraph, MS Word insists on that]
1460 FinishTableRowCell( pNodeInfoInner, true );
1461 }
1462
TableOrientation(ww8::WW8TableNodeInfoInner::Pointer_t)1463 void DocxAttributeOutput::TableOrientation( ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner*/ )
1464 {
1465 OSL_TRACE( "TODO: DocxAttributeOutput::TableOrientation( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )\n" );
1466 }
1467
TableSpacing(ww8::WW8TableNodeInfoInner::Pointer_t)1468 void DocxAttributeOutput::TableSpacing( ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner*/ )
1469 {
1470 #if OSL_DEBUG_LEVEL > 0
1471 fprintf( stderr, "TODO: DocxAttributeOutput::TableSpacing( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )\n" );
1472 #endif
1473 }
1474
TableRowEnd(sal_uInt32)1475 void DocxAttributeOutput::TableRowEnd( sal_uInt32 /*nDepth*/ )
1476 {
1477 OSL_TRACE( "TODO: DocxAttributeOutput::TableRowEnd( sal_uInt32 nDepth = 1 )\n" );
1478 }
1479
StartStyles()1480 void DocxAttributeOutput::StartStyles()
1481 {
1482 m_pSerializer->startElementNS( XML_w, XML_styles,
1483 FSNS( XML_xmlns, XML_w ), "http://schemas.openxmlformats.org/wordprocessingml/2006/main",
1484 FSEND );
1485 }
1486
EndStyles(sal_uInt16)1487 void DocxAttributeOutput::EndStyles( sal_uInt16 /*nNumberOfStyles*/ )
1488 {
1489 m_pSerializer->endElementNS( XML_w, XML_styles );
1490 }
1491
DefaultStyle(sal_uInt16 nStyle)1492 void DocxAttributeOutput::DefaultStyle( sal_uInt16 nStyle )
1493 {
1494 // are these the values of enum ww::sti (see ../inc/wwstyles.hxx)?
1495 #if OSL_DEBUG_LEVEL > 0
1496 OSL_TRACE( "TODO DocxAttributeOutput::DefaultStyle( sal_uInt16 nStyle )- %d\n", nStyle );
1497 #else
1498 (void) nStyle; // to quiet the warning
1499 #endif
1500 }
1501
FlyFrameGraphic(const SwGrfNode & rGrfNode,const Size & rSize)1502 void DocxAttributeOutput::FlyFrameGraphic( const SwGrfNode& rGrfNode, const Size& rSize )
1503 {
1504 #if OSL_DEBUG_LEVEL > 0
1505 OSL_TRACE( "TODO DocxAttributeOutput::FlyFrameGraphic( const SwGrfNode& rGrfNode, const Size& rSize ) - some stuff still missing\n" );
1506 #endif
1507 // create the relation ID
1508 OString aRelId;
1509 sal_Int32 nImageType;
1510 if ( rGrfNode.IsLinkedFile() )
1511 {
1512 // linked image, just create the relation
1513 String aFileName;
1514 rGrfNode.GetFileFilterNms( &aFileName, 0 );
1515
1516 // TODO Convert the file name to relative for better interoperability
1517
1518 aRelId = m_rExport.AddRelation(
1519 S( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" ),
1520 OUString( aFileName ),
1521 S( "External" ) );
1522
1523 nImageType = XML_link;
1524 }
1525 else
1526 {
1527 // inline, we also have to write the image itself
1528 Graphic& rGraphic = const_cast< Graphic& >( rGrfNode.GetGrf() );
1529
1530 m_rDrawingML.SetFS( m_pSerializer ); // to be sure that we write to the right stream
1531 OUString aImageId = m_rDrawingML.WriteImage( rGraphic );
1532
1533 aRelId = OUStringToOString( aImageId, RTL_TEXTENCODING_UTF8 );
1534
1535 nImageType = XML_embed;
1536 }
1537
1538 if ( aRelId.getLength() == 0 )
1539 return;
1540
1541 m_pSerializer->startElementNS( XML_w, XML_drawing,
1542 FSEND );
1543 m_pSerializer->startElementNS( XML_wp, XML_inline,
1544 XML_distT, "0", XML_distB, "0", XML_distL, "0", XML_distR, "0",
1545 FSEND );
1546
1547 // extent of the image
1548 OString aWidth( OString::valueOf( TwipsToEMU( rSize.Width() ) ) );
1549 OString aHeight( OString::valueOf( TwipsToEMU( rSize.Height() ) ) );
1550 m_pSerializer->singleElementNS( XML_wp, XML_extent,
1551 XML_cx, aWidth.getStr(),
1552 XML_cy, aHeight.getStr(),
1553 FSEND );
1554 // TODO - the right effectExtent, extent including the effect
1555 m_pSerializer->singleElementNS( XML_wp, XML_effectExtent,
1556 XML_l, "0", XML_t, "0", XML_r, "0", XML_b, "0",
1557 FSEND );
1558
1559 // picture description
1560 // TODO the right image description
1561 m_pSerializer->startElementNS( XML_wp, XML_docPr,
1562 XML_id, "1",
1563 XML_name, "Picture",
1564 XML_descr, "A description...",
1565 FSEND );
1566 // TODO hyperlink
1567 // m_pSerializer->singleElementNS( XML_a, XML_hlinkClick,
1568 // FSNS( XML_xmlns, XML_a ), "http://schemas.openxmlformats.org/drawingml/2006/main",
1569 // FSNS( XML_r, XML_id ), "rId4",
1570 // FSEND );
1571 m_pSerializer->endElementNS( XML_wp, XML_docPr );
1572
1573 m_pSerializer->startElementNS( XML_wp, XML_cNvGraphicFramePr,
1574 FSEND );
1575 // TODO change aspect?
1576 m_pSerializer->singleElementNS( XML_a, XML_graphicFrameLocks,
1577 FSNS( XML_xmlns, XML_a ), "http://schemas.openxmlformats.org/drawingml/2006/main",
1578 XML_noChangeAspect, "1",
1579 FSEND );
1580 m_pSerializer->endElementNS( XML_wp, XML_cNvGraphicFramePr );
1581
1582 m_pSerializer->startElementNS( XML_a, XML_graphic,
1583 FSNS( XML_xmlns, XML_a ), "http://schemas.openxmlformats.org/drawingml/2006/main",
1584 FSEND );
1585 m_pSerializer->startElementNS( XML_a, XML_graphicData,
1586 XML_uri, "http://schemas.openxmlformats.org/drawingml/2006/picture",
1587 FSEND );
1588
1589 m_pSerializer->startElementNS( XML_pic, XML_pic,
1590 FSNS( XML_xmlns, XML_pic ), "http://schemas.openxmlformats.org/drawingml/2006/picture",
1591 FSEND );
1592
1593 m_pSerializer->startElementNS( XML_pic, XML_nvPicPr,
1594 FSEND );
1595 // TODO the right image description
1596 m_pSerializer->startElementNS( XML_pic, XML_cNvPr,
1597 XML_id, "0",
1598 XML_name, "Picture",
1599 XML_descr, "A description...",
1600 FSEND );
1601 // TODO hyperlink
1602 // m_pSerializer->singleElementNS( XML_a, XML_hlinkClick,
1603 // FSNS( XML_r, XML_id ), "rId4",
1604 // FSEND );
1605 m_pSerializer->endElementNS( XML_pic, XML_cNvPr );
1606
1607 m_pSerializer->startElementNS( XML_pic, XML_cNvPicPr,
1608 FSEND );
1609 // TODO change aspect?
1610 m_pSerializer->singleElementNS( XML_a, XML_picLocks,
1611 XML_noChangeAspect, "1", XML_noChangeArrowheads, "1",
1612 FSEND );
1613 m_pSerializer->endElementNS( XML_pic, XML_cNvPicPr );
1614 m_pSerializer->endElementNS( XML_pic, XML_nvPicPr );
1615
1616 // the actual picture
1617 m_pSerializer->startElementNS( XML_pic, XML_blipFill,
1618 FSEND );
1619 m_pSerializer->singleElementNS( XML_a, XML_blip,
1620 FSNS( XML_r, nImageType ), aRelId.getStr(),
1621 FSEND );
1622 m_pSerializer->singleElementNS( XML_a, XML_srcRect,
1623 FSEND );
1624 m_pSerializer->startElementNS( XML_a, XML_stretch,
1625 FSEND );
1626 m_pSerializer->singleElementNS( XML_a, XML_fillRect,
1627 FSEND );
1628 m_pSerializer->endElementNS( XML_a, XML_stretch );
1629 m_pSerializer->endElementNS( XML_pic, XML_blipFill );
1630
1631 // TODO setup the right values below
1632 m_pSerializer->startElementNS( XML_pic, XML_spPr,
1633 XML_bwMode, "auto",
1634 FSEND );
1635 m_pSerializer->startElementNS( XML_a, XML_xfrm,
1636 FSEND );
1637 m_pSerializer->singleElementNS( XML_a, XML_off,
1638 XML_x, "0", XML_y, "0",
1639 FSEND );
1640 m_pSerializer->singleElementNS( XML_a, XML_ext,
1641 XML_cx, aWidth.getStr(),
1642 XML_cy, aHeight.getStr(),
1643 FSEND );
1644 m_pSerializer->endElementNS( XML_a, XML_xfrm );
1645 m_pSerializer->startElementNS( XML_a, XML_prstGeom,
1646 XML_prst, "rect",
1647 FSEND );
1648 m_pSerializer->singleElementNS( XML_a, XML_avLst,
1649 FSEND );
1650 m_pSerializer->endElementNS( XML_a, XML_prstGeom );
1651 m_pSerializer->singleElementNS( XML_a, XML_noFill,
1652 FSEND );
1653 m_pSerializer->startElementNS( XML_a, XML_ln,
1654 XML_w, "9525",
1655 FSEND );
1656 m_pSerializer->singleElementNS( XML_a, XML_noFill,
1657 FSEND );
1658 m_pSerializer->singleElementNS( XML_a, XML_miter,
1659 XML_lim, "800000",
1660 FSEND );
1661 m_pSerializer->singleElementNS( XML_a, XML_headEnd,
1662 FSEND );
1663 m_pSerializer->singleElementNS( XML_a, XML_tailEnd,
1664 FSEND );
1665 m_pSerializer->endElementNS( XML_a, XML_ln );
1666 m_pSerializer->endElementNS( XML_pic, XML_spPr );
1667
1668 m_pSerializer->endElementNS( XML_pic, XML_pic );
1669
1670 m_pSerializer->endElementNS( XML_a, XML_graphicData );
1671 m_pSerializer->endElementNS( XML_a, XML_graphic );
1672 m_pSerializer->endElementNS( XML_wp, XML_inline );
1673
1674 m_pSerializer->endElementNS( XML_w, XML_drawing );
1675 }
1676
OutputFlyFrame_Impl(const sw::Frame & rFrame,const Point &)1677 void DocxAttributeOutput::OutputFlyFrame_Impl( const sw::Frame &rFrame, const Point& /*rNdTopLeft*/ )
1678 {
1679 m_pSerializer->mark();
1680
1681 switch ( rFrame.GetWriterType() )
1682 {
1683 case sw::Frame::eGraphic:
1684 {
1685 const SwNode *pNode = rFrame.GetContent();
1686 const SwGrfNode *pGrfNode = pNode ? pNode->GetGrfNode() : 0;
1687 if ( pGrfNode )
1688 FlyFrameGraphic( *pGrfNode, rFrame.GetLayoutSize() );
1689 }
1690 break;
1691 case sw::Frame::eDrawing:
1692 {
1693 const SdrObject* pSdrObj = rFrame.GetFrmFmt().FindRealSdrObject();
1694 if ( pSdrObj )
1695 {
1696 bool bSwapInPage = false;
1697 if ( !pSdrObj->GetPage() )
1698 {
1699 if ( SdrModel* pModel = m_rExport.pDoc->GetDrawModel() )
1700 {
1701 if ( SdrPage *pPage = pModel->GetPage( 0 ) )
1702 {
1703 bSwapInPage = true;
1704 const_cast< SdrObject* >( pSdrObj )->SetPage( pPage );
1705 }
1706 }
1707 }
1708
1709 m_pSerializer->startElementNS( XML_w, XML_pict,
1710 FSEND );
1711
1712 m_rExport.VMLExporter().AddSdrObject( *pSdrObj );
1713
1714 m_pSerializer->endElementNS( XML_w, XML_pict );
1715
1716 if ( bSwapInPage )
1717 const_cast< SdrObject* >( pSdrObj )->SetPage( 0 );
1718 }
1719 }
1720 break;
1721 default:
1722 #if OSL_DEBUG_LEVEL > 0
1723 OSL_TRACE( "TODO DocxAttributeOutput::OutputFlyFrame_Impl( const sw::Frame& rFrame, const Point& rNdTopLeft ) - frame type '%s'\n",
1724 rFrame.GetWriterType() == sw::Frame::eTxtBox? "eTxtBox":
1725 ( rFrame.GetWriterType() == sw::Frame::eOle? "eOle":
1726 ( rFrame.GetWriterType() == sw::Frame::eFormControl? "eFormControl": "???" ) ) );
1727 #endif
1728 break;
1729 }
1730
1731 m_pSerializer->mergeTopMarks( sax_fastparser::MERGE_MARKS_POSTPONE );
1732 }
1733
StartStyle(const String & rName,bool bPapFmt,sal_uInt16 nBase,sal_uInt16 nNext,sal_uInt16,sal_uInt16 nId)1734 void DocxAttributeOutput::StartStyle( const String& rName, bool bPapFmt,
1735 sal_uInt16 nBase, sal_uInt16 nNext, sal_uInt16 /*nWwId*/, sal_uInt16 nId )
1736 {
1737 OString aStyle( "style" );
1738
1739 m_pSerializer->startElementNS( XML_w, XML_style,
1740 FSNS( XML_w, XML_type ), bPapFmt? "paragraph": "character", // FIXME is this correct?
1741 FSNS( XML_w, XML_styleId ), ( aStyle + OString::valueOf( sal_Int32( nId ) ) ).getStr(),
1742 FSEND );
1743
1744 m_pSerializer->singleElementNS( XML_w, XML_name,
1745 FSNS( XML_w, XML_val ), OUStringToOString( OUString( rName ), RTL_TEXTENCODING_UTF8 ).getStr(),
1746 FSEND );
1747
1748 if ( nBase != 0x0FFF )
1749 {
1750 m_pSerializer->singleElementNS( XML_w, XML_basedOn,
1751 FSNS( XML_w, XML_val ), ( aStyle + OString::valueOf( sal_Int32( nBase ) ) ).getStr(),
1752 FSEND );
1753 }
1754
1755 m_pSerializer->singleElementNS( XML_w, XML_next,
1756 FSNS( XML_w, XML_val ), ( aStyle + OString::valueOf( sal_Int32( nNext ) ) ).getStr(),
1757 FSEND );
1758 }
1759
EndStyle()1760 void DocxAttributeOutput::EndStyle()
1761 {
1762 m_pSerializer->endElementNS( XML_w, XML_style );
1763 }
1764
StartStyleProperties(bool bParProp,sal_uInt16)1765 void DocxAttributeOutput::StartStyleProperties( bool bParProp, sal_uInt16 /*nStyle*/ )
1766 {
1767 if ( bParProp )
1768 {
1769 m_pSerializer->startElementNS( XML_w, XML_pPr, FSEND );
1770 InitCollectedParagraphProperties();
1771 }
1772 else
1773 {
1774 m_pSerializer->startElementNS( XML_w, XML_rPr, FSEND );
1775 InitCollectedRunProperties();
1776 }
1777 }
1778
EndStyleProperties(bool bParProp)1779 void DocxAttributeOutput::EndStyleProperties( bool bParProp )
1780 {
1781 if ( bParProp )
1782 {
1783 WriteCollectedParagraphProperties();
1784 m_pSerializer->endElementNS( XML_w, XML_pPr );
1785 }
1786 else
1787 {
1788 WriteCollectedRunProperties();
1789 m_pSerializer->endElementNS( XML_w, XML_rPr );
1790 }
1791 }
1792
OutlineNumbering(sal_uInt8 nLvl,const SwNumFmt &,const SwFmt &)1793 void DocxAttributeOutput::OutlineNumbering( sal_uInt8 nLvl, const SwNumFmt& /*rNFmt*/, const SwFmt& /*rFmt*/ )
1794 {
1795 if ( nLvl >= WW8ListManager::nMaxLevel )
1796 nLvl = WW8ListManager::nMaxLevel - 1;
1797
1798 m_pSerializer->singleElementNS( XML_w, XML_outlineLvl,
1799 FSNS( XML_w, XML_val ), OString::valueOf( sal_Int32( nLvl ) ).getStr( ),
1800 FSEND );
1801 }
1802
PageBreakBefore(bool bBreak)1803 void DocxAttributeOutput::PageBreakBefore( bool bBreak )
1804 {
1805 if ( bBreak )
1806 m_pSerializer->singleElementNS( XML_w, XML_pageBreakBefore, FSEND );
1807 else
1808 m_pSerializer->singleElementNS( XML_w, XML_pageBreakBefore,
1809 FSNS( XML_w, XML_val ), "off",
1810 FSEND );
1811 }
1812
SectionBreak(sal_uInt8 nC,const WW8_SepInfo * pSectionInfo)1813 void DocxAttributeOutput::SectionBreak( sal_uInt8 nC, const WW8_SepInfo* pSectionInfo )
1814 {
1815 switch ( nC )
1816 {
1817 case msword::ColumnBreak:
1818 // The column break should be output in the next paragraph...
1819 m_nColBreakStatus = COLBRK_POSTPONE;
1820 break;
1821 case msword::PageBreak:
1822 if ( pSectionInfo )
1823 {
1824 if ( !m_bParagraphOpened )
1825 {
1826 // Create a dummy paragraph if needed
1827 m_pSerializer->startElementNS( XML_w, XML_p, FSEND );
1828 m_pSerializer->startElementNS( XML_w, XML_pPr, FSEND );
1829
1830 m_rExport.SectionProperties( *pSectionInfo );
1831
1832 m_pSerializer->endElementNS( XML_w, XML_pPr );
1833 m_pSerializer->endElementNS( XML_w, XML_p );
1834 }
1835 else
1836 {
1837 // postpone the output of this; it has to be done inside the
1838 // paragraph properties, so remember it until then
1839 m_pSectionInfo = pSectionInfo;
1840 }
1841 }
1842 else
1843 {
1844 m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
1845 m_pSerializer->singleElementNS( XML_w, XML_br,
1846 FSNS( XML_w, XML_type ), "page", FSEND );
1847 m_pSerializer->endElementNS( XML_w, XML_r );
1848 }
1849 break;
1850 default:
1851 #if OSL_DEBUG_LEVEL > 0
1852 OSL_TRACE( "Unknown section break to write: %d\n", nC );
1853 #endif
1854 break;
1855 }
1856 }
1857
StartSection()1858 void DocxAttributeOutput::StartSection()
1859 {
1860 m_pSerializer->startElementNS( XML_w, XML_sectPr, FSEND );
1861 m_bOpenedSectPr = true;
1862 }
1863
EndSection()1864 void DocxAttributeOutput::EndSection()
1865 {
1866 // Write the section properties
1867 if ( m_pSpacingAttrList )
1868 {
1869 XFastAttributeListRef xAttrList( m_pSpacingAttrList );
1870 m_pSpacingAttrList = NULL;
1871
1872 m_pSerializer->singleElementNS( XML_w, XML_pgMar, xAttrList );
1873 }
1874
1875 m_pSerializer->endElementNS( XML_w, XML_sectPr );
1876 m_bOpenedSectPr = false;
1877 }
1878
SectionFormProtection(bool bProtected)1879 void DocxAttributeOutput::SectionFormProtection( bool bProtected )
1880 {
1881 if ( bProtected )
1882 m_pSerializer->singleElementNS( XML_w, XML_formProt, FSEND );
1883 else
1884 m_pSerializer->singleElementNS( XML_w, XML_formProt,
1885 FSNS( XML_w, XML_val ), "off", FSEND );
1886 }
1887
SectionLineNumbering(sal_uLong,const SwLineNumberInfo &)1888 void DocxAttributeOutput::SectionLineNumbering( sal_uLong /*nRestartNo*/, const SwLineNumberInfo& /*rLnNumInfo*/ )
1889 {
1890 // see 2.6.8 lnNumType (Line Numbering Settings)
1891 #if OSL_DEBUG_LEVEL > 0
1892 OSL_TRACE( "TODO DocxAttributeOutput::SectionLineNumbering()\n" );
1893 #endif
1894 }
1895
SectionTitlePage()1896 void DocxAttributeOutput::SectionTitlePage()
1897 {
1898 m_pSerializer->singleElementNS( XML_w, XML_titlePg, FSEND );
1899 }
1900
SectionPageBorders(const SwFrmFmt * pFmt,const SwFrmFmt *)1901 void DocxAttributeOutput::SectionPageBorders( const SwFrmFmt* pFmt, const SwFrmFmt* /*pFirstPageFmt*/ )
1902 {
1903 // Output the margins
1904
1905
1906 const SvxBoxItem& rBox = pFmt->GetBox( );
1907
1908 const SvxBorderLine* pBottom = rBox.GetBottom( );
1909 const SvxBorderLine* pTop = rBox.GetTop( );
1910 const SvxBorderLine* pLeft = rBox.GetLeft( );
1911 const SvxBorderLine* pRight = rBox.GetRight( );
1912
1913 if ( pBottom || pTop || pLeft || pRight )
1914 {
1915 // All distances are relative to the text margins
1916 m_pSerializer->startElementNS( XML_w, XML_pgBorders,
1917 FSNS( XML_w, XML_display ), "allPages",
1918 FSNS( XML_w, XML_offsetFrom ), "text",
1919 FSEND );
1920
1921 m_pSerializer->mark();
1922
1923 m_pSerializer->endElementNS( XML_w, XML_pgBorders );
1924 m_pSerializer->mark();
1925 }
1926 }
1927
SectionBiDi(bool bBiDi)1928 void DocxAttributeOutput::SectionBiDi( bool bBiDi )
1929 {
1930 if ( bBiDi )
1931 m_pSerializer->singleElementNS( XML_w, XML_bidi, FSEND );
1932 }
1933
impl_NumberingType(sal_uInt16 nNumberingType)1934 static OString impl_NumberingType( sal_uInt16 nNumberingType )
1935 {
1936 OString aType;
1937
1938 switch ( nNumberingType )
1939 {
1940 case SVX_NUM_CHARS_UPPER_LETTER:
1941 case SVX_NUM_CHARS_UPPER_LETTER_N: aType = "upperLetter"; break;
1942 case SVX_NUM_CHARS_LOWER_LETTER:
1943 case SVX_NUM_CHARS_LOWER_LETTER_N: aType = "lowerLetter"; break;
1944 case SVX_NUM_ROMAN_UPPER: aType = "upperRoman"; break;
1945 case SVX_NUM_ROMAN_LOWER: aType = "lowerRoman"; break;
1946
1947 case SVX_NUM_ARABIC: aType = "decimal"; break;
1948
1949 case SVX_NUM_BITMAP:
1950 case SVX_NUM_CHAR_SPECIAL: aType = "bullet"; break;
1951
1952 default: aType = "none"; break;
1953 }
1954
1955 return aType;
1956 }
1957
SectionPageNumbering(sal_uInt16 nNumType,sal_uInt16 nPageRestartNumber)1958 void DocxAttributeOutput::SectionPageNumbering( sal_uInt16 nNumType, sal_uInt16 nPageRestartNumber )
1959 {
1960 // FIXME Not called properly with page styles like "First Page"
1961
1962 FastAttributeList* pAttr = m_pSerializer->createAttrList();
1963
1964 // 0 means no restart: then don't output that attribute if 0
1965 if ( nPageRestartNumber > 0 )
1966 pAttr->add( FSNS( XML_w, XML_start ), OString::valueOf( sal_Int32( nPageRestartNumber ) ) );
1967
1968 // nNumType corresponds to w:fmt. See WW8Export::GetNumId() for more precisions
1969 OString aFmt( impl_NumberingType( nNumType ) );
1970 if ( aFmt.getLength() )
1971 pAttr->add( FSNS( XML_w, XML_fmt ), aFmt.getStr() );
1972
1973 XFastAttributeListRef xAttrs( pAttr );
1974 m_pSerializer->singleElementNS( XML_w, XML_pgNumType, xAttrs );
1975
1976 // see 2.6.12 pgNumType (Page Numbering Settings)
1977 #if OSL_DEBUG_LEVEL > 0
1978 OSL_TRACE( "TODO DocxAttributeOutput::SectionPageNumbering()\n" );
1979 #endif
1980 }
1981
SectionType(sal_uInt8 nBreakCode)1982 void DocxAttributeOutput::SectionType( sal_uInt8 nBreakCode )
1983 {
1984 /* break code: 0 No break, 1 New column
1985 2 New page, 3 Even page, 4 Odd page
1986 */
1987 const char* pType = NULL;
1988 switch ( nBreakCode )
1989 {
1990 case 1: pType = "nextColumn"; break;
1991 case 2: pType = "nextPage"; break;
1992 case 3: pType = "evenPage"; break;
1993 case 4: pType = "oddPage"; break;
1994 default: pType = "continuous"; break;
1995 }
1996
1997 if ( pType )
1998 m_pSerializer->singleElementNS( XML_w, XML_type,
1999 FSNS( XML_w, XML_val ), pType,
2000 FSEND );
2001 }
2002
StartFont(const String & rFamilyName) const2003 void DocxAttributeOutput::StartFont( const String& rFamilyName ) const
2004 {
2005 m_pSerializer->startElementNS( XML_w, XML_font,
2006 FSNS( XML_w, XML_name ), OUStringToOString( OUString( rFamilyName ), RTL_TEXTENCODING_UTF8 ).getStr(),
2007 FSEND );
2008 }
2009
EndFont() const2010 void DocxAttributeOutput::EndFont() const
2011 {
2012 m_pSerializer->endElementNS( XML_w, XML_font );
2013 }
2014
FontAlternateName(const String & rName) const2015 void DocxAttributeOutput::FontAlternateName( const String& rName ) const
2016 {
2017 m_pSerializer->singleElementNS( XML_w, XML_altName,
2018 FSNS( XML_w, XML_val ), OUStringToOString( OUString( rName ), RTL_TEXTENCODING_UTF8 ).getStr(),
2019 FSEND );
2020 }
2021
FontCharset(sal_uInt8 nCharSet) const2022 void DocxAttributeOutput::FontCharset( sal_uInt8 nCharSet ) const
2023 {
2024 OString aCharSet( OString::valueOf( sal_Int32( nCharSet ), 16 ) );
2025 if ( aCharSet.getLength() == 1 )
2026 aCharSet = OString( "0" ) + aCharSet;
2027
2028 m_pSerializer->singleElementNS( XML_w, XML_charset,
2029 FSNS( XML_w, XML_val ), aCharSet.getStr(),
2030 FSEND );
2031 }
2032
FontFamilyType(FontFamily eFamily) const2033 void DocxAttributeOutput::FontFamilyType( FontFamily eFamily ) const
2034 {
2035 const char *pFamily = NULL;
2036 switch ( eFamily )
2037 {
2038 case FAMILY_ROMAN: pFamily = "roman"; break;
2039 case FAMILY_SWISS: pFamily = "swiss"; break;
2040 case FAMILY_MODERN: pFamily = "modern"; break;
2041 case FAMILY_SCRIPT: pFamily = "script"; break;
2042 case FAMILY_DECORATIVE: pFamily = "decorative"; break;
2043 default: pFamily = "auto"; break; // no font family
2044 }
2045
2046 if ( pFamily )
2047 m_pSerializer->singleElementNS( XML_w, XML_family,
2048 FSNS( XML_w, XML_val ), pFamily,
2049 FSEND );
2050 }
2051
FontPitchType(FontPitch ePitch) const2052 void DocxAttributeOutput::FontPitchType( FontPitch ePitch ) const
2053 {
2054 const char *pPitch = NULL;
2055 switch ( ePitch )
2056 {
2057 case PITCH_VARIABLE: pPitch = "variable"; break;
2058 case PITCH_FIXED: pPitch = "fixed"; break;
2059 default: pPitch = "default"; break; // no info about the pitch
2060 }
2061
2062 if ( pPitch )
2063 m_pSerializer->singleElementNS( XML_w, XML_pitch,
2064 FSNS( XML_w, XML_val ), pPitch,
2065 FSEND );
2066 }
2067
NumberingDefinition(sal_uInt16 nId,const SwNumRule & rRule)2068 void DocxAttributeOutput::NumberingDefinition( sal_uInt16 nId, const SwNumRule &rRule )
2069 {
2070 // nId is the same both for abstract numbering definition as well as the
2071 // numbering definition itself
2072 // TODO check that this is actually true & fix if not ;-)
2073 OString aId( OString::valueOf( sal_Int32( nId ) ) );
2074
2075 m_pSerializer->startElementNS( XML_w, XML_num,
2076 FSNS( XML_w, XML_numId ), aId.getStr(),
2077 FSEND );
2078
2079 m_pSerializer->singleElementNS( XML_w, XML_abstractNumId,
2080 FSNS( XML_w, XML_val ), aId.getStr(),
2081 FSEND );
2082
2083 #if OSL_DEBUG_LEVEL > 0
2084 // TODO ww8 version writes this, anything to do about it here?
2085 if ( rRule.IsContinusNum() )
2086 OSL_TRACE( "TODO DocxAttributeOutput::NumberingDefinition()\n" );
2087 #else
2088 (void) rRule; // to quiet the warning...
2089 #endif
2090
2091 m_pSerializer->endElementNS( XML_w, XML_num );
2092 }
2093
StartAbstractNumbering(sal_uInt16 nId)2094 void DocxAttributeOutput::StartAbstractNumbering( sal_uInt16 nId )
2095 {
2096 m_pSerializer->startElementNS( XML_w, XML_abstractNum,
2097 FSNS( XML_w, XML_abstractNumId ), OString::valueOf( sal_Int32( nId ) ).getStr(),
2098 FSEND );
2099 }
2100
EndAbstractNumbering()2101 void DocxAttributeOutput::EndAbstractNumbering()
2102 {
2103 m_pSerializer->endElementNS( XML_w, XML_abstractNum );
2104 }
2105
NumberingLevel(sal_uInt8 nLevel,sal_uInt16 nStart,sal_uInt16 nNumberingType,SvxAdjust eAdjust,const sal_uInt8 *,sal_uInt8 nFollow,const wwFont * pFont,const SfxItemSet * pOutSet,sal_Int16 nIndentAt,sal_Int16 nFirstLineIndex,sal_Int16,const String & rNumberingString)2106 void DocxAttributeOutput::NumberingLevel( sal_uInt8 nLevel,
2107 sal_uInt16 nStart,
2108 sal_uInt16 nNumberingType,
2109 SvxAdjust eAdjust,
2110 const sal_uInt8 * /*pNumLvlPos*/,
2111 sal_uInt8 nFollow,
2112 const wwFont *pFont,
2113 const SfxItemSet *pOutSet,
2114 sal_Int16 nIndentAt,
2115 sal_Int16 nFirstLineIndex,
2116 sal_Int16 /*nListTabPos*/,
2117 const String &rNumberingString )
2118 {
2119 m_pSerializer->startElementNS( XML_w, XML_lvl,
2120 FSNS( XML_w, XML_ilvl ), OString::valueOf( sal_Int32( nLevel ) ).getStr(),
2121 FSEND );
2122
2123 // start with the nStart value
2124 m_pSerializer->singleElementNS( XML_w, XML_start,
2125 FSNS( XML_w, XML_val ), OString::valueOf( sal_Int32( nStart ) ).getStr(),
2126 FSEND );
2127
2128 // format
2129 OString aFmt( impl_NumberingType( nNumberingType ) );
2130
2131 if ( aFmt.getLength() )
2132 m_pSerializer->singleElementNS( XML_w, XML_numFmt,
2133 FSNS( XML_w, XML_val ), aFmt.getStr(),
2134 FSEND );
2135
2136 // justification
2137 const char *pJc;
2138 switch ( eAdjust )
2139 {
2140 case SVX_ADJUST_CENTER: pJc = "center"; break;
2141 case SVX_ADJUST_RIGHT: pJc = "right"; break;
2142 default: pJc = "left"; break;
2143 }
2144 m_pSerializer->singleElementNS( XML_w, XML_lvlJc,
2145 FSNS( XML_w, XML_val ), pJc,
2146 FSEND );
2147
2148 // suffix
2149 const char *pSuffix = NULL;
2150 switch ( nFollow )
2151 {
2152 case 1: pSuffix = "space"; break;
2153 case 2: pSuffix = "nothing"; break;
2154 default: /*pSuffix = "tab";*/ break;
2155 }
2156 if ( pSuffix )
2157 m_pSerializer->singleElementNS( XML_w, XML_suff,
2158 FSNS( XML_w, XML_val ), pSuffix,
2159 FSEND );
2160
2161 // text
2162 OUString aText( rNumberingString );
2163 OUStringBuffer aBuffer( aText.getLength() + WW8ListManager::nMaxLevel );
2164
2165 const sal_Unicode *pPrev = aText.getStr();
2166 const sal_Unicode *pIt = aText.getStr();
2167 while ( pIt < aText.getStr() + aText.getLength() )
2168 {
2169 // convert the level values to %NUMBER form
2170 // (we don't use pNumLvlPos at all)
2171 // FIXME so far we support the ww8 limit of levels only
2172 if ( *pIt < sal_Unicode( WW8ListManager::nMaxLevel ) )
2173 {
2174 aBuffer.append( pPrev, pIt - pPrev );
2175 aBuffer.appendAscii( "%" );
2176 aBuffer.append( OUString::valueOf( sal_Int32( *pIt ) + 1 ) );
2177
2178 pPrev = pIt + 1;
2179 }
2180 ++pIt;
2181 }
2182 if ( pPrev < pIt )
2183 aBuffer.append( pPrev, pIt - pPrev );
2184
2185 m_pSerializer->singleElementNS( XML_w, XML_lvlText,
2186 FSNS( XML_w, XML_val ), OUStringToOString( aBuffer.makeStringAndClear(), RTL_TEXTENCODING_UTF8 ).getStr(),
2187 FSEND );
2188
2189 // indentation
2190 m_pSerializer->startElementNS( XML_w, XML_pPr, FSEND );
2191 m_pSerializer->singleElementNS( XML_w, XML_ind,
2192 FSNS( XML_w, XML_left ), OString::valueOf( sal_Int32( nIndentAt ) ).getStr(),
2193 FSNS( XML_w, XML_hanging ), OString::valueOf( sal_Int32( -nFirstLineIndex ) ).getStr(),
2194 FSEND );
2195 m_pSerializer->endElementNS( XML_w, XML_pPr );
2196
2197 // font
2198 if ( pOutSet )
2199 {
2200 m_pSerializer->startElementNS( XML_w, XML_rPr, FSEND );
2201
2202 if ( pFont )
2203 {
2204 OString aFamilyName( OUStringToOString( OUString( pFont->GetFamilyName() ), RTL_TEXTENCODING_UTF8 ) );
2205 m_pSerializer->singleElementNS( XML_w, XML_rFonts,
2206 FSNS( XML_w, XML_ascii ), aFamilyName.getStr(),
2207 FSNS( XML_w, XML_hAnsi ), aFamilyName.getStr(),
2208 FSNS( XML_w, XML_cs ), aFamilyName.getStr(),
2209 FSNS( XML_w, XML_hint ), "default",
2210 FSEND );
2211 }
2212 m_rExport.OutputItemSet( *pOutSet, false, true, i18n::ScriptType::LATIN );
2213
2214 m_pSerializer->endElementNS( XML_w, XML_rPr );
2215 }
2216
2217 // TODO anything to do about nListTabPos?
2218
2219 m_pSerializer->endElementNS( XML_w, XML_lvl );
2220 }
2221
CharCaseMap(const SvxCaseMapItem & rCaseMap)2222 void DocxAttributeOutput::CharCaseMap( const SvxCaseMapItem& rCaseMap )
2223 {
2224 switch ( rCaseMap.GetValue() )
2225 {
2226 case SVX_CASEMAP_KAPITAELCHEN:
2227 m_pSerializer->singleElementNS( XML_w, XML_smallCaps, FSEND );
2228 break;
2229 case SVX_CASEMAP_VERSALIEN:
2230 m_pSerializer->singleElementNS( XML_w, XML_caps, FSEND );
2231 break;
2232 default: // Something that ooxml does not support
2233 m_pSerializer->singleElementNS( XML_w, XML_smallCaps, FSNS( XML_w, XML_val ), "off", FSEND );
2234 m_pSerializer->singleElementNS( XML_w, XML_caps, FSNS( XML_w, XML_val ), "off", FSEND );
2235 break;
2236 }
2237 }
2238
CharColor(const SvxColorItem & rColor)2239 void DocxAttributeOutput::CharColor( const SvxColorItem& rColor )
2240 {
2241 const Color aColor( rColor.GetValue() );
2242 OString aColorString;
2243
2244 aColorString = impl_ConvertColor( aColor );
2245
2246 m_pSerializer->singleElementNS( XML_w, XML_color,
2247 FSNS( XML_w, XML_val ), aColorString.getStr(), FSEND );
2248 }
2249
CharContour(const SvxContourItem & rContour)2250 void DocxAttributeOutput::CharContour( const SvxContourItem& rContour )
2251 {
2252 if ( rContour.GetValue() )
2253 m_pSerializer->singleElementNS( XML_w, XML_outline, FSEND );
2254 else
2255 m_pSerializer->singleElementNS( XML_w, XML_outline, FSNS( XML_w, XML_val ), "off", FSEND );
2256 }
2257
CharCrossedOut(const SvxCrossedOutItem & rCrossedOut)2258 void DocxAttributeOutput::CharCrossedOut( const SvxCrossedOutItem& rCrossedOut )
2259 {
2260 switch ( rCrossedOut.GetStrikeout() )
2261 {
2262 case STRIKEOUT_DOUBLE:
2263 m_pSerializer->singleElementNS( XML_w, XML_dstrike, FSEND );
2264 break;
2265 case STRIKEOUT_NONE:
2266 m_pSerializer->singleElementNS( XML_w, XML_dstrike, FSNS( XML_w, XML_val ), "off", FSEND );
2267 m_pSerializer->singleElementNS( XML_w, XML_strike, FSNS( XML_w, XML_val ), "off", FSEND );
2268 break;
2269 default:
2270 m_pSerializer->singleElementNS( XML_w, XML_strike, FSEND );
2271 break;
2272 }
2273 }
2274
CharEscapement(const SvxEscapementItem &)2275 void DocxAttributeOutput::CharEscapement( const SvxEscapementItem& /*rEscapement*/ )
2276 {
2277 #if OSL_DEBUG_LEVEL > 0
2278 OSL_TRACE( "TODO DocxAttributeOutput::CharEscapement()\n" );
2279 #endif
2280 }
2281
CharFont(const SvxFontItem & rFont)2282 void DocxAttributeOutput::CharFont( const SvxFontItem& rFont)
2283 {
2284 if (!m_pFontsAttrList)
2285 m_pFontsAttrList = m_pSerializer->createAttrList();
2286 OUString sFontName(rFont.GetFamilyName());
2287 OString sFontNameUtf8 = OUStringToOString(sFontName, RTL_TEXTENCODING_UTF8);
2288 m_pFontsAttrList->add(FSNS(XML_w, XML_ascii), sFontNameUtf8);
2289 m_pFontsAttrList->add(FSNS(XML_w, XML_hAnsi), sFontNameUtf8);
2290 }
2291
CharFontSize(const SvxFontHeightItem & rFontSize)2292 void DocxAttributeOutput::CharFontSize( const SvxFontHeightItem& rFontSize)
2293 {
2294 OString fontSize = OString::valueOf( sal_Int32( ( rFontSize.GetHeight() + 5 ) / 10 ) );
2295
2296 switch ( rFontSize.Which() )
2297 {
2298 case RES_CHRATR_FONTSIZE:
2299 case RES_CHRATR_CJK_FONTSIZE:
2300 m_pSerializer->singleElementNS( XML_w, XML_sz, FSNS( XML_w, XML_val ), fontSize.getStr(), FSEND );
2301 break;
2302 case RES_CHRATR_CTL_FONTSIZE:
2303 m_pSerializer->singleElementNS( XML_w, XML_szCs, FSNS( XML_w, XML_val ), fontSize.getStr(), FSEND );
2304 break;
2305 }
2306 }
2307
CharKerning(const SvxKerningItem & rKerning)2308 void DocxAttributeOutput::CharKerning( const SvxKerningItem& rKerning )
2309 {
2310 OString aKerning = OString::valueOf( ( sal_Int32 ) rKerning.GetValue() );
2311 m_pSerializer->singleElementNS( XML_w, XML_kern, FSNS(XML_w, XML_val), aKerning.getStr(), FSEND );
2312 }
2313
CharLanguage(const SvxLanguageItem & rLanguage)2314 void DocxAttributeOutput::CharLanguage( const SvxLanguageItem& rLanguage )
2315 {
2316 if (!m_pCharLangAttrList)
2317 m_pCharLangAttrList = m_pSerializer->createAttrList();
2318
2319 ::com::sun::star::lang::Locale xLocale= MsLangId::convertLanguageToLocale( rLanguage.GetLanguage( ) );
2320 OString sLanguage = OUStringToOString(xLocale.Language, RTL_TEXTENCODING_UTF8);
2321 OString sCountry = OUStringToOString(xLocale.Country, RTL_TEXTENCODING_UTF8);
2322
2323 OString aLanguageCode = sLanguage + "-" + sCountry;
2324
2325 switch ( rLanguage.Which() )
2326 {
2327 case RES_CHRATR_LANGUAGE:
2328 m_pCharLangAttrList->add(FSNS(XML_w, XML_val), aLanguageCode);
2329 break;
2330 case RES_CHRATR_CJK_LANGUAGE:
2331 m_pCharLangAttrList->add(FSNS(XML_w, XML_eastAsia), aLanguageCode);
2332 break;
2333 case RES_CHRATR_CTL_LANGUAGE:
2334 m_pCharLangAttrList->add(FSNS(XML_w, XML_bidi), aLanguageCode);
2335 break;
2336 }
2337 }
2338
CharPosture(const SvxPostureItem & rPosture)2339 void DocxAttributeOutput::CharPosture( const SvxPostureItem& rPosture )
2340 {
2341 if ( rPosture.GetPosture() != ITALIC_NONE )
2342 m_pSerializer->singleElementNS( XML_w, XML_i, FSEND );
2343 else
2344 m_pSerializer->singleElementNS( XML_w, XML_i, FSNS( XML_w, XML_val ), "off", FSEND );
2345 }
2346
CharShadow(const SvxShadowedItem & rShadow)2347 void DocxAttributeOutput::CharShadow( const SvxShadowedItem& rShadow )
2348 {
2349 if ( rShadow.GetValue() )
2350 m_pSerializer->singleElementNS( XML_w, XML_shadow, FSEND );
2351 else
2352 m_pSerializer->singleElementNS( XML_w, XML_shadow, FSNS( XML_w, XML_val ), "off", FSEND );
2353 }
2354
CharUnderline(const SvxUnderlineItem & rUnderline)2355 void DocxAttributeOutput::CharUnderline( const SvxUnderlineItem& rUnderline )
2356 {
2357 const char *pUnderline;
2358
2359 switch ( rUnderline.GetLineStyle() )
2360 {
2361 case UNDERLINE_SINGLE: pUnderline = "single"; break;
2362 case UNDERLINE_BOLD: pUnderline = "thick"; break;
2363 case UNDERLINE_DOUBLE: pUnderline = "double"; break;
2364 case UNDERLINE_DOTTED: pUnderline = "dotted"; break;
2365 case UNDERLINE_DASH: pUnderline = "dash"; break;
2366 case UNDERLINE_DASHDOT: pUnderline = "dotDash"; break;
2367 case UNDERLINE_DASHDOTDOT: pUnderline = "dotDotDash"; break;
2368 case UNDERLINE_WAVE: pUnderline = "wave"; break;
2369 case UNDERLINE_BOLDDOTTED: pUnderline = "dottedHeavy"; break;
2370 case UNDERLINE_BOLDDASH: pUnderline = "dashedHeavy"; break;
2371 case UNDERLINE_LONGDASH: pUnderline = "dashLongHeavy"; break;
2372 case UNDERLINE_BOLDLONGDASH: pUnderline = "dashLongHeavy"; break;
2373 case UNDERLINE_BOLDDASHDOT: pUnderline = "dashDotHeavy"; break;
2374 case UNDERLINE_BOLDDASHDOTDOT: pUnderline = "dashDotDotHeavy"; break;
2375 case UNDERLINE_BOLDWAVE: pUnderline = "wavyHeavy"; break;
2376 case UNDERLINE_DOUBLEWAVE: pUnderline = "wavyDouble"; break;
2377 case UNDERLINE_NONE: // fall through
2378 default: pUnderline = "none"; break;
2379 }
2380
2381 m_pSerializer->singleElementNS( XML_w, XML_u, FSNS( XML_w, XML_val ), pUnderline, FSEND );
2382 }
2383
CharWeight(const SvxWeightItem & rWeight)2384 void DocxAttributeOutput::CharWeight( const SvxWeightItem& rWeight )
2385 {
2386 if ( rWeight.GetWeight() == WEIGHT_BOLD )
2387 m_pSerializer->singleElementNS( XML_w, XML_b, FSEND );
2388 else
2389 m_pSerializer->singleElementNS( XML_w, XML_b, FSNS( XML_w, XML_val ), "off", FSEND );
2390 }
2391
CharAutoKern(const SvxAutoKernItem &)2392 void DocxAttributeOutput::CharAutoKern( const SvxAutoKernItem& )
2393 {
2394 #if OSL_DEBUG_LEVEL > 0
2395 OSL_TRACE( "TODO DocxAttributeOutput::CharAutoKern()\n" );
2396 #endif
2397 }
2398
CharAnimatedText(const SvxBlinkItem & rBlink)2399 void DocxAttributeOutput::CharAnimatedText( const SvxBlinkItem& rBlink )
2400 {
2401 if ( rBlink.GetValue() )
2402 m_pSerializer->singleElementNS(XML_w, XML_effect, FSNS( XML_w, XML_val ), "blinkBackground", FSEND );
2403 else
2404 m_pSerializer->singleElementNS(XML_w, XML_effect, FSNS( XML_w, XML_val ), "none", FSEND );
2405 }
2406
CharBackground(const SvxBrushItem & rBrush)2407 void DocxAttributeOutput::CharBackground( const SvxBrushItem& rBrush )
2408 {
2409 m_pSerializer->singleElementNS( XML_w, XML_shd,
2410 FSNS( XML_w, XML_fill ), impl_ConvertColor( rBrush.GetColor() ).getStr(), FSEND );
2411 }
2412
CharFontCJK(const SvxFontItem & rFont)2413 void DocxAttributeOutput::CharFontCJK( const SvxFontItem& rFont )
2414 {
2415 if (!m_pFontsAttrList)
2416 m_pFontsAttrList = m_pSerializer->createAttrList();
2417 OUString sFontName(rFont.GetFamilyName());
2418 OString sFontNameUtf8 = OUStringToOString(sFontName, RTL_TEXTENCODING_UTF8);
2419 m_pFontsAttrList->add(FSNS(XML_w, XML_eastAsia), sFontNameUtf8);
2420 }
2421
CharPostureCJK(const SvxPostureItem & rPosture)2422 void DocxAttributeOutput::CharPostureCJK( const SvxPostureItem& rPosture )
2423 {
2424 if ( rPosture.GetPosture() != ITALIC_NONE )
2425 m_pSerializer->singleElementNS( XML_w, XML_i, FSEND );
2426 else
2427 m_pSerializer->singleElementNS( XML_w, XML_i, FSNS( XML_w, XML_val ), "off", FSEND );
2428 }
2429
CharWeightCJK(const SvxWeightItem & rWeight)2430 void DocxAttributeOutput::CharWeightCJK( const SvxWeightItem& rWeight )
2431 {
2432 if ( rWeight.GetWeight() == WEIGHT_BOLD )
2433 m_pSerializer->singleElementNS( XML_w, XML_b, FSEND );
2434 else
2435 m_pSerializer->singleElementNS( XML_w, XML_b, FSNS( XML_w, XML_val ), "off", FSEND );
2436 }
2437
CharFontCTL(const SvxFontItem & rFont)2438 void DocxAttributeOutput::CharFontCTL( const SvxFontItem& rFont )
2439 {
2440 if (!m_pFontsAttrList)
2441 m_pFontsAttrList = m_pSerializer->createAttrList();
2442 OUString sFontName(rFont.GetFamilyName());
2443 OString sFontNameUtf8 = OUStringToOString(sFontName, RTL_TEXTENCODING_UTF8);
2444 m_pFontsAttrList->add(FSNS(XML_w, XML_cs), sFontNameUtf8);
2445
2446 }
2447
CharPostureCTL(const SvxPostureItem & rPosture)2448 void DocxAttributeOutput::CharPostureCTL( const SvxPostureItem& rPosture)
2449 {
2450 if ( rPosture.GetPosture() != ITALIC_NONE )
2451 m_pSerializer->singleElementNS( XML_w, XML_iCs, FSEND );
2452 else
2453 m_pSerializer->singleElementNS( XML_w, XML_iCs, FSNS( XML_w, XML_val ), "off", FSEND );
2454 }
2455
CharWeightCTL(const SvxWeightItem & rWeight)2456 void DocxAttributeOutput::CharWeightCTL( const SvxWeightItem& rWeight )
2457 {
2458 if ( rWeight.GetWeight() == WEIGHT_BOLD )
2459 m_pSerializer->singleElementNS( XML_w, XML_bCs, FSEND );
2460 else
2461 m_pSerializer->singleElementNS( XML_w, XML_bCs, FSNS( XML_w, XML_val ), "off", FSEND );
2462 }
2463
CharRotate(const SvxCharRotateItem & rRotate)2464 void DocxAttributeOutput::CharRotate( const SvxCharRotateItem& rRotate)
2465 {
2466 if ( !rRotate.GetValue() )
2467 return;
2468
2469 if (!m_pEastAsianLayoutAttrList)
2470 m_pEastAsianLayoutAttrList = m_pSerializer->createAttrList();
2471 OString sTrue((sal_Char *)"true");
2472 m_pEastAsianLayoutAttrList->add(FSNS(XML_w, XML_vert), sTrue);
2473
2474 if (rRotate.IsFitToLine())
2475 m_pEastAsianLayoutAttrList->add(FSNS(XML_w, XML_vertCompress), sTrue);
2476 }
2477
CharEmphasisMark(const SvxEmphasisMarkItem & rEmphasisMark)2478 void DocxAttributeOutput::CharEmphasisMark( const SvxEmphasisMarkItem& rEmphasisMark )
2479 {
2480 const char *pEmphasis;
2481
2482 switch ( rEmphasisMark.GetValue() )
2483 {
2484 case EMPHASISMARK_NONE: pEmphasis = "none"; break;
2485 case EMPHASISMARK_SIDE_DOTS: pEmphasis = "dot"; break;
2486 case EMPHASISMARK_CIRCLE_ABOVE: pEmphasis = "circle"; break;
2487 case EMPHASISMARK_DOTS_BELOW: pEmphasis = "underDot"; break;
2488 default: pEmphasis = "comma"; break;
2489 }
2490
2491 m_pSerializer->singleElementNS( XML_w, XML_em, FSNS( XML_w, XML_val ), pEmphasis, FSEND );
2492 }
2493
CharTwoLines(const SvxTwoLinesItem & rTwoLines)2494 void DocxAttributeOutput::CharTwoLines( const SvxTwoLinesItem& rTwoLines )
2495 {
2496 if ( !rTwoLines.GetValue() )
2497 return;
2498
2499 if (!m_pEastAsianLayoutAttrList)
2500 m_pEastAsianLayoutAttrList = m_pSerializer->createAttrList();
2501 OString sTrue((sal_Char *)"true");
2502 m_pEastAsianLayoutAttrList->add(FSNS(XML_w, XML_combine), sTrue);
2503
2504 sal_Unicode cStart = rTwoLines.GetStartBracket();
2505 sal_Unicode cEnd = rTwoLines.GetEndBracket();
2506
2507 if (!cStart && !cEnd)
2508 return;
2509
2510 OString sBracket;
2511 if ((cStart == '{') || (cEnd == '}'))
2512 sBracket = (sal_Char *)"curly";
2513 else if ((cStart == '<') || (cEnd == '>'))
2514 sBracket = (sal_Char *)"angle";
2515 else if ((cStart == '[') || (cEnd == ']'))
2516 sBracket = (sal_Char *)"square";
2517 else
2518 sBracket = (sal_Char *)"round";
2519 m_pEastAsianLayoutAttrList->add(FSNS(XML_w, XML_combineBrackets), sBracket);
2520 }
2521
CharScaleWidth(const SvxCharScaleWidthItem & rScaleWidth)2522 void DocxAttributeOutput::CharScaleWidth( const SvxCharScaleWidthItem& rScaleWidth )
2523 {
2524 m_pSerializer->singleElementNS( XML_w, XML_w,
2525 FSNS( XML_w, XML_val ), rtl::OString::valueOf( sal_Int32( rScaleWidth.GetValue() ) ).getStr(), FSEND );
2526 }
2527
CharRelief(const SvxCharReliefItem & rRelief)2528 void DocxAttributeOutput::CharRelief( const SvxCharReliefItem& rRelief )
2529 {
2530 switch ( rRelief.GetValue() )
2531 {
2532 case RELIEF_EMBOSSED:
2533 m_pSerializer->singleElementNS( XML_w, XML_emboss, FSEND );
2534 break;
2535 case RELIEF_ENGRAVED:
2536 m_pSerializer->singleElementNS( XML_w, XML_imprint, FSEND );
2537 break;
2538 default:
2539 m_pSerializer->singleElementNS( XML_w, XML_emboss, FSNS( XML_w, XML_val ), "off", FSEND );
2540 m_pSerializer->singleElementNS( XML_w, XML_imprint, FSNS( XML_w, XML_val ), "off", FSEND );
2541 break;
2542 }
2543 }
2544
CharHidden(const SvxCharHiddenItem & rHidden)2545 void DocxAttributeOutput::CharHidden( const SvxCharHiddenItem& rHidden )
2546 {
2547 if ( rHidden.GetValue() )
2548 m_pSerializer->singleElementNS( XML_w, XML_vanish, FSEND );
2549 else
2550 m_pSerializer->singleElementNS( XML_w, XML_vanish, FSNS( XML_w, XML_val ), "off", FSEND );
2551 }
2552
TextINetFormat(const SwFmtINetFmt & rLink)2553 void DocxAttributeOutput::TextINetFormat( const SwFmtINetFmt& rLink )
2554 {
2555 const SwTxtINetFmt* pINetFmt = rLink.GetTxtINetFmt();
2556 const SwCharFmt* pCharFmt = pINetFmt->GetCharFmt();
2557
2558 OString aStyleId( "style" );
2559 aStyleId += OString::valueOf( sal_Int32( m_rExport.GetId( *pCharFmt ) ) );
2560
2561 m_pSerializer->singleElementNS( XML_w, XML_rStyle, FSNS( XML_w, XML_val ), aStyleId.getStr(), FSEND );
2562 }
2563
TextCharFormat(const SwFmtCharFmt &)2564 void DocxAttributeOutput::TextCharFormat( const SwFmtCharFmt& )
2565 {
2566 #if OSL_DEBUG_LEVEL > 0
2567 OSL_TRACE( "TODO DocxAttributeOutput::TextCharFormat()\n" );
2568 #endif
2569 }
2570
RefField(const SwField & rFld,const String & rRef)2571 void DocxAttributeOutput::RefField( const SwField& rFld, const String& rRef )
2572 {
2573 sal_uInt16 nType = rFld.GetTyp( )->Which( );
2574 if ( nType == RES_GETEXPFLD )
2575 {
2576 String sCmd = FieldString( ww::eREF );
2577 sCmd.APPEND_CONST_ASC( "\"" );
2578 sCmd += rRef;
2579 sCmd.APPEND_CONST_ASC( "\" " );
2580
2581 m_rExport.OutputField( &rFld, ww::eREF, sCmd );
2582 }
2583
2584 // There is nothing to do here for the set fields
2585 }
2586
HiddenField(const SwField &)2587 void DocxAttributeOutput::HiddenField( const SwField& /*rFld*/ )
2588 {
2589 #if OSL_DEBUG_LEVEL > 0
2590 OSL_TRACE( "TODO DocxAttributeOutput::HiddenField()\n" );
2591 #endif
2592 }
2593
PostitField(const SwField *)2594 void DocxAttributeOutput::PostitField( const SwField* /* pFld*/ )
2595 {
2596 #if OSL_DEBUG_LEVEL > 0
2597 OSL_TRACE( "TODO DocxAttributeOutput::PostitField()\n" );
2598 #endif
2599 }
2600
DropdownField(const SwField * pFld)2601 bool DocxAttributeOutput::DropdownField( const SwField* pFld )
2602 {
2603 bool bExpand = false;
2604
2605 ww::eField eType = ww::eFORMDROPDOWN;
2606 String sCmd = FieldString( eType );
2607 GetExport( ).OutputField( pFld, eType, sCmd );
2608
2609 return bExpand;
2610 }
2611
SetField(const SwField & rFld,ww::eField eType,const String & rCmd)2612 void DocxAttributeOutput::SetField( const SwField& rFld, ww::eField eType, const String& rCmd )
2613 {
2614 // field bookmarks are handled in the EndRun method
2615 GetExport().OutputField(&rFld, eType, rCmd );
2616 }
2617
WriteExpand(const SwField * pFld)2618 void DocxAttributeOutput::WriteExpand( const SwField* pFld )
2619 {
2620 // Will be written in the next End Run
2621 String sCmd;
2622 m_rExport.OutputField( pFld, ww::eUNKNOWN, sCmd );
2623 }
2624
WriteField_Impl(const SwField * pFld,ww::eField eType,const String & rFldCmd,sal_uInt8 nMode)2625 void DocxAttributeOutput::WriteField_Impl( const SwField* pFld, ww::eField eType, const String& rFldCmd, sal_uInt8 nMode )
2626 {
2627 struct FieldInfos infos;
2628 infos.pField = pFld;
2629 infos.sCmd = rFldCmd;
2630 infos.eType = eType;
2631 infos.bClose = WRITEFIELD_CLOSE & nMode;
2632 infos.bOpen = WRITEFIELD_START & nMode;
2633
2634 m_Fields.push_back( infos );
2635
2636 if ( pFld )
2637 {
2638 sal_uInt16 nType = pFld->GetTyp( )->Which( );
2639 sal_uInt16 nSubType = pFld->GetSubType();
2640
2641 // TODO Any other field types here ?
2642 if ( ( nType == RES_SETEXPFLD ) && ( nSubType & nsSwGetSetExpType::GSE_STRING ) )
2643 {
2644 const SwSetExpField *pSet = ( const SwSetExpField* )( pFld );
2645 m_sFieldBkm = pSet->GetPar1( );
2646 }
2647 else if ( nType == RES_DROPDOWN )
2648 {
2649 const SwDropDownField* pDropDown = ( const SwDropDownField* )( pFld );
2650 m_sFieldBkm = pDropDown->GetName( );
2651 }
2652 }
2653 }
2654
WriteBookmarks_Impl(std::vector<OUString> & rStarts,std::vector<OUString> & rEnds)2655 void DocxAttributeOutput::WriteBookmarks_Impl( std::vector< OUString >& rStarts,
2656 std::vector< OUString >& rEnds )
2657 {
2658 for ( std::vector< OUString >::const_iterator it = rStarts.begin(), end = rStarts.end(); it < end; ++it )
2659 {
2660 OString rName = OUStringToOString( *it, RTL_TEXTENCODING_UTF8 ).getStr( );
2661 m_rMarksStart.push_back( rName );
2662 }
2663 rStarts.clear();
2664
2665 for ( std::vector< OUString >::const_iterator it = rEnds.begin(), end = rEnds.end(); it < end; ++it )
2666 {
2667 OString rName = OUStringToOString( *it, RTL_TEXTENCODING_UTF8 ).getStr( );
2668 m_rMarksEnd.push_back( rName );
2669 }
2670 rEnds.clear();
2671 }
2672
TextFootnote_Impl(const SwFmtFtn & rFootnote)2673 void DocxAttributeOutput::TextFootnote_Impl( const SwFmtFtn& rFootnote )
2674 {
2675 const SwEndNoteInfo& rInfo = rFootnote.IsEndNote()?
2676 m_rExport.pDoc->GetEndNoteInfo(): m_rExport.pDoc->GetFtnInfo();
2677
2678 // footnote/endnote run properties
2679 const SwCharFmt* pCharFmt = rInfo.GetAnchorCharFmt( *m_rExport.pDoc );
2680
2681 OString aStyleId( "style" );
2682 aStyleId += OString::valueOf( sal_Int32( m_rExport.GetId( *pCharFmt ) ) );
2683
2684 m_pSerializer->singleElementNS( XML_w, XML_rStyle, FSNS( XML_w, XML_val ), aStyleId.getStr(), FSEND );
2685
2686 // remember the footnote/endnote to
2687 // 1) write the footnoteReference/endnoteReference in EndRunProperties()
2688 // 2) be able to dump them all to footnotes.xml/endnotes.xml
2689 if ( !rFootnote.IsEndNote() )
2690 m_pFootnotesList->add( rFootnote );
2691 else
2692 m_pEndnotesList->add( rFootnote );
2693 }
2694
FootnoteEndnoteReference()2695 void DocxAttributeOutput::FootnoteEndnoteReference()
2696 {
2697 sal_Int32 nId;
2698 const SwFmtFtn *pFootnote = m_pFootnotesList->getCurrent( nId );
2699
2700 // both cannot be set at the same time - if they are, it's a bug
2701 if ( !pFootnote )
2702 pFootnote = m_pEndnotesList->getCurrent( nId );
2703
2704 if ( !pFootnote )
2705 return;
2706
2707 sal_Int32 nToken = pFootnote->IsEndNote()? XML_endnoteReference: XML_footnoteReference;
2708
2709 // write it
2710 if ( pFootnote->GetNumStr().Len() == 0 )
2711 {
2712 // autonumbered
2713 m_pSerializer->singleElementNS( XML_w, nToken,
2714 FSNS( XML_w, XML_id ), ::rtl::OString::valueOf( nId ).getStr(),
2715 FSEND );
2716 }
2717 else
2718 {
2719 // not autonumbered
2720 m_pSerializer->singleElementNS( XML_w, nToken,
2721 FSNS( XML_w, XML_customMarkFollows ), "1",
2722 FSNS( XML_w, XML_id ), ::rtl::OString::valueOf( nId ).getStr(),
2723 FSEND );
2724
2725 RunText( pFootnote->GetNumStr() );
2726 }
2727 }
2728
FootnotesEndnotes(bool bFootnotes)2729 void DocxAttributeOutput::FootnotesEndnotes( bool bFootnotes )
2730 {
2731 const FootnotesVector& rVector = bFootnotes? m_pFootnotesList->getVector(): m_pEndnotesList->getVector();
2732
2733 sal_Int32 nBody = bFootnotes? XML_footnotes: XML_endnotes;
2734 sal_Int32 nItem = bFootnotes? XML_footnote: XML_endnote;
2735
2736 m_pSerializer->startElementNS( XML_w, nBody,
2737 FSNS( XML_xmlns, XML_w ), "http://schemas.openxmlformats.org/wordprocessingml/2006/main",
2738 FSEND );
2739
2740 sal_Int32 nIndex = 0;
2741
2742 // separator
2743 m_pSerializer->startElementNS( XML_w, nItem,
2744 FSNS( XML_w, XML_id ), OString::valueOf( nIndex++ ).getStr(),
2745 FSNS( XML_w, XML_type ), "separator",
2746 FSEND );
2747 m_pSerializer->startElementNS( XML_w, XML_p, FSEND );
2748 m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
2749 m_pSerializer->singleElementNS( XML_w, XML_separator, FSEND );
2750 m_pSerializer->endElementNS( XML_w, XML_r );
2751 m_pSerializer->endElementNS( XML_w, XML_p );
2752 m_pSerializer->endElementNS( XML_w, nItem );
2753
2754 // separator
2755 m_pSerializer->startElementNS( XML_w, nItem,
2756 FSNS( XML_w, XML_id ), OString::valueOf( nIndex++ ).getStr(),
2757 FSNS( XML_w, XML_type ), "continuationSeparator",
2758 FSEND );
2759 m_pSerializer->startElementNS( XML_w, XML_p, FSEND );
2760 m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
2761 m_pSerializer->singleElementNS( XML_w, XML_continuationSeparator, FSEND );
2762 m_pSerializer->endElementNS( XML_w, XML_r );
2763 m_pSerializer->endElementNS( XML_w, XML_p );
2764 m_pSerializer->endElementNS( XML_w, nItem );
2765
2766 // footnotes/endnotes themselves
2767 for ( FootnotesVector::const_iterator i = rVector.begin(); i != rVector.end(); ++i, ++nIndex )
2768 {
2769 m_pSerializer->startElementNS( XML_w, nItem,
2770 FSNS( XML_w, XML_id ), OString::valueOf( nIndex ).getStr(),
2771 FSEND );
2772
2773 const SwNodeIndex* pIndex = (*i)->GetTxtFtn()->GetStartNode();
2774
2775 m_rExport.WriteSpecialText( pIndex->GetIndex() + 1,
2776 pIndex->GetNode().EndOfSectionIndex(),
2777 bFootnotes? TXT_FTN: TXT_EDN );
2778
2779 m_pSerializer->endElementNS( XML_w, nItem );
2780 }
2781
2782 m_pSerializer->endElementNS( XML_w, nBody );
2783
2784 }
2785
ParaLineSpacing_Impl(short nSpace,short)2786 void DocxAttributeOutput::ParaLineSpacing_Impl( short nSpace, short /*nMulti*/ )
2787 {
2788 if ( !m_pSpacingAttrList )
2789 m_pSpacingAttrList = m_pSerializer->createAttrList();
2790
2791 if ( nSpace < 0 )
2792 {
2793 m_pSpacingAttrList->add( FSNS( XML_w, XML_lineRule ), "exact" );
2794 m_pSpacingAttrList->add( FSNS( XML_w, XML_line ), OString::valueOf( sal_Int32( -nSpace ) ) );
2795 }
2796 else if ( nSpace > 0 )
2797 {
2798 m_pSpacingAttrList->add( FSNS( XML_w, XML_lineRule ), "atLeast" );
2799 m_pSpacingAttrList->add( FSNS( XML_w, XML_line ), OString::valueOf( sal_Int32( nSpace ) ) );
2800 }
2801 else
2802 m_pSpacingAttrList->add( FSNS( XML_w, XML_lineRule ), "auto" );
2803 }
2804
ParaAdjust(const SvxAdjustItem & rAdjust)2805 void DocxAttributeOutput::ParaAdjust( const SvxAdjustItem& rAdjust )
2806 {
2807 const char *pAdjustString;
2808
2809 switch ( rAdjust.GetAdjust() )
2810 {
2811 case SVX_ADJUST_LEFT:
2812 pAdjustString = "left";
2813 break;
2814 case SVX_ADJUST_RIGHT:
2815 pAdjustString = "right";
2816 break;
2817 case SVX_ADJUST_BLOCKLINE:
2818 case SVX_ADJUST_BLOCK:
2819 pAdjustString = "both";
2820 break;
2821 case SVX_ADJUST_CENTER:
2822 pAdjustString = "center";
2823 break;
2824 default:
2825 return; // not supported attribute
2826 }
2827 m_pSerializer->singleElementNS( XML_w, XML_jc, FSNS( XML_w, XML_val ), pAdjustString, FSEND );
2828 }
2829
ParaSplit(const SvxFmtSplitItem & rSplit)2830 void DocxAttributeOutput::ParaSplit( const SvxFmtSplitItem& rSplit )
2831 {
2832 if (rSplit.GetValue())
2833 m_pSerializer->singleElementNS( XML_w, XML_keepLines, FSNS( XML_w, XML_val ), "off", FSEND );
2834 else
2835 m_pSerializer->singleElementNS( XML_w, XML_keepLines, FSEND );
2836 }
2837
ParaWidows(const SvxWidowsItem & rWidows)2838 void DocxAttributeOutput::ParaWidows( const SvxWidowsItem& rWidows )
2839 {
2840 if (rWidows.GetValue())
2841 m_pSerializer->singleElementNS( XML_w, XML_widowControl, FSEND );
2842 else
2843 m_pSerializer->singleElementNS( XML_w, XML_widowControl, FSNS( XML_w, XML_val ), "off", FSEND );
2844 }
2845
impl_WriteTabElement(FSHelperPtr pSerializer,const SvxTabStop & rTab,long nCurrentLeft)2846 static void impl_WriteTabElement( FSHelperPtr pSerializer,
2847 const SvxTabStop& rTab, long nCurrentLeft )
2848 {
2849 FastAttributeList *pTabElementAttrList = pSerializer->createAttrList();
2850
2851 switch (rTab.GetAdjustment())
2852 {
2853 case SVX_TAB_ADJUST_RIGHT:
2854 pTabElementAttrList->add( FSNS( XML_w, XML_val ), OString( (sal_Char *)"right") );
2855 break;
2856 case SVX_TAB_ADJUST_DECIMAL:
2857 pTabElementAttrList->add( FSNS( XML_w, XML_val ), OString( (sal_Char *)"decimal") );
2858 break;
2859 case SVX_TAB_ADJUST_CENTER:
2860 pTabElementAttrList->add( FSNS( XML_w, XML_val ), OString( (sal_Char *)"center") );
2861 break;
2862 case SVX_TAB_ADJUST_DEFAULT:
2863 case SVX_TAB_ADJUST_LEFT:
2864 default:
2865 pTabElementAttrList->add( FSNS( XML_w, XML_val ), OString( (sal_Char *)"left") );
2866 break;
2867 }
2868
2869 pTabElementAttrList->add( FSNS( XML_w, XML_pos ), OString::valueOf( rTab.GetTabPos() + nCurrentLeft ) );
2870
2871 sal_Unicode cFillChar = rTab.GetFill();
2872
2873 if (sal_Unicode('.') == cFillChar )
2874 pTabElementAttrList->add( FSNS( XML_w, XML_leader ), OString( (sal_Char *) "dot" ) );
2875 else if ( sal_Unicode('-') == cFillChar )
2876 pTabElementAttrList->add( FSNS( XML_w, XML_leader ), OString( (sal_Char *) "hyphen" ) );
2877 else if ( sal_Unicode(0xB7) == cFillChar ) // middle dot
2878 pTabElementAttrList->add( FSNS( XML_w, XML_leader ), OString( (sal_Char *) "middleDot" ) );
2879 else if ( sal_Unicode('_') == cFillChar )
2880 pTabElementAttrList->add( FSNS( XML_w, XML_leader ), OString( (sal_Char *) "underscore" ) );
2881 else
2882 pTabElementAttrList->add( FSNS( XML_w, XML_leader ), OString( (sal_Char *) "none" ) );
2883
2884 pSerializer->singleElementNS( XML_w, XML_tab, pTabElementAttrList );
2885 }
2886
ParaTabStop(const SvxTabStopItem & rTabStop)2887 void DocxAttributeOutput::ParaTabStop( const SvxTabStopItem& rTabStop )
2888 {
2889 const SfxPoolItem* pLR = m_rExport.HasItem( RES_LR_SPACE );
2890 long nCurrentLeft = pLR ? ((const SvxLRSpaceItem*)pLR)->GetTxtLeft() : 0;
2891
2892 m_pSerializer->startElementNS( XML_w, XML_tabs, FSEND );
2893
2894 sal_uInt16 nCount = rTabStop.Count();
2895 for (sal_uInt16 i = 0; i < nCount; i++ )
2896 impl_WriteTabElement( m_pSerializer, rTabStop[i], nCurrentLeft );
2897
2898 m_pSerializer->endElementNS( XML_w, XML_tabs );
2899 }
2900
ParaHyphenZone(const SvxHyphenZoneItem & rHyphenZone)2901 void DocxAttributeOutput::ParaHyphenZone( const SvxHyphenZoneItem& rHyphenZone )
2902 {
2903 m_pSerializer->singleElementNS( XML_w, XML_suppressAutoHyphens,
2904 FSNS( XML_w, XML_val ), rHyphenZone.IsHyphen( ) ? "false" : "true" ,
2905 FSEND );
2906 }
2907
ParaNumRule_Impl(const SwTxtNode *,sal_Int32 nLvl,sal_Int32 nNumId)2908 void DocxAttributeOutput::ParaNumRule_Impl( const SwTxtNode* /*pTxtNd*/, sal_Int32 nLvl, sal_Int32 nNumId )
2909 {
2910 if ( USHRT_MAX != nNumId && 0 != nNumId )
2911 {
2912 m_pSerializer->startElementNS( XML_w, XML_numPr, FSEND );
2913 m_pSerializer->singleElementNS( XML_w, XML_ilvl, FSNS( XML_w, XML_val ), OString::valueOf( sal_Int32( nLvl )).getStr(), FSEND );
2914 m_pSerializer->singleElementNS( XML_w, XML_numId, FSNS( XML_w, XML_val ), OString::valueOf( sal_Int32( nNumId )).getStr(), FSEND );
2915 m_pSerializer->endElementNS( XML_w, XML_numPr );
2916 }
2917 }
2918
ParaScriptSpace(const SfxBoolItem & rScriptSpace)2919 void DocxAttributeOutput::ParaScriptSpace( const SfxBoolItem& rScriptSpace )
2920 {
2921 sal_uInt16 nXmlElement = 0;
2922
2923 switch ( rScriptSpace.Which( ) )
2924 {
2925 case RES_PARATR_SCRIPTSPACE:
2926 nXmlElement = XML_autoSpaceDE;
2927 break;
2928 case RES_PARATR_HANGINGPUNCTUATION:
2929 nXmlElement = XML_overflowPunct;
2930 break;
2931 case RES_PARATR_FORBIDDEN_RULES:
2932 nXmlElement = XML_kinsoku;
2933 break;
2934 }
2935
2936 if ( nXmlElement )
2937 {
2938 m_pSerializer->singleElementNS( XML_w, nXmlElement,
2939 FSNS( XML_w, XML_val ), rScriptSpace.GetValue( ) ? "true": "false",
2940 FSEND );
2941 }
2942 }
2943
ParaVerticalAlign(const SvxParaVertAlignItem & rAlign)2944 void DocxAttributeOutput::ParaVerticalAlign( const SvxParaVertAlignItem& rAlign )
2945 {
2946 const char *pAlignString;
2947
2948 switch ( rAlign.GetValue() )
2949 {
2950 case SvxParaVertAlignItem::BASELINE:
2951 pAlignString = "baseline";
2952 break;
2953 case SvxParaVertAlignItem::TOP:
2954 pAlignString = "top";
2955 break;
2956 case SvxParaVertAlignItem::CENTER:
2957 pAlignString = "center";
2958 break;
2959 case SvxParaVertAlignItem::BOTTOM:
2960 pAlignString = "bottom";
2961 break;
2962 case SvxParaVertAlignItem::AUTOMATIC:
2963 pAlignString = "auto";
2964 break;
2965 default:
2966 return; // not supported attribute
2967 }
2968 m_pSerializer->singleElementNS( XML_w, XML_textAlignment, FSNS( XML_w, XML_val ), pAlignString, FSEND );
2969 }
2970
ParaSnapToGrid(const SvxParaGridItem & rGrid)2971 void DocxAttributeOutput::ParaSnapToGrid( const SvxParaGridItem& rGrid )
2972 {
2973 m_pSerializer->singleElementNS( XML_w, XML_snapToGrid,
2974 FSNS( XML_w, XML_val ), rGrid.GetValue( ) ? "true": "false",
2975 FSEND );
2976 }
2977
FormatFrameSize(const SwFmtFrmSize & rSize)2978 void DocxAttributeOutput::FormatFrameSize( const SwFmtFrmSize& rSize )
2979 {
2980 if ( m_rExport.bOutFlyFrmAttrs )
2981 {
2982 #if OSL_DEBUG_LEVEL > 0
2983 OSL_TRACE( "TODO DocxAttributeOutput::FormatFrameSize() - Fly frames\n" );
2984 #endif
2985 }
2986 else if ( m_rExport.bOutPageDescs )
2987 {
2988 FastAttributeList *attrList = m_pSerializer->createAttrList( );
2989 if ( m_rExport.pAktPageDesc->GetLandscape( ) )
2990 attrList->add( FSNS( XML_w, XML_orient ), "landscape" );
2991
2992
2993 attrList->add( FSNS( XML_w, XML_w ), OString::valueOf( rSize.GetWidth( ) ) );
2994 attrList->add( FSNS( XML_w, XML_h ), OString::valueOf( rSize.GetHeight( ) ) );
2995
2996 XFastAttributeListRef xAttrList( attrList );
2997 attrList = NULL;
2998
2999 m_pSerializer->singleElementNS( XML_w, XML_pgSz, xAttrList );
3000 }
3001 }
3002
FormatPaperBin(const SvxPaperBinItem &)3003 void DocxAttributeOutput::FormatPaperBin( const SvxPaperBinItem& )
3004 {
3005 #if OSL_DEBUG_LEVEL > 0
3006 OSL_TRACE( "TODO DocxAttributeOutput::FormatPaperBin()\n" );
3007 #endif
3008 }
3009
FormatLRSpace(const SvxLRSpaceItem & rLRSpace)3010 void DocxAttributeOutput::FormatLRSpace( const SvxLRSpaceItem& rLRSpace )
3011 {
3012 if ( m_rExport.bOutFlyFrmAttrs )
3013 {
3014 #if OSL_DEBUG_LEVEL > 0
3015 OSL_TRACE( "DocxAttributeOutput::FormatLRSpace() - Fly frames\n" );
3016 #endif
3017 }
3018 else if ( m_rExport.bOutPageDescs )
3019 {
3020 if ( !m_pSpacingAttrList )
3021 m_pSpacingAttrList = m_pSerializer->createAttrList();
3022
3023
3024 sal_uInt16 nLDist, nRDist;
3025 const SfxPoolItem* pItem = m_rExport.HasItem( RES_BOX );
3026 if ( pItem )
3027 {
3028 nRDist = ((SvxBoxItem*)pItem)->CalcLineSpace( BOX_LINE_LEFT );
3029 nLDist = ((SvxBoxItem*)pItem)->CalcLineSpace( BOX_LINE_RIGHT );
3030 }
3031 else
3032 nLDist = nRDist = 0;
3033 nLDist = nLDist + (sal_uInt16)rLRSpace.GetLeft();
3034 nRDist = nRDist + (sal_uInt16)rLRSpace.GetRight();
3035
3036 m_pSpacingAttrList->add( FSNS( XML_w, XML_left ), OString::valueOf( sal_Int32( nLDist ) ) );
3037 m_pSpacingAttrList->add( FSNS( XML_w, XML_right ), OString::valueOf( sal_Int32( nRDist ) ) );
3038 }
3039 else
3040 {
3041 FastAttributeList *pLRSpaceAttrList = m_pSerializer->createAttrList();
3042
3043 pLRSpaceAttrList->add( FSNS( XML_w, XML_left ), OString::valueOf( (sal_Int32) rLRSpace.GetTxtLeft() ) );
3044 pLRSpaceAttrList->add( FSNS( XML_w, XML_right ), OString::valueOf( (sal_Int32) rLRSpace.GetRight() ) );
3045
3046 sal_Int32 nFirstLineAdjustment = rLRSpace.GetTxtFirstLineOfst();
3047 if (nFirstLineAdjustment > 0)
3048 pLRSpaceAttrList->add( FSNS( XML_w, XML_firstLine ), OString::valueOf( nFirstLineAdjustment ) );
3049 else
3050 pLRSpaceAttrList->add( FSNS( XML_w, XML_hanging ), OString::valueOf( - nFirstLineAdjustment ) );
3051 m_pSerializer->singleElementNS( XML_w, XML_ind, pLRSpaceAttrList );
3052 }
3053 }
3054
FormatULSpace(const SvxULSpaceItem & rULSpace)3055 void DocxAttributeOutput::FormatULSpace( const SvxULSpaceItem& rULSpace )
3056 {
3057 if (!m_pSpacingAttrList)
3058 m_pSpacingAttrList = m_pSerializer->createAttrList();
3059
3060 if ( m_rExport.bOutFlyFrmAttrs )
3061 {
3062 }
3063 else if (m_rExport.bOutPageDescs )
3064 {
3065 ASSERT( m_rExport.GetCurItemSet(), "Impossible" );
3066 if ( !m_rExport.GetCurItemSet() )
3067 return;
3068
3069 HdFtDistanceGlue aDistances( *m_rExport.GetCurItemSet() );
3070
3071 if ( aDistances.HasHeader() )
3072 {
3073 // Header top
3074 m_pSpacingAttrList->add( FSNS( XML_w, XML_header ),
3075 OString::valueOf( sal_Int32( aDistances.dyaHdrTop ) ) );
3076 }
3077
3078 // Page top
3079 m_pSpacingAttrList->add( FSNS( XML_w, XML_top ),
3080 OString::valueOf( sal_Int32( aDistances.dyaTop ) ) );
3081
3082 if ( aDistances.HasFooter() )
3083 {
3084 // Footer bottom
3085 m_pSpacingAttrList->add( FSNS( XML_w, XML_footer ),
3086 OString::valueOf( sal_Int32( aDistances.dyaHdrBottom ) ) );
3087 }
3088
3089 // Page Bottom
3090 m_pSpacingAttrList->add( FSNS( XML_w, XML_bottom ),
3091 OString::valueOf( sal_Int32( aDistances.dyaBottom ) ) );
3092
3093 }
3094 else
3095 {
3096 m_pSpacingAttrList->add( FSNS( XML_w, XML_before ),
3097 OString::valueOf( (sal_Int32)rULSpace.GetUpper() ) );
3098 m_pSpacingAttrList->add( FSNS( XML_w, XML_after ),
3099 OString::valueOf( (sal_Int32)rULSpace.GetLower() ) );
3100 }
3101 }
3102
FormatSurround(const SwFmtSurround &)3103 void DocxAttributeOutput::FormatSurround( const SwFmtSurround& )
3104 {
3105 #if OSL_DEBUG_LEVEL > 0
3106 OSL_TRACE( "TODO DocxAttributeOutput::FormatSurround()\n" );
3107 #endif
3108 }
3109
FormatVertOrientation(const SwFmtVertOrient &)3110 void DocxAttributeOutput::FormatVertOrientation( const SwFmtVertOrient& )
3111 {
3112 #if OSL_DEBUG_LEVEL > 0
3113 OSL_TRACE( "TODO DocxAttributeOutput::FormatVertOrientation()\n" );
3114 #endif
3115 }
3116
FormatHorizOrientation(const SwFmtHoriOrient &)3117 void DocxAttributeOutput::FormatHorizOrientation( const SwFmtHoriOrient& )
3118 {
3119 #if OSL_DEBUG_LEVEL > 0
3120 OSL_TRACE( "TODO DocxAttributeOutput::FormatHorizOrientation()\n" );
3121 #endif
3122 }
3123
FormatAnchor(const SwFmtAnchor &)3124 void DocxAttributeOutput::FormatAnchor( const SwFmtAnchor& )
3125 {
3126 #if OSL_DEBUG_LEVEL > 0
3127 OSL_TRACE( "TODO DocxAttributeOutput::FormatAnchor()\n" );
3128 #endif
3129 }
3130
FormatBackground(const SvxBrushItem & rBrush)3131 void DocxAttributeOutput::FormatBackground( const SvxBrushItem& rBrush )
3132 {
3133 if ( !m_rExport.bOutPageDescs )
3134 {
3135 OString sColor = impl_ConvertColor( rBrush.GetColor( ) );
3136 m_pSerializer->singleElementNS( XML_w, XML_shd,
3137 FSNS( XML_w, XML_fill ), sColor.getStr( ),
3138 FSEND );
3139 }
3140
3141 #if OSL_DEBUG_LEVEL > 0
3142 OSL_TRACE( "TODO DocxAttributeOutput::FormatBackground()\n" );
3143 #endif
3144 }
3145
FormatBox(const SvxBoxItem & rBox)3146 void DocxAttributeOutput::FormatBox( const SvxBoxItem& rBox )
3147 {
3148
3149 if ( !m_bOpenedSectPr )
3150 {
3151 // Normally open the borders tag for paragraphs
3152 m_pSerializer->startElementNS( XML_w, XML_pBdr, FSEND );
3153 }
3154
3155 impl_pageBorders( m_pSerializer, rBox );
3156
3157 if ( m_bOpenedSectPr )
3158 {
3159 // Special handling for pgBorder
3160 m_pSerializer->mergeTopMarks( sax_fastparser::MERGE_MARKS_PREPEND );
3161 m_pSerializer->mergeTopMarks( );
3162 }
3163 else
3164 {
3165 // Normally close the borders tag for paragraphs
3166 m_pSerializer->endElementNS( XML_w, XML_pBdr );
3167 }
3168 }
3169
FormatColumns_Impl(sal_uInt16 nCols,const SwFmtCol & rCol,bool bEven,SwTwips nPageSize)3170 void DocxAttributeOutput::FormatColumns_Impl( sal_uInt16 nCols, const SwFmtCol& rCol, bool bEven, SwTwips nPageSize )
3171 {
3172 // Get the columns attributes
3173 FastAttributeList *pColsAttrList = m_pSerializer->createAttrList();
3174
3175 pColsAttrList->add( FSNS( XML_w, XML_num ),
3176 OString::valueOf( sal_Int32( nCols ) ). getStr( ) );
3177
3178 const char* pEquals = "false";
3179 if ( bEven )
3180 {
3181 sal_uInt16 nWidth = rCol.GetGutterWidth( true );
3182 pColsAttrList->add( FSNS( XML_w, XML_space ),
3183 OString::valueOf( sal_Int32( nWidth ) ).getStr( ) );
3184
3185 pEquals = "true";
3186 }
3187
3188 pColsAttrList->add( FSNS( XML_w, XML_equalWidth ), pEquals );
3189
3190 bool bHasSep = COLADJ_NONE == rCol.GetLineAdj( );
3191 pColsAttrList->add( FSNS( XML_w, XML_sep ), bHasSep ? "true" : "false" );
3192
3193 // Write the element
3194 m_pSerializer->startElementNS( XML_w, XML_cols, pColsAttrList );
3195
3196 // Write the columns width if non-equals
3197 const SwColumns & rColumns = rCol.GetColumns( );
3198 if ( !bEven )
3199 {
3200 for ( sal_uInt16 n = 0; n < nCols; ++n )
3201 {
3202 FastAttributeList *pColAttrList = m_pSerializer->createAttrList();
3203 sal_uInt16 nWidth = rCol.CalcPrtColWidth( n, ( sal_uInt16 ) nPageSize );
3204 pColAttrList->add( FSNS( XML_w, XML_w ),
3205 OString::valueOf( sal_Int32( nWidth ) ).getStr( ) );
3206
3207 if ( n + 1 != nCols )
3208 {
3209 sal_uInt16 nSpacing = rColumns[n]->GetRight( ) + rColumns[n + 1]->GetLeft( );
3210 pColAttrList->add( FSNS( XML_w, XML_space ),
3211 OString::valueOf( sal_Int32( nSpacing ) ).getStr( ) );
3212 }
3213
3214 m_pSerializer->singleElementNS( XML_w, XML_col, pColAttrList );
3215 }
3216 }
3217
3218 m_pSerializer->endElementNS( XML_w, XML_cols );
3219 }
3220
FormatKeep(const SvxFmtKeepItem &)3221 void DocxAttributeOutput::FormatKeep( const SvxFmtKeepItem& )
3222 {
3223 m_pSerializer->singleElementNS( XML_w, XML_keepNext, FSEND );
3224 }
3225
FormatTextGrid(const SwTextGridItem &)3226 void DocxAttributeOutput::FormatTextGrid( const SwTextGridItem& )
3227 {
3228 OSL_TRACE( "TODO DocxAttributeOutput::FormatTextGrid()\n" );
3229 }
3230
FormatLineNumbering(const SwFmtLineNumber & rNumbering)3231 void DocxAttributeOutput::FormatLineNumbering( const SwFmtLineNumber& rNumbering )
3232 {
3233 if ( !rNumbering.IsCount( ) )
3234 m_pSerializer->singleElementNS( XML_w, XML_suppressLineNumbers, FSEND );
3235 }
3236
FormatFrameDirection(const SvxFrameDirectionItem & rDirection)3237 void DocxAttributeOutput::FormatFrameDirection( const SvxFrameDirectionItem& rDirection )
3238 {
3239 OString sTextFlow;
3240 bool bBiDi = false;
3241 short nDir = rDirection.GetValue();
3242
3243 if ( nDir == FRMDIR_ENVIRONMENT )
3244 nDir = GetExport( ).GetDefaultFrameDirection( );
3245
3246 switch ( nDir )
3247 {
3248 default:
3249 case FRMDIR_HORI_LEFT_TOP:
3250 sTextFlow = OString( "lrTb" );
3251 break;
3252 case FRMDIR_HORI_RIGHT_TOP:
3253 sTextFlow = OString( "lrTb" );
3254 bBiDi = true;
3255 break;
3256 case FRMDIR_VERT_TOP_LEFT: // many things but not this one
3257 case FRMDIR_VERT_TOP_RIGHT:
3258 sTextFlow = OString( "tbRl" );
3259 break;
3260 }
3261
3262 if ( m_rExport.bOutPageDescs )
3263 {
3264 m_pSerializer->singleElementNS( XML_w, XML_textDirection,
3265 FSNS( XML_w, XML_val ), sTextFlow.getStr( ),
3266 FSEND );
3267 if ( bBiDi )
3268 m_pSerializer->singleElementNS( XML_w, XML_bidi, FSEND );
3269 }
3270 else if ( !m_rExport.bOutFlyFrmAttrs )
3271 {
3272 if ( bBiDi )
3273 m_pSerializer->singleElementNS( XML_w, XML_bidi, FSEND );
3274 }
3275 }
3276
DocxAttributeOutput(DocxExport & rExport,FSHelperPtr pSerializer,oox::drawingml::DrawingML * pDrawingML)3277 DocxAttributeOutput::DocxAttributeOutput( DocxExport &rExport, FSHelperPtr pSerializer, oox::drawingml::DrawingML* pDrawingML )
3278 : m_rExport( rExport ),
3279 m_pSerializer( pSerializer ),
3280 m_rDrawingML( *pDrawingML ),
3281 m_pFontsAttrList( NULL ),
3282 m_pEastAsianLayoutAttrList( NULL ),
3283 m_pCharLangAttrList( NULL ),
3284 m_pSpacingAttrList( NULL ),
3285 m_pHyperlinkAttrList( NULL ),
3286 m_pFootnotesList( new ::docx::FootnotesList() ),
3287 m_pEndnotesList( new ::docx::FootnotesList() ),
3288 m_pSectionInfo( NULL ),
3289 m_pRedlineData( NULL ),
3290 m_nRedlineId( 0 ),
3291 m_bOpenedSectPr( false ),
3292 m_sFieldBkm( ),
3293 m_nNextMarkId( 0 ),
3294 m_bPostitStart(false),
3295 m_bPostitEnd(false),
3296 m_pTableWrt( NULL ),
3297 m_bTableCellOpen( false ),
3298 m_nTableDepth( 0 ),
3299 m_bParagraphOpened( false ),
3300 m_nColBreakStatus( COLBRK_NONE )
3301 {
3302 }
3303
~DocxAttributeOutput()3304 DocxAttributeOutput::~DocxAttributeOutput()
3305 {
3306 delete m_pFontsAttrList, m_pFontsAttrList = NULL;
3307 delete m_pEastAsianLayoutAttrList, m_pEastAsianLayoutAttrList = NULL;
3308 delete m_pCharLangAttrList, m_pCharLangAttrList = NULL;
3309 delete m_pSpacingAttrList, m_pSpacingAttrList = NULL;
3310 delete m_pHyperlinkAttrList, m_pHyperlinkAttrList = NULL;
3311
3312 delete m_pFootnotesList, m_pFootnotesList = NULL;
3313 delete m_pEndnotesList, m_pEndnotesList = NULL;
3314
3315 delete m_pTableWrt, m_pTableWrt = NULL;
3316 }
3317
GetExport()3318 MSWordExportBase& DocxAttributeOutput::GetExport()
3319 {
3320 return m_rExport;
3321 }
3322
HasFootnotes()3323 bool DocxAttributeOutput::HasFootnotes()
3324 {
3325 return !m_pFootnotesList->isEmpty();
3326 }
3327
HasEndnotes()3328 bool DocxAttributeOutput::HasEndnotes()
3329 {
3330 return !m_pEndnotesList->isEmpty();
3331 }
3332