[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