Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*
3 : : * This file is part of the LibreOffice project.
4 : : *
5 : : * This Source Code Form is subject to the terms of the Mozilla Public
6 : : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : : *
9 : : * This file incorporates work covered by the following license notice:
10 : : *
11 : : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : : * contributor license agreements. See the NOTICE file distributed
13 : : * with this work for additional information regarding copyright
14 : : * ownership. The ASF licenses this file to you under the Apache
15 : : * License, Version 2.0 (the "License"); you may not use this file
16 : : * except in compliance with the License. You may obtain a copy of
17 : : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : : */
19 : :
20 : : #include "docxexport.hxx"
21 : : #include "docxexportfilter.hxx"
22 : : #include "docxattributeoutput.hxx"
23 : :
24 : : #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
25 : : #include <com/sun/star/document/XDocumentProperties.hpp>
26 : : #include <com/sun/star/i18n/ScriptType.hpp>
27 : : #include <com/sun/star/frame/XModel.hpp>
28 : :
29 : : #include <oox/token/tokens.hxx>
30 : : #include <oox/export/drawingml.hxx>
31 : : #include <oox/export/vmlexport.hxx>
32 : : #include <oox/export/chartexport.hxx>
33 : :
34 : : #include <map>
35 : : #include <algorithm>
36 : :
37 : : #include <IMark.hxx>
38 : : #include <docsh.hxx>
39 : : #include <ndtxt.hxx>
40 : : #include <wrtww8.hxx>
41 : : #include <fltini.hxx>
42 : : #include <fmtline.hxx>
43 : : #include <fmtpdsc.hxx>
44 : : #include <frmfmt.hxx>
45 : : #include <section.hxx>
46 : : #include <ftninfo.hxx>
47 : :
48 : : #include <editeng/editobj.hxx>
49 : : #include <editeng/outlobj.hxx>
50 : :
51 : : #include <docary.hxx>
52 : : #include <numrule.hxx>
53 : : #include <charfmt.hxx>
54 : : #include <viewsh.hxx>
55 : : #include <viewopt.hxx>
56 : :
57 : : #include "ww8par.hxx"
58 : : #include "ww8scan.hxx"
59 : :
60 : : #include <comphelper/string.hxx>
61 : : #include <rtl/ustrbuf.hxx>
62 : : #include <vcl/font.hxx>
63 : :
64 : : using namespace sax_fastparser;
65 : : using namespace ::comphelper;
66 : : using namespace ::com::sun::star;
67 : : using namespace ::oox;
68 : :
69 : : using oox::vml::VMLExport;
70 : :
71 : : using sw::mark::IMark;
72 : :
73 : 8361 : AttributeOutputBase& DocxExport::AttrOutput() const
74 : : {
75 : 8361 : return *m_pAttrOutput;
76 : : }
77 : :
78 : 0 : MSWordSections& DocxExport::Sections() const
79 : : {
80 : 0 : return *m_pSections;
81 : : }
82 : :
83 : 2178 : bool DocxExport::CollapseScriptsforWordOk( sal_uInt16 nScript, sal_uInt16 nWhich )
84 : : {
85 : : // TODO FIXME is this actually true for docx? - this is ~copied from WW8
86 [ - + ]: 2178 : if ( nScript == i18n::ScriptType::ASIAN )
87 : : {
88 : : // for asian in ww8, there is only one fontsize
89 : : // and one fontstyle (posture/weight)
90 [ # # ]: 0 : switch ( nWhich )
91 : : {
92 : : case RES_CHRATR_FONTSIZE:
93 : : case RES_CHRATR_POSTURE:
94 : : case RES_CHRATR_WEIGHT:
95 : 0 : return false;
96 : : default:
97 : 0 : break;
98 : : }
99 : : }
100 [ + - ]: 2178 : else if ( nScript != i18n::ScriptType::COMPLEX )
101 : : {
102 : : // for western in ww8, there is only one fontsize
103 : : // and one fontstyle (posture/weight)
104 [ + + ]: 2178 : switch ( nWhich )
105 : : {
106 : : case RES_CHRATR_CJK_FONTSIZE:
107 : : case RES_CHRATR_CJK_POSTURE:
108 : : case RES_CHRATR_CJK_WEIGHT:
109 : 375 : return false;
110 : : default:
111 : 1803 : break;
112 : : }
113 : : }
114 : 2178 : return true;
115 : : }
116 : :
117 : 264 : void DocxExport::AppendBookmarks( const SwTxtNode& rNode, xub_StrLen nAktPos, xub_StrLen nLen )
118 : : {
119 [ + - ]: 264 : std::vector< OUString > aStarts;
120 [ + - ]: 264 : std::vector< OUString > aEnds;
121 : :
122 [ + - ]: 264 : IMarkVector aMarks;
123 [ + - ][ + + ]: 264 : if ( GetBookmarks( rNode, nAktPos, nAktPos + nLen, aMarks ) )
124 : : {
125 [ + - ][ + - ]: 6 : for ( IMarkVector::const_iterator it = aMarks.begin(), end = aMarks.end();
[ + - ][ + - ]
[ + + ]
126 : : it != end; ++it )
127 : : {
128 [ + - ]: 3 : IMark* pMark = (*it);
129 : :
130 [ + - ]: 3 : xub_StrLen nStart = pMark->GetMarkStart().nContent.GetIndex();
131 [ + - ]: 3 : xub_StrLen nEnd = pMark->GetMarkEnd().nContent.GetIndex();
132 : :
133 [ + - ]: 3 : if ( nStart == nAktPos )
134 [ + - ][ + - ]: 3 : aStarts.push_back( pMark->GetName() );
135 : :
136 [ + - ]: 3 : if ( nEnd == nAktPos )
137 [ + - ][ + - ]: 3 : aEnds.push_back( pMark->GetName() );
138 : : }
139 : : }
140 : :
141 [ + - ]: 264 : m_pAttrOutput->WriteBookmarks_Impl( aStarts, aEnds );
142 : 264 : }
143 : :
144 : 0 : void DocxExport::AppendBookmark( const OUString& rName, bool /*bSkip*/ )
145 : : {
146 [ # # ]: 0 : std::vector< OUString > aStarts;
147 [ # # ]: 0 : std::vector< OUString > aEnds;
148 : :
149 [ # # ]: 0 : aStarts.push_back( rName );
150 [ # # ]: 0 : aEnds.push_back( rName );
151 : :
152 [ # # ]: 0 : m_pAttrOutput->WriteBookmarks_Impl( aStarts, aEnds );
153 : 0 : }
154 : :
155 : 0 : ::rtl::OString DocxExport::AddRelation( const OUString& rType, const OUString& rTarget )
156 : : {
157 : : OUString sId = m_pFilter->addRelation( m_pDocumentFS->getOutputStream(),
158 [ # # ][ # # ]: 0 : rType, rTarget, true );
159 : :
160 [ # # ]: 0 : return ::rtl::OUStringToOString( sId, RTL_TEXTENCODING_UTF8 );
161 : : }
162 : :
163 : 357 : bool DocxExport::DisallowInheritingOutlineNumbering( const SwFmt& rFmt )
164 : : {
165 : 357 : bool bRet( false );
166 : :
167 [ + - ]: 357 : if (SFX_ITEM_SET != rFmt.GetItemState(RES_PARATR_NUMRULE, false))
168 : : {
169 [ + - ]: 357 : if (const SwFmt *pParent = rFmt.DerivedFrom())
170 : : {
171 [ - + ]: 357 : if (((const SwTxtFmtColl*)pParent)->IsAssignedToListLevelOfOutlineStyle())
172 : : {
173 [ # # ]: 0 : ::sax_fastparser::FSHelperPtr pSerializer = m_pAttrOutput->GetSerializer( );
174 : : // Level 9 disables the outline
175 : : pSerializer->singleElementNS( XML_w, XML_outlineLvl,
176 : : FSNS( XML_w, XML_val ), "9" ,
177 [ # # ]: 0 : FSEND );
178 : :
179 [ # # ]: 0 : bRet = true;
180 : : }
181 : : }
182 : : }
183 : :
184 : 357 : return bRet;
185 : : }
186 : :
187 : 57 : void DocxExport::WriteHeadersFooters( sal_uInt8 nHeadFootFlags,
188 : : const SwFrmFmt& rFmt, const SwFrmFmt& rLeftFmt, const SwFrmFmt& rFirstPageFmt, sal_uInt8 /*nBreakCode*/ )
189 : : {
190 : : // headers
191 [ - + ]: 57 : if ( nHeadFootFlags & nsHdFtFlags::WW8_HEADER_EVEN )
192 : 0 : WriteHeaderFooter( rLeftFmt, true, "even" );
193 : :
194 [ - + ]: 57 : if ( nHeadFootFlags & nsHdFtFlags::WW8_HEADER_ODD )
195 : 0 : WriteHeaderFooter( rFmt, true, "default" );
196 : :
197 [ - + ]: 57 : if ( nHeadFootFlags & nsHdFtFlags::WW8_HEADER_FIRST )
198 : 0 : WriteHeaderFooter( rFirstPageFmt, true, "first" );
199 : :
200 : : // footers
201 [ - + ]: 57 : if ( nHeadFootFlags & nsHdFtFlags::WW8_FOOTER_EVEN )
202 : 0 : WriteHeaderFooter( rLeftFmt, false, "even" );
203 : :
204 [ - + ]: 57 : if ( nHeadFootFlags & nsHdFtFlags::WW8_FOOTER_ODD )
205 : 0 : WriteHeaderFooter( rFmt, false, "default" );
206 : :
207 [ - + ]: 57 : if ( nHeadFootFlags & nsHdFtFlags::WW8_FOOTER_FIRST )
208 : 0 : WriteHeaderFooter( rFirstPageFmt, false, "first" );
209 : :
210 [ - + ]: 57 : if ( nHeadFootFlags & ( nsHdFtFlags::WW8_FOOTER_EVEN | nsHdFtFlags::WW8_HEADER_EVEN ))
211 : 0 : settings.evenAndOddHeaders = true;
212 : :
213 : : #if OSL_DEBUG_LEVEL > 1
214 : : fprintf( stderr, "DocxExport::WriteHeadersFooters() - nBreakCode introduced, but ignored\n" );
215 : : #endif
216 : 57 : }
217 : :
218 : 3 : void DocxExport::OutputField( const SwField* pFld, ww::eField eFldType, const String& rFldCmd, sal_uInt8 nMode )
219 : : {
220 : 3 : m_pAttrOutput->WriteField_Impl( pFld, eFldType, rFldCmd, nMode );
221 : 3 : }
222 : :
223 : 0 : void DocxExport::WriteFormData( const ::sw::mark::IFieldmark& rFieldmark )
224 : : {
225 : 0 : m_pAttrOutput->WriteFormData_Impl( rFieldmark );
226 : 0 : }
227 : :
228 : 0 : void DocxExport::WriteHyperlinkData( const ::sw::mark::IFieldmark& /*rFieldmark*/ )
229 : : {
230 : : #if OSL_DEBUG_LEVEL > 1
231 : : fprintf( stderr, "TODO DocxExport::WriteHyperlinkData()\n" );
232 : : #endif
233 : 0 : }
234 : :
235 : 0 : void DocxExport::DoComboBox(const rtl::OUString& rName,
236 : : const rtl::OUString& rHelp,
237 : : const rtl::OUString& rToolTip,
238 : : const rtl::OUString& rSelected,
239 : : uno::Sequence<rtl::OUString>& rListItems)
240 : : {
241 : 0 : m_pDocumentFS->startElementNS( XML_w, XML_ffData, FSEND );
242 : :
243 : : m_pDocumentFS->singleElementNS( XML_w, XML_name,
244 : : FSNS( XML_w, XML_val ), OUStringToOString( rName, RTL_TEXTENCODING_UTF8 ).getStr(),
245 [ # # ]: 0 : FSEND );
246 : :
247 : 0 : m_pDocumentFS->singleElementNS( XML_w, XML_enabled, FSEND );
248 : :
249 [ # # ]: 0 : if ( !rHelp.isEmpty() )
250 : : m_pDocumentFS->singleElementNS( XML_w, XML_helpText,
251 : : FSNS( XML_w, XML_val ), OUStringToOString( rHelp, RTL_TEXTENCODING_UTF8 ).getStr(),
252 [ # # ]: 0 : FSEND );
253 : :
254 [ # # ]: 0 : if ( !rToolTip.isEmpty() )
255 : : m_pDocumentFS->singleElementNS( XML_w, XML_statusText,
256 : : FSNS( XML_w, XML_val ), OUStringToOString( rToolTip, RTL_TEXTENCODING_UTF8 ).getStr(),
257 [ # # ]: 0 : FSEND );
258 : :
259 : 0 : m_pDocumentFS->startElementNS( XML_w, XML_ddList, FSEND );
260 : :
261 : : // Output the 0-based index of the selected value
262 : 0 : sal_uInt32 nListItems = rListItems.getLength();
263 : 0 : sal_Int32 nId = 0;
264 : 0 : sal_uInt32 nI = 0;
265 [ # # ][ # # ]: 0 : while ( ( nI < nListItems ) && ( nId == 0 ) )
[ # # ]
266 : : {
267 [ # # ]: 0 : if ( rListItems[nI] == rSelected )
268 : 0 : nId = nI;
269 : 0 : nI++;
270 : : }
271 : :
272 : : m_pDocumentFS->singleElementNS( XML_w, XML_result,
273 : : FSNS( XML_w, XML_val ), rtl::OString::valueOf( nId ).getStr( ),
274 [ # # ]: 0 : FSEND );
275 : :
276 : : // Loop over the entries
277 : :
278 [ # # ]: 0 : for (sal_uInt32 i = 0; i < nListItems; i++)
279 : : {
280 : : m_pDocumentFS->singleElementNS( XML_w, XML_listEntry,
281 : 0 : FSNS( XML_w, XML_val ), OUStringToOString( rListItems[i], RTL_TEXTENCODING_UTF8 ).getStr(),
282 [ # # ]: 0 : FSEND );
283 : : }
284 : :
285 : 0 : m_pDocumentFS->endElementNS( XML_w, XML_ddList );
286 : :
287 : 0 : m_pDocumentFS->endElementNS( XML_w, XML_ffData );
288 : 0 : }
289 : :
290 : 0 : void DocxExport::DoFormText(const SwInputField* /*pFld*/)
291 : : {
292 : : OSL_TRACE( "TODO DocxExport::ForFormText()" );
293 : 0 : }
294 : :
295 : 0 : rtl::OString DocxExport::OutputChart( uno::Reference< frame::XModel >& xModel, sal_Int32 nCount )
296 : : {
297 [ # # ][ # # ]: 0 : rtl::OUString aFileName = rtl::OUStringBuffer().append("charts/chart").append(nCount).append(".xml").makeStringAndClear();
[ # # ][ # # ]
298 : :
299 : : OUString sId = m_pFilter->addRelation( m_pDocumentFS->getOutputStream(),
300 : : "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart",
301 [ # # ][ # # ]: 0 : aFileName );
302 : :
303 [ # # ][ # # ]: 0 : aFileName = rtl::OUStringBuffer().append("word/charts/chart").append(nCount).append(".xml").makeStringAndClear();
[ # # ][ # # ]
304 : :
305 : : ::sax_fastparser::FSHelperPtr pChartFS =
306 : : m_pFilter->openFragmentStreamWithSerializer( aFileName,
307 [ # # ]: 0 : "application/vnd.openxmlformats-officedocument.drawingml.chart" );
308 : :
309 [ # # ][ # # ]: 0 : oox::drawingml::ChartExport aChartExport( XML_w, pChartFS, xModel, m_pFilter, oox::drawingml::DrawingML::DOCUMENT_DOCX );
[ # # ]
310 [ # # ]: 0 : aChartExport.ExportContent();
311 [ # # ][ # # ]: 0 : return ::rtl::OUStringToOString( sId, RTL_TEXTENCODING_UTF8 );
[ # # ]
312 : : }
313 : :
314 : 57 : void DocxExport::ExportDocument_Impl()
315 : : {
316 : 57 : InitStyles();
317 : :
318 : : // init sections
319 [ + - ]: 57 : m_pSections = new MSWordSections( *this );
320 : :
321 : 57 : WriteMainText();
322 : :
323 : 57 : WriteFootnotesEndnotes();
324 : :
325 : 57 : WritePostitFields();
326 : :
327 : 57 : WriteNumbering();
328 : :
329 : 57 : WriteFonts();
330 : :
331 : 57 : WriteSettings();
332 : :
333 [ + - ]: 57 : delete pStyles, pStyles = NULL;
334 [ + - ]: 57 : delete m_pSections, m_pSections = NULL;
335 : 57 : }
336 : :
337 : 0 : void DocxExport::OutputPageSectionBreaks( const SwTxtNode& )
338 : : {
339 : : OSL_TRACE( "TODO DocxExport::OutputPageSectionBreaks( const SwTxtNode& )" );
340 : 0 : }
341 : :
342 : :
343 : 0 : void DocxExport::AppendSection( const SwPageDesc *pPageDesc, const SwSectionFmt* pFmt, sal_uLong nLnNum )
344 : : {
345 : 0 : AttrOutput().SectionBreak( msword::PageBreak, m_pSections->CurrentSectionInfo() );
346 : 0 : m_pSections->AppendSection( pPageDesc, pFmt, nLnNum );
347 : 0 : }
348 : :
349 : 57 : void DocxExport::OutputEndNode( const SwEndNode& rEndNode )
350 : : {
351 : 57 : MSWordExportBase::OutputEndNode( rEndNode );
352 : :
353 [ - + ][ - + ]: 57 : if ( TXT_MAINTEXT == nTxtTyp && rEndNode.StartOfSectionNode()->IsSectionNode() )
[ + - ]
354 : : {
355 : : // this originally comes from WW8Export::WriteText(), and looks like it
356 : : // could have some code common with SectionNode()...
357 : :
358 : 0 : const SwSection& rSect = rEndNode.StartOfSectionNode()->GetSectionNode()->GetSection();
359 [ # # ][ # # ]: 0 : if ( bStartTOX && TOX_CONTENT_SECTION == rSect.GetType() )
[ # # ]
360 : 0 : bStartTOX = false;
361 : :
362 [ # # ]: 0 : SwNodeIndex aIdx( rEndNode, 1 );
363 : 0 : const SwNode& rNd = aIdx.GetNode();
364 [ # # ][ # # ]: 0 : if ( rNd.IsEndNode() && rNd.StartOfSectionNode()->IsSectionNode() )
[ # # ]
365 : 57 : return;
366 : :
367 [ # # ]: 0 : bool isInTable = IsInTable();
368 [ # # ][ # # ]: 0 : if ( !rNd.IsSectionNode() && isInTable ) // No sections in table
[ # # ]
369 : : {
370 [ # # ]: 0 : const SwSectionFmt* pParentFmt = rSect.GetFmt()->GetParent();
371 [ # # ]: 0 : if( !pParentFmt )
372 : 0 : pParentFmt = (SwSectionFmt*)0xFFFFFFFF;
373 : :
374 : : sal_uLong nRstLnNum;
375 [ # # ]: 0 : if( rNd.IsCntntNode() )
376 [ # # ][ # # ]: 0 : nRstLnNum = const_cast< SwCntntNode* >( rNd.GetCntntNode() )->GetSwAttrSet().GetLineNumber().GetStartValue();
377 : : else
378 : 0 : nRstLnNum = 0;
379 : :
380 [ # # ][ # # ]: 0 : AttrOutput().SectionBreak( msword::PageBreak, m_pSections->CurrentSectionInfo( ) );
[ # # ]
381 [ # # ]: 0 : m_pSections->AppendSection( pAktPageDesc, pParentFmt, nRstLnNum );
382 [ # # ][ # # ]: 0 : }
383 : : }
384 : : }
385 : :
386 : 0 : void DocxExport::OutputTableNode( const SwTableNode& )
387 : : {
388 : : OSL_TRACE( "TODO DocxExport::OutputTableNode( const SwTableNode& )" );
389 : 0 : }
390 : :
391 : 0 : void DocxExport::OutputGrfNode( const SwGrfNode& )
392 : : {
393 : : OSL_TRACE( "TODO DocxExport::OutputGrfNode( const SwGrfNode& )" );
394 : 0 : }
395 : :
396 : 0 : void DocxExport::OutputOLENode( const SwOLENode& )
397 : : {
398 : : OSL_TRACE( "TODO DocxExport::OutputOLENode( const SwOLENode& )" );
399 : 0 : }
400 : :
401 : 0 : void DocxExport::OutputLinkedOLE( const OUString& )
402 : : {
403 : : // Nothing to implement here: WW8 only
404 : 0 : }
405 : :
406 : 0 : sal_uLong DocxExport::ReplaceCr( sal_uInt8 )
407 : : {
408 : : // Completely unused for Docx export... only here for code sharing
409 : : // purpose with binary export
410 : 0 : return 0;
411 : : }
412 : :
413 : 0 : void DocxExport::PrepareNewPageDesc( const SfxItemSet* pSet,
414 : : const SwNode& rNd, const SwFmtPageDesc* pNewPgDescFmt,
415 : : const SwPageDesc* pNewPgDesc )
416 : : {
417 : : // tell the attribute output that we are ready to write the section
418 : : // break [has to be output inside paragraph properties]
419 : 0 : AttrOutput().SectionBreak( msword::PageBreak, m_pSections->CurrentSectionInfo() );
420 : :
421 : 0 : const SwSectionFmt* pFmt = GetSectionFormat( rNd );
422 : 0 : const sal_uLong nLnNm = GetSectionLineNo( pSet, rNd );
423 : :
424 : : OSL_ENSURE( pNewPgDescFmt || pNewPgDesc, "Neither page desc format nor page desc provided." );
425 : :
426 [ # # ]: 0 : if ( pNewPgDescFmt )
427 : : {
428 : 0 : m_pSections->AppendSection( *pNewPgDescFmt, rNd, pFmt, nLnNm );
429 : : }
430 [ # # ]: 0 : else if ( pNewPgDesc )
431 : : {
432 [ # # ]: 0 : m_pSections->AppendSection( pNewPgDesc, rNd, pFmt, nLnNm );
433 : : }
434 : :
435 : 0 : }
436 : :
437 : 57 : void DocxExport::InitStyles()
438 : : {
439 [ + - ][ + - ]: 57 : pStyles = new MSWordStyles( *this );
440 : :
441 : : // setup word/styles.xml and the relations + content type
442 : : m_pFilter->addRelation( m_pDocumentFS->getOutputStream(),
443 : : "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles",
444 [ + - ][ + - ]: 57 : "styles.xml" );
445 : :
446 : : ::sax_fastparser::FSHelperPtr pStylesFS =
447 : : m_pFilter->openFragmentStreamWithSerializer( "word/styles.xml",
448 [ + - ]: 57 : "application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml" );
449 : :
450 : : // switch the serializer to redirect the output to word/styles.xml
451 [ + - ][ + - ]: 57 : m_pAttrOutput->SetSerializer( pStylesFS );
[ + - ]
452 : :
453 : : // do the work
454 [ + - ]: 57 : pStyles->OutputStylesTable();
455 : :
456 : : // switch the serializer back
457 [ + - ][ + - ]: 57 : m_pAttrOutput->SetSerializer( m_pDocumentFS );
[ + - ][ + - ]
458 : 57 : }
459 : :
460 : 57 : void DocxExport::WriteFootnotesEndnotes()
461 : : {
462 [ - + ]: 57 : if ( m_pAttrOutput->HasFootnotes() )
463 : : {
464 : : // setup word/styles.xml and the relations + content type
465 : : m_pFilter->addRelation( m_pDocumentFS->getOutputStream(),
466 : : "http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes",
467 [ # # ][ # # ]: 0 : "footnotes.xml" );
468 : :
469 : : ::sax_fastparser::FSHelperPtr pFootnotesFS =
470 : : m_pFilter->openFragmentStreamWithSerializer( "word/footnotes.xml",
471 [ # # ]: 0 : "application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml" );
472 : :
473 : : // switch the serializer to redirect the output to word/footnotes.xml
474 [ # # ][ # # ]: 0 : m_pAttrOutput->SetSerializer( pFootnotesFS );
[ # # ]
475 : :
476 : : // do the work
477 [ # # ]: 0 : m_pAttrOutput->FootnotesEndnotes( true );
478 : :
479 : : // switch the serializer back
480 [ # # ][ # # ]: 0 : m_pAttrOutput->SetSerializer( m_pDocumentFS );
[ # # ][ # # ]
481 : : }
482 : :
483 [ - + ]: 57 : if ( m_pAttrOutput->HasEndnotes() )
484 : : {
485 : : // setup word/styles.xml and the relations + content type
486 : : m_pFilter->addRelation( m_pDocumentFS->getOutputStream(),
487 : : "http://schemas.openxmlformats.org/officeDocument/2006/relationships/endnotes",
488 [ # # ][ # # ]: 0 : "endnotes.xml" );
489 : :
490 : : ::sax_fastparser::FSHelperPtr pEndnotesFS =
491 : : m_pFilter->openFragmentStreamWithSerializer( "word/endnotes.xml",
492 [ # # ]: 0 : "application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml" );
493 : :
494 : : // switch the serializer to redirect the output to word/endnotes.xml
495 [ # # ][ # # ]: 0 : m_pAttrOutput->SetSerializer( pEndnotesFS );
[ # # ]
496 : :
497 : : // do the work
498 [ # # ]: 0 : m_pAttrOutput->FootnotesEndnotes( false );
499 : :
500 : : // switch the serializer back
501 [ # # ][ # # ]: 0 : m_pAttrOutput->SetSerializer( m_pDocumentFS );
[ # # ][ # # ]
502 : : }
503 : 57 : }
504 : :
505 : 57 : void DocxExport::WritePostitFields()
506 : : {
507 [ + + ]: 57 : if ( m_pAttrOutput->HasPostitFields() )
508 : : {
509 : : m_pFilter->addRelation( m_pDocumentFS->getOutputStream(),
510 : : "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments",
511 [ + - ][ + - ]: 3 : "comments.xml" );
512 : :
513 : : ::sax_fastparser::FSHelperPtr pPostitFS =
514 : : m_pFilter->openFragmentStreamWithSerializer( "word/comments.xml",
515 [ + - ]: 3 : "application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml" );
516 : :
517 [ + - ][ + - ]: 3 : pPostitFS->startElementNS( XML_w, XML_comments, MainXmlNamespaces( pPostitFS ));
[ + - ][ + - ]
518 [ + - ][ + - ]: 3 : m_pAttrOutput->SetSerializer( pPostitFS );
[ + - ]
519 [ + - ]: 3 : m_pAttrOutput->WritePostitFields();
520 [ + - ][ + - ]: 3 : m_pAttrOutput->SetSerializer( m_pDocumentFS );
[ + - ]
521 [ + - ][ + - ]: 3 : pPostitFS->endElementNS( XML_w, XML_comments );
522 : : }
523 : 57 : }
524 : :
525 : 57 : void DocxExport::WriteNumbering()
526 : : {
527 [ - + ]: 57 : if ( !pUsedNumTbl )
528 : 57 : return; // no numbering is used
529 : :
530 : : m_pFilter->addRelation( m_pDocumentFS->getOutputStream(),
531 : : "http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering",
532 [ # # ][ # # ]: 0 : "numbering.xml" );
533 : :
534 : : ::sax_fastparser::FSHelperPtr pNumberingFS = m_pFilter->openFragmentStreamWithSerializer( "word/numbering.xml",
535 [ # # ]: 0 : "application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml" );
536 : :
537 : : // switch the serializer to redirect the output to word/nubering.xml
538 [ # # ][ # # ]: 0 : m_pAttrOutput->SetSerializer( pNumberingFS );
[ # # ]
539 : :
540 : : pNumberingFS->startElementNS( XML_w, XML_numbering,
541 : : FSNS( XML_xmlns, XML_w ), "http://schemas.openxmlformats.org/wordprocessingml/2006/main",
542 [ # # ]: 0 : FSEND );
543 : :
544 [ # # ]: 0 : AbstractNumberingDefinitions();
545 : :
546 [ # # ]: 0 : NumberingDefinitions();
547 : :
548 [ # # ]: 0 : pNumberingFS->endElementNS( XML_w, XML_numbering );
549 : :
550 : : // switch the serializer back
551 [ # # ][ # # ]: 57 : m_pAttrOutput->SetSerializer( m_pDocumentFS );
[ # # ][ # # ]
552 : : }
553 : :
554 : 0 : void DocxExport::WriteHeaderFooter( const SwFmt& rFmt, bool bHeader, const char* pType )
555 : : {
556 : : // setup the xml stream
557 : 0 : OUString aRelId;
558 [ # # ]: 0 : ::sax_fastparser::FSHelperPtr pFS;
559 [ # # ]: 0 : if ( bHeader )
560 : : {
561 [ # # ][ # # ]: 0 : OUString aName( OUStringBuffer().append("header").append( ++m_nHeaders ).append(".xml").makeStringAndClear() );
[ # # ][ # # ]
562 : :
563 : : aRelId = m_pFilter->addRelation( m_pDocumentFS->getOutputStream(),
564 : : "http://schemas.openxmlformats.org/officeDocument/2006/relationships/header",
565 [ # # ][ # # ]: 0 : aName );
566 : :
567 [ # # ][ # # ]: 0 : pFS = m_pFilter->openFragmentStreamWithSerializer( OUStringBuffer().append("word/").append( aName ).makeStringAndClear(),
568 [ # # ][ # # ]: 0 : "application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml" );
[ # # ][ # # ]
569 : :
570 [ # # ][ # # ]: 0 : pFS->startElementNS( XML_w, XML_hdr, MainXmlNamespaces( pFS ));
[ # # ][ # # ]
571 : : }
572 : : else
573 : : {
574 [ # # ][ # # ]: 0 : OUString aName( OUStringBuffer().append("footer").append( ++m_nFooters ).append(".xml").makeStringAndClear() );
[ # # ][ # # ]
575 : :
576 : : aRelId = m_pFilter->addRelation( m_pDocumentFS->getOutputStream(),
577 : : "http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer",
578 [ # # ][ # # ]: 0 : aName );
579 : :
580 [ # # ][ # # ]: 0 : pFS = m_pFilter->openFragmentStreamWithSerializer( OUStringBuffer().append("word/").append( aName ).makeStringAndClear(),
581 [ # # ][ # # ]: 0 : "application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml" );
[ # # ][ # # ]
582 : :
583 [ # # ][ # # ]: 0 : pFS->startElementNS( XML_w, XML_ftr, MainXmlNamespaces( pFS ));
[ # # ][ # # ]
584 : : }
585 : :
586 : : // switch the serializer to redirect the output to word/styles.xml
587 [ # # ][ # # ]: 0 : m_pAttrOutput->SetSerializer( pFS );
[ # # ]
588 : :
589 : : // do the work
590 [ # # ]: 0 : WriteHeaderFooterText( rFmt, bHeader );
591 : :
592 : : // switch the serializer back
593 [ # # ][ # # ]: 0 : m_pAttrOutput->SetSerializer( m_pDocumentFS );
[ # # ]
594 : :
595 : : // close the tag
596 : : sal_Int32 nReference;
597 [ # # ]: 0 : if ( bHeader )
598 : : {
599 [ # # ]: 0 : pFS->endElementNS( XML_w, XML_hdr );
600 : 0 : nReference = XML_headerReference;
601 : : }
602 : : else
603 : : {
604 [ # # ]: 0 : pFS->endElementNS( XML_w, XML_ftr );
605 : 0 : nReference = XML_footerReference;
606 : : }
607 : :
608 : : // and write the reference
609 : : m_pDocumentFS->singleElementNS( XML_w, nReference,
610 : : FSNS( XML_w, XML_type ), pType,
611 : : FSNS( XML_r, XML_id ), rtl::OUStringToOString( aRelId, RTL_TEXTENCODING_UTF8 ).getStr(),
612 [ # # ][ # # ]: 0 : FSEND );
[ # # ]
613 : 0 : }
614 : :
615 : 57 : void DocxExport::WriteFonts()
616 : : {
617 : : m_pFilter->addRelation( m_pDocumentFS->getOutputStream(),
618 : : "http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable",
619 [ + - ][ + - ]: 57 : "fontTable.xml" );
620 : :
621 : : ::sax_fastparser::FSHelperPtr pFS = m_pFilter->openFragmentStreamWithSerializer(
622 : : "word/fontTable.xml",
623 [ + - ]: 57 : "application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml" );
624 : :
625 : : pFS->startElementNS( XML_w, XML_fonts,
626 : : FSNS( XML_xmlns, XML_w ), "http://schemas.openxmlformats.org/wordprocessingml/2006/main",
627 [ + - ]: 57 : FSEND );
628 : :
629 : : // switch the serializer to redirect the output to word/styles.xml
630 [ + - ][ + - ]: 57 : m_pAttrOutput->SetSerializer( pFS );
[ + - ]
631 : :
632 : : // do the work
633 [ + - ]: 57 : maFontHelper.WriteFontTable( *m_pAttrOutput );
634 : :
635 : : // switch the serializer back
636 [ + - ][ + - ]: 57 : m_pAttrOutput->SetSerializer( m_pDocumentFS );
[ + - ]
637 : :
638 [ + - ][ + - ]: 57 : pFS->endElementNS( XML_w, XML_fonts );
639 : 57 : }
640 : :
641 : :
642 : 57 : void DocxExport::WriteProperties( )
643 : : {
644 : : // Write the core properties
645 : 57 : SwDocShell* pDocShell( pDoc->GetDocShell( ) );
646 : 57 : uno::Reference<document::XDocumentProperties> xDocProps;
647 [ + - ]: 57 : if ( pDocShell )
648 : : {
649 : : uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
650 [ + - ][ + - ]: 57 : pDocShell->GetModel( ), uno::UNO_QUERY );
651 [ + - ][ + - ]: 57 : xDocProps = xDPS->getDocumentProperties();
[ + - ]
652 : : }
653 : :
654 [ + - ]: 57 : m_pFilter->exportDocumentProperties( xDocProps );
655 : 57 : }
656 : :
657 : 57 : void DocxExport::WriteSettings()
658 : : {
659 [ + - ]: 57 : ViewShell *pViewShell(pDoc->GetCurrentViewShell());
660 [ - + ][ # # ]: 57 : if( !pViewShell && !settings.hasData() && !m_pAttrOutput->HasFootnotes() && !m_pAttrOutput->HasEndnotes())
[ # # ][ # # ]
[ # # ][ # # ]
[ + - ]
661 : 57 : return;
662 : :
663 : : m_pFilter->addRelation( m_pDocumentFS->getOutputStream(),
664 : : "http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings",
665 [ + - ][ + - ]: 57 : "settings.xml" );
666 : :
667 : : ::sax_fastparser::FSHelperPtr pFS = m_pFilter->openFragmentStreamWithSerializer(
668 : : "word/settings.xml",
669 [ + - ]: 57 : "application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml" );
670 : :
671 : : pFS->startElementNS( XML_w, XML_settings,
672 : : FSNS( XML_xmlns, XML_w ), "http://schemas.openxmlformats.org/wordprocessingml/2006/main",
673 [ + - ]: 57 : FSEND );
674 : :
675 : : // Zoom
676 : 57 : rtl::OString aZoom(rtl::OString::valueOf(sal_Int32(pViewShell->GetViewOptions()->GetZoom())));
677 [ + - ]: 57 : pFS->singleElementNS(XML_w, XML_zoom, FSNS(XML_w, XML_percent), aZoom.getStr(), FSEND);
678 : :
679 [ + + ]: 57 : if( settings.defaultTabStop != 0 )
680 : : pFS->singleElementNS( XML_w, XML_defaultTabStop, FSNS( XML_w, XML_val ),
681 [ + - ]: 15 : rtl::OString::valueOf( sal_Int32( settings.defaultTabStop )).getStr(), FSEND );
682 [ - + ]: 57 : if( settings.evenAndOddHeaders )
683 [ # # ]: 0 : pFS->singleElementNS( XML_w, XML_evenAndOddHeaders, FSEND );
684 : :
685 [ + - ][ - + ]: 57 : if( m_pAttrOutput->HasFootnotes())
686 [ # # ][ # # ]: 0 : m_pAttrOutput->WriteFootnoteEndnotePr( pFS, XML_footnotePr, pDoc->GetFtnInfo(), XML_footnote );
[ # # ]
687 [ + - ][ - + ]: 57 : if( m_pAttrOutput->HasEndnotes())
688 [ # # ][ # # ]: 0 : m_pAttrOutput->WriteFootnoteEndnotePr( pFS, XML_endnotePr, pDoc->GetEndNoteInfo(), XML_endnote );
[ # # ]
689 : :
690 [ + - ][ + - ]: 57 : pFS->endElementNS( XML_w, XML_settings );
691 : : }
692 : :
693 : 0 : VMLExport& DocxExport::VMLExporter()
694 : : {
695 : 0 : return *m_pVMLExport;
696 : : }
697 : :
698 : 57 : void DocxExport::WriteMainText()
699 : : {
700 : : // setup the namespaces
701 [ + - ][ + - ]: 57 : m_pDocumentFS->startElementNS( XML_w, XML_document, MainXmlNamespaces( m_pDocumentFS ));
702 : :
703 : : // body
704 : 57 : m_pDocumentFS->startElementNS( XML_w, XML_body, FSEND );
705 : :
706 : 57 : pCurPam->GetPoint()->nNode = pDoc->GetNodes().GetEndOfContent().StartOfSectionNode()->GetIndex();
707 : :
708 : : // the text
709 : 57 : WriteText();
710 : :
711 : : // the last section info
712 [ + - ]: 57 : const WW8_SepInfo *pSectionInfo = m_pSections? m_pSections->CurrentSectionInfo(): NULL;
713 [ + - ]: 57 : if ( pSectionInfo )
714 : 57 : SectionProperties( *pSectionInfo );
715 : :
716 : : // finish body and document
717 : 57 : m_pDocumentFS->endElementNS( XML_w, XML_body );
718 : 57 : m_pDocumentFS->endElementNS( XML_w, XML_document );
719 : 57 : }
720 : :
721 : 60 : XFastAttributeListRef DocxExport::MainXmlNamespaces( FSHelperPtr serializer )
722 : : {
723 : 60 : FastAttributeList* pAttr = serializer->createAttrList();
724 [ + - ]: 60 : pAttr->add( FSNS( XML_xmlns, XML_o ), "urn:schemas-microsoft-com:office:office" );
725 [ + - ]: 60 : pAttr->add( FSNS( XML_xmlns, XML_r ), "http://schemas.openxmlformats.org/officeDocument/2006/relationships" );
726 [ + - ]: 60 : pAttr->add( FSNS( XML_xmlns, XML_v ), "urn:schemas-microsoft-com:vml" );
727 [ + - ]: 60 : pAttr->add( FSNS( XML_xmlns, XML_w ), "http://schemas.openxmlformats.org/wordprocessingml/2006/main" );
728 [ + - ]: 60 : pAttr->add( FSNS( XML_xmlns, XML_w10 ), "urn:schemas-microsoft-com:office:word" );
729 [ + - ]: 60 : pAttr->add( FSNS( XML_xmlns, XML_wp ), "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" );
730 [ + - ]: 60 : return XFastAttributeListRef( pAttr );
731 : : }
732 : :
733 : 960 : bool DocxExport::ignoreAttributeForStyles( sal_uInt16 nWhich ) const
734 : : {
735 [ - + ]: 960 : if( nWhich == RES_TEXTGRID )
736 : 0 : return true; // w:docGrid is written only to document.xml, not to styles.xml
737 : 960 : return MSWordExportBase::ignoreAttributeForStyles( nWhich );
738 : : }
739 : :
740 : 3 : void DocxExport::WriteOutliner(const OutlinerParaObject& rParaObj, sal_uInt8 nTyp)
741 : : {
742 [ + - ]: 3 : const EditTextObject& rEditObj = rParaObj.GetTextObject();
743 [ + - ]: 3 : MSWord_SdrAttrIter aAttrIter( *this, rEditObj, nTyp );
744 : :
745 [ + - ]: 3 : sal_uInt16 nPara = rEditObj.GetParagraphCount();
746 [ + + ]: 6 : for( sal_uInt16 n = 0; n < nPara; ++n )
747 : : {
748 [ - + ]: 3 : if( n )
749 [ # # ]: 0 : aAttrIter.NextPara( n );
750 : :
751 [ + - ][ + - ]: 3 : AttrOutput().StartParagraph( ww8::WW8TableNodeInfo::Pointer_t());
[ + - ][ + - ]
752 : 3 : rtl_TextEncoding eChrSet = aAttrIter.GetNodeCharSet();
753 [ + - ]: 3 : String aStr( rEditObj.GetText( n ));
754 : 3 : xub_StrLen nAktPos = 0;
755 : 3 : xub_StrLen nEnd = aStr.Len();
756 [ - + ]: 3 : do {
757 [ + - ][ + - ]: 3 : AttrOutput().StartRun( NULL );
758 : 3 : xub_StrLen nNextAttr = aAttrIter.WhereNext();
759 [ + - ]: 3 : rtl_TextEncoding eNextChrSet = aAttrIter.GetNextCharSet();
760 : :
761 [ + - ]: 3 : if( nNextAttr > nEnd )
762 : 3 : nNextAttr = nEnd;
763 : :
764 [ + - ]: 3 : bool bTxtAtr = aAttrIter.IsTxtAttr( nAktPos );
765 [ + - ]: 3 : if( !bTxtAtr )
766 : : {
767 [ + - ][ + - ]: 3 : if( nAktPos == 0 && nNextAttr - nAktPos == aStr.Len())
[ + - ]
768 [ + - ][ + - ]: 3 : AttrOutput().RunText( aStr, eChrSet );
769 : : else
770 : : {
771 [ # # ]: 0 : String tmp( aStr.Copy( nAktPos, nNextAttr - nAktPos ));
772 [ # # ][ # # ]: 0 : AttrOutput().RunText( tmp, eChrSet );
[ # # ]
773 : : }
774 : : }
775 [ + - ][ + - ]: 3 : AttrOutput().StartRunProperties();
776 [ + - ]: 3 : aAttrIter.OutAttr( nAktPos );
777 [ + - ][ + - ]: 3 : AttrOutput().EndRunProperties( NULL );
778 : :
779 : 3 : nAktPos = nNextAttr;
780 : 3 : eChrSet = eNextChrSet;
781 [ + - ]: 3 : aAttrIter.NextPos();
782 [ + - ][ + - ]: 3 : AttrOutput().EndRun();
783 : : } while( nAktPos < nEnd );
784 : : // aAttrIter.OutParaAttr(false);
785 [ + - ][ + - ]: 3 : AttrOutput().EndParagraph( ww8::WW8TableNodeInfoInner::Pointer_t());
[ + - ][ + - ]
786 [ + - ][ + - ]: 6 : }
787 : 3 : }
788 : :
789 : 57 : DocxExport::DocxExport( DocxExportFilter *pFilter, SwDoc *pDocument, SwPaM *pCurrentPam, SwPaM *pOriginalPam )
790 : : : MSWordExportBase( pDocument, pCurrentPam, pOriginalPam ),
791 : : m_pFilter( pFilter ),
792 : : m_pAttrOutput( NULL ),
793 : : m_pSections( NULL ),
794 : : m_nHeaders( 0 ),
795 : : m_nFooters( 0 ),
796 [ + - ]: 57 : m_pVMLExport( NULL )
797 : : {
798 : : // Write the document properies
799 [ + - ]: 57 : WriteProperties( );
800 : :
801 : : // relations for the document
802 : : m_pFilter->addRelation( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument",
803 [ + - ]: 57 : "word/document.xml" );
804 : :
805 : : // the actual document
806 : : m_pDocumentFS = m_pFilter->openFragmentStreamWithSerializer( "word/document.xml",
807 [ + - ][ + - ]: 57 : "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml" );
[ + - ]
808 : :
809 : : // the DrawingML access
810 [ + - ][ + - ]: 57 : m_pDrawingML = new oox::drawingml::DrawingML( m_pDocumentFS, m_pFilter, oox::drawingml::DrawingML::DOCUMENT_DOCX );
[ + - ][ + - ]
811 : :
812 : : // the attribute output for the document
813 [ + - ][ + - ]: 57 : m_pAttrOutput = new DocxAttributeOutput( *this, m_pDocumentFS, m_pDrawingML );
[ + - ][ + - ]
814 : :
815 : : // the related VMLExport
816 [ + - ][ + - ]: 57 : m_pVMLExport = new VMLExport( m_pDocumentFS, m_pAttrOutput );
[ + - ][ + - ]
[ + - ]
817 : 57 : }
818 : :
819 [ + - ]: 57 : DocxExport::~DocxExport()
820 : : {
821 [ + - ][ + - ]: 57 : delete m_pVMLExport, m_pVMLExport = NULL;
822 [ + - ][ + - ]: 57 : delete m_pAttrOutput, m_pAttrOutput = NULL;
823 [ + - ][ + - ]: 57 : delete m_pDrawingML, m_pDrawingML = NULL;
824 [ - + ]: 57 : }
825 : :
826 : 57 : DocxSettingsData::DocxSettingsData()
827 : : : evenAndOddHeaders( false )
828 : 57 : , defaultTabStop( 0 )
829 : : {
830 : 57 : }
831 : :
832 : 0 : bool DocxSettingsData::hasData() const
833 : : {
834 [ # # ]: 0 : if( evenAndOddHeaders )
835 : 0 : return true;
836 [ # # ]: 0 : if( defaultTabStop != 0 )
837 : 0 : return true;
838 : 0 : return false;
839 [ + - ][ + - ]: 54 : }
840 : :
841 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|