summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuboš Luňák <l.lunak@suse.cz>2012-08-06 17:55:07 +0200
committerLuboš Luňák <l.lunak@suse.cz>2012-08-08 16:32:55 +0200
commit5c20cc0202170508176da577662fb6daead312b0 (patch)
treebb40d8dc6005ac0bdfd704a320d58505811bfb91
parent2f8f63f15a5a93781e4feceddeee18df74dc326a (diff)
support for deferred property processing in writerfilter
There currently does not seem to be any sane way to process an attribute or sprm that depends on another one that may not possibly be there yet (e.g. in e7ab4bb6b0e83f01148ffff41e8c5eaa0c5ba0a4, or w:position which for Svx internal reasons depends on fontsize and thus w:sz). So make it possible to defer such properties and process them only before they are actually used, instead of trying to get them out of PropertyMap, possibly in more places and possibly having to undo the changes that have been done to them already. Change-Id: I1630057ecdf46443647ec1dd5253983ae15a083f
-rw-r--r--writerfilter/inc/dmapper/DomainMapper.hxx5
-rw-r--r--writerfilter/source/dmapper/DomainMapper.cxx20
-rw-r--r--writerfilter/source/dmapper/DomainMapper_Impl.cxx22
-rw-r--r--writerfilter/source/dmapper/DomainMapper_Impl.hxx14
4 files changed, 61 insertions, 0 deletions
diff --git a/writerfilter/inc/dmapper/DomainMapper.hxx b/writerfilter/inc/dmapper/DomainMapper.hxx
index c22eebe69857..4dbbe87e5b5e 100644
--- a/writerfilter/inc/dmapper/DomainMapper.hxx
+++ b/writerfilter/inc/dmapper/DomainMapper.hxx
@@ -109,6 +109,11 @@ public:
GraphicZOrderHelper* graphicZOrderHelper();
bool IsInHeaderFooter() const;
+ /**
+ @see DomainMapper_Impl::processDeferredCharacterProperties()
+ */
+ void processDeferredCharacterProperties(
+ const std::map< sal_Int32, com::sun::star::uno::Any >& deferredCharacterProperties );
private:
// Stream
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx
index 4aa843c70b8b..686c10feaf22 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -3237,6 +3237,26 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, PropertyMapPtr rContext, SprmType
}
+void DomainMapper::processDeferredCharacterProperties( const std::map< sal_Int32, uno::Any >& deferredCharacterProperties )
+{
+ for( std::map< sal_Int32, uno::Any >::const_iterator it = deferredCharacterProperties.begin();
+ it != deferredCharacterProperties.end();
+ ++it )
+ {
+ sal_Int32 Id = it->first;
+ sal_Int32 nIntValue = 0;
+ OUString sStringValue;
+ it->second >>= nIntValue;
+ it->second >>= sStringValue;
+ switch( Id )
+ {
+ default:
+ SAL_WARN( "writerfilter", "Unhandled property in processDeferredCharacterProperty()" );
+ break;
+ }
+ }
+}
+
void DomainMapper::lcl_entry(int /*pos*/,
writerfilter::Reference<Properties>::Pointer_t ref)
{
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index 164a2d40282c..8bc792646952 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -384,7 +384,12 @@ void DomainMapper_Impl::PopProperties(ContextType eId)
m_pLastSectionContext = m_aPropertyStacks[eId].top( );
}
else if (eId == CONTEXT_CHARACTER)
+ {
m_pLastCharacterContext = m_aPropertyStacks[eId].top();
+ // Sadly an assert about deferredCharacterProperties being empty is not possible
+ // here, becase appendTextPortion() may not be called for every character section.
+ deferredCharacterProperties.clear();
+ }
m_aPropertyStacks[eId].pop();
m_aContextStack.pop();
@@ -1107,6 +1112,8 @@ void DomainMapper_Impl::appendTextPortion( const OUString& rString, PropertyMapP
{
if (m_aTextAppendStack.empty())
return;
+ if( pPropertyMap == m_pTopContext && !deferredCharacterProperties.empty())
+ processDeferredCharacterProperties();
uno::Reference< text::XTextAppend > xTextAppend = m_aTextAppendStack.top().xTextAppend;
if(xTextAppend.is() && ! getTableManager( ).isIgnore())
{
@@ -3725,6 +3732,21 @@ SectionPropertyMap * DomainMapper_Impl::GetSectionContext()
return pSectionContext;
}
+void DomainMapper_Impl::deferCharacterProperty( sal_Int32 id, com::sun::star::uno::Any value )
+{
+ deferredCharacterProperties[ id ] = value;
+}
+
+void DomainMapper_Impl::processDeferredCharacterProperties()
+{
+ // ACtually process in DomainMapper, so that it's the same source file like normal processing.
+ if( !deferredCharacterProperties.empty())
+ {
+ m_rDMapper.processDeferredCharacterProperties( deferredCharacterProperties );
+ deferredCharacterProperties.clear();
+ }
+}
+
}}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.hxx b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
index 2622cb70c3ee..abe5ef4b17c1 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
@@ -369,6 +369,8 @@ private:
throw(::com::sun::star::uno::Exception);
::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > GetDocumentSettings();
+ std::map< sal_Int32, com::sun::star::uno::Any > deferredCharacterProperties;
+
public:
DomainMapper_Impl(
DomainMapper& rDMapper,
@@ -629,6 +631,18 @@ public:
SectionPropertyMap * GetSectionContext();
/// If the current paragraph has a numbering style associated, this method returns its character style
com::sun::star::uno::Reference<com::sun::star::beans::XPropertySet> GetCurrentNumberingCharStyle();
+
+ /**
+ Used for attributes/sprms which cannot be evaluated immediatelly (e.g. they depend
+ on another one that comes in the same CONTEXT_CHARACTER). The property will be processed
+ again in DomainMapper::processDeferredCharacterProperties().
+ */
+ void deferCharacterProperty( sal_Int32 id, com::sun::star::uno::Any value );
+ /**
+ Processes properties deferred using deferCharacterProperty(). To be called whenever the top
+ CONTEXT_CHARACTER is going to be used (e.g. by appendText()).
+ */
+ void processDeferredCharacterProperties();
};
} //namespace dmapper
} //namespace writerfilter