| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| #include "docxattributeoutput.hxx" |
| #include "docxexport.hxx" |
| #include "docxfootnotes.hxx" |
| #include "writerwordglue.hxx" |
| #include "wrtww8.hxx" |
| #include "ww8par.hxx" |
| |
| #include <oox/token/tokens.hxx> |
| #include <oox/export/drawingml.hxx> |
| #include <oox/export/utils.hxx> |
| #include <oox/export/vmlexport.hxx> |
| |
| #include <i18npool/mslangid.hxx> |
| |
| #include <hintids.hxx> |
| |
| #include <svl/poolitem.hxx> |
| |
| #include <editeng/fontitem.hxx> |
| #include <editeng/tstpitem.hxx> |
| #include <editeng/adjitem.hxx> |
| #include <editeng/spltitem.hxx> |
| #include <editeng/widwitem.hxx> |
| #include <editeng/lspcitem.hxx> |
| #include <editeng/keepitem.hxx> |
| #include <editeng/shaditem.hxx> |
| #include <editeng/brshitem.hxx> |
| #include <editeng/postitem.hxx> |
| #include <editeng/wghtitem.hxx> |
| #include <editeng/kernitem.hxx> |
| #include <editeng/crsditem.hxx> |
| #include <editeng/cmapitem.hxx> |
| #include <editeng/wrlmitem.hxx> |
| #include <editeng/udlnitem.hxx> |
| #include <editeng/langitem.hxx> |
| #include <editeng/escpitem.hxx> |
| #include <editeng/fhgtitem.hxx> |
| #include <editeng/colritem.hxx> |
| #include <editeng/hyznitem.hxx> |
| #include <editeng/brkitem.hxx> |
| #include <editeng/lrspitem.hxx> |
| #include <editeng/ulspitem.hxx> |
| #include <editeng/boxitem.hxx> |
| #include <editeng/cntritem.hxx> |
| #include <editeng/shdditem.hxx> |
| #include <editeng/akrnitem.hxx> |
| #include <editeng/pbinitem.hxx> |
| #include <editeng/emphitem.hxx> |
| #include <editeng/twolinesitem.hxx> |
| #include <editeng/charscaleitem.hxx> |
| #include <editeng/charrotateitem.hxx> |
| #include <editeng/charreliefitem.hxx> |
| #include <editeng/paravertalignitem.hxx> |
| #include <editeng/pgrditem.hxx> |
| #include <editeng/frmdiritem.hxx> |
| #include <editeng/blnkitem.hxx> |
| #include <editeng/charhiddenitem.hxx> |
| #include <svx/svdmodel.hxx> |
| #include <svx/svdobj.hxx> |
| |
| #include <docufld.hxx> |
| #include <flddropdown.hxx> |
| #include <format.hxx> |
| #include <fmtclds.hxx> |
| #include <fmtinfmt.hxx> |
| #include <fmtfld.hxx> |
| #include <fmtfsize.hxx> |
| #include <fmtftn.hxx> |
| #include <fmtrowsplt.hxx> |
| #include <fmtline.hxx> |
| #include <frmfmt.hxx> |
| #include <frmatr.hxx> |
| #include <ftninfo.hxx> |
| #include <htmltbl.hxx> |
| #include <ndgrf.hxx> |
| #include <ndtxt.hxx> |
| #include <node.hxx> |
| #include <pagedesc.hxx> |
| #include <paratr.hxx> |
| #include <swmodule.hxx> |
| #include <swtable.hxx> |
| #include <txtftn.hxx> |
| #include <txtinet.hxx> |
| #include <numrule.hxx> |
| |
| #include <rtl/strbuf.hxx> |
| #include <rtl/ustrbuf.hxx> |
| #include <rtl/ustring.hxx> |
| |
| #include <tools/color.hxx> |
| |
| #include <com/sun/star/i18n/ScriptType.hdl> |
| |
| #if OSL_DEBUG_LEVEL > 0 |
| #include <stdio.h> |
| #endif |
| |
| using rtl::OString; |
| using rtl::OStringBuffer; |
| using rtl::OUString; |
| using rtl::OUStringBuffer; |
| using rtl::OUStringToOString; |
| |
| using namespace oox; |
| using namespace docx; |
| using namespace sax_fastparser; |
| using namespace nsSwDocInfoSubType; |
| using namespace nsFieldFlags; |
| using namespace sw::util; |
| |
| void DocxAttributeOutput::RTLAndCJKState( bool bIsRTL, sal_uInt16 /*nScript*/ ) |
| { |
| if (bIsRTL) |
| m_pSerializer->singleElementNS( XML_w, XML_rtl, FSNS( XML_w, XML_val ), "true", FSEND ); |
| } |
| |
| void DocxAttributeOutput::StartParagraph( ww8::WW8TableNodeInfo::Pointer_t pTextNodeInfo ) |
| { |
| if ( m_nColBreakStatus == COLBRK_POSTPONE ) |
| m_nColBreakStatus = COLBRK_WRITE; |
| |
| // Output table/table row/table cell starts if needed |
| if ( pTextNodeInfo.get() ) |
| { |
| sal_uInt32 nRow = pTextNodeInfo->getRow(); |
| sal_uInt32 nCell = pTextNodeInfo->getCell(); |
| |
| // New cell/row? |
| if ( m_nTableDepth > 0 && !m_bTableCellOpen ) |
| { |
| ww8::WW8TableNodeInfoInner::Pointer_t pDeepInner( pTextNodeInfo->getInnerForDepth( m_nTableDepth ) ); |
| if ( pDeepInner->getCell() == 0 ) |
| StartTableRow( pDeepInner ); |
| |
| StartTableCell( pDeepInner ); |
| } |
| |
| if ( nRow == 0 && nCell == 0 ) |
| { |
| // Do we have to start the table? |
| // [If we are at the rigth depth already, it means that we |
| // continue the table cell] |
| sal_uInt32 nCurrentDepth = pTextNodeInfo->getDepth(); |
| |
| if ( nCurrentDepth > m_nTableDepth ) |
| { |
| // Start all the tables that begin here |
| for ( sal_uInt32 nDepth = m_nTableDepth + 1; nDepth <= pTextNodeInfo->getDepth(); ++nDepth ) |
| { |
| ww8::WW8TableNodeInfoInner::Pointer_t pInner( pTextNodeInfo->getInnerForDepth( nDepth ) ); |
| |
| StartTable( pInner ); |
| StartTableRow( pInner ); |
| StartTableCell( pInner ); |
| } |
| |
| m_nTableDepth = nCurrentDepth; |
| } |
| } |
| } |
| |
| m_pSerializer->startElementNS( XML_w, XML_p, FSEND ); |
| |
| // postpone the output of the run (we get it before the paragraph |
| // properties, but must write it after them) |
| m_pSerializer->mark(); |
| |
| // no section break in this paragraph yet; can be set in SectionBreak() |
| m_pSectionInfo = NULL; |
| |
| m_bParagraphOpened = true; |
| } |
| |
| void DocxAttributeOutput::EndParagraph( ww8::WW8TableNodeInfoInner::Pointer_t pTextNodeInfoInner ) |
| { |
| // write the paragraph properties + the run, already in the correct order |
| m_pSerializer->mergeTopMarks(); |
| m_pSerializer->endElementNS( XML_w, XML_p ); |
| |
| // Check for end of cell, rows, tables here |
| FinishTableRowCell( pTextNodeInfoInner ); |
| |
| m_bParagraphOpened = false; |
| } |
| |
| void DocxAttributeOutput::FinishTableRowCell( ww8::WW8TableNodeInfoInner::Pointer_t pInner, bool bForceEmptyParagraph ) |
| { |
| if ( pInner.get() ) |
| { |
| // Where are we in the table |
| sal_uInt32 nRow = pInner->getRow( ); |
| |
| const SwTable *pTable = pInner->getTable( ); |
| const SwTableLines& rLines = pTable->GetTabLines( ); |
| sal_uInt16 nLinesCount = rLines.Count( ); |
| |
| if ( pInner->isEndOfCell() ) |
| { |
| if ( bForceEmptyParagraph ) |
| m_pSerializer->singleElementNS( XML_w, XML_p, FSEND ); |
| |
| EndTableCell(); |
| } |
| |
| // This is a line end |
| if ( pInner->isEndOfLine() ) |
| EndTableRow(); |
| |
| // This is the end of the table |
| if ( pInner->isEndOfLine( ) && ( nRow + 1 ) == nLinesCount ) |
| EndTable(); |
| } |
| } |
| |
| void DocxAttributeOutput::EmptyParagraph() |
| { |
| m_pSerializer->singleElementNS( XML_w, XML_p, FSEND ); |
| } |
| |
| void DocxAttributeOutput::StartParagraphProperties( const SwTxtNode& rNode ) |
| { |
| // output page/section breaks |
| // Writer can have them at the beginning of a paragraph, or at the end, but |
| // in docx, we have to output them in the paragraph properties of the last |
| // paragraph in a section. To get it right, we have to switch to the next |
| // paragraph, and detect the section breaks there. |
| SwNodeIndex aNextIndex( rNode, 1 ); |
| if ( aNextIndex.GetNode().IsTxtNode() ) |
| { |
| const SwTxtNode* pTxtNode = static_cast< SwTxtNode* >( &aNextIndex.GetNode() ); |
| m_rExport.OutputSectionBreaks( pTxtNode->GetpSwAttrSet(), *pTxtNode ); |
| } |
| else if ( aNextIndex.GetNode().IsTableNode() ) |
| { |
| const SwTableNode* pTableNode = static_cast< SwTableNode* >( &aNextIndex.GetNode() ); |
| const SwFrmFmt *pFmt = pTableNode->GetTable().GetFrmFmt(); |
| m_rExport.OutputSectionBreaks( &(pFmt->GetAttrSet()), *pTableNode ); |
| } |
| |
| // postpone the output so that we can later [in EndParagraphProperties()] |
| // prepend the properties before the run |
| m_pSerializer->mark(); |
| |
| m_pSerializer->startElementNS( XML_w, XML_pPr, FSEND ); |
| |
| // and output the section break now (if it appeared) |
| if ( m_pSectionInfo ) |
| { |
| m_rExport.SectionProperties( *m_pSectionInfo ); |
| m_pSectionInfo = NULL; |
| } |
| |
| InitCollectedParagraphProperties(); |
| } |
| |
| void DocxAttributeOutput::InitCollectedParagraphProperties() |
| { |
| m_pSpacingAttrList = NULL; |
| } |
| |
| void DocxAttributeOutput::WriteCollectedParagraphProperties() |
| { |
| if ( m_pSpacingAttrList ) |
| { |
| XFastAttributeListRef xAttrList( m_pSpacingAttrList ); |
| m_pSpacingAttrList = NULL; |
| |
| m_pSerializer->singleElementNS( XML_w, XML_spacing, xAttrList ); |
| } |
| } |
| |
| void DocxAttributeOutput::EndParagraphProperties() |
| { |
| WriteCollectedParagraphProperties(); |
| |
| m_pSerializer->endElementNS( XML_w, XML_pPr ); |
| |
| if ( m_nColBreakStatus == COLBRK_WRITE ) |
| { |
| m_pSerializer->startElementNS( XML_w, XML_r, FSEND ); |
| m_pSerializer->singleElementNS( XML_w, XML_br, |
| FSNS( XML_w, XML_type ), "column", FSEND ); |
| m_pSerializer->endElementNS( XML_w, XML_r ); |
| |
| m_nColBreakStatus = COLBRK_NONE; |
| } |
| |
| // merge the properties _before_ the run (strictly speaking, just |
| // after the start of the paragraph) |
| m_pSerializer->mergeTopMarks( sax_fastparser::MERGE_MARKS_PREPEND ); |
| } |
| |
| void DocxAttributeOutput::StartRun( const SwRedlineData* pRedlineData ) |
| { |
| // if there is some redlining in the document, output it |
| StartRedline( pRedlineData ); |
| |
| // postpone the output of the start of a run (there are elements that need |
| // to be written before the start of the run, but we learn which they are |
| // _inside_ of the run) |
| m_pSerializer->mark(); // let's call it "postponed run start" |
| |
| // postpone the output of the text (we get it before the run properties, |
| // but must write it after them) |
| m_pSerializer->mark(); // let's call it "postponed text" |
| } |
| |
| void DocxAttributeOutput::EndRun() |
| { |
| // Write field starts |
| for ( std::vector<FieldInfos>::iterator pIt = m_Fields.begin(); pIt != m_Fields.end(); ++pIt ) |
| { |
| // Add the fields starts for all but hyperlinks and TOCs |
| if ( pIt->bOpen && pIt->pField ) |
| { |
| StartField_Impl( *pIt ); |
| |
| // Remove the field from the stack if only the start has to be written |
| // Unknown fields sould be removed too |
| if ( !pIt->bClose || ( pIt->eType == ww::eUNKNOWN ) ) |
| { |
| m_Fields.erase( pIt ); |
| --pIt; |
| } |
| } |
| } |
| |
| |
| // write the run properties + the text, already in the correct order |
| m_pSerializer->mergeTopMarks(); // merges with "postponed text", see above |
| |
| // level down, to be able to prepend the actual run start attribute (just |
| // before "postponed run start") |
| m_pSerializer->mark(); // let's call it "actual run start" |
| |
| // prepend the actual run start |
| if ( m_pHyperlinkAttrList ) |
| { |
| XFastAttributeListRef xAttrList ( m_pHyperlinkAttrList ); |
| |
| m_pSerializer->startElementNS( XML_w, XML_hyperlink, xAttrList ); |
| } |
| |
| // Write the hyperlink and toc fields starts |
| for ( std::vector<FieldInfos>::iterator pIt = m_Fields.begin(); pIt != m_Fields.end(); ++pIt ) |
| { |
| // Add the fields starts for hyperlinks, TOCs and index marks |
| if ( pIt->bOpen ) |
| { |
| StartField_Impl( *pIt, sal_True ); |
| |
| // Remove the field if no end needs to be written |
| if ( !pIt->bClose ) { |
| m_Fields.erase( pIt ); |
| --pIt; |
| } |
| } |
| } |
| |
| DoWriteBookmarks( ); |
| WriteCommentRanges(); |
| |
| m_pSerializer->startElementNS( XML_w, XML_r, FSEND ); |
| m_pSerializer->mergeTopMarks( sax_fastparser::MERGE_MARKS_PREPEND ); // merges with "postponed run start", see above |
| |
| // write the run start + the run content |
| m_pSerializer->mergeTopMarks(); // merges the "actual run start" |
| |
| // append the actual run end |
| m_pSerializer->endElementNS( XML_w, XML_r ); |
| |
| if ( m_pHyperlinkAttrList ) |
| { |
| m_pSerializer->endElementNS( XML_w, XML_hyperlink ); |
| m_pHyperlinkAttrList = NULL; |
| } |
| |
| while ( m_Fields.begin() != m_Fields.end() ) |
| { |
| EndField_Impl( m_Fields.front( ) ); |
| m_Fields.erase( m_Fields.begin( ) ); |
| } |
| |
| // if there is some redlining in the document, output it |
| EndRedline(); |
| } |
| |
| void DocxAttributeOutput::WriteCommentRanges() |
| { |
| if (m_bPostitStart) |
| { |
| m_bPostitStart = false; |
| OString idstr = OString::valueOf( sal_Int32( m_postitFieldsMaxId )); |
| m_pSerializer->singleElementNS( XML_w, XML_commentRangeStart, FSNS( XML_w, XML_id ), idstr.getStr(), FSEND ); |
| } |
| if (m_bPostitEnd) |
| { |
| m_bPostitEnd = false; |
| OString idstr = OString::valueOf( sal_Int32( m_postitFieldsMaxId )); |
| m_pSerializer->singleElementNS( XML_w, XML_commentRangeEnd, FSNS( XML_w, XML_id ), idstr.getStr(), FSEND ); |
| } |
| } |
| |
| void DocxAttributeOutput::WritePostitFieldStart() |
| { |
| m_bPostitStart = true; |
| } |
| |
| void DocxAttributeOutput::WritePostitFieldEnd() |
| { |
| m_bPostitEnd = true; |
| } |
| |
| |
| void DocxAttributeOutput::DoWriteBookmarks() |
| { |
| // Write the start bookmarks |
| for ( std::vector< OString >::const_iterator it = m_rMarksStart.begin(), end = m_rMarksStart.end(); |
| it < end; ++it ) |
| { |
| const OString& rName = *it; |
| |
| // Output the bookmark |
| sal_uInt16 nId = m_nNextMarkId++; |
| m_rOpenedMarksIds[rName] = nId; |
| m_pSerializer->singleElementNS( XML_w, XML_bookmarkStart, |
| FSNS( XML_w, XML_id ), OString::valueOf( sal_Int32( nId ) ).getStr( ), |
| FSNS( XML_w, XML_name ), rName.getStr(), |
| FSEND ); |
| } |
| m_rMarksStart.clear(); |
| |
| // export the end bookmarks |
| for ( std::vector< OString >::const_iterator it = m_rMarksEnd.begin(), end = m_rMarksEnd.end(); |
| it < end; ++it ) |
| { |
| const OString& rName = *it; |
| |
| // Get the id of the bookmark |
| std::map< OString, sal_uInt16 >::iterator pPos = m_rOpenedMarksIds.find( rName ); |
| if ( pPos != m_rOpenedMarksIds.end( ) ) |
| { |
| sal_uInt16 nId = ( *pPos ).second; |
| m_pSerializer->singleElementNS( XML_w, XML_bookmarkEnd, |
| FSNS( XML_w, XML_id ), OString::valueOf( sal_Int32( nId ) ).getStr( ), |
| FSEND ); |
| m_rOpenedMarksIds.erase( rName ); |
| } |
| } |
| m_rMarksEnd.clear(); |
| } |
| |
| void DocxAttributeOutput::StartField_Impl( FieldInfos& rInfos, sal_Bool bWriteRun ) |
| { |
| if ( rInfos.pField && rInfos.eType == ww::eUNKNOWN ) |
| { |
| // Expand unsupported fields |
| RunText( rInfos.pField->Expand( ) ); |
| } |
| else if ( rInfos.eType != ww::eNONE ) // HYPERLINK fields are just commands |
| { |
| if ( bWriteRun ) |
| m_pSerializer->startElementNS( XML_w, XML_r, FSEND ); |
| |
| if ( rInfos.eType == ww::eFORMDROPDOWN ) |
| { |
| m_pSerializer->startElementNS( XML_w, XML_fldChar, |
| FSNS( XML_w, XML_fldCharType ), "begin", |
| FSEND ); |
| |
| const SwDropDownField& rFld2 = *(SwDropDownField*)rInfos.pField; |
| uno::Sequence<rtl::OUString> aItems = |
| rFld2.GetItemSequence(); |
| GetExport().DoComboBox(rFld2.GetName(), |
| rFld2.GetHelp(), |
| rFld2.GetToolTip(), |
| rFld2.GetSelectedItem(), aItems); |
| |
| m_pSerializer->endElementNS( XML_w, XML_fldChar ); |
| |
| if ( bWriteRun ) |
| m_pSerializer->endElementNS( XML_w, XML_r ); |
| |
| } |
| else |
| { |
| // Write the field start |
| m_pSerializer->singleElementNS( XML_w, XML_fldChar, |
| FSNS( XML_w, XML_fldCharType ), "begin", |
| FSEND ); |
| |
| if ( bWriteRun ) |
| m_pSerializer->endElementNS( XML_w, XML_r ); |
| |
| // The hyperlinks fields can't be expanded: the value is |
| // normally in the text run |
| if ( !rInfos.pField ) |
| CmdField_Impl( rInfos ); |
| } |
| } |
| } |
| |
| void DocxAttributeOutput::DoWriteCmd( String& rCmd ) |
| { |
| // Write the Field command |
| m_pSerializer->startElementNS( XML_w, XML_instrText, FSEND ); |
| m_pSerializer->writeEscaped( OUString( rCmd ) ); |
| m_pSerializer->endElementNS( XML_w, XML_instrText ); |
| |
| } |
| |
| void DocxAttributeOutput::CmdField_Impl( FieldInfos& rInfos ) |
| { |
| m_pSerializer->startElementNS( XML_w, XML_r, FSEND ); |
| xub_StrLen nNbToken = rInfos.sCmd.GetTokenCount( '\t' ); |
| |
| for ( xub_StrLen i = 0; i < nNbToken; i++ ) |
| { |
| String sToken = rInfos.sCmd.GetToken( i, '\t' ); |
| // Write the Field command |
| DoWriteCmd( sToken ); |
| |
| // Replace tabs by </instrText><tab/><instrText> |
| if ( i < ( nNbToken - 1 ) ) |
| RunText( String::CreateFromAscii( "\t" ) ); |
| } |
| |
| m_pSerializer->endElementNS( XML_w, XML_r ); |
| |
| |
| // Write the Field separator |
| m_pSerializer->startElementNS( XML_w, XML_r, FSEND ); |
| m_pSerializer->singleElementNS( XML_w, XML_fldChar, |
| FSNS( XML_w, XML_fldCharType ), "separate", |
| FSEND ); |
| m_pSerializer->endElementNS( XML_w, XML_r ); |
| } |
| |
| void DocxAttributeOutput::EndField_Impl( FieldInfos& rInfos ) |
| { |
| // The command has to be written before for the hyperlinks |
| if ( rInfos.pField ) |
| { |
| CmdField_Impl( rInfos ); |
| } |
| |
| // Write the bookmark start if any |
| OUString aBkmName( m_sFieldBkm ); |
| if ( aBkmName.getLength( ) > 0 ) |
| { |
| m_pSerializer->singleElementNS( XML_w, XML_bookmarkStart, |
| FSNS( XML_w, XML_id ), OString::valueOf( sal_Int32( m_nNextMarkId ) ).getStr( ), |
| FSNS( XML_w, XML_name ), OUStringToOString( aBkmName, RTL_TEXTENCODING_UTF8 ).getStr( ), |
| FSEND ); |
| } |
| |
| if (rInfos.pField ) // For hyperlinks and TOX |
| { |
| // Write the Field latest value |
| m_pSerializer->startElementNS( XML_w, XML_r, FSEND ); |
| |
| // Find another way for hyperlinks |
| RunText( rInfos.pField->Expand( ) ); |
| m_pSerializer->endElementNS( XML_w, XML_r ); |
| } |
| |
| // Write the bookmark end if any |
| if ( aBkmName.getLength( ) > 0 ) |
| { |
| m_pSerializer->singleElementNS( XML_w, XML_bookmarkEnd, |
| FSNS( XML_w, XML_id ), OString::valueOf( sal_Int32( m_nNextMarkId ) ).getStr( ), |
| FSEND ); |
| |
| m_nNextMarkId++; |
| } |
| |
| // Write the Field end |
| m_pSerializer->startElementNS( XML_w, XML_r, FSEND ); |
| m_pSerializer->singleElementNS( XML_w, XML_fldChar, |
| FSNS( XML_w, XML_fldCharType ), "end", |
| FSEND ); |
| m_pSerializer->endElementNS( XML_w, XML_r ); |
| |
| |
| // Write the ref field if a bookmark had to be set and the field |
| // should be visible |
| if ( rInfos.pField ) |
| { |
| sal_uInt16 nSubType = rInfos.pField->GetSubType( ); |
| bool bIsSetField = rInfos.pField->GetTyp( )->Which( ) == RES_SETEXPFLD; |
| bool bShowRef = ( !bIsSetField || ( nSubType & nsSwExtendedSubType::SUB_INVISIBLE ) ) ? false : true; |
| |
| if ( ( m_sFieldBkm.Len( ) > 0 ) && bShowRef ) |
| { |
| // Write the field beginning |
| m_pSerializer->startElementNS( XML_w, XML_r, FSEND ); |
| m_pSerializer->singleElementNS( XML_w, XML_fldChar, |
| FSNS( XML_w, XML_fldCharType ), "begin", |
| FSEND ); |
| m_pSerializer->endElementNS( XML_w, XML_r ); |
| |
| rInfos.sCmd = FieldString( ww::eREF ); |
| rInfos.sCmd.APPEND_CONST_ASC( "\"" ); |
| rInfos.sCmd += m_sFieldBkm; |
| rInfos.sCmd.APPEND_CONST_ASC( "\" " ); |
| |
| // Clean the field bookmark data to avoid infinite loop |
| m_sFieldBkm = String( ); |
| |
| // Write the end of the field |
| EndField_Impl( rInfos ); |
| } |
| } |
| } |
| |
| void DocxAttributeOutput::StartRunProperties() |
| { |
| // postpone the output so that we can later [in EndRunProperties()] |
| // prepend the properties before the text |
| m_pSerializer->mark(); |
| |
| m_pSerializer->startElementNS( XML_w, XML_rPr, FSEND ); |
| |
| InitCollectedRunProperties(); |
| } |
| |
| void DocxAttributeOutput::InitCollectedRunProperties() |
| { |
| m_pFontsAttrList = NULL; |
| m_pEastAsianLayoutAttrList = NULL; |
| m_pCharLangAttrList = NULL; |
| } |
| |
| void DocxAttributeOutput::WriteCollectedRunProperties() |
| { |
| // Write all differed properties |
| if ( m_pFontsAttrList ) |
| { |
| XFastAttributeListRef xAttrList( m_pFontsAttrList ); |
| m_pFontsAttrList = NULL; |
| |
| m_pSerializer->singleElementNS( XML_w, XML_rFonts, xAttrList ); |
| } |
| |
| if ( m_pEastAsianLayoutAttrList ) |
| { |
| XFastAttributeListRef xAttrList( m_pEastAsianLayoutAttrList ); |
| m_pEastAsianLayoutAttrList = NULL; |
| |
| m_pSerializer->singleElementNS( XML_w, XML_eastAsianLayout, xAttrList ); |
| } |
| |
| if ( m_pCharLangAttrList ) |
| { |
| XFastAttributeListRef xAttrList( m_pCharLangAttrList ); |
| m_pCharLangAttrList = NULL; |
| |
| m_pSerializer->singleElementNS( XML_w, XML_lang, xAttrList ); |
| } |
| } |
| |
| void DocxAttributeOutput::EndRunProperties( const SwRedlineData* /*pRedlineData*/ ) |
| { |
| WriteCollectedRunProperties(); |
| |
| m_pSerializer->endElementNS( XML_w, XML_rPr ); |
| |
| // write footnotes/endnotes if we have any |
| FootnoteEndnoteReference(); |
| |
| // merge the properties _before_ the run text (strictly speaking, just |
| // after the start of the run) |
| m_pSerializer->mergeTopMarks( sax_fastparser::MERGE_MARKS_PREPEND ); |
| } |
| |
| /** Output sal_Unicode* as a run text (<t>the text</t>). |
| |
| When bMove is true, update rBegin to point _after_ the end of the text + |
| 1, meaning that it skips one character after the text. This is to make |
| the switch in DocxAttributeOutput::RunText() nicer ;-) |
| */ |
| static void impl_WriteRunText( FSHelperPtr pSerializer, sal_Int32 nTextToken, |
| const sal_Unicode* &rBegin, const sal_Unicode* pEnd, bool bMove = true ) |
| { |
| const sal_Unicode *pBegin = rBegin; |
| |
| // skip one character after the end |
| if ( bMove ) |
| rBegin = pEnd + 1; |
| |
| if ( pBegin >= pEnd ) |
| return; // we want to write at least one character |
| |
| // we have to add 'preserve' when starting/ending with space |
| if ( *pBegin == sal_Unicode( ' ' ) || *( pEnd - 1 ) == sal_Unicode( ' ' ) ) |
| { |
| pSerializer->startElementNS( XML_w, nTextToken, FSNS( XML_xml, XML_space ), "preserve", FSEND ); |
| } |
| else |
| pSerializer->startElementNS( XML_w, nTextToken, FSEND ); |
| |
| pSerializer->writeEscaped( OUString( pBegin, pEnd - pBegin ) ); |
| |
| pSerializer->endElementNS( XML_w, nTextToken ); |
| } |
| |
| void DocxAttributeOutput::RunText( const String& rText, rtl_TextEncoding /*eCharSet*/ ) |
| { |
| OUString aText( rText ); |
| |
| // one text can be split into more <w:t>blah</w:t>'s by line breaks etc. |
| const sal_Unicode *pBegin = aText.getStr(); |
| const sal_Unicode *pEnd = pBegin + aText.getLength(); |
| |
| // the text run is usually XML_t, with the exception of the deleted text |
| sal_Int32 nTextToken = XML_t; |
| if ( m_pRedlineData && m_pRedlineData->GetType() == nsRedlineType_t::REDLINE_DELETE ) |
| nTextToken = XML_delText; |
| |
| for ( const sal_Unicode *pIt = pBegin; pIt < pEnd; ++pIt ) |
| { |
| switch ( *pIt ) |
| { |
| case 0x09: // tab |
| impl_WriteRunText( m_pSerializer, nTextToken, pBegin, pIt ); |
| m_pSerializer->singleElementNS( XML_w, XML_tab, FSEND ); |
| break; |
| case 0x0b: // line break |
| impl_WriteRunText( m_pSerializer, nTextToken, pBegin, pIt ); |
| m_pSerializer->singleElementNS( XML_w, XML_br, FSEND ); |
| break; |
| default: |
| if ( *pIt < 0x0020 ) // filter out the control codes |
| { |
| impl_WriteRunText( m_pSerializer, nTextToken, pBegin, pIt ); |
| OSL_TRACE( "Ignored control code %x in a text run.", *pIt ); |
| } |
| break; |
| } |
| } |
| |
| impl_WriteRunText( m_pSerializer, nTextToken, pBegin, pEnd, false ); |
| } |
| |
| void DocxAttributeOutput::RawText( const String& /*rText*/, bool /*bForceUnicode*/, rtl_TextEncoding /*eCharSet*/ ) |
| { |
| OSL_TRACE("TODO DocxAttributeOutput::RawText( const String& rText, bool bForceUnicode, rtl_TextEncoding eCharSet )\n" ); |
| } |
| |
| void DocxAttributeOutput::StartRuby( const SwTxtNode& /*rNode*/, const SwFmtRuby& /*rRuby*/ ) |
| { |
| OSL_TRACE("TODO DocxAttributeOutput::StartRuby( const SwTxtNode& rNode, const SwFmtRuby& rRuby )\n" ); |
| } |
| |
| void DocxAttributeOutput::EndRuby() |
| { |
| OSL_TRACE( "TODO DocxAttributeOutput::EndRuby()\n" ); |
| } |
| |
| bool DocxAttributeOutput::AnalyzeURL( const String& rUrl, const String& rTarget, String* pLinkURL, String* pMark ) |
| { |
| bool bBookMarkOnly = AttributeOutputBase::AnalyzeURL( rUrl, rTarget, pLinkURL, pMark ); |
| |
| String sURL = *pLinkURL; |
| String sMark = *pMark; |
| |
| bool bOutputField = sMark.Len(); |
| |
| if ( bOutputField ) |
| { |
| if ( bBookMarkOnly ) |
| sURL = FieldString( ww::eHYPERLINK ); |
| else |
| { |
| String sFld( FieldString( ww::eHYPERLINK ) ); |
| sFld.APPEND_CONST_ASC( "\"" ); |
| sURL.Insert( sFld, 0 ); |
| sURL += '\"'; |
| } |
| |
| if ( sMark.Len() ) |
| ( ( sURL.APPEND_CONST_ASC( " \\l \"" ) ) += sMark ) += '\"'; |
| |
| if ( rTarget.Len() ) |
| ( sURL.APPEND_CONST_ASC( " \\n " ) ) += rTarget; |
| } |
| |
| *pLinkURL = sURL; |
| *pMark = sMark; |
| |
| return bBookMarkOnly; |
| } |
| |
| bool DocxAttributeOutput::StartURL( const String& rUrl, const String& rTarget ) |
| { |
| String sMark; |
| String sUrl; |
| |
| bool bBookmarkOnly = AnalyzeURL( rUrl, rTarget, &sUrl, &sMark ); |
| |
| if ( sMark.Len() && !bBookmarkOnly ) |
| { |
| m_rExport.OutputField( NULL, ww::eHYPERLINK, sUrl ); |
| } |
| else |
| { |
| // Output a hyperlink XML element |
| |
| m_pHyperlinkAttrList = m_pSerializer->createAttrList(); |
| if ( !bBookmarkOnly ) |
| { |
| OUString osUrl( sUrl ); |
| |
| ::rtl::OString sId = m_rExport.AddRelation( |
| S( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink" ), |
| osUrl, S("External") ); |
| m_pHyperlinkAttrList->add( FSNS( XML_r, XML_id), sId.getStr()); |
| } |
| else |
| m_pHyperlinkAttrList->add( FSNS( XML_w, XML_anchor ), |
| OUStringToOString( OUString( sMark ), RTL_TEXTENCODING_UTF8 ).getStr( ) ); |
| |
| OUString sTarget( rTarget ); |
| if ( sTarget.getLength( ) > 0 ) |
| { |
| OString soTarget = OUStringToOString( sTarget, RTL_TEXTENCODING_UTF8 ); |
| m_pHyperlinkAttrList->add(FSNS( XML_w, XML_tgtFrame ), soTarget.getStr()); |
| } |
| } |
| |
| return true; |
| } |
| |
| bool DocxAttributeOutput::EndURL() |
| { |
| return true; |
| } |
| |
| void DocxAttributeOutput::FieldVanish( const String& rTxt, ww::eField eType ) |
| { |
| WriteField_Impl( NULL, eType, rTxt, WRITEFIELD_ALL ); |
| } |
| |
| void DocxAttributeOutput::Redline( const SwRedlineData* /*pRedline*/ ) |
| { |
| OSL_TRACE( "TODO DocxAttributeOutput::Redline( const SwRedlineData* pRedline )\n" ); |
| } |
| |
| /// Append the number as 2-digit when less than 10. |
| static void impl_AppendTwoDigits( OStringBuffer &rBuffer, sal_Int32 nNum ) |
| { |
| if ( nNum < 0 || nNum > 99 ) |
| { |
| rBuffer.append( "00" ); |
| return; |
| } |
| |
| if ( nNum < 10 ) |
| rBuffer.append( '0' ); |
| |
| rBuffer.append( nNum ); |
| } |
| |
| /** Convert DateTime to xsd::dateTime string. |
| |
| I guess there must be an implementation of this somewhere in OOo, but I failed |
| to find it, unfortunately :-( |
| */ |
| static OString impl_DateTimeToOString( const DateTime& rDateTime ) |
| { |
| DateTime aInUTC( rDateTime ); |
| aInUTC.ConvertToUTC(); |
| |
| OStringBuffer aBuffer( 25 ); |
| aBuffer.append( sal_Int32( aInUTC.GetYear() ) ); |
| aBuffer.append( '-' ); |
| |
| impl_AppendTwoDigits( aBuffer, aInUTC.GetMonth() ); |
| aBuffer.append( '-' ); |
| |
| impl_AppendTwoDigits( aBuffer, aInUTC.GetDay() ); |
| aBuffer.append( 'T' ); |
| |
| impl_AppendTwoDigits( aBuffer, aInUTC.GetHour() ); |
| aBuffer.append( ':' ); |
| |
| impl_AppendTwoDigits( aBuffer, aInUTC.GetMin() ); |
| aBuffer.append( ':' ); |
| |
| impl_AppendTwoDigits( aBuffer, aInUTC.GetSec() ); |
| aBuffer.append( 'Z' ); // we are in UTC |
| |
| return aBuffer.makeStringAndClear(); |
| } |
| |
| void DocxAttributeOutput::StartRedline( const SwRedlineData* pRedlineData ) |
| { |
| m_pRedlineData = pRedlineData; |
| |
| if ( !m_pRedlineData ) |
| return; |
| |
| // FIXME check if it's necessary to travel over the Next()'s in pRedlineData |
| |
| OString aId( OString::valueOf( m_nRedlineId++ ) ); |
| |
| const String &rAuthor( SW_MOD()->GetRedlineAuthor( pRedlineData->GetAuthor() ) ); |
| OString aAuthor( OUStringToOString( rAuthor, RTL_TEXTENCODING_UTF8 ) ); |
| |
| OString aDate( impl_DateTimeToOString( pRedlineData->GetTimeStamp() ) ); |
| |
| switch ( pRedlineData->GetType() ) |
| { |
| case nsRedlineType_t::REDLINE_INSERT: |
| m_pSerializer->startElementNS( XML_w, XML_ins, |
| FSNS( XML_w, XML_id ), aId.getStr(), |
| FSNS( XML_w, XML_author ), aAuthor.getStr(), |
| FSNS( XML_w, XML_date ), aDate.getStr(), |
| FSEND ); |
| break; |
| |
| case nsRedlineType_t::REDLINE_DELETE: |
| m_pSerializer->startElementNS( XML_w, XML_del, |
| FSNS( XML_w, XML_id ), aId.getStr(), |
| FSNS( XML_w, XML_author ), aAuthor.getStr(), |
| FSNS( XML_w, XML_date ), aDate.getStr(), |
| FSEND ); |
| break; |
| |
| case nsRedlineType_t::REDLINE_FORMAT: |
| OSL_TRACE( "TODO DocxAttributeOutput::StartRedline()\n" ); |
| default: |
| break; |
| } |
| } |
| |
| void DocxAttributeOutput::EndRedline() |
| { |
| if ( !m_pRedlineData ) |
| return; |
| |
| switch ( m_pRedlineData->GetType() ) |
| { |
| case nsRedlineType_t::REDLINE_INSERT: |
| m_pSerializer->endElementNS( XML_w, XML_ins ); |
| break; |
| |
| case nsRedlineType_t::REDLINE_DELETE: |
| m_pSerializer->endElementNS( XML_w, XML_del ); |
| break; |
| |
| case nsRedlineType_t::REDLINE_FORMAT: |
| OSL_TRACE( "TODO DocxAttributeOutput::EndRedline()\n" ); |
| break; |
| default: |
| break; |
| } |
| |
| m_pRedlineData = NULL; |
| } |
| |
| void DocxAttributeOutput::FormatDrop( const SwTxtNode& /*rNode*/, const SwFmtDrop& /*rSwFmtDrop*/, sal_uInt16 /*nStyle*/, ww8::WW8TableNodeInfo::Pointer_t /*pTextNodeInfo*/, ww8::WW8TableNodeInfoInner::Pointer_t ) |
| { |
| OSL_TRACE( "TODO DocxAttributeOutput::FormatDrop( const SwTxtNode& rNode, const SwFmtDrop& rSwFmtDrop, sal_uInt16 nStyle )\n" ); |
| } |
| |
| void DocxAttributeOutput::ParagraphStyle( sal_uInt16 nStyle ) |
| { |
| OString aStyleId( "style" ); |
| aStyleId += OString::valueOf( sal_Int32( nStyle ) ); |
| |
| m_pSerializer->singleElementNS( XML_w, XML_pStyle, FSNS( XML_w, XML_val ), aStyleId.getStr(), FSEND ); |
| } |
| |
| #if 0 |
| void DocxAttributeOutput::InTable() |
| { |
| #if OSL_DEBUG_LEVEL > 0 |
| OSL_TRACE( "TODO DocxAttributeOutput::InTable()\n" ); |
| #endif |
| } |
| |
| |
| void DocxAttributeOutput::TableRowProperties( bool /*bHeader*/, long /*nCellHeight*/, bool /*bCannotSplit*/, bool /*bRightToLeft*/ ) |
| { |
| #if OSL_DEBUG_LEVEL > 0 |
| OSL_TRACE( "TODO DocxAttributeOutput::TableRowProperties()\n" ); |
| #endif |
| } |
| #endif |
| |
| static OString impl_ConvertColor( const Color &rColor ) |
| { |
| OString color( "auto" ); |
| if ( rColor.GetColor() != COL_AUTO ) |
| { |
| const char pHexDigits[] = "0123456789ABCDEF"; |
| char pBuffer[] = "000000"; |
| |
| pBuffer[0] = pHexDigits[ ( rColor.GetRed() >> 4 ) & 0x0F ]; |
| pBuffer[1] = pHexDigits[ rColor.GetRed() & 0x0F ]; |
| pBuffer[2] = pHexDigits[ ( rColor.GetGreen() >> 4 ) & 0x0F ]; |
| pBuffer[3] = pHexDigits[ rColor.GetGreen() & 0x0F ]; |
| pBuffer[4] = pHexDigits[ ( rColor.GetBlue() >> 4 ) & 0x0F ]; |
| pBuffer[5] = pHexDigits[ rColor.GetBlue() & 0x0F ]; |
| |
| color = OString( pBuffer ); |
| } |
| return color; |
| } |
| |
| static void impl_borderLine( FSHelperPtr pSerializer, sal_Int32 elementToken, const SvxBorderLine* pBorderLine, sal_uInt16 nDist ) |
| { |
| FastAttributeList* pAttr = pSerializer->createAttrList(); |
| |
| sal_uInt16 inW = pBorderLine->GetInWidth(); |
| sal_uInt16 outW = pBorderLine->GetOutWidth(); |
| sal_uInt16 nWidth = inW + outW; |
| |
| // Compute val attribute value |
| // Can be one of: |
| // single, double, |
| // basicWideOutline, basicWideInline |
| // OOXml also supports those types of borders, but we'll try to play with the first ones. |
| // thickThinMediumGap, thickThinLargeGap, thickThinSmallGap |
| // thinThickLargeGap, thinThickMediumGap, thinThickSmallGap |
| const char* pVal = "single"; |
| if ( pBorderLine->isDouble() ) |
| { |
| if ( inW == outW ) |
| pVal = ( sal_Char* )"double"; |
| else if ( inW > outW ) |
| { |
| pVal = ( sal_Char* )"thinThickMediumGap"; |
| } |
| else if ( inW < outW ) |
| { |
| pVal = ( sal_Char* )"thickThinMediumGap"; |
| } |
| } |
| |
| pAttr->add( FSNS( XML_w, XML_val ), OString( pVal ) ); |
| |
| // Compute the sz attribute |
| |
| // The unit is the 8th of point |
| nWidth = sal_Int32( nWidth / 2.5 ); |
| sal_uInt16 nMinWidth = 2; |
| sal_uInt16 nMaxWidth = 96; |
| |
| if ( nWidth > nMaxWidth ) |
| nWidth = nMaxWidth; |
| else if ( nWidth < nMinWidth ) |
| nWidth = nMinWidth; |
| |
| pAttr->add( FSNS( XML_w, XML_sz ), OString::valueOf( sal_Int32( nWidth ) ) ); |
| |
| // Get the distance (in pt) |
| pAttr->add( FSNS( XML_w, XML_space ), OString::valueOf( sal_Int32( nDist / 20 ) ) ); |
| |
| // Get the color code as an RRGGBB hex value |
| OString sColor( impl_ConvertColor( pBorderLine->GetColor( ) ) ); |
| pAttr->add( FSNS( XML_w, XML_color ), sColor ); |
| |
| XFastAttributeListRef xAttrs( pAttr ); |
| pSerializer->singleElementNS( XML_w, elementToken, xAttrs ); |
| } |
| |
| static void impl_pageBorders( FSHelperPtr pSerializer, const SvxBoxItem& rBox ) |
| { |
| static const sal_uInt16 aBorders[] = |
| { |
| BOX_LINE_TOP, BOX_LINE_LEFT, BOX_LINE_BOTTOM, BOX_LINE_RIGHT |
| }; |
| |
| static const sal_uInt16 aXmlElements[] = |
| { |
| XML_top, XML_left, XML_bottom, XML_right |
| }; |
| const sal_uInt16* pBrd = aBorders; |
| for( int i = 0; i < 4; ++i, ++pBrd ) |
| { |
| const SvxBorderLine* pLn = rBox.GetLine( *pBrd ); |
| if ( pLn ) |
| impl_borderLine( pSerializer, aXmlElements[i], pLn, 0 ); |
| } |
| } |
| |
| void DocxAttributeOutput::TableCellProperties( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ) |
| { |
| m_pSerializer->startElementNS( XML_w, XML_tcPr, FSEND ); |
| |
| const SwTableBox *pTblBox = pTableTextNodeInfoInner->getTableBox( ); |
| |
| // The cell borders |
| m_pSerializer->startElementNS( XML_w, XML_tcBorders, FSEND ); |
| SwFrmFmt *pFmt = pTblBox->GetFrmFmt( ); |
| impl_pageBorders( m_pSerializer, pFmt->GetBox( ) ); |
| m_pSerializer->endElementNS( XML_w, XML_tcBorders ); |
| |
| // Vertical merges |
| long vSpan = pTblBox->getRowSpan( ); |
| if ( vSpan > 1 ) |
| { |
| m_pSerializer->singleElementNS( XML_w, XML_vMerge, |
| FSNS( XML_w, XML_val ), "restart", |
| FSEND ); |
| } |
| else if ( vSpan < 0 ) |
| { |
| m_pSerializer->singleElementNS( XML_w, XML_vMerge, |
| FSNS( XML_w, XML_val ), "continue", |
| FSEND ); |
| } |
| |
| // Horizontal spans |
| const SwWriteTableRows& aRows = m_pTableWrt->GetRows( ); |
| SwWriteTableRow *pRow = aRows[ pTableTextNodeInfoInner->getRow( ) ]; |
| SwWriteTableCell *pCell = pRow->GetCells( )[ pTableTextNodeInfoInner->getCell( ) ]; |
| |
| sal_uInt16 nColSpan = pCell->GetColSpan(); |
| if ( nColSpan > 1 ) |
| m_pSerializer->singleElementNS( XML_w, XML_gridSpan, |
| FSNS( XML_w, XML_val ), OString::valueOf( sal_Int32( nColSpan ) ).getStr(), |
| FSEND ); |
| |
| TableBackgrounds( pTableTextNodeInfoInner ); |
| |
| // Cell prefered width |
| SwTwips nWidth = GetGridCols( pTableTextNodeInfoInner )[ pTableTextNodeInfoInner->getCell() ]; |
| m_pSerializer->singleElementNS( XML_w, XML_tcW, |
| FSNS( XML_w, XML_w ), OString::valueOf( sal_Int32( nWidth ) ).getStr( ), |
| FSNS( XML_w, XML_type ), "dxa", |
| FSEND ); |
| |
| // Cell margins |
| m_pSerializer->startElementNS( XML_w, XML_tcMar, FSEND ); |
| const SvxBoxItem& rBox = pFmt->GetBox( ); |
| static const sal_uInt16 aBorders[] = |
| { |
| BOX_LINE_TOP, BOX_LINE_LEFT, BOX_LINE_BOTTOM, BOX_LINE_RIGHT |
| }; |
| |
| static const sal_uInt16 aXmlElements[] = |
| { |
| XML_top, XML_left, XML_bottom, XML_right |
| }; |
| const sal_uInt16* pBrd = aBorders; |
| for( int i = 0; i < 4; ++i, ++pBrd ) |
| { |
| sal_Int32 nDist = sal_Int32( rBox.GetDistance( *pBrd ) ); |
| m_pSerializer->singleElementNS( XML_w, aXmlElements[i], |
| FSNS( XML_w, XML_w ), OString::valueOf( nDist ).getStr( ), |
| FSNS( XML_w, XML_type ), "dxa", |
| FSEND ); |
| } |
| |
| m_pSerializer->endElementNS( XML_w, XML_tcMar ); |
| |
| TableVerticalCell( pTableTextNodeInfoInner ); |
| |
| m_pSerializer->endElementNS( XML_w, XML_tcPr ); |
| } |
| |
| void DocxAttributeOutput::InitTableHelper( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ) |
| { |
| sal_uInt32 nPageSize = 0; |
| bool bRelBoxSize = false; |
| |
| // Create the SwWriteTable instance to use col spans (and maybe other infos) |
| GetTablePageSize( pTableTextNodeInfoInner, nPageSize, bRelBoxSize ); |
| |
| const SwTable* pTable = pTableTextNodeInfoInner->getTable( ); |
| const SwFrmFmt *pFmt = pTable->GetFrmFmt( ); |
| SwTwips nTblSz = pFmt->GetFrmSize( ).GetWidth( ); |
| |
| const SwHTMLTableLayout *pLayout = pTable->GetHTMLTableLayout(); |
| if( pLayout && pLayout->IsExportable() ) |
| m_pTableWrt = new SwWriteTable( pLayout ); |
| else |
| m_pTableWrt = new SwWriteTable( pTable->GetTabLines(), (sal_uInt16)nPageSize, |
| (sal_uInt16)nTblSz, false); |
| } |
| |
| void DocxAttributeOutput::StartTable( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ) |
| { |
| m_pSerializer->startElementNS( XML_w, XML_tbl, FSEND ); |
| |
| InitTableHelper( pTableTextNodeInfoInner ); |
| TableDefinition( pTableTextNodeInfoInner ); |
| } |
| |
| void DocxAttributeOutput::EndTable() |
| { |
| m_pSerializer->endElementNS( XML_w, XML_tbl ); |
| |
| if ( m_nTableDepth > 0 ) |
| --m_nTableDepth; |
| |
| // We closed the table; if it is a nested table, the cell that contains it |
| // still continues |
| m_bTableCellOpen = true; |
| |
| // Cleans the table helper |
| delete m_pTableWrt, m_pTableWrt = NULL; |
| } |
| |
| void DocxAttributeOutput::StartTableRow( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ) |
| { |
| m_pSerializer->startElementNS( XML_w, XML_tr, FSEND ); |
| |
| // Output the row properties |
| m_pSerializer->startElementNS( XML_w, XML_trPr, FSEND ); |
| |
| // Header row: tblHeader |
| const SwTable *pTable = pTableTextNodeInfoInner->getTable( ); |
| if ( pTable->GetRowsToRepeat( ) > pTableTextNodeInfoInner->getRow( ) ) |
| m_pSerializer->singleElementNS( XML_w, XML_tblHeader, |
| FSNS( XML_w, XML_val ), "true", |
| FSEND ); |
| |
| TableHeight( pTableTextNodeInfoInner ); |
| TableCanSplit( pTableTextNodeInfoInner ); |
| |
| m_pSerializer->endElementNS( XML_w, XML_trPr ); |
| } |
| |
| void DocxAttributeOutput::EndTableRow( ) |
| { |
| m_pSerializer->endElementNS( XML_w, XML_tr ); |
| } |
| |
| |
| void DocxAttributeOutput::StartTableCell( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ) |
| { |
| if ( !m_pTableWrt ) |
| InitTableHelper( pTableTextNodeInfoInner ); |
| |
| m_pSerializer->startElementNS( XML_w, XML_tc, FSEND ); |
| |
| // Write the cell properties here |
| TableCellProperties( pTableTextNodeInfoInner ); |
| |
| m_bTableCellOpen = true; |
| } |
| |
| void DocxAttributeOutput::EndTableCell( ) |
| { |
| m_pSerializer->endElementNS( XML_w, XML_tc ); |
| |
| m_bTableCellOpen = false; |
| } |
| |
| void DocxAttributeOutput::TableInfoCell( ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner*/ ) |
| { |
| } |
| |
| void DocxAttributeOutput::TableInfoRow( ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfo*/ ) |
| { |
| } |
| |
| void DocxAttributeOutput::TableDefinition( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ) |
| { |
| // Write the table properties |
| m_pSerializer->startElementNS( XML_w, XML_tblPr, FSEND ); |
| |
| sal_uInt32 nPageSize = 0; |
| bool bRelBoxSize = false; |
| |
| // Create the SwWriteTable instance to use col spans (and maybe other infos) |
| GetTablePageSize( pTableTextNodeInfoInner, nPageSize, bRelBoxSize ); |
| |
| // Output the table prefered width |
| if ( nPageSize != 0 ) |
| m_pSerializer->singleElementNS( XML_w, XML_tblW, |
| FSNS( XML_w, XML_w ), OString::valueOf( sal_Int32( nPageSize ) ).getStr( ), |
| FSNS( XML_w, XML_type ), "dxa", |
| FSEND ); |
| |
| // Output the table borders |
| TableDefaultBorders( pTableTextNodeInfoInner ); |
| TableBidi( pTableTextNodeInfoInner ); |
| |
| // Output the table alignement |
| const SwTable *pTable = pTableTextNodeInfoInner->getTable(); |
| SwFrmFmt *pTblFmt = pTable->GetFrmFmt( ); |
| const char* pJcVal; |
| sal_Int32 nIndent = 0; |
| switch ( pTblFmt->GetHoriOrient( ).GetHoriOrient( ) ) |
| { |
| case text::HoriOrientation::CENTER: |
| pJcVal = "center"; |
| break; |
| case text::HoriOrientation::RIGHT: |
| pJcVal = "right"; |
| break; |
| default: |
| case text::HoriOrientation::NONE: |
| case text::HoriOrientation::LEFT_AND_WIDTH: |
| { |
| pJcVal = "left"; |
| nIndent = sal_Int32( pTblFmt->GetLRSpace( ).GetLeft( ) ); |
| break; |
| } |
| } |
| m_pSerializer->singleElementNS( XML_w, XML_jc, |
| FSNS( XML_w, XML_val ), pJcVal, |
| FSEND ); |
| |
| // Table indent |
| if ( nIndent != 0 ) |
| m_pSerializer->singleElementNS( XML_w, XML_tblInd, |
| FSNS( XML_w, XML_w ), OString::valueOf( nIndent ).getStr( ), |
| FSNS( XML_w, XML_type ), "dxa", |
| FSEND ); |
| |
| m_pSerializer->endElementNS( XML_w, XML_tblPr ); |
| |
| |
| // Write the table grid infos |
| m_pSerializer->startElementNS( XML_w, XML_tblGrid, FSEND ); |
| |
| std::vector<SwTwips> gridCols = GetGridCols( pTableTextNodeInfoInner ); |
| for ( std::vector<SwTwips>::const_iterator it = gridCols.begin(); it != gridCols.end(); ++it ) |
| m_pSerializer->singleElementNS( XML_w, XML_gridCol, |
| FSNS( XML_w, XML_w ), OString::valueOf( sal_Int32( *it ) ).getStr( ), |
| FSEND ); |
| |
| m_pSerializer->endElementNS( XML_w, XML_tblGrid ); |
| } |
| |
| void DocxAttributeOutput::TableDefaultBorders( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ) |
| { |
| const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox(); |
| const SwFrmFmt * pFrmFmt = pTabBox->GetFrmFmt(); |
| |
| // the defaults of the table are taken from the top-left cell |
| m_pSerializer->startElementNS( XML_w, XML_tblBorders, FSEND ); |
| impl_pageBorders( m_pSerializer, pFrmFmt->GetBox( ) ); |
| m_pSerializer->endElementNS( XML_w, XML_tblBorders ); |
| } |
| |
| void DocxAttributeOutput::TableBackgrounds( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ) |
| { |
| const SwTableBox *pTblBox = pTableTextNodeInfoInner->getTableBox( ); |
| const SwFrmFmt *pFmt = pTblBox->GetFrmFmt( ); |
| const SfxPoolItem *pI = NULL; |
| |
| Color aColor; |
| if ( SFX_ITEM_ON == pFmt->GetAttrSet().GetItemState( RES_BACKGROUND, false, &pI ) ) |
| aColor = dynamic_cast<const SvxBrushItem *>(pI)->GetColor(); |
| else |
| aColor = COL_AUTO; |
| |
| OString sColor = impl_ConvertColor( aColor ); |
| m_pSerializer->singleElementNS( XML_w, XML_shd, |
| FSNS( XML_w, XML_fill ), sColor.getStr( ), |
| FSEND ); |
| } |
| |
| void DocxAttributeOutput::TableHeight( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ) |
| { |
| const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox(); |
| const SwTableLine * pTabLine = pTabBox->GetUpper(); |
| const SwFrmFmt * pLineFmt = pTabLine->GetFrmFmt(); |
| |
| const SwFmtFrmSize& rLSz = pLineFmt->GetFrmSize(); |
| if ( ATT_VAR_SIZE != rLSz.GetHeightSizeType() && rLSz.GetHeight() ) |
| { |
| sal_Int32 nHeight = rLSz.GetHeight(); |
| const char *pRule = NULL; |
| |
| switch ( rLSz.GetHeightSizeType() ) |
| { |
| case ATT_FIX_SIZE: pRule = "exact"; break; |
| case ATT_MIN_SIZE: pRule = "atLeast"; break; |
| default: break; |
| } |
| |
| if ( pRule ) |
| m_pSerializer->singleElementNS( XML_w, XML_trHeight, |
| FSNS( XML_w, XML_val ), OString::valueOf( nHeight ).getStr( ), |
| FSNS( XML_w, XML_hRule ), pRule, |
| FSEND ); |
| } |
| } |
| |
| void DocxAttributeOutput::TableCanSplit( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ) |
| { |
| const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox(); |
| const SwTableLine * pTabLine = pTabBox->GetUpper(); |
| const SwFrmFmt * pLineFmt = pTabLine->GetFrmFmt(); |
| |
| const SwFmtRowSplit& rSplittable = pLineFmt->GetRowSplit( ); |
| const char* pCantSplit = ( !rSplittable.GetValue( ) ) ? "on" : "off"; |
| |
| m_pSerializer->singleElementNS( XML_w, XML_cantSplit, |
| FSNS( XML_w, XML_val ), pCantSplit, |
| FSEND ); |
| } |
| |
| void DocxAttributeOutput::TableBidi( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ) |
| { |
| const SwTable * pTable = pTableTextNodeInfoInner->getTable(); |
| const SwFrmFmt * pFrmFmt = pTable->GetFrmFmt(); |
| |
| if ( m_rExport.TrueFrameDirection( *pFrmFmt ) == FRMDIR_HORI_RIGHT_TOP ) |
| { |
| m_pSerializer->singleElementNS( XML_w, XML_bidiVisual, |
| FSNS( XML_w, XML_val ), "on", |
| FSEND ); |
| } |
| } |
| |
| void DocxAttributeOutput::TableVerticalCell( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ) |
| { |
| const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox(); |
| const SwFrmFmt *pFrmFmt = pTabBox->GetFrmFmt( ); |
| |
| if ( FRMDIR_VERT_TOP_RIGHT == m_rExport.TrueFrameDirection( *pFrmFmt ) ) |
| m_pSerializer->singleElementNS( XML_w, XML_textDirection, |
| FSNS( XML_w, XML_val ), "tbRl", |
| FSEND ); |
| } |
| |
| void DocxAttributeOutput::TableNodeInfo( ww8::WW8TableNodeInfo::Pointer_t /*pNodeInfo*/ ) |
| { |
| OSL_TRACE( "TODO: DocxAttributeOutput::TableNodeInfo( ww8::WW8TableNodeInfo::Pointer_t pNodeInfo )\n" ); |
| } |
| |
| void DocxAttributeOutput::TableNodeInfoInner( ww8::WW8TableNodeInfoInner::Pointer_t pNodeInfoInner ) |
| { |
| // This is called when the nested table ends in a cell, and there's no |
| // paragraph benhind that; so we must check for the ends of cell, rows, |
| // tables |
| // ['true' to write an empty paragraph, MS Word insists on that] |
| FinishTableRowCell( pNodeInfoInner, true ); |
| } |
| |
| void DocxAttributeOutput::TableOrientation( ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner*/ ) |
| { |
| OSL_TRACE( "TODO: DocxAttributeOutput::TableOrientation( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )\n" ); |
| } |
| |
| void DocxAttributeOutput::TableSpacing( ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner*/ ) |
| { |
| #if OSL_DEBUG_LEVEL > 0 |
| fprintf( stderr, "TODO: DocxAttributeOutput::TableSpacing( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )\n" ); |
| #endif |
| } |
| |
| void DocxAttributeOutput::TableRowEnd( sal_uInt32 /*nDepth*/ ) |
| { |
| OSL_TRACE( "TODO: DocxAttributeOutput::TableRowEnd( sal_uInt32 nDepth = 1 )\n" ); |
| } |
| |
| void DocxAttributeOutput::StartStyles() |
| { |
| m_pSerializer->startElementNS( XML_w, XML_styles, |
| FSNS( XML_xmlns, XML_w ), "http://schemas.openxmlformats.org/wordprocessingml/2006/main", |
| FSEND ); |
| } |
| |
| void DocxAttributeOutput::EndStyles( sal_uInt16 /*nNumberOfStyles*/ ) |
| { |
| m_pSerializer->endElementNS( XML_w, XML_styles ); |
| } |
| |
| void DocxAttributeOutput::DefaultStyle( sal_uInt16 nStyle ) |
| { |
| // are these the values of enum ww::sti (see ../inc/wwstyles.hxx)? |
| #if OSL_DEBUG_LEVEL > 0 |
| OSL_TRACE( "TODO DocxAttributeOutput::DefaultStyle( sal_uInt16 nStyle )- %d\n", nStyle ); |
| #else |
| (void) nStyle; // to quiet the warning |
| #endif |
| } |
| |
| void DocxAttributeOutput::FlyFrameGraphic( const SwGrfNode& rGrfNode, const Size& rSize ) |
| { |
| #if OSL_DEBUG_LEVEL > 0 |
| OSL_TRACE( "TODO DocxAttributeOutput::FlyFrameGraphic( const SwGrfNode& rGrfNode, const Size& rSize ) - some stuff still missing\n" ); |
| #endif |
| // create the relation ID |
| OString aRelId; |
| sal_Int32 nImageType; |
| if ( rGrfNode.IsLinkedFile() ) |
| { |
| // linked image, just create the relation |
| String aFileName; |
| rGrfNode.GetFileFilterNms( &aFileName, 0 ); |
| |
| // TODO Convert the file name to relative for better interoperability |
| |
| aRelId = m_rExport.AddRelation( |
| S( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" ), |
| OUString( aFileName ), |
| S( "External" ) ); |
| |
| nImageType = XML_link; |
| } |
| else |
| { |
| // inline, we also have to write the image itself |
| Graphic& rGraphic = const_cast< Graphic& >( rGrfNode.GetGrf() ); |
| |
| m_rDrawingML.SetFS( m_pSerializer ); // to be sure that we write to the right stream |
| OUString aImageId = m_rDrawingML.WriteImage( rGraphic ); |
| |
| aRelId = OUStringToOString( aImageId, RTL_TEXTENCODING_UTF8 ); |
| |
| nImageType = XML_embed; |
| } |
| |
| if ( aRelId.getLength() == 0 ) |
| return; |
| |
| m_pSerializer->startElementNS( XML_w, XML_drawing, |
| FSEND ); |
| m_pSerializer->startElementNS( XML_wp, XML_inline, |
| XML_distT, "0", XML_distB, "0", XML_distL, "0", XML_distR, "0", |
| FSEND ); |
| |
| // extent of the image |
| OString aWidth( OString::valueOf( TwipsToEMU( rSize.Width() ) ) ); |
| OString aHeight( OString::valueOf( TwipsToEMU( rSize.Height() ) ) ); |
| m_pSerializer->singleElementNS( XML_wp, XML_extent, |
| XML_cx, aWidth.getStr(), |
| XML_cy, aHeight.getStr(), |
| FSEND ); |
| // TODO - the right effectExtent, extent including the effect |
| m_pSerializer->singleElementNS( XML_wp, XML_effectExtent, |
| XML_l, "0", XML_t, "0", XML_r, "0", XML_b, "0", |
| FSEND ); |
| |
| // picture description |
| // TODO the right image description |
| m_pSerializer->startElementNS( XML_wp, XML_docPr, |
| XML_id, "1", |
| XML_name, "Picture", |
| XML_descr, "A description...", |
| FSEND ); |
| // TODO hyperlink |
| // m_pSerializer->singleElementNS( XML_a, XML_hlinkClick, |
| // FSNS( XML_xmlns, XML_a ), "http://schemas.openxmlformats.org/drawingml/2006/main", |
| // FSNS( XML_r, XML_id ), "rId4", |
| // FSEND ); |
| m_pSerializer->endElementNS( XML_wp, XML_docPr ); |
| |
| m_pSerializer->startElementNS( XML_wp, XML_cNvGraphicFramePr, |
| FSEND ); |
| // TODO change aspect? |
| m_pSerializer->singleElementNS( XML_a, XML_graphicFrameLocks, |
| FSNS( XML_xmlns, XML_a ), "http://schemas.openxmlformats.org/drawingml/2006/main", |
| XML_noChangeAspect, "1", |
| FSEND ); |
| m_pSerializer->endElementNS( XML_wp, XML_cNvGraphicFramePr ); |
| |
| m_pSerializer->startElementNS( XML_a, XML_graphic, |
| FSNS( XML_xmlns, XML_a ), "http://schemas.openxmlformats.org/drawingml/2006/main", |
| FSEND ); |
| m_pSerializer->startElementNS( XML_a, XML_graphicData, |
| XML_uri, "http://schemas.openxmlformats.org/drawingml/2006/picture", |
| FSEND ); |
| |
| m_pSerializer->startElementNS( XML_pic, XML_pic, |
| FSNS( XML_xmlns, XML_pic ), "http://schemas.openxmlformats.org/drawingml/2006/picture", |
| FSEND ); |
| |
| m_pSerializer->startElementNS( XML_pic, XML_nvPicPr, |
| FSEND ); |
| // TODO the right image description |
| m_pSerializer->startElementNS( XML_pic, XML_cNvPr, |
| XML_id, "0", |
| XML_name, "Picture", |
| XML_descr, "A description...", |
| FSEND ); |
| // TODO hyperlink |
| // m_pSerializer->singleElementNS( XML_a, XML_hlinkClick, |
| // FSNS( XML_r, XML_id ), "rId4", |
| // FSEND ); |
| m_pSerializer->endElementNS( XML_pic, XML_cNvPr ); |
| |
| m_pSerializer->startElementNS( XML_pic, XML_cNvPicPr, |
| FSEND ); |
| // TODO change aspect? |
| m_pSerializer->singleElementNS( XML_a, XML_picLocks, |
| XML_noChangeAspect, "1", XML_noChangeArrowheads, "1", |
| FSEND ); |
| m_pSerializer->endElementNS( XML_pic, XML_cNvPicPr ); |
| m_pSerializer->endElementNS( XML_pic, XML_nvPicPr ); |
| |
| // the actual picture |
| m_pSerializer->startElementNS( XML_pic, XML_blipFill, |
| FSEND ); |
| m_pSerializer->singleElementNS( XML_a, XML_blip, |
| FSNS( XML_r, nImageType ), aRelId.getStr(), |
| FSEND ); |
| m_pSerializer->singleElementNS( XML_a, XML_srcRect, |
| FSEND ); |
| m_pSerializer->startElementNS( XML_a, XML_stretch, |
| FSEND ); |
| m_pSerializer->singleElementNS( XML_a, XML_fillRect, |
| FSEND ); |
| m_pSerializer->endElementNS( XML_a, XML_stretch ); |
| m_pSerializer->endElementNS( XML_pic, XML_blipFill ); |
| |
| // TODO setup the right values below |
| m_pSerializer->startElementNS( XML_pic, XML_spPr, |
| XML_bwMode, "auto", |
| FSEND ); |
| m_pSerializer->startElementNS( XML_a, XML_xfrm, |
| FSEND ); |
| m_pSerializer->singleElementNS( XML_a, XML_off, |
| XML_x, "0", XML_y, "0", |
| FSEND ); |
| m_pSerializer->singleElementNS( XML_a, XML_ext, |
| XML_cx, aWidth.getStr(), |
| XML_cy, aHeight.getStr(), |
| FSEND ); |
| m_pSerializer->endElementNS( XML_a, XML_xfrm ); |
| m_pSerializer->startElementNS( XML_a, XML_prstGeom, |
| XML_prst, "rect", |
| FSEND ); |
| m_pSerializer->singleElementNS( XML_a, XML_avLst, |
| FSEND ); |
| m_pSerializer->endElementNS( XML_a, XML_prstGeom ); |
| m_pSerializer->singleElementNS( XML_a, XML_noFill, |
| FSEND ); |
| m_pSerializer->startElementNS( XML_a, XML_ln, |
| XML_w, "9525", |
| FSEND ); |
| m_pSerializer->singleElementNS( XML_a, XML_noFill, |
| FSEND ); |
| m_pSerializer->singleElementNS( XML_a, XML_miter, |
| XML_lim, "800000", |
| FSEND ); |
| m_pSerializer->singleElementNS( XML_a, XML_headEnd, |
| FSEND ); |
| m_pSerializer->singleElementNS( XML_a, XML_tailEnd, |
| FSEND ); |
| m_pSerializer->endElementNS( XML_a, XML_ln ); |
| m_pSerializer->endElementNS( XML_pic, XML_spPr ); |
| |
| m_pSerializer->endElementNS( XML_pic, XML_pic ); |
| |
| m_pSerializer->endElementNS( XML_a, XML_graphicData ); |
| m_pSerializer->endElementNS( XML_a, XML_graphic ); |
| m_pSerializer->endElementNS( XML_wp, XML_inline ); |
| |
| m_pSerializer->endElementNS( XML_w, XML_drawing ); |
| } |
| |
| void DocxAttributeOutput::OutputFlyFrame_Impl( const sw::Frame &rFrame, const Point& /*rNdTopLeft*/ ) |
| { |
| m_pSerializer->mark(); |
| |
| switch ( rFrame.GetWriterType() ) |
| { |
| case sw::Frame::eGraphic: |
| { |
| const SwNode *pNode = rFrame.GetContent(); |
| const SwGrfNode *pGrfNode = pNode ? pNode->GetGrfNode() : 0; |
| if ( pGrfNode ) |
| FlyFrameGraphic( *pGrfNode, rFrame.GetLayoutSize() ); |
| } |
| break; |
| case sw::Frame::eDrawing: |
| { |
| const SdrObject* pSdrObj = rFrame.GetFrmFmt().FindRealSdrObject(); |
| if ( pSdrObj ) |
| { |
| bool bSwapInPage = false; |
| if ( !pSdrObj->GetPage() ) |
| { |
| if ( SdrModel* pModel = m_rExport.pDoc->GetDrawModel() ) |
| { |
| if ( SdrPage *pPage = pModel->GetPage( 0 ) ) |
| { |
| bSwapInPage = true; |
| const_cast< SdrObject* >( pSdrObj )->SetPage( pPage ); |
| } |
| } |
| } |
| |
| m_pSerializer->startElementNS( XML_w, XML_pict, |
| FSEND ); |
| |
| m_rExport.VMLExporter().AddSdrObject( *pSdrObj ); |
| |
| m_pSerializer->endElementNS( XML_w, XML_pict ); |
| |
| if ( bSwapInPage ) |
| const_cast< SdrObject* >( pSdrObj )->SetPage( 0 ); |
| } |
| } |
| break; |
| default: |
| #if OSL_DEBUG_LEVEL > 0 |
| OSL_TRACE( "TODO DocxAttributeOutput::OutputFlyFrame_Impl( const sw::Frame& rFrame, const Point& rNdTopLeft ) - frame type '%s'\n", |
| rFrame.GetWriterType() == sw::Frame::eTxtBox? "eTxtBox": |
| ( rFrame.GetWriterType() == sw::Frame::eOle? "eOle": |
| ( rFrame.GetWriterType() == sw::Frame::eFormControl? "eFormControl": "???" ) ) ); |
| #endif |
| break; |
| } |
| |
| m_pSerializer->mergeTopMarks( sax_fastparser::MERGE_MARKS_POSTPONE ); |
| } |
| |
| void DocxAttributeOutput::StartStyle( const String& rName, bool bPapFmt, |
| sal_uInt16 nBase, sal_uInt16 nNext, sal_uInt16 /*nWwId*/, sal_uInt16 nId ) |
| { |
| OString aStyle( "style" ); |
| |
| m_pSerializer->startElementNS( XML_w, XML_style, |
| FSNS( XML_w, XML_type ), bPapFmt? "paragraph": "character", // FIXME is this correct? |
| FSNS( XML_w, XML_styleId ), ( aStyle + OString::valueOf( sal_Int32( nId ) ) ).getStr(), |
| FSEND ); |
| |
| m_pSerializer->singleElementNS( XML_w, XML_name, |
| FSNS( XML_w, XML_val ), OUStringToOString( OUString( rName ), RTL_TEXTENCODING_UTF8 ).getStr(), |
| FSEND ); |
| |
| if ( nBase != 0x0FFF ) |
| { |
| m_pSerializer->singleElementNS( XML_w, XML_basedOn, |
| FSNS( XML_w, XML_val ), ( aStyle + OString::valueOf( sal_Int32( nBase ) ) ).getStr(), |
| FSEND ); |
| } |
| |
| m_pSerializer->singleElementNS( XML_w, XML_next, |
| FSNS( XML_w, XML_val ), ( aStyle + OString::valueOf( sal_Int32( nNext ) ) ).getStr(), |
| FSEND ); |
| } |
| |
| void DocxAttributeOutput::EndStyle() |
| { |
| m_pSerializer->endElementNS( XML_w, XML_style ); |
| } |
| |
| void DocxAttributeOutput::StartStyleProperties( bool bParProp, sal_uInt16 /*nStyle*/ ) |
| { |
| if ( bParProp ) |
| { |
| m_pSerializer->startElementNS( XML_w, XML_pPr, FSEND ); |
| InitCollectedParagraphProperties(); |
| } |
| else |
| { |
| m_pSerializer->startElementNS( XML_w, XML_rPr, FSEND ); |
| InitCollectedRunProperties(); |
| } |
| } |
| |
| void DocxAttributeOutput::EndStyleProperties( bool bParProp ) |
| { |
| if ( bParProp ) |
| { |
| WriteCollectedParagraphProperties(); |
| m_pSerializer->endElementNS( XML_w, XML_pPr ); |
| } |
| else |
| { |
| WriteCollectedRunProperties(); |
| m_pSerializer->endElementNS( XML_w, XML_rPr ); |
| } |
| } |
| |
| void DocxAttributeOutput::OutlineNumbering( sal_uInt8 nLvl, const SwNumFmt& /*rNFmt*/, const SwFmt& /*rFmt*/ ) |
| { |
| if ( nLvl >= WW8ListManager::nMaxLevel ) |
| nLvl = WW8ListManager::nMaxLevel - 1; |
| |
| m_pSerializer->singleElementNS( XML_w, XML_outlineLvl, |
| FSNS( XML_w, XML_val ), OString::valueOf( sal_Int32( nLvl ) ).getStr( ), |
| FSEND ); |
| } |
| |
| void DocxAttributeOutput::PageBreakBefore( bool bBreak ) |
| { |
| if ( bBreak ) |
| m_pSerializer->singleElementNS( XML_w, XML_pageBreakBefore, FSEND ); |
| else |
| m_pSerializer->singleElementNS( XML_w, XML_pageBreakBefore, |
| FSNS( XML_w, XML_val ), "off", |
| FSEND ); |
| } |
| |
| void DocxAttributeOutput::SectionBreak( sal_uInt8 nC, const WW8_SepInfo* pSectionInfo ) |
| { |
| switch ( nC ) |
| { |
| case msword::ColumnBreak: |
| // The column break should be output in the next paragraph... |
| m_nColBreakStatus = COLBRK_POSTPONE; |
| break; |
| case msword::PageBreak: |
| if ( pSectionInfo ) |
| { |
| if ( !m_bParagraphOpened ) |
| { |
| // Create a dummy paragraph if needed |
| m_pSerializer->startElementNS( XML_w, XML_p, FSEND ); |
| m_pSerializer->startElementNS( XML_w, XML_pPr, FSEND ); |
| |
| m_rExport.SectionProperties( *pSectionInfo ); |
| |
| m_pSerializer->endElementNS( XML_w, XML_pPr ); |
| m_pSerializer->endElementNS( XML_w, XML_p ); |
| } |
| else |
| { |
| // postpone the output of this; it has to be done inside the |
| // paragraph properties, so remember it until then |
| m_pSectionInfo = pSectionInfo; |
| } |
| } |
| else |
| { |
| m_pSerializer->startElementNS( XML_w, XML_r, FSEND ); |
| m_pSerializer->singleElementNS( XML_w, XML_br, |
| FSNS( XML_w, XML_type ), "page", FSEND ); |
| m_pSerializer->endElementNS( XML_w, XML_r ); |
| } |
| break; |
| default: |
| #if OSL_DEBUG_LEVEL > 0 |
| OSL_TRACE( "Unknown section break to write: %d\n", nC ); |
| #endif |
| break; |
| } |
| } |
| |
| void DocxAttributeOutput::StartSection() |
| { |
| m_pSerializer->startElementNS( XML_w, XML_sectPr, FSEND ); |
| m_bOpenedSectPr = true; |
| } |
| |
| void DocxAttributeOutput::EndSection() |
| { |
| // Write the section properties |
| if ( m_pSpacingAttrList ) |
| { |
| XFastAttributeListRef xAttrList( m_pSpacingAttrList ); |
| m_pSpacingAttrList = NULL; |
| |
| m_pSerializer->singleElementNS( XML_w, XML_pgMar, xAttrList ); |
| } |
| |
| m_pSerializer->endElementNS( XML_w, XML_sectPr ); |
| m_bOpenedSectPr = false; |
| } |
| |
| void DocxAttributeOutput::SectionFormProtection( bool bProtected ) |
| { |
| if ( bProtected ) |
| m_pSerializer->singleElementNS( XML_w, XML_formProt, FSEND ); |
| else |
| m_pSerializer->singleElementNS( XML_w, XML_formProt, |
| FSNS( XML_w, XML_val ), "off", FSEND ); |
| } |
| |
| void DocxAttributeOutput::SectionLineNumbering( sal_uLong /*nRestartNo*/, const SwLineNumberInfo& /*rLnNumInfo*/ ) |
| { |
| // see 2.6.8 lnNumType (Line Numbering Settings) |
| #if OSL_DEBUG_LEVEL > 0 |
| OSL_TRACE( "TODO DocxAttributeOutput::SectionLineNumbering()\n" ); |
| #endif |
| } |
| |
| void DocxAttributeOutput::SectionTitlePage() |
| { |
| m_pSerializer->singleElementNS( XML_w, XML_titlePg, FSEND ); |
| } |
| |
| void DocxAttributeOutput::SectionPageBorders( const SwFrmFmt* pFmt, const SwFrmFmt* /*pFirstPageFmt*/ ) |
| { |
| // Output the margins |
| |
| |
| const SvxBoxItem& rBox = pFmt->GetBox( ); |
| |
| const SvxBorderLine* pBottom = rBox.GetBottom( ); |
| const SvxBorderLine* pTop = rBox.GetTop( ); |
| const SvxBorderLine* pLeft = rBox.GetLeft( ); |
| const SvxBorderLine* pRight = rBox.GetRight( ); |
| |
| if ( pBottom || pTop || pLeft || pRight ) |
| { |
| // All distances are relative to the text margins |
| m_pSerializer->startElementNS( XML_w, XML_pgBorders, |
| FSNS( XML_w, XML_display ), "allPages", |
| FSNS( XML_w, XML_offsetFrom ), "text", |
| FSEND ); |
| |
| m_pSerializer->mark(); |
| |
| m_pSerializer->endElementNS( XML_w, XML_pgBorders ); |
| m_pSerializer->mark(); |
| } |
| } |
| |
| void DocxAttributeOutput::SectionBiDi( bool bBiDi ) |
| { |
| if ( bBiDi ) |
| m_pSerializer->singleElementNS( XML_w, XML_bidi, FSEND ); |
| } |
| |
| static OString impl_NumberingType( sal_uInt16 nNumberingType ) |
| { |
| OString aType; |
| |
| switch ( nNumberingType ) |
| { |
| case SVX_NUM_CHARS_UPPER_LETTER: |
| case SVX_NUM_CHARS_UPPER_LETTER_N: aType = "upperLetter"; break; |
| case SVX_NUM_CHARS_LOWER_LETTER: |
| case SVX_NUM_CHARS_LOWER_LETTER_N: aType = "lowerLetter"; break; |
| case SVX_NUM_ROMAN_UPPER: aType = "upperRoman"; break; |
| case SVX_NUM_ROMAN_LOWER: aType = "lowerRoman"; break; |
| |
| case SVX_NUM_ARABIC: aType = "decimal"; break; |
| |
| case SVX_NUM_BITMAP: |
| case SVX_NUM_CHAR_SPECIAL: aType = "bullet"; break; |
| |
| default: aType = "none"; break; |
| } |
| |
| return aType; |
| } |
| |
| void DocxAttributeOutput::SectionPageNumbering( sal_uInt16 nNumType, sal_uInt16 nPageRestartNumber ) |
| { |
| // FIXME Not called properly with page styles like "First Page" |
| |
| FastAttributeList* pAttr = m_pSerializer->createAttrList(); |
| |
| // 0 means no restart: then don't output that attribute if 0 |
| if ( nPageRestartNumber > 0 ) |
| pAttr->add( FSNS( XML_w, XML_start ), OString::valueOf( sal_Int32( nPageRestartNumber ) ) ); |
| |
| // nNumType corresponds to w:fmt. See WW8Export::GetNumId() for more precisions |
| OString aFmt( impl_NumberingType( nNumType ) ); |
| if ( aFmt.getLength() ) |
| pAttr->add( FSNS( XML_w, XML_fmt ), aFmt.getStr() ); |
| |
| XFastAttributeListRef xAttrs( pAttr ); |
| m_pSerializer->singleElementNS( XML_w, XML_pgNumType, xAttrs ); |
| |
| // see 2.6.12 pgNumType (Page Numbering Settings) |
| #if OSL_DEBUG_LEVEL > 0 |
| OSL_TRACE( "TODO DocxAttributeOutput::SectionPageNumbering()\n" ); |
| #endif |
| } |
| |
| void DocxAttributeOutput::SectionType( sal_uInt8 nBreakCode ) |
| { |
| /* break code: 0 No break, 1 New column |
| 2 New page, 3 Even page, 4 Odd page |
| */ |
| const char* pType = NULL; |
| switch ( nBreakCode ) |
| { |
| case 1: pType = "nextColumn"; break; |
| case 2: pType = "nextPage"; break; |
| case 3: pType = "evenPage"; break; |
| case 4: pType = "oddPage"; break; |
| default: pType = "continuous"; break; |
| } |
| |
| if ( pType ) |
| m_pSerializer->singleElementNS( XML_w, XML_type, |
| FSNS( XML_w, XML_val ), pType, |
| FSEND ); |
| } |
| |
| void DocxAttributeOutput::StartFont( const String& rFamilyName ) const |
| { |
| m_pSerializer->startElementNS( XML_w, XML_font, |
| FSNS( XML_w, XML_name ), OUStringToOString( OUString( rFamilyName ), RTL_TEXTENCODING_UTF8 ).getStr(), |
| FSEND ); |
| } |
| |
| void DocxAttributeOutput::EndFont() const |
| { |
| m_pSerializer->endElementNS( XML_w, XML_font ); |
| } |
| |
| void DocxAttributeOutput::FontAlternateName( const String& rName ) const |
| { |
| m_pSerializer->singleElementNS( XML_w, XML_altName, |
| FSNS( XML_w, XML_val ), OUStringToOString( OUString( rName ), RTL_TEXTENCODING_UTF8 ).getStr(), |
| FSEND ); |
| } |
| |
| void DocxAttributeOutput::FontCharset( sal_uInt8 nCharSet ) const |
| { |
| OString aCharSet( OString::valueOf( sal_Int32( nCharSet ), 16 ) ); |
| if ( aCharSet.getLength() == 1 ) |
| aCharSet = OString( "0" ) + aCharSet; |
| |
| m_pSerializer->singleElementNS( XML_w, XML_charset, |
| FSNS( XML_w, XML_val ), aCharSet.getStr(), |
| FSEND ); |
| } |
| |
| void DocxAttributeOutput::FontFamilyType( FontFamily eFamily ) const |
| { |
| const char *pFamily = NULL; |
| switch ( eFamily ) |
| { |
| case FAMILY_ROMAN: pFamily = "roman"; break; |
| case FAMILY_SWISS: pFamily = "swiss"; break; |
| case FAMILY_MODERN: pFamily = "modern"; break; |
| case FAMILY_SCRIPT: pFamily = "script"; break; |
| case FAMILY_DECORATIVE: pFamily = "decorative"; break; |
| default: pFamily = "auto"; break; // no font family |
| } |
| |
| if ( pFamily ) |
| m_pSerializer->singleElementNS( XML_w, XML_family, |
| FSNS( XML_w, XML_val ), pFamily, |
| FSEND ); |
| } |
| |
| void DocxAttributeOutput::FontPitchType( FontPitch ePitch ) const |
| { |
| const char *pPitch = NULL; |
| switch ( ePitch ) |
| { |
| case PITCH_VARIABLE: pPitch = "variable"; break; |
| case PITCH_FIXED: pPitch = "fixed"; break; |
| default: pPitch = "default"; break; // no info about the pitch |
| } |
| |
| if ( pPitch ) |
| m_pSerializer->singleElementNS( XML_w, XML_pitch, |
| FSNS( XML_w, XML_val ), pPitch, |
| FSEND ); |
| } |
| |
| void DocxAttributeOutput::NumberingDefinition( sal_uInt16 nId, const SwNumRule &rRule ) |
| { |
| // nId is the same both for abstract numbering definition as well as the |
| // numbering definition itself |
| // TODO check that this is actually true & fix if not ;-) |
| OString aId( OString::valueOf( sal_Int32( nId ) ) ); |
| |
| m_pSerializer->startElementNS( XML_w, XML_num, |
| FSNS( XML_w, XML_numId ), aId.getStr(), |
| FSEND ); |
| |
| m_pSerializer->singleElementNS( XML_w, XML_abstractNumId, |
| FSNS( XML_w, XML_val ), aId.getStr(), |
| FSEND ); |
| |
| #if OSL_DEBUG_LEVEL > 0 |
| // TODO ww8 version writes this, anything to do about it here? |
| if ( rRule.IsContinusNum() ) |
| OSL_TRACE( "TODO DocxAttributeOutput::NumberingDefinition()\n" ); |
| #else |
| (void) rRule; // to quiet the warning... |
| #endif |
| |
| m_pSerializer->endElementNS( XML_w, XML_num ); |
| } |
| |
| void DocxAttributeOutput::StartAbstractNumbering( sal_uInt16 nId ) |
| { |
| m_pSerializer->startElementNS( XML_w, XML_abstractNum, |
| FSNS( XML_w, XML_abstractNumId ), OString::valueOf( sal_Int32( nId ) ).getStr(), |
| FSEND ); |
| } |
| |
| void DocxAttributeOutput::EndAbstractNumbering() |
| { |
| m_pSerializer->endElementNS( XML_w, XML_abstractNum ); |
| } |
| |
| void DocxAttributeOutput::NumberingLevel( sal_uInt8 nLevel, |
| sal_uInt16 nStart, |
| sal_uInt16 nNumberingType, |
| SvxAdjust eAdjust, |
| const sal_uInt8 * /*pNumLvlPos*/, |
| sal_uInt8 nFollow, |
| const wwFont *pFont, |
| const SfxItemSet *pOutSet, |
| sal_Int16 nIndentAt, |
| sal_Int16 nFirstLineIndex, |
| sal_Int16 /*nListTabPos*/, |
| const String &rNumberingString ) |
| { |
| m_pSerializer->startElementNS( XML_w, XML_lvl, |
| FSNS( XML_w, XML_ilvl ), OString::valueOf( sal_Int32( nLevel ) ).getStr(), |
| FSEND ); |
| |
| // start with the nStart value |
| m_pSerializer->singleElementNS( XML_w, XML_start, |
| FSNS( XML_w, XML_val ), OString::valueOf( sal_Int32( nStart ) ).getStr(), |
| FSEND ); |
| |
| // format |
| OString aFmt( impl_NumberingType( nNumberingType ) ); |
| |
| if ( aFmt.getLength() ) |
| m_pSerializer->singleElementNS( XML_w, XML_numFmt, |
| FSNS( XML_w, XML_val ), aFmt.getStr(), |
| FSEND ); |
| |
| // justification |
| const char *pJc; |
| switch ( eAdjust ) |
| { |
| case SVX_ADJUST_CENTER: pJc = "center"; break; |
| case SVX_ADJUST_RIGHT: pJc = "right"; break; |
| default: pJc = "left"; break; |
| } |
| m_pSerializer->singleElementNS( XML_w, XML_lvlJc, |
| FSNS( XML_w, XML_val ), pJc, |
| FSEND ); |
| |
| // suffix |
| const char *pSuffix = NULL; |
| switch ( nFollow ) |
| { |
| case 1: pSuffix = "space"; break; |
| case 2: pSuffix = "nothing"; break; |
| default: /*pSuffix = "tab";*/ break; |
| } |
| if ( pSuffix ) |
| m_pSerializer->singleElementNS( XML_w, XML_suff, |
| FSNS( XML_w, XML_val ), pSuffix, |
| FSEND ); |
| |
| // text |
| OUString aText( rNumberingString ); |
| OUStringBuffer aBuffer( aText.getLength() + WW8ListManager::nMaxLevel ); |
| |
| const sal_Unicode *pPrev = aText.getStr(); |
| const sal_Unicode *pIt = aText.getStr(); |
| while ( pIt < aText.getStr() + aText.getLength() ) |
| { |
| // convert the level values to %NUMBER form |
| // (we don't use pNumLvlPos at all) |
| // FIXME so far we support the ww8 limit of levels only |
| if ( *pIt < sal_Unicode( WW8ListManager::nMaxLevel ) ) |
| { |
| aBuffer.append( pPrev, pIt - pPrev ); |
| aBuffer.appendAscii( "%" ); |
| aBuffer.append( OUString::valueOf( sal_Int32( *pIt ) + 1 ) ); |
| |
| pPrev = pIt + 1; |
| } |
| ++pIt; |
| } |
| if ( pPrev < pIt ) |
| aBuffer.append( pPrev, pIt - pPrev ); |
| |
| m_pSerializer->singleElementNS( XML_w, XML_lvlText, |
| FSNS( XML_w, XML_val ), OUStringToOString( aBuffer.makeStringAndClear(), RTL_TEXTENCODING_UTF8 ).getStr(), |
| FSEND ); |
| |
| // indentation |
| m_pSerializer->startElementNS( XML_w, XML_pPr, FSEND ); |
| m_pSerializer->singleElementNS( XML_w, XML_ind, |
| FSNS( XML_w, XML_left ), OString::valueOf( sal_Int32( nIndentAt ) ).getStr(), |
| FSNS( XML_w, XML_hanging ), OString::valueOf( sal_Int32( -nFirstLineIndex ) ).getStr(), |
| FSEND ); |
| m_pSerializer->endElementNS( XML_w, XML_pPr ); |
| |
| // font |
| if ( pOutSet ) |
| { |
| m_pSerializer->startElementNS( XML_w, XML_rPr, FSEND ); |
| |
| if ( pFont ) |
| { |
| OString aFamilyName( OUStringToOString( OUString( pFont->GetFamilyName() ), RTL_TEXTENCODING_UTF8 ) ); |
| m_pSerializer->singleElementNS( XML_w, XML_rFonts, |
| FSNS( XML_w, XML_ascii ), aFamilyName.getStr(), |
| FSNS( XML_w, XML_hAnsi ), aFamilyName.getStr(), |
| FSNS( XML_w, XML_cs ), aFamilyName.getStr(), |
| FSNS( XML_w, XML_hint ), "default", |
| FSEND ); |
| } |
| m_rExport.OutputItemSet( *pOutSet, false, true, i18n::ScriptType::LATIN ); |
| |
| m_pSerializer->endElementNS( XML_w, XML_rPr ); |
| } |
| |
| // TODO anything to do about nListTabPos? |
| |
| m_pSerializer->endElementNS( XML_w, XML_lvl ); |
| } |
| |
| void DocxAttributeOutput::CharCaseMap( const SvxCaseMapItem& rCaseMap ) |
| { |
| switch ( rCaseMap.GetValue() ) |
| { |
| case SVX_CASEMAP_KAPITAELCHEN: |
| m_pSerializer->singleElementNS( XML_w, XML_smallCaps, FSEND ); |
| break; |
| case SVX_CASEMAP_VERSALIEN: |
| m_pSerializer->singleElementNS( XML_w, XML_caps, FSEND ); |
| break; |
| default: // Something that ooxml does not support |
| m_pSerializer->singleElementNS( XML_w, XML_smallCaps, FSNS( XML_w, XML_val ), "off", FSEND ); |
| m_pSerializer->singleElementNS( XML_w, XML_caps, FSNS( XML_w, XML_val ), "off", FSEND ); |
| break; |
| } |
| } |
| |
| void DocxAttributeOutput::CharColor( const SvxColorItem& rColor ) |
| { |
| const Color aColor( rColor.GetValue() ); |
| OString aColorString; |
| |
| aColorString = impl_ConvertColor( aColor ); |
| |
| m_pSerializer->singleElementNS( XML_w, XML_color, |
| FSNS( XML_w, XML_val ), aColorString.getStr(), FSEND ); |
| } |
| |
| void DocxAttributeOutput::CharContour( const SvxContourItem& rContour ) |
| { |
| if ( rContour.GetValue() ) |
| m_pSerializer->singleElementNS( XML_w, XML_outline, FSEND ); |
| else |
| m_pSerializer->singleElementNS( XML_w, XML_outline, FSNS( XML_w, XML_val ), "off", FSEND ); |
| } |
| |
| void DocxAttributeOutput::CharCrossedOut( const SvxCrossedOutItem& rCrossedOut ) |
| { |
| switch ( rCrossedOut.GetStrikeout() ) |
| { |
| case STRIKEOUT_DOUBLE: |
| m_pSerializer->singleElementNS( XML_w, XML_dstrike, FSEND ); |
| break; |
| case STRIKEOUT_NONE: |
| m_pSerializer->singleElementNS( XML_w, XML_dstrike, FSNS( XML_w, XML_val ), "off", FSEND ); |
| m_pSerializer->singleElementNS( XML_w, XML_strike, FSNS( XML_w, XML_val ), "off", FSEND ); |
| break; |
| default: |
| m_pSerializer->singleElementNS( XML_w, XML_strike, FSEND ); |
| break; |
| } |
| } |
| |
| void DocxAttributeOutput::CharEscapement( const SvxEscapementItem& /*rEscapement*/ ) |
| { |
| #if OSL_DEBUG_LEVEL > 0 |
| OSL_TRACE( "TODO DocxAttributeOutput::CharEscapement()\n" ); |
| #endif |
| } |
| |
| void DocxAttributeOutput::CharFont( const SvxFontItem& rFont) |
| { |
| if (!m_pFontsAttrList) |
| m_pFontsAttrList = m_pSerializer->createAttrList(); |
| OUString sFontName(rFont.GetFamilyName()); |
| OString sFontNameUtf8 = OUStringToOString(sFontName, RTL_TEXTENCODING_UTF8); |
| m_pFontsAttrList->add(FSNS(XML_w, XML_ascii), sFontNameUtf8); |
| m_pFontsAttrList->add(FSNS(XML_w, XML_hAnsi), sFontNameUtf8); |
| } |
| |
| void DocxAttributeOutput::CharFontSize( const SvxFontHeightItem& rFontSize) |
| { |
| OString fontSize = OString::valueOf( sal_Int32( ( rFontSize.GetHeight() + 5 ) / 10 ) ); |
| |
| switch ( rFontSize.Which() ) |
| { |
| case RES_CHRATR_FONTSIZE: |
| case RES_CHRATR_CJK_FONTSIZE: |
| m_pSerializer->singleElementNS( XML_w, XML_sz, FSNS( XML_w, XML_val ), fontSize.getStr(), FSEND ); |
| break; |
| case RES_CHRATR_CTL_FONTSIZE: |
| m_pSerializer->singleElementNS( XML_w, XML_szCs, FSNS( XML_w, XML_val ), fontSize.getStr(), FSEND ); |
| break; |
| } |
| } |
| |
| void DocxAttributeOutput::CharKerning( const SvxKerningItem& rKerning ) |
| { |
| OString aKerning = OString::valueOf( ( sal_Int32 ) rKerning.GetValue() ); |
| m_pSerializer->singleElementNS( XML_w, XML_kern, FSNS(XML_w, XML_val), aKerning.getStr(), FSEND ); |
| } |
| |
| void DocxAttributeOutput::CharLanguage( const SvxLanguageItem& rLanguage ) |
| { |
| if (!m_pCharLangAttrList) |
| m_pCharLangAttrList = m_pSerializer->createAttrList(); |
| |
| ::com::sun::star::lang::Locale xLocale= MsLangId::convertLanguageToLocale( rLanguage.GetLanguage( ) ); |
| OString sLanguage = OUStringToOString(xLocale.Language, RTL_TEXTENCODING_UTF8); |
| OString sCountry = OUStringToOString(xLocale.Country, RTL_TEXTENCODING_UTF8); |
| |
| OString aLanguageCode = sLanguage + "-" + sCountry; |
| |
| switch ( rLanguage.Which() ) |
| { |
| case RES_CHRATR_LANGUAGE: |
| m_pCharLangAttrList->add(FSNS(XML_w, XML_val), aLanguageCode); |
| break; |
| case RES_CHRATR_CJK_LANGUAGE: |
| m_pCharLangAttrList->add(FSNS(XML_w, XML_eastAsia), aLanguageCode); |
| break; |
| case RES_CHRATR_CTL_LANGUAGE: |
| m_pCharLangAttrList->add(FSNS(XML_w, XML_bidi), aLanguageCode); |
| break; |
| } |
| } |
| |
| void DocxAttributeOutput::CharPosture( const SvxPostureItem& rPosture ) |
| { |
| if ( rPosture.GetPosture() != ITALIC_NONE ) |
| m_pSerializer->singleElementNS( XML_w, XML_i, FSEND ); |
| else |
| m_pSerializer->singleElementNS( XML_w, XML_i, FSNS( XML_w, XML_val ), "off", FSEND ); |
| } |
| |
| void DocxAttributeOutput::CharShadow( const SvxShadowedItem& rShadow ) |
| { |
| if ( rShadow.GetValue() ) |
| m_pSerializer->singleElementNS( XML_w, XML_shadow, FSEND ); |
| else |
| m_pSerializer->singleElementNS( XML_w, XML_shadow, FSNS( XML_w, XML_val ), "off", FSEND ); |
| } |
| |
| void DocxAttributeOutput::CharUnderline( const SvxUnderlineItem& rUnderline ) |
| { |
| const char *pUnderline; |
| |
| switch ( rUnderline.GetLineStyle() ) |
| { |
| case UNDERLINE_SINGLE: pUnderline = "single"; break; |
| case UNDERLINE_BOLD: pUnderline = "thick"; break; |
| case UNDERLINE_DOUBLE: pUnderline = "double"; break; |
| case UNDERLINE_DOTTED: pUnderline = "dotted"; break; |
| case UNDERLINE_DASH: pUnderline = "dash"; break; |
| case UNDERLINE_DASHDOT: pUnderline = "dotDash"; break; |
| case UNDERLINE_DASHDOTDOT: pUnderline = "dotDotDash"; break; |
| case UNDERLINE_WAVE: pUnderline = "wave"; break; |
| case UNDERLINE_BOLDDOTTED: pUnderline = "dottedHeavy"; break; |
| case UNDERLINE_BOLDDASH: pUnderline = "dashedHeavy"; break; |
| case UNDERLINE_LONGDASH: pUnderline = "dashLongHeavy"; break; |
| case UNDERLINE_BOLDLONGDASH: pUnderline = "dashLongHeavy"; break; |
| case UNDERLINE_BOLDDASHDOT: pUnderline = "dashDotHeavy"; break; |
| case UNDERLINE_BOLDDASHDOTDOT: pUnderline = "dashDotDotHeavy"; break; |
| case UNDERLINE_BOLDWAVE: pUnderline = "wavyHeavy"; break; |
| case UNDERLINE_DOUBLEWAVE: pUnderline = "wavyDouble"; break; |
| case UNDERLINE_NONE: // fall through |
| default: pUnderline = "none"; break; |
| } |
| |
| m_pSerializer->singleElementNS( XML_w, XML_u, FSNS( XML_w, XML_val ), pUnderline, FSEND ); |
| } |
| |
| void DocxAttributeOutput::CharWeight( const SvxWeightItem& rWeight ) |
| { |
| if ( rWeight.GetWeight() == WEIGHT_BOLD ) |
| m_pSerializer->singleElementNS( XML_w, XML_b, FSEND ); |
| else |
| m_pSerializer->singleElementNS( XML_w, XML_b, FSNS( XML_w, XML_val ), "off", FSEND ); |
| } |
| |
| void DocxAttributeOutput::CharAutoKern( const SvxAutoKernItem& ) |
| { |
| #if OSL_DEBUG_LEVEL > 0 |
| OSL_TRACE( "TODO DocxAttributeOutput::CharAutoKern()\n" ); |
| #endif |
| } |
| |
| void DocxAttributeOutput::CharAnimatedText( const SvxBlinkItem& rBlink ) |
| { |
| if ( rBlink.GetValue() ) |
| m_pSerializer->singleElementNS(XML_w, XML_effect, FSNS( XML_w, XML_val ), "blinkBackground", FSEND ); |
| else |
| m_pSerializer->singleElementNS(XML_w, XML_effect, FSNS( XML_w, XML_val ), "none", FSEND ); |
| } |
| |
| void DocxAttributeOutput::CharBackground( const SvxBrushItem& rBrush ) |
| { |
| m_pSerializer->singleElementNS( XML_w, XML_shd, |
| FSNS( XML_w, XML_fill ), impl_ConvertColor( rBrush.GetColor() ).getStr(), FSEND ); |
| } |
| |
| void DocxAttributeOutput::CharFontCJK( const SvxFontItem& rFont ) |
| { |
| if (!m_pFontsAttrList) |
| m_pFontsAttrList = m_pSerializer->createAttrList(); |
| OUString sFontName(rFont.GetFamilyName()); |
| OString sFontNameUtf8 = OUStringToOString(sFontName, RTL_TEXTENCODING_UTF8); |
| m_pFontsAttrList->add(FSNS(XML_w, XML_eastAsia), sFontNameUtf8); |
| } |
| |
| void DocxAttributeOutput::CharPostureCJK( const SvxPostureItem& rPosture ) |
| { |
| if ( rPosture.GetPosture() != ITALIC_NONE ) |
| m_pSerializer->singleElementNS( XML_w, XML_i, FSEND ); |
| else |
| m_pSerializer->singleElementNS( XML_w, XML_i, FSNS( XML_w, XML_val ), "off", FSEND ); |
| } |
| |
| void DocxAttributeOutput::CharWeightCJK( const SvxWeightItem& rWeight ) |
| { |
| if ( rWeight.GetWeight() == WEIGHT_BOLD ) |
| m_pSerializer->singleElementNS( XML_w, XML_b, FSEND ); |
| else |
| m_pSerializer->singleElementNS( XML_w, XML_b, FSNS( XML_w, XML_val ), "off", FSEND ); |
| } |
| |
| void DocxAttributeOutput::CharFontCTL( const SvxFontItem& rFont ) |
| { |
| if (!m_pFontsAttrList) |
| m_pFontsAttrList = m_pSerializer->createAttrList(); |
| OUString sFontName(rFont.GetFamilyName()); |
| OString sFontNameUtf8 = OUStringToOString(sFontName, RTL_TEXTENCODING_UTF8); |
| m_pFontsAttrList->add(FSNS(XML_w, XML_cs), sFontNameUtf8); |
| |
| } |
| |
| void DocxAttributeOutput::CharPostureCTL( const SvxPostureItem& rPosture) |
| { |
| if ( rPosture.GetPosture() != ITALIC_NONE ) |
| m_pSerializer->singleElementNS( XML_w, XML_iCs, FSEND ); |
| else |
| m_pSerializer->singleElementNS( XML_w, XML_iCs, FSNS( XML_w, XML_val ), "off", FSEND ); |
| } |
| |
| void DocxAttributeOutput::CharWeightCTL( const SvxWeightItem& rWeight ) |
| { |
| if ( rWeight.GetWeight() == WEIGHT_BOLD ) |
| m_pSerializer->singleElementNS( XML_w, XML_bCs, FSEND ); |
| else |
| m_pSerializer->singleElementNS( XML_w, XML_bCs, FSNS( XML_w, XML_val ), "off", FSEND ); |
| } |
| |
| void DocxAttributeOutput::CharRotate( const SvxCharRotateItem& rRotate) |
| { |
| if ( !rRotate.GetValue() ) |
| return; |
| |
| if (!m_pEastAsianLayoutAttrList) |
| m_pEastAsianLayoutAttrList = m_pSerializer->createAttrList(); |
| OString sTrue((sal_Char *)"true"); |
| m_pEastAsianLayoutAttrList->add(FSNS(XML_w, XML_vert), sTrue); |
| |
| if (rRotate.IsFitToLine()) |
| m_pEastAsianLayoutAttrList->add(FSNS(XML_w, XML_vertCompress), sTrue); |
| } |
| |
| void DocxAttributeOutput::CharEmphasisMark( const SvxEmphasisMarkItem& rEmphasisMark ) |
| { |
| const char *pEmphasis; |
| |
| switch ( rEmphasisMark.GetValue() ) |
| { |
| case EMPHASISMARK_NONE: pEmphasis = "none"; break; |
| case EMPHASISMARK_SIDE_DOTS: pEmphasis = "dot"; break; |
| case EMPHASISMARK_CIRCLE_ABOVE: pEmphasis = "circle"; break; |
| case EMPHASISMARK_DOTS_BELOW: pEmphasis = "underDot"; break; |
| default: pEmphasis = "comma"; break; |
| } |
| |
| m_pSerializer->singleElementNS( XML_w, XML_em, FSNS( XML_w, XML_val ), pEmphasis, FSEND ); |
| } |
| |
| void DocxAttributeOutput::CharTwoLines( const SvxTwoLinesItem& rTwoLines ) |
| { |
| if ( !rTwoLines.GetValue() ) |
| return; |
| |
| if (!m_pEastAsianLayoutAttrList) |
| m_pEastAsianLayoutAttrList = m_pSerializer->createAttrList(); |
| OString sTrue((sal_Char *)"true"); |
| m_pEastAsianLayoutAttrList->add(FSNS(XML_w, XML_combine), sTrue); |
| |
| sal_Unicode cStart = rTwoLines.GetStartBracket(); |
| sal_Unicode cEnd = rTwoLines.GetEndBracket(); |
| |
| if (!cStart && !cEnd) |
| return; |
| |
| OString sBracket; |
| if ((cStart == '{') || (cEnd == '}')) |
| sBracket = (sal_Char *)"curly"; |
| else if ((cStart == '<') || (cEnd == '>')) |
| sBracket = (sal_Char *)"angle"; |
| else if ((cStart == '[') || (cEnd == ']')) |
| sBracket = (sal_Char *)"square"; |
| else |
| sBracket = (sal_Char *)"round"; |
| m_pEastAsianLayoutAttrList->add(FSNS(XML_w, XML_combineBrackets), sBracket); |
| } |
| |
| void DocxAttributeOutput::CharScaleWidth( const SvxCharScaleWidthItem& rScaleWidth ) |
| { |
| m_pSerializer->singleElementNS( XML_w, XML_w, |
| FSNS( XML_w, XML_val ), rtl::OString::valueOf( sal_Int32( rScaleWidth.GetValue() ) ).getStr(), FSEND ); |
| } |
| |
| void DocxAttributeOutput::CharRelief( const SvxCharReliefItem& rRelief ) |
| { |
| switch ( rRelief.GetValue() ) |
| { |
| case RELIEF_EMBOSSED: |
| m_pSerializer->singleElementNS( XML_w, XML_emboss, FSEND ); |
| break; |
| case RELIEF_ENGRAVED: |
| m_pSerializer->singleElementNS( XML_w, XML_imprint, FSEND ); |
| break; |
| default: |
| m_pSerializer->singleElementNS( XML_w, XML_emboss, FSNS( XML_w, XML_val ), "off", FSEND ); |
| m_pSerializer->singleElementNS( XML_w, XML_imprint, FSNS( XML_w, XML_val ), "off", FSEND ); |
| break; |
| } |
| } |
| |
| void DocxAttributeOutput::CharHidden( const SvxCharHiddenItem& rHidden ) |
| { |
| if ( rHidden.GetValue() ) |
| m_pSerializer->singleElementNS( XML_w, XML_vanish, FSEND ); |
| else |
| m_pSerializer->singleElementNS( XML_w, XML_vanish, FSNS( XML_w, XML_val ), "off", FSEND ); |
| } |
| |
| void DocxAttributeOutput::TextINetFormat( const SwFmtINetFmt& rLink ) |
| { |
| const SwTxtINetFmt* pINetFmt = rLink.GetTxtINetFmt(); |
| const SwCharFmt* pCharFmt = pINetFmt->GetCharFmt(); |
| |
| OString aStyleId( "style" ); |
| aStyleId += OString::valueOf( sal_Int32( m_rExport.GetId( *pCharFmt ) ) ); |
| |
| m_pSerializer->singleElementNS( XML_w, XML_rStyle, FSNS( XML_w, XML_val ), aStyleId.getStr(), FSEND ); |
| } |
| |
| void DocxAttributeOutput::TextCharFormat( const SwFmtCharFmt& ) |
| { |
| #if OSL_DEBUG_LEVEL > 0 |
| OSL_TRACE( "TODO DocxAttributeOutput::TextCharFormat()\n" ); |
| #endif |
| } |
| |
| void DocxAttributeOutput::RefField( const SwField& rFld, const String& rRef ) |
| { |
| sal_uInt16 nType = rFld.GetTyp( )->Which( ); |
| if ( nType == RES_GETEXPFLD ) |
| { |
| String sCmd = FieldString( ww::eREF ); |
| sCmd.APPEND_CONST_ASC( "\"" ); |
| sCmd += rRef; |
| sCmd.APPEND_CONST_ASC( "\" " ); |
| |
| m_rExport.OutputField( &rFld, ww::eREF, sCmd ); |
| } |
| |
| // There is nothing to do here for the set fields |
| } |
| |
| void DocxAttributeOutput::HiddenField( const SwField& /*rFld*/ ) |
| { |
| #if OSL_DEBUG_LEVEL > 0 |
| OSL_TRACE( "TODO DocxAttributeOutput::HiddenField()\n" ); |
| #endif |
| } |
| |
| void DocxAttributeOutput::PostitField( const SwField* /* pFld*/ ) |
| { |
| #if OSL_DEBUG_LEVEL > 0 |
| OSL_TRACE( "TODO DocxAttributeOutput::PostitField()\n" ); |
| #endif |
| } |
| |
| bool DocxAttributeOutput::DropdownField( const SwField* pFld ) |
| { |
| bool bExpand = false; |
| |
| ww::eField eType = ww::eFORMDROPDOWN; |
| String sCmd = FieldString( eType ); |
| GetExport( ).OutputField( pFld, eType, sCmd ); |
| |
| return bExpand; |
| } |
| |
| void DocxAttributeOutput::SetField( const SwField& rFld, ww::eField eType, const String& rCmd ) |
| { |
| // field bookmarks are handled in the EndRun method |
| GetExport().OutputField(&rFld, eType, rCmd ); |
| } |
| |
| void DocxAttributeOutput::WriteExpand( const SwField* pFld ) |
| { |
| // Will be written in the next End Run |
| String sCmd; |
| m_rExport.OutputField( pFld, ww::eUNKNOWN, sCmd ); |
| } |
| |
| void DocxAttributeOutput::WriteField_Impl( const SwField* pFld, ww::eField eType, const String& rFldCmd, sal_uInt8 nMode ) |
| { |
| struct FieldInfos infos; |
| infos.pField = pFld; |
| infos.sCmd = rFldCmd; |
| infos.eType = eType; |
| infos.bClose = WRITEFIELD_CLOSE & nMode; |
| infos.bOpen = WRITEFIELD_START & nMode; |
| |
| m_Fields.push_back( infos ); |
| |
| if ( pFld ) |
| { |
| sal_uInt16 nType = pFld->GetTyp( )->Which( ); |
| sal_uInt16 nSubType = pFld->GetSubType(); |
| |
| // TODO Any other field types here ? |
| if ( ( nType == RES_SETEXPFLD ) && ( nSubType & nsSwGetSetExpType::GSE_STRING ) ) |
| { |
| const SwSetExpField *pSet = ( const SwSetExpField* )( pFld ); |
| m_sFieldBkm = pSet->GetPar1( ); |
| } |
| else if ( nType == RES_DROPDOWN ) |
| { |
| const SwDropDownField* pDropDown = ( const SwDropDownField* )( pFld ); |
| m_sFieldBkm = pDropDown->GetName( ); |
| } |
| } |
| } |
| |
| void DocxAttributeOutput::WriteBookmarks_Impl( std::vector< OUString >& rStarts, |
| std::vector< OUString >& rEnds ) |
| { |
| for ( std::vector< OUString >::const_iterator it = rStarts.begin(), end = rStarts.end(); it < end; ++it ) |
| { |
| OString rName = OUStringToOString( *it, RTL_TEXTENCODING_UTF8 ).getStr( ); |
| m_rMarksStart.push_back( rName ); |
| } |
| rStarts.clear(); |
| |
| for ( std::vector< OUString >::const_iterator it = rEnds.begin(), end = rEnds.end(); it < end; ++it ) |
| { |
| OString rName = OUStringToOString( *it, RTL_TEXTENCODING_UTF8 ).getStr( ); |
| m_rMarksEnd.push_back( rName ); |
| } |
| rEnds.clear(); |
| } |
| |
| void DocxAttributeOutput::TextFootnote_Impl( const SwFmtFtn& rFootnote ) |
| { |
| const SwEndNoteInfo& rInfo = rFootnote.IsEndNote()? |
| m_rExport.pDoc->GetEndNoteInfo(): m_rExport.pDoc->GetFtnInfo(); |
| |
| // footnote/endnote run properties |
| const SwCharFmt* pCharFmt = rInfo.GetAnchorCharFmt( *m_rExport.pDoc ); |
| |
| OString aStyleId( "style" ); |
| aStyleId += OString::valueOf( sal_Int32( m_rExport.GetId( *pCharFmt ) ) ); |
| |
| m_pSerializer->singleElementNS( XML_w, XML_rStyle, FSNS( XML_w, XML_val ), aStyleId.getStr(), FSEND ); |
| |
| // remember the footnote/endnote to |
| // 1) write the footnoteReference/endnoteReference in EndRunProperties() |
| // 2) be able to dump them all to footnotes.xml/endnotes.xml |
| if ( !rFootnote.IsEndNote() ) |
| m_pFootnotesList->add( rFootnote ); |
| else |
| m_pEndnotesList->add( rFootnote ); |
| } |
| |
| void DocxAttributeOutput::FootnoteEndnoteReference() |
| { |
| sal_Int32 nId; |
| const SwFmtFtn *pFootnote = m_pFootnotesList->getCurrent( nId ); |
| |
| // both cannot be set at the same time - if they are, it's a bug |
| if ( !pFootnote ) |
| pFootnote = m_pEndnotesList->getCurrent( nId ); |
| |
| if ( !pFootnote ) |
| return; |
| |
| sal_Int32 nToken = pFootnote->IsEndNote()? XML_endnoteReference: XML_footnoteReference; |
| |
| // write it |
| if ( pFootnote->GetNumStr().Len() == 0 ) |
| { |
| // autonumbered |
| m_pSerializer->singleElementNS( XML_w, nToken, |
| FSNS( XML_w, XML_id ), ::rtl::OString::valueOf( nId ).getStr(), |
| FSEND ); |
| } |
| else |
| { |
| // not autonumbered |
| m_pSerializer->singleElementNS( XML_w, nToken, |
| FSNS( XML_w, XML_customMarkFollows ), "1", |
| FSNS( XML_w, XML_id ), ::rtl::OString::valueOf( nId ).getStr(), |
| FSEND ); |
| |
| RunText( pFootnote->GetNumStr() ); |
| } |
| } |
| |
| void DocxAttributeOutput::FootnotesEndnotes( bool bFootnotes ) |
| { |
| const FootnotesVector& rVector = bFootnotes? m_pFootnotesList->getVector(): m_pEndnotesList->getVector(); |
| |
| sal_Int32 nBody = bFootnotes? XML_footnotes: XML_endnotes; |
| sal_Int32 nItem = bFootnotes? XML_footnote: XML_endnote; |
| |
| m_pSerializer->startElementNS( XML_w, nBody, |
| FSNS( XML_xmlns, XML_w ), "http://schemas.openxmlformats.org/wordprocessingml/2006/main", |
| FSEND ); |
| |
| sal_Int32 nIndex = 0; |
| |
| // separator |
| m_pSerializer->startElementNS( XML_w, nItem, |
| FSNS( XML_w, XML_id ), OString::valueOf( nIndex++ ).getStr(), |
| FSNS( XML_w, XML_type ), "separator", |
| FSEND ); |
| m_pSerializer->startElementNS( XML_w, XML_p, FSEND ); |
| m_pSerializer->startElementNS( XML_w, XML_r, FSEND ); |
| m_pSerializer->singleElementNS( XML_w, XML_separator, FSEND ); |
| m_pSerializer->endElementNS( XML_w, XML_r ); |
| m_pSerializer->endElementNS( XML_w, XML_p ); |
| m_pSerializer->endElementNS( XML_w, nItem ); |
| |
| // separator |
| m_pSerializer->startElementNS( XML_w, nItem, |
| FSNS( XML_w, XML_id ), OString::valueOf( nIndex++ ).getStr(), |
| FSNS( XML_w, XML_type ), "continuationSeparator", |
| FSEND ); |
| m_pSerializer->startElementNS( XML_w, XML_p, FSEND ); |
| m_pSerializer->startElementNS( XML_w, XML_r, FSEND ); |
| m_pSerializer->singleElementNS( XML_w, XML_continuationSeparator, FSEND ); |
| m_pSerializer->endElementNS( XML_w, XML_r ); |
| m_pSerializer->endElementNS( XML_w, XML_p ); |
| m_pSerializer->endElementNS( XML_w, nItem ); |
| |
| // footnotes/endnotes themselves |
| for ( FootnotesVector::const_iterator i = rVector.begin(); i != rVector.end(); ++i, ++nIndex ) |
| { |
| m_pSerializer->startElementNS( XML_w, nItem, |
| FSNS( XML_w, XML_id ), OString::valueOf( nIndex ).getStr(), |
| FSEND ); |
| |
| const SwNodeIndex* pIndex = (*i)->GetTxtFtn()->GetStartNode(); |
| |
| m_rExport.WriteSpecialText( pIndex->GetIndex() + 1, |
| pIndex->GetNode().EndOfSectionIndex(), |
| bFootnotes? TXT_FTN: TXT_EDN ); |
| |
| m_pSerializer->endElementNS( XML_w, nItem ); |
| } |
| |
| m_pSerializer->endElementNS( XML_w, nBody ); |
| |
| } |
| |
| void DocxAttributeOutput::ParaLineSpacing_Impl( short nSpace, short /*nMulti*/ ) |
| { |
| if ( !m_pSpacingAttrList ) |
| m_pSpacingAttrList = m_pSerializer->createAttrList(); |
| |
| if ( nSpace < 0 ) |
| { |
| m_pSpacingAttrList->add( FSNS( XML_w, XML_lineRule ), "exact" ); |
| m_pSpacingAttrList->add( FSNS( XML_w, XML_line ), OString::valueOf( sal_Int32( -nSpace ) ) ); |
| } |
| else if ( nSpace > 0 ) |
| { |
| m_pSpacingAttrList->add( FSNS( XML_w, XML_lineRule ), "atLeast" ); |
| m_pSpacingAttrList->add( FSNS( XML_w, XML_line ), OString::valueOf( sal_Int32( nSpace ) ) ); |
| } |
| else |
| m_pSpacingAttrList->add( FSNS( XML_w, XML_lineRule ), "auto" ); |
| } |
| |
| void DocxAttributeOutput::ParaAdjust( const SvxAdjustItem& rAdjust ) |
| { |
| const char *pAdjustString; |
| |
| switch ( rAdjust.GetAdjust() ) |
| { |
| case SVX_ADJUST_LEFT: |
| pAdjustString = "left"; |
| break; |
| case SVX_ADJUST_RIGHT: |
| pAdjustString = "right"; |
| break; |
| case SVX_ADJUST_BLOCKLINE: |
| case SVX_ADJUST_BLOCK: |
| pAdjustString = "both"; |
| break; |
| case SVX_ADJUST_CENTER: |
| pAdjustString = "center"; |
| break; |
| default: |
| return; // not supported attribute |
| } |
| m_pSerializer->singleElementNS( XML_w, XML_jc, FSNS( XML_w, XML_val ), pAdjustString, FSEND ); |
| } |
| |
| void DocxAttributeOutput::ParaSplit( const SvxFmtSplitItem& rSplit ) |
| { |
| if (rSplit.GetValue()) |
| m_pSerializer->singleElementNS( XML_w, XML_keepLines, FSNS( XML_w, XML_val ), "off", FSEND ); |
| else |
| m_pSerializer->singleElementNS( XML_w, XML_keepLines, FSEND ); |
| } |
| |
| void DocxAttributeOutput::ParaWidows( const SvxWidowsItem& rWidows ) |
| { |
| if (rWidows.GetValue()) |
| m_pSerializer->singleElementNS( XML_w, XML_widowControl, FSEND ); |
| else |
| m_pSerializer->singleElementNS( XML_w, XML_widowControl, FSNS( XML_w, XML_val ), "off", FSEND ); |
| } |
| |
| static void impl_WriteTabElement( FSHelperPtr pSerializer, |
| const SvxTabStop& rTab, long nCurrentLeft ) |
| { |
| FastAttributeList *pTabElementAttrList = pSerializer->createAttrList(); |
| |
| switch (rTab.GetAdjustment()) |
| { |
| case SVX_TAB_ADJUST_RIGHT: |
| pTabElementAttrList->add( FSNS( XML_w, XML_val ), OString( (sal_Char *)"right") ); |
| break; |
| case SVX_TAB_ADJUST_DECIMAL: |
| pTabElementAttrList->add( FSNS( XML_w, XML_val ), OString( (sal_Char *)"decimal") ); |
| break; |
| case SVX_TAB_ADJUST_CENTER: |
| pTabElementAttrList->add( FSNS( XML_w, XML_val ), OString( (sal_Char *)"center") ); |
| break; |
| case SVX_TAB_ADJUST_DEFAULT: |
| case SVX_TAB_ADJUST_LEFT: |
| default: |
| pTabElementAttrList->add( FSNS( XML_w, XML_val ), OString( (sal_Char *)"left") ); |
| break; |
| } |
| |
| pTabElementAttrList->add( FSNS( XML_w, XML_pos ), OString::valueOf( rTab.GetTabPos() + nCurrentLeft ) ); |
| |
| sal_Unicode cFillChar = rTab.GetFill(); |
| |
| if (sal_Unicode('.') == cFillChar ) |
| pTabElementAttrList->add( FSNS( XML_w, XML_leader ), OString( (sal_Char *) "dot" ) ); |
| else if ( sal_Unicode('-') == cFillChar ) |
| pTabElementAttrList->add( FSNS( XML_w, XML_leader ), OString( (sal_Char *) "hyphen" ) ); |
| else if ( sal_Unicode(0xB7) == cFillChar ) // middle dot |
| pTabElementAttrList->add( FSNS( XML_w, XML_leader ), OString( (sal_Char *) "middleDot" ) ); |
| else if ( sal_Unicode('_') == cFillChar ) |
| pTabElementAttrList->add( FSNS( XML_w, XML_leader ), OString( (sal_Char *) "underscore" ) ); |
| else |
| pTabElementAttrList->add( FSNS( XML_w, XML_leader ), OString( (sal_Char *) "none" ) ); |
| |
| pSerializer->singleElementNS( XML_w, XML_tab, pTabElementAttrList ); |
| } |
| |
| void DocxAttributeOutput::ParaTabStop( const SvxTabStopItem& rTabStop ) |
| { |
| const SfxPoolItem* pLR = m_rExport.HasItem( RES_LR_SPACE ); |
| long nCurrentLeft = pLR ? ((const SvxLRSpaceItem*)pLR)->GetTxtLeft() : 0; |
| |
| m_pSerializer->startElementNS( XML_w, XML_tabs, FSEND ); |
| |
| sal_uInt16 nCount = rTabStop.Count(); |
| for (sal_uInt16 i = 0; i < nCount; i++ ) |
| impl_WriteTabElement( m_pSerializer, rTabStop[i], nCurrentLeft ); |
| |
| m_pSerializer->endElementNS( XML_w, XML_tabs ); |
| } |
| |
| void DocxAttributeOutput::ParaHyphenZone( const SvxHyphenZoneItem& rHyphenZone ) |
| { |
| m_pSerializer->singleElementNS( XML_w, XML_suppressAutoHyphens, |
| FSNS( XML_w, XML_val ), rHyphenZone.IsHyphen( ) ? "false" : "true" , |
| FSEND ); |
| } |
| |
| void DocxAttributeOutput::ParaNumRule_Impl( const SwTxtNode* /*pTxtNd*/, sal_Int32 nLvl, sal_Int32 nNumId ) |
| { |
| if ( USHRT_MAX != nNumId && 0 != nNumId ) |
| { |
| m_pSerializer->startElementNS( XML_w, XML_numPr, FSEND ); |
| m_pSerializer->singleElementNS( XML_w, XML_ilvl, FSNS( XML_w, XML_val ), OString::valueOf( sal_Int32( nLvl )).getStr(), FSEND ); |
| m_pSerializer->singleElementNS( XML_w, XML_numId, FSNS( XML_w, XML_val ), OString::valueOf( sal_Int32( nNumId )).getStr(), FSEND ); |
| m_pSerializer->endElementNS( XML_w, XML_numPr ); |
| } |
| } |
| |
| void DocxAttributeOutput::ParaScriptSpace( const SfxBoolItem& rScriptSpace ) |
| { |
| sal_uInt16 nXmlElement = 0; |
| |
| switch ( rScriptSpace.Which( ) ) |
| { |
| case RES_PARATR_SCRIPTSPACE: |
| nXmlElement = XML_autoSpaceDE; |
| break; |
| case RES_PARATR_HANGINGPUNCTUATION: |
| nXmlElement = XML_overflowPunct; |
| break; |
| case RES_PARATR_FORBIDDEN_RULES: |
| nXmlElement = XML_kinsoku; |
| break; |
| } |
| |
| if ( nXmlElement ) |
| { |
| m_pSerializer->singleElementNS( XML_w, nXmlElement, |
| FSNS( XML_w, XML_val ), rScriptSpace.GetValue( ) ? "true": "false", |
| FSEND ); |
| } |
| } |
| |
| void DocxAttributeOutput::ParaVerticalAlign( const SvxParaVertAlignItem& rAlign ) |
| { |
| const char *pAlignString; |
| |
| switch ( rAlign.GetValue() ) |
| { |
| case SvxParaVertAlignItem::BASELINE: |
| pAlignString = "baseline"; |
| break; |
| case SvxParaVertAlignItem::TOP: |
| pAlignString = "top"; |
| break; |
| case SvxParaVertAlignItem::CENTER: |
| pAlignString = "center"; |
| break; |
| case SvxParaVertAlignItem::BOTTOM: |
| pAlignString = "bottom"; |
| break; |
| case SvxParaVertAlignItem::AUTOMATIC: |
| pAlignString = "auto"; |
| break; |
| default: |
| return; // not supported attribute |
| } |
| m_pSerializer->singleElementNS( XML_w, XML_textAlignment, FSNS( XML_w, XML_val ), pAlignString, FSEND ); |
| } |
| |
| void DocxAttributeOutput::ParaSnapToGrid( const SvxParaGridItem& rGrid ) |
| { |
| m_pSerializer->singleElementNS( XML_w, XML_snapToGrid, |
| FSNS( XML_w, XML_val ), rGrid.GetValue( ) ? "true": "false", |
| FSEND ); |
| } |
| |
| void DocxAttributeOutput::FormatFrameSize( const SwFmtFrmSize& rSize ) |
| { |
| if ( m_rExport.bOutFlyFrmAttrs ) |
| { |
| #if OSL_DEBUG_LEVEL > 0 |
| OSL_TRACE( "TODO DocxAttributeOutput::FormatFrameSize() - Fly frames\n" ); |
| #endif |
| } |
| else if ( m_rExport.bOutPageDescs ) |
| { |
| FastAttributeList *attrList = m_pSerializer->createAttrList( ); |
| if ( m_rExport.pAktPageDesc->GetLandscape( ) ) |
| attrList->add( FSNS( XML_w, XML_orient ), "landscape" ); |
| |
| |
| attrList->add( FSNS( XML_w, XML_w ), OString::valueOf( rSize.GetWidth( ) ) ); |
| attrList->add( FSNS( XML_w, XML_h ), OString::valueOf( rSize.GetHeight( ) ) ); |
| |
| XFastAttributeListRef xAttrList( attrList ); |
| attrList = NULL; |
| |
| m_pSerializer->singleElementNS( XML_w, XML_pgSz, xAttrList ); |
| } |
| } |
| |
| void DocxAttributeOutput::FormatPaperBin( const SvxPaperBinItem& ) |
| { |
| #if OSL_DEBUG_LEVEL > 0 |
| OSL_TRACE( "TODO DocxAttributeOutput::FormatPaperBin()\n" ); |
| #endif |
| } |
| |
| void DocxAttributeOutput::FormatLRSpace( const SvxLRSpaceItem& rLRSpace ) |
| { |
| if ( m_rExport.bOutFlyFrmAttrs ) |
| { |
| #if OSL_DEBUG_LEVEL > 0 |
| OSL_TRACE( "DocxAttributeOutput::FormatLRSpace() - Fly frames\n" ); |
| #endif |
| } |
| else if ( m_rExport.bOutPageDescs ) |
| { |
| if ( !m_pSpacingAttrList ) |
| m_pSpacingAttrList = m_pSerializer->createAttrList(); |
| |
| |
| sal_uInt16 nLDist, nRDist; |
| const SfxPoolItem* pItem = m_rExport.HasItem( RES_BOX ); |
| if ( pItem ) |
| { |
| nRDist = ((SvxBoxItem*)pItem)->CalcLineSpace( BOX_LINE_LEFT ); |
| nLDist = ((SvxBoxItem*)pItem)->CalcLineSpace( BOX_LINE_RIGHT ); |
| } |
| else |
| nLDist = nRDist = 0; |
| nLDist = nLDist + (sal_uInt16)rLRSpace.GetLeft(); |
| nRDist = nRDist + (sal_uInt16)rLRSpace.GetRight(); |
| |
| m_pSpacingAttrList->add( FSNS( XML_w, XML_left ), OString::valueOf( sal_Int32( nLDist ) ) ); |
| m_pSpacingAttrList->add( FSNS( XML_w, XML_right ), OString::valueOf( sal_Int32( nRDist ) ) ); |
| } |
| else |
| { |
| FastAttributeList *pLRSpaceAttrList = m_pSerializer->createAttrList(); |
| |
| pLRSpaceAttrList->add( FSNS( XML_w, XML_left ), OString::valueOf( (sal_Int32) rLRSpace.GetTxtLeft() ) ); |
| pLRSpaceAttrList->add( FSNS( XML_w, XML_right ), OString::valueOf( (sal_Int32) rLRSpace.GetRight() ) ); |
| |
| sal_Int32 nFirstLineAdjustment = rLRSpace.GetTxtFirstLineOfst(); |
| if (nFirstLineAdjustment > 0) |
| pLRSpaceAttrList->add( FSNS( XML_w, XML_firstLine ), OString::valueOf( nFirstLineAdjustment ) ); |
| else |
| pLRSpaceAttrList->add( FSNS( XML_w, XML_hanging ), OString::valueOf( - nFirstLineAdjustment ) ); |
| m_pSerializer->singleElementNS( XML_w, XML_ind, pLRSpaceAttrList ); |
| } |
| } |
| |
| void DocxAttributeOutput::FormatULSpace( const SvxULSpaceItem& rULSpace ) |
| { |
| if (!m_pSpacingAttrList) |
| m_pSpacingAttrList = m_pSerializer->createAttrList(); |
| |
| if ( m_rExport.bOutFlyFrmAttrs ) |
| { |
| } |
| else if (m_rExport.bOutPageDescs ) |
| { |
| ASSERT( m_rExport.GetCurItemSet(), "Impossible" ); |
| if ( !m_rExport.GetCurItemSet() ) |
| return; |
| |
| HdFtDistanceGlue aDistances( *m_rExport.GetCurItemSet() ); |
| |
| if ( aDistances.HasHeader() ) |
| { |
| // Header top |
| m_pSpacingAttrList->add( FSNS( XML_w, XML_header ), |
| OString::valueOf( sal_Int32( aDistances.dyaHdrTop ) ) ); |
| } |
| |
| // Page top |
| m_pSpacingAttrList->add( FSNS( XML_w, XML_top ), |
| OString::valueOf( sal_Int32( aDistances.dyaTop ) ) ); |
| |
| if ( aDistances.HasFooter() ) |
| { |
| // Footer bottom |
| m_pSpacingAttrList->add( FSNS( XML_w, XML_footer ), |
| OString::valueOf( sal_Int32( aDistances.dyaHdrBottom ) ) ); |
| } |
| |
| // Page Bottom |
| m_pSpacingAttrList->add( FSNS( XML_w, XML_bottom ), |
| OString::valueOf( sal_Int32( aDistances.dyaBottom ) ) ); |
| |
| } |
| else |
| { |
| m_pSpacingAttrList->add( FSNS( XML_w, XML_before ), |
| OString::valueOf( (sal_Int32)rULSpace.GetUpper() ) ); |
| m_pSpacingAttrList->add( FSNS( XML_w, XML_after ), |
| OString::valueOf( (sal_Int32)rULSpace.GetLower() ) ); |
| } |
| } |
| |
| void DocxAttributeOutput::FormatSurround( const SwFmtSurround& ) |
| { |
| #if OSL_DEBUG_LEVEL > 0 |
| OSL_TRACE( "TODO DocxAttributeOutput::FormatSurround()\n" ); |
| #endif |
| } |
| |
| void DocxAttributeOutput::FormatVertOrientation( const SwFmtVertOrient& ) |
| { |
| #if OSL_DEBUG_LEVEL > 0 |
| OSL_TRACE( "TODO DocxAttributeOutput::FormatVertOrientation()\n" ); |
| #endif |
| } |
| |
| void DocxAttributeOutput::FormatHorizOrientation( const SwFmtHoriOrient& ) |
| { |
| #if OSL_DEBUG_LEVEL > 0 |
| OSL_TRACE( "TODO DocxAttributeOutput::FormatHorizOrientation()\n" ); |
| #endif |
| } |
| |
| void DocxAttributeOutput::FormatAnchor( const SwFmtAnchor& ) |
| { |
| #if OSL_DEBUG_LEVEL > 0 |
| OSL_TRACE( "TODO DocxAttributeOutput::FormatAnchor()\n" ); |
| #endif |
| } |
| |
| void DocxAttributeOutput::FormatBackground( const SvxBrushItem& rBrush ) |
| { |
| if ( !m_rExport.bOutPageDescs ) |
| { |
| OString sColor = impl_ConvertColor( rBrush.GetColor( ) ); |
| m_pSerializer->singleElementNS( XML_w, XML_shd, |
| FSNS( XML_w, XML_fill ), sColor.getStr( ), |
| FSEND ); |
| } |
| |
| #if OSL_DEBUG_LEVEL > 0 |
| OSL_TRACE( "TODO DocxAttributeOutput::FormatBackground()\n" ); |
| #endif |
| } |
| |
| void DocxAttributeOutput::FormatBox( const SvxBoxItem& rBox ) |
| { |
| |
| if ( !m_bOpenedSectPr ) |
| { |
| // Normally open the borders tag for paragraphs |
| m_pSerializer->startElementNS( XML_w, XML_pBdr, FSEND ); |
| } |
| |
| impl_pageBorders( m_pSerializer, rBox ); |
| |
| if ( m_bOpenedSectPr ) |
| { |
| // Special handling for pgBorder |
| m_pSerializer->mergeTopMarks( sax_fastparser::MERGE_MARKS_PREPEND ); |
| m_pSerializer->mergeTopMarks( ); |
| } |
| else |
| { |
| // Normally close the borders tag for paragraphs |
| m_pSerializer->endElementNS( XML_w, XML_pBdr ); |
| } |
| } |
| |
| void DocxAttributeOutput::FormatColumns_Impl( sal_uInt16 nCols, const SwFmtCol& rCol, bool bEven, SwTwips nPageSize ) |
| { |
| // Get the columns attributes |
| FastAttributeList *pColsAttrList = m_pSerializer->createAttrList(); |
| |
| pColsAttrList->add( FSNS( XML_w, XML_num ), |
| OString::valueOf( sal_Int32( nCols ) ). getStr( ) ); |
| |
| const char* pEquals = "false"; |
| if ( bEven ) |
| { |
| sal_uInt16 nWidth = rCol.GetGutterWidth( true ); |
| pColsAttrList->add( FSNS( XML_w, XML_space ), |
| OString::valueOf( sal_Int32( nWidth ) ).getStr( ) ); |
| |
| pEquals = "true"; |
| } |
| |
| pColsAttrList->add( FSNS( XML_w, XML_equalWidth ), pEquals ); |
| |
| bool bHasSep = COLADJ_NONE == rCol.GetLineAdj( ); |
| pColsAttrList->add( FSNS( XML_w, XML_sep ), bHasSep ? "true" : "false" ); |
| |
| // Write the element |
| m_pSerializer->startElementNS( XML_w, XML_cols, pColsAttrList ); |
| |
| // Write the columns width if non-equals |
| const SwColumns & rColumns = rCol.GetColumns( ); |
| if ( !bEven ) |
| { |
| for ( sal_uInt16 n = 0; n < nCols; ++n ) |
| { |
| FastAttributeList *pColAttrList = m_pSerializer->createAttrList(); |
| sal_uInt16 nWidth = rCol.CalcPrtColWidth( n, ( sal_uInt16 ) nPageSize ); |
| pColAttrList->add( FSNS( XML_w, XML_w ), |
| OString::valueOf( sal_Int32( nWidth ) ).getStr( ) ); |
| |
| if ( n + 1 != nCols ) |
| { |
| sal_uInt16 nSpacing = rColumns[n]->GetRight( ) + rColumns[n + 1]->GetLeft( ); |
| pColAttrList->add( FSNS( XML_w, XML_space ), |
| OString::valueOf( sal_Int32( nSpacing ) ).getStr( ) ); |
| } |
| |
| m_pSerializer->singleElementNS( XML_w, XML_col, pColAttrList ); |
| } |
| } |
| |
| m_pSerializer->endElementNS( XML_w, XML_cols ); |
| } |
| |
| void DocxAttributeOutput::FormatKeep( const SvxFmtKeepItem& ) |
| { |
| m_pSerializer->singleElementNS( XML_w, XML_keepNext, FSEND ); |
| } |
| |
| void DocxAttributeOutput::FormatTextGrid( const SwTextGridItem& ) |
| { |
| OSL_TRACE( "TODO DocxAttributeOutput::FormatTextGrid()\n" ); |
| } |
| |
| void DocxAttributeOutput::FormatLineNumbering( const SwFmtLineNumber& rNumbering ) |
| { |
| if ( !rNumbering.IsCount( ) ) |
| m_pSerializer->singleElementNS( XML_w, XML_suppressLineNumbers, FSEND ); |
| } |
| |
| void DocxAttributeOutput::FormatFrameDirection( const SvxFrameDirectionItem& rDirection ) |
| { |
| OString sTextFlow; |
| bool bBiDi = false; |
| short nDir = rDirection.GetValue(); |
| |
| if ( nDir == FRMDIR_ENVIRONMENT ) |
| nDir = GetExport( ).GetDefaultFrameDirection( ); |
| |
| switch ( nDir ) |
| { |
| default: |
| case FRMDIR_HORI_LEFT_TOP: |
| sTextFlow = OString( "lrTb" ); |
| break; |
| case FRMDIR_HORI_RIGHT_TOP: |
| sTextFlow = OString( "lrTb" ); |
| bBiDi = true; |
| break; |
| case FRMDIR_VERT_TOP_LEFT: // many things but not this one |
| case FRMDIR_VERT_TOP_RIGHT: |
| sTextFlow = OString( "tbRl" ); |
| break; |
| } |
| |
| if ( m_rExport.bOutPageDescs ) |
| { |
| m_pSerializer->singleElementNS( XML_w, XML_textDirection, |
| FSNS( XML_w, XML_val ), sTextFlow.getStr( ), |
| FSEND ); |
| if ( bBiDi ) |
| m_pSerializer->singleElementNS( XML_w, XML_bidi, FSEND ); |
| } |
| else if ( !m_rExport.bOutFlyFrmAttrs ) |
| { |
| if ( bBiDi ) |
| m_pSerializer->singleElementNS( XML_w, XML_bidi, FSEND ); |
| } |
| } |
| |
| DocxAttributeOutput::DocxAttributeOutput( DocxExport &rExport, FSHelperPtr pSerializer, oox::drawingml::DrawingML* pDrawingML ) |
| : m_rExport( rExport ), |
| m_pSerializer( pSerializer ), |
| m_rDrawingML( *pDrawingML ), |
| m_pFontsAttrList( NULL ), |
| m_pEastAsianLayoutAttrList( NULL ), |
| m_pCharLangAttrList( NULL ), |
| m_pSpacingAttrList( NULL ), |
| m_pHyperlinkAttrList( NULL ), |
| m_pFootnotesList( new ::docx::FootnotesList() ), |
| m_pEndnotesList( new ::docx::FootnotesList() ), |
| m_pSectionInfo( NULL ), |
| m_pRedlineData( NULL ), |
| m_nRedlineId( 0 ), |
| m_bOpenedSectPr( false ), |
| m_sFieldBkm( ), |
| m_nNextMarkId( 0 ), |
| m_bPostitStart(false), |
| m_bPostitEnd(false), |
| m_pTableWrt( NULL ), |
| m_bTableCellOpen( false ), |
| m_nTableDepth( 0 ), |
| m_bParagraphOpened( false ), |
| m_nColBreakStatus( COLBRK_NONE ) |
| { |
| } |
| |
| DocxAttributeOutput::~DocxAttributeOutput() |
| { |
| delete m_pFontsAttrList, m_pFontsAttrList = NULL; |
| delete m_pEastAsianLayoutAttrList, m_pEastAsianLayoutAttrList = NULL; |
| delete m_pCharLangAttrList, m_pCharLangAttrList = NULL; |
| delete m_pSpacingAttrList, m_pSpacingAttrList = NULL; |
| delete m_pHyperlinkAttrList, m_pHyperlinkAttrList = NULL; |
| |
| delete m_pFootnotesList, m_pFootnotesList = NULL; |
| delete m_pEndnotesList, m_pEndnotesList = NULL; |
| |
| delete m_pTableWrt, m_pTableWrt = NULL; |
| } |
| |
| MSWordExportBase& DocxAttributeOutput::GetExport() |
| { |
| return m_rExport; |
| } |
| |
| bool DocxAttributeOutput::HasFootnotes() |
| { |
| return !m_pFootnotesList->isEmpty(); |
| } |
| |
| bool DocxAttributeOutput::HasEndnotes() |
| { |
| return !m_pEndnotesList->isEmpty(); |
| } |