[ooo-build-commit] .: patches/dev300
Cédric Bosdonnat
cbosdo at kemper.freedesktop.org
Tue Sep 21 07:07:39 PDT 2010
patches/dev300/apply | 2
patches/dev300/dummy-fields.diff | 788 +++++++++++++++++++++++++++++++++++++++
2 files changed, 790 insertions(+)
New commits:
commit 6b371cff07100a14e50f346f5c9ea75d76e359fb
Author: Cédric Bosdonnat <cedricbosdo at openoffice.org>
Date: Tue Sep 21 16:05:01 2010 +0200
n#628098: Roundtrip OLE links in doc files
This fix bring also an important roundtrip feature for all the ww8
fields not supported by OOo.
diff --git a/patches/dev300/apply b/patches/dev300/apply
index 3f3955d..680cda7 100644
--- a/patches/dev300/apply
+++ b/patches/dev300/apply
@@ -2176,6 +2176,8 @@ win32-restore-associations.diff, n#530872, tml
[ Fixes ]
fix-ppt-linespacing-import-export.diff, n#355302, rodo
+dummy-fields.diff, n#628098, cbosdo
+
svx-hacky-htmlselect-control-import.diff, n#523191, noelpwer
sd-slideshow-slideshowview-transformation-fix.diff, rodo
diff --git a/patches/dev300/dummy-fields.diff b/patches/dev300/dummy-fields.diff
new file mode 100644
index 0000000..248a770
--- /dev/null
+++ b/patches/dev300/dummy-fields.diff
@@ -0,0 +1,788 @@
+diff --git sw/inc/unobookmark.hxx sw/inc/unobookmark.hxx
+index d1062eb..729c556 100644
+--- sw/inc/unobookmark.hxx
++++ sw/inc/unobookmark.hxx
+@@ -80,6 +80,8 @@ protected:
+
+ const ::sw::mark::IMark* GetBookmark() const;
+
++ void registerInMark( SwXBookmark& rXMark, ::sw::mark::IMark* const pMarkBase );
++
+ virtual ~SwXBookmark();
+
+ /// @param pDoc and pMark != 0, but not & because of ImplInheritanceHelper
+@@ -239,6 +241,10 @@ private:
+
+ public:
+
++ static ::com::sun::star::uno::Reference<
++ ::com::sun::star::text::XTextContent>
++ CreateXFieldmark( SwDoc & rDoc, ::sw::mark::IMark & rMark );
++
+ SwXFieldmark(bool isReplacementObject,
+ ::sw::mark::IMark* pBkm = 0, SwDoc* pDoc = 0);
+
+diff --git sw/source/core/crsr/bookmrk.cxx sw/source/core/crsr/bookmrk.cxx
+index 5bca4c8..dca5995 100644
+--- sw/source/core/crsr/bookmrk.cxx
++++ sw/source/core/crsr/bookmrk.cxx
+@@ -82,15 +82,17 @@ namespace
+ SwTxtNode const * const pStartTxtNode = io_pDoc->GetNodes()[rStart.nNode]->GetTxtNode();
+ SwTxtNode const * const pEndTxtNode = io_pDoc->GetNodes()[rEnd.nNode]->GetTxtNode();
+ const sal_Unicode ch_start=pStartTxtNode->GetTxt().GetChar(rStart.nContent.GetIndex());
+- const sal_Unicode ch_end=pEndTxtNode->GetTxt().GetChar(rEnd.nContent.GetIndex()-1);
++ xub_StrLen nEndPos = rEnd.nContent.GetIndex() == 0 ? 0 : rEnd.nContent.GetIndex() - 1;
++ const sal_Unicode ch_end=pEndTxtNode->GetTxt().GetChar( nEndPos );
+ SwPaM aStartPaM(rStart);
+ SwPaM aEndPaM(rEnd);
+ io_pDoc->StartUndo(UNDO_UI_REPLACE, NULL);
+- if(ch_start != aStartMark)
++ if( ( ch_start != aStartMark ) && ( rStart != rEnd ) )
+ {
+ io_pDoc->InsertString(aStartPaM, aStartMark);
++ rStart.nContent--;
+ }
+- if ( aEndMark && ( ch_end != aEndMark ) && ( rStart != rEnd ) )
++ if ( aEndMark && ( ch_end != aEndMark ) )
+ {
+ io_pDoc->InsertString(aEndPaM, aEndMark);
+ }
+@@ -323,7 +325,7 @@ namespace sw { namespace mark
+
+ void CheckboxFieldmark::InitDoc(SwDoc* const io_pDoc)
+ {
+- lcl_AssureFieldMarksSet(this, io_pDoc, CH_TXT_ATR_FORMELEMENT, CH_TXT_ATR_FIELDEND);
++ lcl_AssureFieldMarksSet(this, io_pDoc, CH_TXT_ATR_FIELDSTART, CH_TXT_ATR_FORMELEMENT);
+
+ // For some reason the end mark is moved from 1 by the Insert: we don't
+ // want this for checkboxes
+@@ -343,4 +345,17 @@ namespace sw { namespace mark
+ return bResult;
+ }
+
++ rtl::OUString CheckboxFieldmark::toString( ) const
++ {
++ rtl::OUStringBuffer buf;
++ buf.appendAscii( "CheckboxFieldmark: ( Name, Type, [ Nd1, Id1 ], [ Nd2, Id2 ] ): ( " );
++ buf.append( m_aName ).appendAscii( ", " );
++ buf.append( GetFieldname() ).appendAscii( ", [ " );
++ buf.append( sal_Int32( GetMarkPos().nNode.GetIndex( ) ) ).appendAscii( ", " );
++ buf.append( sal_Int32( GetMarkPos( ).nContent.GetIndex( ) ) ).appendAscii( " ], [" );
++ buf.append( sal_Int32( GetOtherMarkPos().nNode.GetIndex( ) ) ).appendAscii( ", " );
++ buf.append( sal_Int32( GetOtherMarkPos( ).nContent.GetIndex( ) ) ).appendAscii( " ] ) " );
++
++ return buf.makeStringAndClear( );
++ }
+ }}
+diff --git sw/source/core/crsr/pam.cxx sw/source/core/crsr/pam.cxx
+index 6de3089..0f071a1 100644
+--- sw/source/core/crsr/pam.cxx
++++ sw/source/core/crsr/pam.cxx
+@@ -55,6 +55,8 @@
+ #include <IMark.hxx>
+ #include <hints.hxx>
+
++#include <xmloff/odffields.hxx>
++
+ // fuer den dummen ?MSC-? Compiler
+ inline xub_StrLen GetSttOrEnd( BOOL bCondition, const SwCntntNode& rNd )
+ {
+@@ -828,19 +830,31 @@ BOOL SwPaM::HasReadonlySel( bool bFormView ) const
+ const SwDoc *pDoc = GetDoc();
+ sw::mark::IMark* pA = NULL;
+ sw::mark::IMark* pB = NULL;
++ bool bUnhandledMark = false;
+ if ( pDoc )
+ {
+ const IDocumentMarkAccess* pMarksAccess = pDoc->getIDocumentMarkAccess( );
+ pA = GetPoint() ? pMarksAccess->getFieldmarkFor( *GetPoint( ) ) : NULL;
+ pB = GetMark( ) ? pMarksAccess->getFieldmarkFor( *GetMark( ) ) : pA;
++
++ sw::mark::IFieldmark* pFieldmark = pMarksAccess->getFieldmarkFor( *GetPoint() );
++ if ( pFieldmark )
++ bUnhandledMark = pFieldmark->GetFieldname( ).equalsAscii( ODF_UNHANDLED );
+ }
+
+ if (!bRet)
+ {
+- bRet = ( pA != pB );
+- bool bProtectForm = pDoc->get( IDocumentSettingAccess::PROTECT_FORM );
+- if ( bProtectForm )
+- bRet |= ( pA == NULL || pB == NULL );
++ // Unhandled fieldmarks case shouldn't be edited manually to avoid breaking anything
++ if ( ( pA == pB ) && bUnhandledMark )
++ bRet = TRUE;
++ else
++ {
++ // Form protection case
++ bRet = ( pA != pB );
++ bool bProtectForm = pDoc->get( IDocumentSettingAccess::PROTECT_FORM );
++ if ( bProtectForm )
++ bRet |= ( pA == NULL || pB == NULL );
++ }
+ }
+ else
+ {
+diff --git sw/source/core/doc/docbm.cxx sw/source/core/doc/docbm.cxx
+index 23ecd3f..e4cfbbd 100644
+--- sw/source/core/doc/docbm.cxx
++++ sw/source/core/doc/docbm.cxx
+@@ -419,6 +419,7 @@ namespace sw { namespace mark
+ OSL_TRACE("Fieldmarks");
+ lcl_DebugMarks(m_vFieldmarks);
+ #endif
++
+ return pMark.get();
+ }
+
+@@ -811,6 +812,7 @@ namespace sw { namespace mark
+ IFieldmark* MarkManager::getFieldmarkBefore(const SwPosition& rPos) const
+ { return dynamic_cast<IFieldmark*>(lcl_getMarkBefore(m_vFieldmarks, rPos)); }
+
++
+ ::rtl::OUString MarkManager::getUniqueMarkName(const ::rtl::OUString& rName) const
+ {
+ OSL_ENSURE(rName.getLength(),
+diff --git sw/source/core/inc/bookmrk.hxx sw/source/core/inc/bookmrk.hxx
+index a47a059..2ff0409 100644
+--- sw/source/core/inc/bookmrk.hxx
++++ sw/source/core/inc/bookmrk.hxx
+@@ -35,6 +35,7 @@
+ #include <boost/scoped_ptr.hpp>
+ #include <boost/noncopyable.hpp>
+ #include <map>
++#include <rtl/ustring.hxx>
+
+ #include <IMark.hxx>
+
+@@ -255,6 +256,8 @@ namespace sw { namespace mark
+ virtual void InitDoc(SwDoc* const io_pDoc);
+ bool IsChecked() const;
+ void SetChecked(bool checked);
++
++ virtual rtl::OUString toString( ) const;
+ };
+
+ }}
+diff --git sw/source/core/unocore/unobkm.cxx sw/source/core/unocore/unobkm.cxx
+index 19b7791..3c76516 100644
+--- sw/source/core/unocore/unobkm.cxx
++++ sw/source/core/unocore/unobkm.cxx
+@@ -131,6 +131,11 @@ void SwXBookmark::Impl::registerInMark(SwXBookmark & rThis,
+ m_pRegisteredBookmark = pBkmk;
+ }
+
++void SwXBookmark::registerInMark(SwXBookmark & rThis,
++ ::sw::mark::IMark *const pBkmk)
++{
++ m_pImpl->registerInMark( rThis, pBkmk );
++}
+
+ const ::sw::mark::IMark* SwXBookmark::GetBookmark() const
+ {
+@@ -649,3 +654,27 @@ uno::Reference<container::XNameContainer> SwXFieldmark::getParameters()
+ return uno::Reference<container::XNameContainer>(new SwXFieldmarkParameters(pBkm));
+ }
+
++uno::Reference<text::XTextContent>
++SwXFieldmark::CreateXFieldmark(SwDoc & rDoc, ::sw::mark::IMark & rMark)
++{
++ // #i105557#: do not iterate over the registered clients: race condition
++ ::sw::mark::MarkBase *const pMarkBase(
++ dynamic_cast< ::sw::mark::MarkBase * >(&rMark));
++ OSL_ENSURE(pMarkBase, "CreateXBookmark: no MarkBase?");
++ if (!pMarkBase) { return 0; }
++ uno::Reference<text::XTextContent> xMark(pMarkBase->GetXBookmark());
++ if (!xMark.is())
++ {
++ // FIXME: These belong in XTextFieldsSupplier
++ SwXFieldmark* pXBkmk = NULL;
++ if (dynamic_cast< ::sw::mark::TextFieldmark* >(&rMark))
++ pXBkmk = new SwXFieldmark(false, &rMark, &rDoc);
++ else if (dynamic_cast< ::sw::mark::CheckboxFieldmark* >(&rMark))
++ pXBkmk = new SwXFieldmark(true, &rMark, &rDoc);
++
++ xMark.set(pXBkmk);
++ pXBkmk->registerInMark(*pXBkmk, pMarkBase);
++ }
++ return xMark;
++}
++
+diff --git sw/source/core/unocore/unoportenum.cxx sw/source/core/unocore/unoportenum.cxx
+index 0a5115b..d68f505 100644
+--- sw/source/core/unocore/unoportenum.cxx
++++ sw/source/core/unocore/unoportenum.cxx
+@@ -376,7 +376,7 @@ lcl_ExportFieldMark(
+ pUnoCrsr, i_xParentText, PORTION_FIELD_START);
+ xRef = pPortion;
+ if (pPortion && pFieldmark && pDoc)
+- pPortion->SetBookmark(new SwXFieldmark(false, pFieldmark, pDoc));
++ pPortion->SetBookmark( SwXFieldmark::CreateXFieldmark( *pDoc, *pFieldmark ) );
+ }
+ else if (CH_TXT_ATR_FIELDEND == Char)
+ {
+@@ -390,7 +390,7 @@ lcl_ExportFieldMark(
+ pUnoCrsr, i_xParentText, PORTION_FIELD_END);
+ xRef = pPortion;
+ if (pPortion && pFieldmark && pDoc)
+- pPortion->SetBookmark(new SwXFieldmark(false, pFieldmark, pDoc));
++ pPortion->SetBookmark( SwXFieldmark::CreateXFieldmark( *pDoc, *pFieldmark ) );
+ }
+ else if (CH_TXT_ATR_FORMELEMENT == Char)
+ {
+@@ -404,7 +404,7 @@ lcl_ExportFieldMark(
+ pUnoCrsr, i_xParentText, PORTION_FIELD_START_END);
+ xRef = pPortion;
+ if (pPortion && pFieldmark && pDoc)
+- pPortion->SetBookmark(new SwXFieldmark(true, pFieldmark, pDoc));
++ pPortion->SetBookmark( SwXFieldmark::CreateXFieldmark( *pDoc, *pFieldmark ) );
+ }
+ else
+ {
+diff --git sw/source/filter/ww8/docxexport.cxx sw/source/filter/ww8/docxexport.cxx
+index ca491ab..fb38a5e 100644
+--- sw/source/filter/ww8/docxexport.cxx
++++ sw/source/filter/ww8/docxexport.cxx
+@@ -402,6 +402,11 @@ void DocxExport::OutputOLENode( const SwOLENode& )
+ OSL_TRACE( "TODO DocxExport::OutputOLENode( const SwOLENode& )\n" );
+ }
+
++void DocxExport::OutputLinkedOLE( const OUString& )
++{
++ // Nothing to implement here: WW8 only
++}
++
+ ULONG DocxExport::ReplaceCr( BYTE )
+ {
+ // Completely unused for Docx export... only here for code sharing
+diff --git sw/source/filter/ww8/docxexport.hxx sw/source/filter/ww8/docxexport.hxx
+index 63d62a0..239929c 100644
+--- sw/source/filter/ww8/docxexport.hxx
++++ sw/source/filter/ww8/docxexport.hxx
+@@ -157,6 +157,9 @@ protected:
+ /// Output SwOLENode
+ virtual void OutputOLENode( const SwOLENode& );
+
++ virtual void OutputLinkedOLE( const rtl::OUString& );
++
++
+
+ virtual void AppendSection( const SwPageDesc *pPageDesc, const SwSectionFmt* pFmt, ULONG nLnNum );
+
+diff --git sw/source/filter/ww8/rtfexport.cxx sw/source/filter/ww8/rtfexport.cxx
+index 6e92224..8eb518b 100644
+--- sw/source/filter/ww8/rtfexport.cxx
++++ sw/source/filter/ww8/rtfexport.cxx
+@@ -728,6 +728,11 @@ void RtfExport::OutputOLENode( const SwOLENode& )
+ /* noop, see RtfAttributeOutput::FlyFrameOLE */
+ }
+
++void RtfExport::OutputLinkedOLE( const rtl::OUString& )
++{
++ OSL_TRACE("%s", OSL_THIS_FUNC);
++}
++
+ void RtfExport::AppendSection( const SwPageDesc* pPageDesc, const SwSectionFmt* pFmt, ULONG nLnNum )
+ {
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+diff --git sw/source/filter/ww8/rtfexport.hxx sw/source/filter/ww8/rtfexport.hxx
+index 0a2f3f4..ea96f9c 100644
+--- sw/source/filter/ww8/rtfexport.hxx
++++ sw/source/filter/ww8/rtfexport.hxx
+@@ -142,6 +142,8 @@ protected:
+ /// Output SwOLENode
+ virtual void OutputOLENode( const SwOLENode& );
+
++ virtual void OutputLinkedOLE(const rtl::OUString&);
++
+ virtual void AppendSection( const SwPageDesc *pPageDesc, const SwSectionFmt* pFmt, ULONG nLnNum );
+
+ public:
+diff --git sw/source/filter/ww8/wrtw8nds.cxx sw/source/filter/ww8/wrtw8nds.cxx
+index fa2b75a..3191b6b 100644
+--- sw/source/filter/ww8/wrtw8nds.cxx
++++ sw/source/filter/ww8/wrtw8nds.cxx
+@@ -116,9 +116,9 @@ using namespace sw::types;
+ using namespace sw::mark;
+ using namespace nsFieldFlags;
+
+-
+ static String lcl_getFieldCode( const IFieldmark* pFieldmark ) {
+ ASSERT(pFieldmark!=NULL, "where is my fieldmark???");
++
+ if ( pFieldmark->GetFieldname( ).equalsAscii( ODF_FORMTEXT ) ) {
+ return String::CreateFromAscii(" FORMTEXT ");
+ } else if ( pFieldmark->GetFieldname( ).equalsAscii( ODF_FORMDROPDOWN ) ) {
+@@ -1827,12 +1827,49 @@ void MSWordExportBase::OutputTextNode( const SwTxtNode& rNode )
+
+ if ( pFieldmark->GetFieldname().equalsAscii( ODF_FORMTEXT ) )
+ AppendBookmark( pFieldmark->GetName(), false );
+- OutputField( NULL, lcl_getFieldId( pFieldmark ), lcl_getFieldCode( pFieldmark ), WRITEFIELD_START | WRITEFIELD_CMD_START );
++ ww::eField eFieldId = lcl_getFieldId( pFieldmark );
++ String sCode = lcl_getFieldCode( pFieldmark );
++ if ( pFieldmark->GetFieldname().equalsAscii( ODF_UNHANDLED ) )
++ {
++ IFieldmark::parameter_map_t::const_iterator it = pFieldmark->GetParameters()->find(
++ rtl::OUString::createFromAscii( ODF_ID_PARAM ) );
++ if ( it != pFieldmark->GetParameters()->end() )
++ {
++ rtl::OUString sFieldId;
++ it->second >>= sFieldId;
++ eFieldId = (ww::eField)sFieldId.toInt32();
++ }
++
++ it = pFieldmark->GetParameters()->find(
++ rtl::OUString::createFromAscii( ODF_CODE_PARAM ) );
++ if ( it != pFieldmark->GetParameters()->end() )
++ {
++ rtl::OUString sOUCode;
++ it->second >>= sOUCode;
++ sCode = sOUCode;
++ }
++ }
++ OutputField( NULL, eFieldId, sCode, WRITEFIELD_START | WRITEFIELD_CMD_START );
+ if ( pFieldmark->GetFieldname( ).equalsAscii( ODF_FORMTEXT ) )
+ WriteFormData( *pFieldmark );
+ else if ( pFieldmark->GetFieldname( ).equalsAscii( ODF_HYPERLINK ) )
+ WriteHyperlinkData( *pFieldmark );
+ OutputField( NULL, lcl_getFieldId( pFieldmark ), String(), WRITEFIELD_CMD_END );
++
++ if ( pFieldmark->GetFieldname().equalsAscii( ODF_UNHANDLED ) )
++ {
++ // Check for the presence of a linked OLE object
++ IFieldmark::parameter_map_t::const_iterator it = pFieldmark->GetParameters()->find(
++ rtl::OUString::createFromAscii( ODF_OLE_PARAM ) );
++ if ( it != pFieldmark->GetParameters()->end() )
++ {
++ rtl::OUString sOleId;
++ uno::Any aValue = it->second;
++ aValue >>= sOleId;
++ if ( sOleId.getLength( ) > 0 )
++ OutputLinkedOLE( sOleId );
++ }
++ }
+ }
+ else if ( ch == CH_TXT_ATR_FIELDEND )
+ {
+@@ -1840,7 +1877,20 @@ void MSWordExportBase::OutputTextNode( const SwTxtNode& rNode )
+ ::sw::mark::IFieldmark const * const pFieldmark = pMarkAccess->getFieldmarkFor( aPosition );
+ OSL_ENSURE( pFieldmark, "Looks like this doc is broken...; where is the Fieldmark for the FIELDSTART??" );
+
+- OutputField( NULL, lcl_getFieldId( pFieldmark ), String(), WRITEFIELD_CLOSE );
++ ww::eField eFieldId = lcl_getFieldId( pFieldmark );
++ if ( pFieldmark->GetFieldname().equalsAscii( ODF_UNHANDLED ) )
++ {
++ IFieldmark::parameter_map_t::const_iterator it = pFieldmark->GetParameters()->find(
++ rtl::OUString::createFromAscii( ODF_ID_PARAM ) );
++ if ( it != pFieldmark->GetParameters()->end() )
++ {
++ rtl::OUString sFieldId;
++ it->second >>= sFieldId;
++ eFieldId = (ww::eField)sFieldId.toInt32();
++ }
++ }
++
++ OutputField( NULL, eFieldId, String(), WRITEFIELD_CLOSE );
+ if ( pFieldmark->GetFieldname().equalsAscii( ODF_FORMTEXT ) )
+ AppendBookmark( pFieldmark->GetName(), false );
+ }
+diff --git sw/source/filter/ww8/wrtww8.hxx sw/source/filter/ww8/wrtww8.hxx
+index 94d6505..56225dc 100644
+--- sw/source/filter/ww8/wrtww8.hxx
++++ sw/source/filter/ww8/wrtww8.hxx
+@@ -784,6 +784,9 @@ protected:
+ /// Output SwOLENode
+ virtual void OutputOLENode( const SwOLENode& ) = 0;
+
++ virtual void OutputLinkedOLE( const rtl::OUString& ) = 0;
++
++
+ /// Output SwSectionNode
+ virtual void OutputSectionNode( const SwSectionNode& );
+
+@@ -1123,6 +1126,8 @@ protected:
+ /// Output SwOLENode
+ virtual void OutputOLENode( const SwOLENode& );
+
++ virtual void OutputLinkedOLE( const rtl::OUString& );
++
+ virtual void AppendSection( const SwPageDesc *pPageDesc, const SwSectionFmt* pFmt, ULONG nLnNum );
+
+ private:
+diff --git sw/source/filter/ww8/wrtww8gr.cxx sw/source/filter/ww8/wrtww8gr.cxx
+index 88670de..9e18faf 100644
+--- sw/source/filter/ww8/wrtww8gr.cxx
++++ sw/source/filter/ww8/wrtww8gr.cxx
+@@ -36,6 +36,7 @@
+
+ #include <com/sun/star/embed/XEmbedPersist.hpp>
+ #include <com/sun/star/embed/Aspects.hpp>
++#include <com/sun/star/embed/ElementModes.hpp>
+ #include <rtl/math.hxx>
+ #include <svtools/filter.hxx>
+ #include <svl/itemiter.hxx>
+@@ -368,6 +369,48 @@ void WW8Export::OutputOLENode( const SwOLENode& rOLENode )
+ }
+ }
+
++void WW8Export::OutputLinkedOLE( const rtl::OUString& rOleId )
++{
++ uno::Reference< embed::XStorage > xDocStg = pDoc->GetDocStorage();
++ uno::Reference< embed::XStorage > xOleStg = xDocStg->openStorageElement(
++ rtl::OUString::createFromAscii( "OLELinks" ), embed::ElementModes::READ );
++ SotStorageRef xObjSrc = SotStorage::OpenOLEStorage( xOleStg, rOleId, STREAM_READ );
++
++ SotStorageRef xObjStg = GetWriter().GetStorage().OpenSotStorage(
++ CREATE_CONST_ASC(SL::aObjectPool), STREAM_READWRITE |
++ STREAM_SHARE_DENYALL );
++
++ if( xObjStg.Is() && xObjSrc.Is() )
++ {
++ SotStorageRef xOleDst = xObjStg->OpenSotStorage( rOleId,
++ STREAM_READWRITE | STREAM_SHARE_DENYALL );
++ if ( xOleDst.Is() )
++ xObjSrc->CopyTo( xOleDst );
++
++ if ( !xOleDst->GetError( ) )
++ {
++ xOleDst->Commit();
++
++ // Ouput the cPicLocation attribute
++ WW8Bytes* pBuf = new WW8Bytes( 128, 128 );
++ GetWriter().InsUInt16( *pBuf, NS_sprm::LN_CPicLocation );
++ GetWriter().InsUInt32( *pBuf, rOleId.copy( 1 ).toInt32() );
++
++ GetWriter().InsUInt16( *pBuf, NS_sprm::LN_CFOle2 );
++ pBuf->Insert( 1, pBuf->Count() );
++
++ GetWriter().InsUInt16( *pBuf, NS_sprm::LN_CFSpec );
++ pBuf->Insert( 1, pBuf->Count() );
++
++ GetWriter().InsUInt16( *pBuf, NS_sprm::LN_CFObj );
++ pBuf->Insert( 1, pBuf->Count() );
++
++ pChpPlc->AppendFkpEntry( Strm().Tell(), pBuf->Count(), pBuf->GetData() );
++ delete pBuf;
++ }
++ }
++}
++
+ void WW8Export::OutGrf(const sw::Frame &rFrame)
+ {
+ // GrfNode fuer spaeteres rausschreiben der Grafik merken
+diff --git sw/source/filter/ww8/ww8par.hxx sw/source/filter/ww8/ww8par.hxx
+index 52a7113..8f25441 100644
+--- sw/source/filter/ww8/ww8par.hxx
++++ sw/source/filter/ww8/ww8par.hxx
+@@ -363,6 +363,7 @@ class FieldEntry
+ private:
+ ::rtl::OUString msBookmarkName;
+ ::rtl::OUString msMarkType;
++ ::rtl::OUString msMarkCode;
+ ::sw::mark::IFieldmark::parameter_map_t maParams;
+
+ public:
+@@ -378,8 +379,10 @@ class FieldEntry
+
+ ::rtl::OUString GetBookmarkName();
+ ::rtl::OUString GetBookmarkType();
++ ::rtl::OUString GetBookmarkCode();
+ void SetBookmarkName(::rtl::OUString bookmarkName);
+ void SetBookmarkType(::rtl::OUString bookmarkType);
++ void SetBookmarkCode(::rtl::OUString bookmarkCode);
+ ::sw::mark::IFieldmark::parameter_map_t& getParameters();
+ };
+
+diff --git sw/source/filter/ww8/ww8par5.cxx sw/source/filter/ww8/ww8par5.cxx
+index 57dfd8a..2b9cb00 100644
+--- sw/source/filter/ww8/ww8par5.cxx
++++ sw/source/filter/ww8/ww8par5.cxx
+@@ -36,6 +36,13 @@
+ #include <sal/types.h>
+ #include <tools/solar.h>
+
++#include <comphelper/storagehelper.hxx>
++#include <sot/storinfo.hxx>
++#include <com/sun/star/embed/XStorage.hpp>
++#include <com/sun/star/embed/ElementModes.hpp>
++#include <com/sun/star/embed/XTransactedObject.hpp>
++#include <com/sun/star/io/XStream.hpp>
++
+ #include <com/sun/star/ucb/XCommandEnvironment.hpp>
+ #include <svl/urihelper.hxx>
+ #include <svl/zforlist.hxx>
+@@ -87,6 +94,7 @@
+ #include "writerhelper.hxx"
+ #include "fields.hxx"
+ #include <unotools/fltrcfg.hxx>
++#include <xmloff/odffields.hxx>
+
+ #include <algorithm> // #i24377#
+
+@@ -725,6 +733,72 @@ sal_uInt16 SwWW8ImplReader::End_Field()
+ *pPaM->GetPoint() = maFieldStack.back().maStartPos;
+ break;
+ default:
++ rtl::OUString aCode = maFieldStack.back().GetBookmarkCode();
++ if ( aCode.getLength() > 0 )
++ {
++ // Unhandled field with stored code
++ SwPosition aEndPos = *pPaM->GetPoint();
++ SwPaM aFldPam(
++ maFieldStack.back().GetPtNode(), maFieldStack.back().GetPtCntnt(),
++ aEndPos.nNode, aEndPos.nContent.GetIndex());
++
++ IDocumentMarkAccess* pMarksAccess = rDoc.getIDocumentMarkAccess( );
++
++ IFieldmark* pFieldmark = pMarksAccess->makeFieldBookmark(
++ aFldPam,
++ maFieldStack.back().GetBookmarkName(),
++ rtl::OUString::createFromAscii( ODF_UNHANDLED ) );
++ if ( pFieldmark )
++ {
++ const IFieldmark::parameter_map_t& pParametersToAdd = maFieldStack.back().getParameters();
++ pFieldmark->GetParameters()->insert(pParametersToAdd.begin(), pParametersToAdd.end());
++ rtl::OUString sFieldId = rtl::OUString::valueOf( sal_Int32( maFieldStack.back().mnFieldId ) );
++ pFieldmark->GetParameters()->insert(
++ std::pair< rtl::OUString, uno::Any > (
++ rtl::OUString::createFromAscii( ODF_ID_PARAM ),
++ uno::makeAny( sFieldId ) ) );
++ pFieldmark->GetParameters()->insert(
++ std::pair< rtl::OUString, uno::Any > (
++ rtl::OUString::createFromAscii( ODF_CODE_PARAM ),
++ uno::makeAny( aCode ) ) );
++
++ if ( nObjLocFc > 0 )
++ {
++ // Store the OLE object as an internal link
++ String sOleId = '_';
++ sOleId += String::CreateFromInt32( nObjLocFc );
++
++ SvStorageRef xSrc0 = pStg->OpenSotStorage(CREATE_CONST_ASC(SL::aObjectPool));
++ SvStorageRef xSrc1 = xSrc0->OpenSotStorage( sOleId, STREAM_READ );
++
++ // Store it now!
++ uno::Reference< embed::XStorage > xDocStg = GetDoc().GetDocStorage();
++ uno::Reference< embed::XStorage > xOleStg = xDocStg->openStorageElement(
++ rtl::OUString::createFromAscii( "OLELinks" ), embed::ElementModes::WRITE );
++ SotStorageRef xObjDst = SotStorage::OpenOLEStorage( xOleStg, sOleId );
++
++ if ( xObjDst.Is() )
++ {
++ xSrc1->CopyTo( xObjDst );
++
++ if ( !xObjDst->GetError() )
++ xObjDst->Commit();
++ }
++
++ uno::Reference< embed::XTransactedObject > xTransact( xOleStg, uno::UNO_QUERY );
++ if ( xTransact.is() )
++ xTransact->commit();
++
++ // Store the OLE Id as a parameter
++ pFieldmark->GetParameters()->insert(
++ std::pair< rtl::OUString, uno::Any >(
++ rtl::OUString::createFromAscii( ODF_OLE_PARAM ),
++ uno::makeAny( rtl::OUString( sOleId ) ) ) );
++ }
++
++ }
++ }
++
+ break;
+ }
+ maFieldStack.pop_back();
+@@ -788,6 +862,11 @@ FieldEntry &FieldEntry::operator=(const FieldEntry &rOther) throw()
+ return msMarkType;
+ }
+
++::rtl::OUString FieldEntry::GetBookmarkCode()
++{
++ return msMarkCode;
++}
++
+ void FieldEntry::SetBookmarkName(::rtl::OUString bookmarkName)
+ {
+ msBookmarkName=bookmarkName;
+@@ -798,6 +877,11 @@ void FieldEntry::SetBookmarkType(::rtl::OUString bookmarkType)
+ msMarkType=bookmarkType;
+ }
+
++void FieldEntry::SetBookmarkCode(::rtl::OUString bookmarkCode)
++{
++ msMarkCode = bookmarkCode;
++}
++
+
+ ::sw::mark::IFieldmark::parameter_map_t& FieldEntry::getParameters() {
+ return maParams;
+@@ -871,7 +955,7 @@ long SwWW8ImplReader::Read_Field(WW8PLCFManResult* pRes)
+ 0,
+
+
+- 0, // 56: VERKNUePFUNG // fehlt noch !!!!!!!!!!!!!!!!!!!!!!!
++ 0, // 56
+
+
+ &SwWW8ImplReader::Read_F_Symbol, // 57
+@@ -993,8 +1077,16 @@ long SwWW8ImplReader::Read_Field(WW8PLCFManResult* pRes)
+ ( ( nSearchPos = aStr.Search('/') ) != STRING_NOTFOUND && nSearchPos < nSpacePos ) )
+ return aF.nLen;
+ else
++ {
++ // Link fields aren't supported, but they are bound to an OLE object
++ // that needs to be roundtripped
++ if ( aF.nId == 56 )
++ bEmbeddObj = true;
++ // Field not supported: store the field code for later use
++ maFieldStack.back().SetBookmarkCode( aStr );
+ return aF.nLen - aF.nLRes - 1; // so viele ueberlesen, das Resultfeld
+ // wird wie Haupttext eingelesen
++ }
+ }
+ else
+ { // Lies Feld
+diff --git xmloff/inc/xmloff/odffields.hxx xmloff/inc/xmloff/odffields.hxx
+index ef8121a..152e181 100644
+--- xmloff/inc/xmloff/odffields.hxx
++++ xmloff/inc/xmloff/odffields.hxx
+@@ -53,4 +53,9 @@
+
+ #define ODF_PAGEREF "vnd.oasis.opendocument.field.PAGEREF"
+
++#define ODF_UNHANDLED "vnd.oasis.opendocument.field.UNHANDLED"
++#define ODF_OLE_PARAM "vnd.oasis.opendocument.field.ole"
++#define ODF_ID_PARAM "vnd.oasis.opendocument.field.id"
++#define ODF_CODE_PARAM "vnd.oasis.opendocument.field.code"
++
+ #endif /* _ODFFIELDS_HXX */
+diff --git xmloff/source/text/txtparae.cxx xmloff/source/text/txtparae.cxx
+index a73600b..7ba4ade 100644
+--- xmloff/source/text/txtparae.cxx
++++ xmloff/source/text/txtparae.cxx
+@@ -117,6 +117,11 @@
+ #include "XMLTextCharStyleNamesElementExport.hxx"
+ #include <comphelper/stlunosequence.hxx>
+
++#include <xmloff/odffields.hxx>
++#include <com/sun/star/embed/ElementModes.hpp>
++#include <com/sun/star/embed/XTransactedObject.hpp>
++#include <com/sun/star/document/XStorageBasedDocument.hpp>
++
+ // --> OD 2008-04-25 #refactorlists#
+ #include <txtlists.hxx>
+ // <--
+@@ -417,6 +422,27 @@ void FieldParamExporter::Export()
+ OUString sValue;
+ aValue >>= sValue;
+ ExportParameter(*pCurrent,sValue);
++
++ if ( pCurrent->equalsAscii( ODF_OLE_PARAM ) )
++ {
++ // Save the OLE object
++ Reference< embed::XStorage > xTargetStg = m_pExport->GetTargetStorage();
++ Reference< embed::XStorage > xDstStg = xTargetStg->openStorageElement(
++ rtl::OUString::createFromAscii( "OLELinks" ), embed::ElementModes::WRITE );
++
++ if ( !xDstStg->hasByName( sValue ) ) {
++ Reference< XStorageBasedDocument > xStgDoc (
++ m_pExport->GetModel( ), UNO_QUERY );
++ Reference< embed::XStorage > xDocStg = xStgDoc->getDocumentStorage();
++ Reference< embed::XStorage > xOleStg = xDocStg->openStorageElement(
++ rtl::OUString::createFromAscii( "OLELinks" ), embed::ElementModes::READ );
++
++ xOleStg->copyElementTo( sValue, xDstStg, sValue );
++ Reference< embed::XTransactedObject > xTransact( xDstStg, UNO_QUERY );
++ if ( xTransact.is( ) )
++ xTransact->commit( );
++ }
++ }
+ }
+ else if(aValueType == aBoolType)
+ {
+@@ -2311,46 +2337,55 @@ void XMLTextParagraphExport::exportTextRangeEnumeration(
+ }
+ else if (sType.equals(sTextFieldStart))
+ {
+- Reference<XNamed> xBookmark(xPropSet->getPropertyValue(sBookmark), UNO_QUERY);
+- if (xBookmark.is())
++ if ( GetExport().getDefaultVersion() == SvtSaveOptions::ODFVER_LATEST )
+ {
+- GetExport().AddAttribute(XML_NAMESPACE_TEXT, XML_NAME, xBookmark->getName());
+- }
+- Reference< ::com::sun::star::text::XFormField > xFormField(xPropSet->getPropertyValue(sBookmark), UNO_QUERY);
+- if (xFormField.is())
+- {
+- GetExport().AddAttribute(XML_NAMESPACE_FIELD, XML_TYPE, xFormField->getFieldType());
+- }
+- GetExport().StartElement(XML_NAMESPACE_FIELD, XML_FIELDMARK_START, sal_False);
+- if (xFormField.is())
+- {
+- FieldParamExporter(&GetExport(), xFormField->getParameters()).Export();
++ Reference<XNamed> xBookmark(xPropSet->getPropertyValue(sBookmark), UNO_QUERY);
++ if (xBookmark.is())
++ {
++ GetExport().AddAttribute(XML_NAMESPACE_TEXT, XML_NAME, xBookmark->getName());
++ }
++ Reference< ::com::sun::star::text::XFormField > xFormField(xPropSet->getPropertyValue(sBookmark), UNO_QUERY);
++ if (xFormField.is())
++ {
++ GetExport().AddAttribute(XML_NAMESPACE_FIELD, XML_TYPE, xFormField->getFieldType());
++ }
++ GetExport().StartElement(XML_NAMESPACE_FIELD, XML_FIELDMARK_START, sal_False);
++ if (xFormField.is())
++ {
++ FieldParamExporter(&GetExport(), xFormField->getParameters()).Export();
++ }
++ GetExport().EndElement(XML_NAMESPACE_FIELD, XML_FIELDMARK_START, sal_False);
+ }
+- GetExport().EndElement(XML_NAMESPACE_FIELD, XML_FIELDMARK_START, sal_False);
+ }
+ else if (sType.equals(sTextFieldEnd))
+ {
+- GetExport().StartElement(XML_NAMESPACE_FIELD, XML_FIELDMARK_END, sal_False);
+- GetExport().EndElement(XML_NAMESPACE_FIELD, XML_FIELDMARK_END, sal_False);
++ if ( GetExport().getDefaultVersion() == SvtSaveOptions::ODFVER_LATEST )
++ {
++ GetExport().StartElement(XML_NAMESPACE_FIELD, XML_FIELDMARK_END, sal_False);
++ GetExport().EndElement(XML_NAMESPACE_FIELD, XML_FIELDMARK_END, sal_False);
++ }
+ }
+ else if (sType.equals(sTextFieldStartEnd))
+ {
+- Reference<XNamed> xBookmark(xPropSet->getPropertyValue(sBookmark), UNO_QUERY);
+- if (xBookmark.is())
+- {
+- GetExport().AddAttribute(XML_NAMESPACE_TEXT, XML_NAME, xBookmark->getName());
+- }
+- Reference< ::com::sun::star::text::XFormField > xFormField(xPropSet->getPropertyValue(sBookmark), UNO_QUERY);
+- if (xFormField.is())
+- {
+- GetExport().AddAttribute(XML_NAMESPACE_FIELD, XML_TYPE, xFormField->getFieldType());
+- }
+- GetExport().StartElement(XML_NAMESPACE_FIELD, XML_FIELDMARK, sal_False);
+- if (xFormField.is())
++ if ( GetExport().getDefaultVersion() == SvtSaveOptions::ODFVER_LATEST )
+ {
+- FieldParamExporter(&GetExport(), xFormField->getParameters()).Export();
++ Reference<XNamed> xBookmark(xPropSet->getPropertyValue(sBookmark), UNO_QUERY);
++ if (xBookmark.is())
++ {
++ GetExport().AddAttribute(XML_NAMESPACE_TEXT, XML_NAME, xBookmark->getName());
++ }
++ Reference< ::com::sun::star::text::XFormField > xFormField(xPropSet->getPropertyValue(sBookmark), UNO_QUERY);
++ if (xFormField.is())
++ {
++ GetExport().AddAttribute(XML_NAMESPACE_FIELD, XML_TYPE, xFormField->getFieldType());
++ }
++ GetExport().StartElement(XML_NAMESPACE_FIELD, XML_FIELDMARK, sal_False);
++ if (xFormField.is())
++ {
++ FieldParamExporter(&GetExport(), xFormField->getParameters()).Export();
++ }
++ GetExport().EndElement(XML_NAMESPACE_FIELD, XML_FIELDMARK, sal_False);
+ }
+- GetExport().EndElement(XML_NAMESPACE_FIELD, XML_FIELDMARK, sal_False);
+ }
+ else if (sType.equals(sSoftPageBreak))
+ {
More information about the ooo-build-commit
mailing list