diff options
author | Jan Holesovsky <kendy@collabora.com> | 2013-09-18 12:19:45 +0200 |
---|---|---|
committer | Jan Holesovsky <kendy@collabora.com> | 2013-09-18 12:21:21 +0200 |
commit | e47c7970a43d95a65f2a6d6942777314aea41bba (patch) | |
tree | 56222289034f5c21011ddfbebac4d3c601d784ec /sw | |
parent | 47fb53309cb8f5171431df6d49395880a3c034f2 (diff) |
DOCX styles: Generate the styleIds similar ways as MSO does.
Makes the id's nicer than the styleXY.
Change-Id: Ica0da1404578f834a79f940bf31c93d25f842e7f
Diffstat (limited to 'sw')
-rw-r--r-- | sw/source/filter/ww8/docxattributeoutput.cxx | 25 | ||||
-rw-r--r-- | sw/source/filter/ww8/wrtw8sty.cxx | 58 | ||||
-rw-r--r-- | sw/source/filter/ww8/wrtww8.hxx | 9 |
3 files changed, 77 insertions, 15 deletions
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx index f0055009f9ce..dc317cae101a 100644 --- a/sw/source/filter/ww8/docxattributeoutput.cxx +++ b/sw/source/filter/ww8/docxattributeoutput.cxx @@ -1280,11 +1280,12 @@ void DocxAttributeOutput::StartRuby( const SwTxtNode& rNode, xub_StrLen nPos, co StartRunProperties( ); SwWW8AttrIter aAttrIt( m_rExport, rNode ); aAttrIt.OutAttr( nPos, true ); + sal_uInt16 nStyle = m_rExport.GetId( *rRuby.GetTxtRuby()->GetCharFmt() ); - OString aStyleId( "style" ); - aStyleId += OString::number( nStyle ); + OString aStyleId(m_rExport.pStyles->GetStyleId(nStyle)); m_pSerializer->singleElementNS( XML_w, XML_rStyle, FSNS( XML_w, XML_val ), aStyleId.getStr(), FSEND ); + EndRunProperties( NULL ); RunText( rRuby.GetText( ) ); EndRun( ); @@ -1531,8 +1532,7 @@ void DocxAttributeOutput::FormatDrop( const SwTxtNode& /*rNode*/, const SwFmtDro void DocxAttributeOutput::ParagraphStyle( sal_uInt16 nStyle ) { - OString aStyleId( "style" ); - aStyleId += OString::number( nStyle ); + OString aStyleId(m_rExport.pStyles->GetStyleId(nStyle)); m_pSerializer->singleElementNS( XML_w, XML_pStyle, FSNS( XML_w, XML_val ), aStyleId.getStr(), FSEND ); } @@ -3249,11 +3249,9 @@ oox::drawingml::DrawingML& DocxAttributeOutput::GetDrawingML() void DocxAttributeOutput::StartStyle( const String& rName, bool bPapFmt, sal_uInt16 nBase, sal_uInt16 nNext, sal_uInt16 /*nWwId*/, sal_uInt16 nId, bool bAutoUpdate ) { - 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 ), OString( aStyle + OString::number( nId ) ).getStr(), + FSNS( XML_w, XML_styleId ), m_rExport.pStyles->GetStyleId(nId).getStr(), FSEND ); m_pSerializer->singleElementNS( XML_w, XML_name, @@ -3263,12 +3261,12 @@ void DocxAttributeOutput::StartStyle( const String& rName, bool bPapFmt, if ( nBase != 0x0FFF ) { m_pSerializer->singleElementNS( XML_w, XML_basedOn, - FSNS( XML_w, XML_val ), OString( aStyle + OString::number( nBase ) ).getStr(), + FSNS( XML_w, XML_val ), m_rExport.pStyles->GetStyleId(nBase).getStr(), FSEND ); } m_pSerializer->singleElementNS( XML_w, XML_next, - FSNS( XML_w, XML_val ), OString( aStyle + OString::number( nNext ) ).getStr(), + FSNS( XML_w, XML_val ), m_rExport.pStyles->GetStyleId(nNext).getStr(), FSEND ); if ( bAutoUpdate ) @@ -4336,16 +4334,14 @@ void DocxAttributeOutput::TextINetFormat( const SwFmtINetFmt& rLink ) const SwTxtINetFmt* pINetFmt = rLink.GetTxtINetFmt(); const SwCharFmt* pCharFmt = pINetFmt->GetCharFmt(); - OString aStyleId( "style" ); - aStyleId += OString::number( m_rExport.GetId( *pCharFmt ) ); + OString aStyleId(m_rExport.pStyles->GetStyleId(m_rExport.GetId(*pCharFmt))); m_pSerializer->singleElementNS( XML_w, XML_rStyle, FSNS( XML_w, XML_val ), aStyleId.getStr(), FSEND ); } void DocxAttributeOutput::TextCharFormat( const SwFmtCharFmt& rCharFmt ) { - OString aStyleId( "style" ); - aStyleId += OString::number( m_rExport.GetId( *rCharFmt.GetCharFmt() ) ); + OString aStyleId(m_rExport.pStyles->GetStyleId(m_rExport.GetId(*rCharFmt.GetCharFmt()))); m_pSerializer->singleElementNS( XML_w, XML_rStyle, FSNS( XML_w, XML_val ), aStyleId.getStr(), FSEND ); } @@ -4534,8 +4530,7 @@ void DocxAttributeOutput::TextFootnote_Impl( const SwFmtFtn& rFootnote ) // footnote/endnote run properties const SwCharFmt* pCharFmt = rInfo.GetAnchorCharFmt( *m_rExport.pDoc ); - OString aStyleId( "style" ); - aStyleId += OString::number( m_rExport.GetId( *pCharFmt ) ); + OString aStyleId(m_rExport.pStyles->GetStyleId(m_rExport.GetId(*pCharFmt))); m_pSerializer->singleElementNS( XML_w, XML_rStyle, FSNS( XML_w, XML_val ), aStyleId.getStr(), FSEND ); diff --git a/sw/source/filter/ww8/wrtw8sty.cxx b/sw/source/filter/ww8/wrtw8sty.cxx index 573e98a1bdcb..2ca0b04bba99 100644 --- a/sw/source/filter/ww8/wrtw8sty.cxx +++ b/sw/source/filter/ww8/wrtw8sty.cxx @@ -20,6 +20,7 @@ #include <algorithm> #include <functional> +#include <unordered_set> #include <boost/scoped_array.hpp> @@ -158,6 +159,7 @@ MSWordStyles::MSWordStyles( MSWordExportBase& rExport ) memset( pFmtA, 0, nAlloc * sizeof( SwFmt* ) ); BuildStylesTable(); + BuildStyleIds(); } MSWordStyles::~MSWordStyles() @@ -293,6 +295,62 @@ void MSWordStyles::BuildStylesTable() } } +void MSWordStyles::BuildStyleIds() +{ + std::unordered_set<OString, OStringHash> aUsed; + + m_aStyleIds.push_back("Normal"); + aUsed.insert("normal"); + + for (sal_uInt16 n = 1; n < nUsedSlots; ++n) + { + const OUString aName(pFmtA[n]? pFmtA[n]->GetName(): OUString()); + + OStringBuffer aStyleIdBuf(aName.getLength()); + for (int i = 0; i < aName.getLength(); ++i) + { + sal_Unicode nChar = aName[i]; + if (('0' <= nChar && nChar <= '9') || + ('a' <= nChar && nChar <= 'z') || + ('A' <= nChar && nChar <= 'Z')) + { + // first letter should be uppercase + if (aStyleIdBuf.isEmpty() && ('a' < nChar && nChar <= 'z')) + aStyleIdBuf.append(char(nChar - ('a' - 'A'))); + else + aStyleIdBuf.append(char(nChar)); + } + } + + OString aStyleId(aStyleIdBuf.makeStringAndClear()); + if (aStyleId.isEmpty()) + aStyleId = "Style"; + + OString aLower(aStyleId.toAsciiLowerCase()); + + // check for uniqueness & construct something unique if we have to + if (aUsed.find(aLower) == aUsed.end()) + { + aUsed.insert(aLower); + m_aStyleIds.push_back(aStyleId); + } + else + { + int nFree = 1; + while (aUsed.find(aLower + OString::number(nFree)) != aUsed.end()) + ++nFree; + + aUsed.insert(aLower + OString::number(nFree)); + m_aStyleIds.push_back(aStyleId + OString::number(nFree)); + } + } +} + +OString MSWordStyles::GetStyleId(sal_uInt16 nId) const +{ + return m_aStyleIds[nId]; +} + /// For WW8 only - extend pO so that the size of pTableStrm is even. static void impl_SkipOdd( ww::bytes* pO, sal_Size nTableStrmTell ) { diff --git a/sw/source/filter/ww8/wrtww8.hxx b/sw/source/filter/ww8/wrtww8.hxx index 5ae203f618dd..8d4534937ad5 100644 --- a/sw/source/filter/ww8/wrtww8.hxx +++ b/sw/source/filter/ww8/wrtww8.hxx @@ -1509,9 +1509,15 @@ class MSWordStyles SwFmt** pFmtA; sal_uInt16 nUsedSlots; + /// We need to build style id's for DOCX export; ideally we should roundtrip that, but this is good enough. + std::vector<OString> m_aStyleIds; + /// Create the style table, called from the constructor. void BuildStylesTable(); + /// Based on pFmtA, fill in m_aStyleIds with unique, MS-like names. + void BuildStyleIds(); + /// Get slot number during building the style table. sal_uInt16 BuildGetSlot( const SwFmt& rFmt ); @@ -1542,6 +1548,9 @@ public: /// Get id of the style (rFmt). sal_uInt16 GetSlot( const SwFmt& rFmt ) const; + /// Get styleId of the nId-th style (nId is its position in pFmtA). + OString GetStyleId(sal_uInt16 nId) const; + const SwFmt* GetSwFmt() const { return (*pFmtA); } }; |