summaryrefslogtreecommitdiff
path: root/sw/source/filter/ww8/docxattributeoutput.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/filter/ww8/docxattributeoutput.cxx')
-rw-r--r--sw/source/filter/ww8/docxattributeoutput.cxx179
1 files changed, 137 insertions, 42 deletions
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx
index 9f2e11da3a61..0461408b0a67 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -1104,7 +1104,7 @@ void DocxAttributeOutput::StartRun( const SwRedlineData* pRedlineData, bool /*bS
m_pSerializer->mark(Tag_StartRun_3); // let's call it "postponed text"
}
-void DocxAttributeOutput::EndRun()
+void DocxAttributeOutput::EndRun(const SwTextNode* pNode, sal_Int32 nPos)
{
int nFieldsInPrevHyperlink = m_nFieldsInHyperlink;
// Reset m_nFieldsInHyperlink if a new hyperlink is about to start
@@ -1119,7 +1119,7 @@ void DocxAttributeOutput::EndRun()
// Add the fields starts for all but hyperlinks and TOCs
if ( pIt->bOpen && pIt->pField )
{
- StartField_Impl( *pIt );
+ StartField_Impl( pNode, nPos, *pIt );
// Remove the field from the stack if only the start has to be written
// Unknown fields should be removed too
@@ -1167,7 +1167,7 @@ void DocxAttributeOutput::EndRun()
{
// If fields begin before hyperlink then
// it should end before hyperlink close
- EndField_Impl( m_Fields.back( ) );
+ EndField_Impl( pNode, nPos, m_Fields.back( ) );
m_Fields.pop_back();
}
m_pSerializer->endElementNS( XML_w, XML_hyperlink );
@@ -1184,7 +1184,7 @@ void DocxAttributeOutput::EndRun()
// Add the fields starts for hyperlinks, TOCs and index marks
if ( pIt->bOpen && !pIt->pField )
{
- StartField_Impl( *pIt, true );
+ StartField_Impl( pNode, nPos, *pIt, true );
if (m_startedHyperlink)
++m_nFieldsInHyperlink;
@@ -1213,7 +1213,7 @@ void DocxAttributeOutput::EndRun()
{
if (it->bClose && !it->pField)
{
- EndField_Impl(*it);
+ EndField_Impl( pNode, nPos, *it );
it = decltype(m_Fields)::reverse_iterator(m_Fields.erase(it.base() - 1));
}
else
@@ -1356,7 +1356,7 @@ void DocxAttributeOutput::EndRun()
{
// If fields begin after hyperlink start then
// it should end before hyperlink close
- EndField_Impl( m_Fields.back( ) );
+ EndField_Impl( pNode, nPos, m_Fields.back( ) );
m_Fields.pop_back();
}
m_nFieldsInHyperlink = 0;
@@ -1372,7 +1372,7 @@ void DocxAttributeOutput::EndRun()
{
while ( m_Fields.begin() != m_Fields.end() )
{
- EndField_Impl( m_Fields.front( ) );
+ EndField_Impl( pNode, nPos, m_Fields.front( ) );
m_Fields.erase( m_Fields.begin( ) );
}
m_nFieldsInHyperlink = 0;
@@ -1622,7 +1622,7 @@ void DocxAttributeOutput::WriteFFData( const FieldInfos& rInfos )
}
}
-void DocxAttributeOutput::StartField_Impl( FieldInfos const & rInfos, bool bWriteRun )
+void DocxAttributeOutput::StartField_Impl( const SwTextNode* pNode, sal_Int32 nPos, FieldInfos const & rInfos, bool bWriteRun )
{
if ( rInfos.pField && rInfos.eType == ww::eUNKNOWN )
{
@@ -1655,9 +1655,9 @@ void DocxAttributeOutput::StartField_Impl( FieldInfos const & rInfos, bool bWrit
if ( bWriteRun )
m_pSerializer->endElementNS( XML_w, XML_r );
- if ( !rInfos.pField )
- CmdField_Impl( rInfos );
+ if ( !rInfos.pField )
+ CmdField_Impl( pNode, nPos, rInfos, bWriteRun );
}
else
{
@@ -1687,7 +1687,7 @@ void DocxAttributeOutput::StartField_Impl( FieldInfos const & rInfos, bool bWrit
// The hyperlinks fields can't be expanded: the value is
// normally in the text run
if ( !rInfos.pField )
- CmdField_Impl( rInfos );
+ CmdField_Impl( pNode, nPos, rInfos, bWriteRun );
}
}
}
@@ -1707,48 +1707,130 @@ void DocxAttributeOutput::DoWriteCmd( const OUString& rCmd )
}
-void DocxAttributeOutput::CmdField_Impl( FieldInfos const & rInfos )
+void DocxAttributeOutput::CmdField_Impl( const SwTextNode* pNode, sal_Int32 nPos, FieldInfos const & rInfos, bool bWriteRun )
{
- m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
- sal_Int32 nNbToken = comphelper::string::getTokenCount(rInfos.sCmd, '\t');
+ // Write the Field instruction
+ {
+ if ( bWriteRun )
+ {
+ m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
+ DoWriteFieldRunProperties( pNode, nPos );
+ }
- for ( sal_Int32 i = 0; i < nNbToken; i++ )
+ sal_Int32 nNbToken = comphelper::string::getTokenCount(rInfos.sCmd, '\t');
+
+ for ( sal_Int32 i = 0; i < nNbToken; i++ )
+ {
+ OUString sToken = rInfos.sCmd.getToken( i, '\t' );
+ if ( rInfos.eType == ww::eCREATEDATE
+ || rInfos.eType == ww::eSAVEDATE
+ || rInfos.eType == ww::ePRINTDATE
+ || rInfos.eType == ww::eDATE
+ || rInfos.eType == ww::eTIME )
+ {
+ sToken = sToken.replaceAll("NNNN", "dddd");
+ sToken = sToken.replaceAll("NN", "ddd");
+ }
+
+ // Write the Field command
+ DoWriteCmd( sToken );
+
+ // Replace tabs by </instrText><tab/><instrText>
+ if ( i < ( nNbToken - 1 ) )
+ RunText( "\t" );
+ }
+
+ if ( bWriteRun )
+ {
+ m_pSerializer->endElementNS( XML_w, XML_r );
+ }
+ }
+
+ // Write the Field separator
{
- OUString sToken = rInfos.sCmd.getToken( i, '\t' );
- if ( rInfos.eType == ww::eCREATEDATE
- || rInfos.eType == ww::eSAVEDATE
- || rInfos.eType == ww::ePRINTDATE
- || rInfos.eType == ww::eDATE
- || rInfos.eType == ww::eTIME )
+ if ( bWriteRun )
{
- sToken = sToken.replaceAll("NNNN", "dddd");
- sToken = sToken.replaceAll("NN", "ddd");
+ m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
+ DoWriteFieldRunProperties( pNode, nPos );
}
- // Write the Field command
- DoWriteCmd( sToken );
+ m_pSerializer->singleElementNS( XML_w, XML_fldChar,
+ FSNS( XML_w, XML_fldCharType ), "separate",
+ FSEND );
- // Replace tabs by </instrText><tab/><instrText>
- if ( i < ( nNbToken - 1 ) )
- RunText( "\t" );
+ if ( bWriteRun )
+ {
+ m_pSerializer->endElementNS( XML_w, XML_r );
+ }
}
+}
- m_pSerializer->endElementNS( XML_w, XML_r );
+/// Writes properties for run that is used to separate field implementation.
+/// There are several runs are used:
+/// <w:r>
+/// <w:rPr>
+/// <!-- properties written with StartRunProperties() / EndRunProperties().
+/// </w:rPr>
+/// <w:fldChar w:fldCharType="begin" />
+/// </w:r>
+/// <w:r>
+/// <w:rPr>
+/// <!-- properties written with DoWriteFieldRunProperties()
+/// </w:rPr>
+/// <w:instrText>TIME \@"HH:mm:ss"</w:instrText>
+/// </w:r>
+/// <w:r>
+/// <w:rPr>
+/// <!-- properties written with DoWriteFieldRunProperties()
+/// </w:rPr>
+/// <w:fldChar w:fldCharType="separate" />
+/// </w:r>
+/// <w:r>
+/// <w:rPr>
+/// <!-- properties written with DoWriteFieldRunProperties()
+/// </w:rPr>
+/// <w:t>14:01:13</w:t>
+/// </w:r>
+/// <w:r>
+/// <w:rPr>
+/// <!-- properties written with DoWriteFieldRunProperties()
+/// </w:rPr>
+/// <w:fldChar w:fldCharType="end" />
+/// </w:r>
+/// See, tdf#38778
+void DocxAttributeOutput::DoWriteFieldRunProperties( const SwTextNode * pNode, sal_Int32 nPos )
+{
+ if (! pNode)
+ {
+ // nothing to do
+ return;
+ }
- // 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 );
+ m_bPreventDoubleFieldsHandling = true;
+
+ {
+ m_pSerializer->startElementNS( XML_w, XML_rPr, FSEND );
+
+ if(GetExport().m_bHideTabLeaderAndPageNumbers && m_pHyperlinkAttrList.is() )
+ {
+ m_pSerializer->singleElementNS( XML_w, XML_webHidden, FSEND );
+ }
+
+ SwWW8AttrIter aAttrIt( m_rExport, *pNode );
+ aAttrIt.OutAttr( nPos, false );
+
+ m_pSerializer->endElementNS( XML_w, XML_rPr );
+ }
+
+ m_bPreventDoubleFieldsHandling = false;
}
-void DocxAttributeOutput::EndField_Impl( FieldInfos& rInfos )
+void DocxAttributeOutput::EndField_Impl( const SwTextNode* pNode, sal_Int32 nPos, FieldInfos& rInfos )
{
// The command has to be written before for the hyperlinks
if ( rInfos.pField )
{
- CmdField_Impl( rInfos );
+ CmdField_Impl( pNode, nPos, rInfos, true );
}
// Write the bookmark start if any
@@ -1761,6 +1843,8 @@ void DocxAttributeOutput::EndField_Impl( FieldInfos& rInfos )
{
// Write the Field latest value
m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
+ DoWriteFieldRunProperties( pNode, nPos );
+
OUString sExpand;
if(rInfos.eType == ww::eCITATION)
{
@@ -1789,6 +1873,7 @@ void DocxAttributeOutput::EndField_Impl( FieldInfos& rInfos )
if ( rInfos.bClose )
{
m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
+ DoWriteFieldRunProperties( pNode, nPos );
m_pSerializer->singleElementNS( XML_w, XML_fldChar,
FSNS( XML_w, XML_fldCharType ), "end",
FSEND );
@@ -1820,7 +1905,7 @@ void DocxAttributeOutput::EndField_Impl( FieldInfos& rInfos )
m_sFieldBkm = OUString( );
// Write the end of the field
- EndField_Impl( rInfos );
+ EndField_Impl( pNode, nPos, rInfos );
}
}
}
@@ -2339,7 +2424,7 @@ void DocxAttributeOutput::RawText(const OUString& /*rText*/, rtl_TextEncoding /*
void DocxAttributeOutput::StartRuby( const SwTextNode& rNode, sal_Int32 nPos, const SwFormatRuby& rRuby )
{
SAL_INFO("sw.ww8", "TODO DocxAttributeOutput::StartRuby( const SwTextNode& rNode, const SwFormatRuby& rRuby )" );
- EndRun(); // end run before starting ruby to avoid nested runs, and overlap
+ EndRun( &rNode, nPos ); // end run before starting ruby to avoid nested runs, and overlap
assert(!m_closeHyperlinkInThisRun); // check that no hyperlink overlaps ruby
assert(!m_closeHyperlinkInPreviousRun);
m_pSerializer->startElementNS( XML_w, XML_ruby, FSEND );
@@ -2393,17 +2478,17 @@ void DocxAttributeOutput::StartRuby( const SwTextNode& rNode, sal_Int32 nPos, co
EndRunProperties( nullptr );
RunText( rRuby.GetText( ) );
- EndRun( );
+ EndRun( &rNode, nPos );
m_pSerializer->endElementNS( XML_w, XML_rt );
m_pSerializer->startElementNS( XML_w, XML_rubyBase, FSEND );
StartRun( nullptr );
}
-void DocxAttributeOutput::EndRuby()
+void DocxAttributeOutput::EndRuby(const SwTextNode& rNode, sal_Int32 nPos)
{
SAL_INFO("sw.ww8", "TODO DocxAttributeOutput::EndRuby()" );
- EndRun( );
+ EndRun( &rNode, nPos );
m_pSerializer->endElementNS( XML_w, XML_rubyBase );
m_pSerializer->endElementNS( XML_w, XML_ruby );
StartRun(nullptr); // open Run again so OutputTextNode loop can close it
@@ -6515,6 +6600,9 @@ void DocxAttributeOutput::CharCaseMap( const SvxCaseMapItem& rCaseMap )
void DocxAttributeOutput::CharColor( const SvxColorItem& rColor )
{
+ if (m_bPreventDoubleFieldsHandling)
+ return;
+
const Color aColor( rColor.GetValue() );
OString aColorString;
@@ -7066,6 +7154,9 @@ void DocxAttributeOutput::WriteExpand( const SwField* pField )
void DocxAttributeOutput::WriteField_Impl( const SwField* pField, ww::eField eType, const OUString& rFieldCmd, FieldFlags nMode )
{
+ if (m_bPreventDoubleFieldsHandling)
+ return;
+
struct FieldInfos infos;
if (pField)
infos.pField.reset(pField->CopyField());
@@ -8620,6 +8711,9 @@ void DocxAttributeOutput::ParaGrabBag(const SfxGrabBagItem& rItem)
void DocxAttributeOutput::CharGrabBag( const SfxGrabBagItem& rItem )
{
+ if (m_bPreventDoubleFieldsHandling)
+ return;
+
const std::map< OUString, css::uno::Any >& rMap = rItem.GetGrabBag();
// get original values of theme-derived properties to check if they have changed during the edition
@@ -8821,6 +8915,7 @@ DocxAttributeOutput::DocxAttributeOutput( DocxExport &rExport, const FSHelperPtr
m_bRunTextIsOn( false ),
m_bWritingHeaderFooter( false ),
m_bAnchorLinkedToNode(false),
+ m_bPreventDoubleFieldsHandling( false ),
m_sFieldBkm( ),
m_nNextBookmarkId( 0 ),
m_nNextAnnotationMarkId( 0 ),