summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorJan Holesovsky <kendy@collabora.com>2013-09-18 12:19:45 +0200
committerJan Holesovsky <kendy@collabora.com>2013-09-18 12:21:21 +0200
commite47c7970a43d95a65f2a6d6942777314aea41bba (patch)
tree56222289034f5c21011ddfbebac4d3c601d784ec /sw
parent47fb53309cb8f5171431df6d49395880a3c034f2 (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.cxx25
-rw-r--r--sw/source/filter/ww8/wrtw8sty.cxx58
-rw-r--r--sw/source/filter/ww8/wrtww8.hxx9
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); }
};