[Libreoffice-commits] core.git: 4 commits - connectivity/source sw/source

Caolán McNamara caolanm at redhat.com
Fri Nov 1 12:24:18 CET 2013


 connectivity/source/drivers/mozab/MResultSet.cxx |    2 
 sw/source/filter/ww8/escher.hxx                  |    7 
 sw/source/filter/ww8/wrtw8esh.cxx                |  225 +++++++++++++++++
 sw/source/filter/ww8/wrtww8.cxx                  |   10 
 sw/source/filter/ww8/wrtww8.hxx                  |    2 
 sw/source/filter/ww8/ww8graf.cxx                 |   42 +++
 sw/source/filter/ww8/ww8par.cxx                  |  304 ++++++++++++++++++++++-
 sw/source/filter/ww8/ww8par.hxx                  |   48 +++
 8 files changed, 633 insertions(+), 7 deletions(-)

New commits:
commit 0b79f6ce62cf0d11e971b15e43b56e06a913389e
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Fri Nov 1 11:18:44 2013 +0000

    cannot convert parameter 1 from ´const char [2]´ to ´sal_Unicode
    
    Change-Id: I66a1005c3f6bcad448ed2c162a8399c7c32ad78e

diff --git a/connectivity/source/drivers/mozab/MResultSet.cxx b/connectivity/source/drivers/mozab/MResultSet.cxx
index 845ba0e..fbf0b853 100644
--- a/connectivity/source/drivers/mozab/MResultSet.cxx
+++ b/connectivity/source/drivers/mozab/MResultSet.cxx
@@ -908,7 +908,7 @@ void OResultSet::analyseWhereClause( const OSQLParseNode*                 parseT
             parseParameter( pAtom, matchString );
             // Replace all '*' with '%' : UI Usually does this but not with
             // Parameters for some reason.
-            matchString = matchString.replace( ALT_WILDCARD, WILDCARD );
+            matchString = matchString.replaceAll( ALT_WILDCARD, WILDCARD );
         }
         else
         {
commit d0b30f90d4be58ba78fded099f25a75d3cf88d56
Author: Jian Hong Cheng <chengjh at apache.org>
Date:   Mon Dec 3 14:09:34 2012 +0000

    Made some changes to remove the compile warnings...
    
    on the comparison between un-uniform data types
    
    (cherry picked from commit e0705e2a87726c6d8a04eae624d4f032c5d596ce)
    
    Conflicts:
    	sw/source/filter/ww8/wrtw8esh.cxx
    	sw/source/filter/ww8/wrtww8.cxx
    	sw/source/filter/ww8/ww8par.cxx
    	sw/source/filter/ww8/ww8par.hxx
    	sw/source/filter/ww8/ww8par3.cxx
    
    Change-Id: I1e6931e01fdcce6c1a4e98a86fcbc08f5e0933bd

diff --git a/sw/source/filter/ww8/wrtww8.cxx b/sw/source/filter/ww8/wrtww8.cxx
index 24ab7c4..627ed85 100644
--- a/sw/source/filter/ww8/wrtww8.cxx
+++ b/sw/source/filter/ww8/wrtww8.cxx
@@ -305,7 +305,7 @@ void WW8_WrtBookmarks::MoveFieldMarks(WW8_CP nFrom, WW8_CP nTo)
     {
         if (aItr->second)
         {
-            if (aItr->second->first == nFrom)
+            if (aItr->second->first == (long)nFrom)
             {
                 aItr->second->second.first = true;
                 aItr->second->first = nTo;
@@ -1407,8 +1407,8 @@ int MSWordExportBase::CollectGrfsOfBullets()
 
     if ( pDoc )
     {
-        int nCountRule = pDoc->GetNumRuleTbl().size();
-        for (int n = 0; n < nCountRule; ++n)
+        size_t nCountRule = pDoc->GetNumRuleTbl().size();
+        for (size_t n = 0; n < nCountRule; ++n)
         {
             const SwNumRule &rRule = *( pDoc->GetNumRuleTbl().at(n) );
             sal_uInt16 nLevels = rRule.IsContinusNum() ? 1 : 9;
@@ -1423,7 +1423,7 @@ int MSWordExportBase::CollectGrfsOfBullets()
                 if ( pGraf )
                 {
                     bool bHas = false;
-                    for (unsigned i = 0; i < m_vecBulletPic.size(); ++i)
+                    for (size_t i = 0; i < m_vecBulletPic.size(); ++i)
                     {
                         if (m_vecBulletPic[i]->GetChecksum() == pGraf->GetChecksum())
                         {
@@ -1522,7 +1522,7 @@ int MSWordExportBase::GetGrfIndex(const SvxBrushItem& rBrush)
     int nIndex = -1;
     if ( rBrush.GetGraphic() )
     {
-        for (unsigned i = 0; i < m_vecBulletPic.size(); ++i)
+        for (size_t i = 0; i < m_vecBulletPic.size(); ++i)
         {
             if (m_vecBulletPic[i]->GetChecksum() == rBrush.GetGraphic()->GetChecksum())
             {
diff --git a/sw/source/filter/ww8/ww8graf.cxx b/sw/source/filter/ww8/ww8graf.cxx
index c74f8bd..6ff803e 100644
--- a/sw/source/filter/ww8/ww8graf.cxx
+++ b/sw/source/filter/ww8/ww8graf.cxx
@@ -2589,12 +2589,17 @@ SwFrmFmt* SwWW8ImplReader::Read_GrafLayer( long nGrafAnchorCp )
                         && pData->GetId() == SW_UD_IMAPDATA)
                 {
                     SwMacroInfo* macInf = dynamic_cast<SwMacroInfo*>(pData);
-                    if( macInf && macInf->GetShapeId() == pF->nSpId)
+
+                    if( macInf )// && macInf->GetShapeId() == pF->nSpId)
                     {
-                        lnName = macInf->GetHlink();
-                        aObjName = macInf->GetName();
-                        aTarFrm = macInf->GetTarFrm();
-                        break;
+                        sal_Int32 nShapeId = macInf->GetShapeId();
+                        if ( nShapeId ==  pF->nSpId )
+                        {
+                            lnName = macInf->GetHlink();
+                            aObjName = macInf->GetName();
+                            aTarFrm = macInf->GetTarFrm();
+                            break;
+                        }
                     }
                 }
             }
diff --git a/sw/source/filter/ww8/ww8par.cxx b/sw/source/filter/ww8/ww8par.cxx
index 0382873..cc4336f 100644
--- a/sw/source/filter/ww8/ww8par.cxx
+++ b/sw/source/filter/ww8/ww8par.cxx
@@ -5194,7 +5194,7 @@ sal_uLong SwWW8ImplReader::CoreLoad(WW8Glossary *pGloss, const SwPosition &rPos)
                     for (size_t i = 0; i < nCount; ++i)
                     {
                         SwNumRule* pRule = pLstManager->GetNumRule(i);
-                        for (int j = 0; j < MAXLEVEL; ++j)
+                        for (sal_uInt16 j = 0; j < MAXLEVEL; ++j)
                         {
                             SwNumFmt aNumFmt(pRule->Get(j));
                             const sal_Int16 nType = aNumFmt.GetNumberingType();
commit 40543e5321c8f618c125fd6f7f9a24b87431277a
Author: Jian Hong Cheng <chengjh at apache.org>
Date:   Mon Dec 3 06:47:16 2012 +0000

    Revise un-necessary checking..
    
    Patch by: chengjh,<chengjh at apache.org>
    (cherry picked from commit 3869d0164607a1576826dcc338b1f8b52f1147bd)

diff --git a/sw/source/filter/ww8/ww8graf.cxx b/sw/source/filter/ww8/ww8graf.cxx
index 911149e..c74f8bd 100644
--- a/sw/source/filter/ww8/ww8graf.cxx
+++ b/sw/source/filter/ww8/ww8graf.cxx
@@ -2578,7 +2578,7 @@ SwFrmFmt* SwWW8ImplReader::Read_GrafLayer( long nGrafAnchorCp )
 
     if(pObject)
     {
-        sal_uInt16 nCount = pObject ? pObject->GetUserDataCount() : 0;
+        sal_uInt16 nCount = pObject->GetUserDataCount();
         if(nCount)
         {
             OUString lnName, aObjName, aTarFrm;
@@ -2589,7 +2589,7 @@ SwFrmFmt* SwWW8ImplReader::Read_GrafLayer( long nGrafAnchorCp )
                         && pData->GetId() == SW_UD_IMAPDATA)
                 {
                     SwMacroInfo* macInf = dynamic_cast<SwMacroInfo*>(pData);
-                    if( macInf->GetShapeId() == pF->nSpId)
+                    if( macInf && macInf->GetShapeId() == pF->nSpId)
                     {
                         lnName = macInf->GetHlink();
                         aObjName = macInf->GetName();
commit c1c49d8fdf78ed820ab3b9e4b82ea383ecce39e1
Author: Jian Hong Cheng <chengjh at apache.org>
Date:   Fri Nov 30 01:09:14 2012 +0000

    Resolves: #i120927: Import/Export Hyperlink Info of Graphic with Anchor...
    
    Type Except “As Character” to MS Word Binary File
    
    * sw/source/filter/ww8/escher.hxx
    * sw/source/filter/ww8/wrtw8esh.cxx
    * sw/source/filter/ww8/wrtww8.hxx
    * sw/source/filter/ww8/ww8graf.cxx
    * sw/source/filter/ww8/ww8par.cxx
    * sw/source/filter/ww8/ww8par.hxx
    
    Interoperability of Hyperlink within Flying object
    
    Patch by: Jane Kang,<kangjane2012 at gmail.com>
    Found by: Yan Ji,<yanji.yj at gmail.com>
    Review by: Jian Hong Cheng,<chengjh at apache.org>
    (cherry picked from commit 8f7c7a5713e92aecfe4837e628a001b7668c9540)
    
    Conflicts:
    	sw/source/filter/ww8/wrtw8esh.cxx
    	sw/source/filter/ww8/wrtww8.hxx
    	sw/source/filter/ww8/ww8graf.cxx
    	sw/source/filter/ww8/ww8par.cxx
    
    Fix non-pro build breaker: SvMemoryStream has no member GetRecLeft()
    
    Possible introduced from copy and paste from sc, see
    sal_Size XclImpStream::GetRecLeft() function in class:XclImpStream
    sc/source/filter/inc/xistream.hxx
    (cherry picked from commit 4a3a3afa32785d0b1051d9d1104adbbb0e61a820)
    
    Conflicts:
    	sw/source/filter/ww8/ww8par.cxx
    
    9ce792333ba3f6aa0f8d8660533bc740e1354597
    
    Change-Id: Icbecea61bf6ec3e7baa02e678a575d64fcfca731

diff --git a/sw/source/filter/ww8/escher.hxx b/sw/source/filter/ww8/escher.hxx
index 4adf3d8..4a1127a 100644
--- a/sw/source/filter/ww8/escher.hxx
+++ b/sw/source/filter/ww8/escher.hxx
@@ -123,6 +123,13 @@ public:
     virtual void WriteFrmExtraData(const SwFrmFmt&);
     virtual void WritePictures();
     virtual ~SwBasicEscherEx();
+    //i120927,this function is added to export hyperlink info,such as graphic/frame/OLE
+    bool IsRelUrl();
+    OUString GetBasePath();
+    OUString BuildFileName(sal_uInt16& rnLevel, bool& rbRel, const OUString& rUrl);
+    void WriteHyperlinkWithinFly( SvMemoryStream& rStrm, const SwFmtURL* pINetFmtArg);
+    void PreWriteHyperlinkWithinFly(const SwFrmFmt& rFmt,EscherPropertyContainer& rPropOpt);
+
 private:
     //No copying
     SwBasicEscherEx(const SwBasicEscherEx&);
diff --git a/sw/source/filter/ww8/wrtw8esh.cxx b/sw/source/filter/ww8/wrtw8esh.cxx
index 2803d16..695523f 100644
--- a/sw/source/filter/ww8/wrtw8esh.cxx
+++ b/sw/source/filter/ww8/wrtw8esh.cxx
@@ -92,12 +92,233 @@
 #include <oox/ole/olehelper.hxx>
 #include <fstream>
 #include <unotools/streamwrap.hxx>
+#include <editeng/shaditem.hxx>
+#include <svx/unoapi.hxx>
+#include <escher.hxx>
+#include <fmtinfmt.hxx>
+#include <fmturl.hxx>
+#include "sfx2/sfxsids.hrc"
+#include <svl/urihelper.hxx>
+#include <unotools/saveopt.hxx>
 
 using ::editeng::SvxBorderLine;
 using namespace com::sun::star;
 using namespace sw::util;
 using namespace sw::types;
 using namespace nsFieldFlags;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::beans::XPropertySet;
+using ::com::sun::star::drawing::XShape;
+
+bool SwBasicEscherEx::IsRelUrl()
+{
+    SvtSaveOptions aSaveOpt;
+    bool bRelUrl = false;
+    SfxMedium * pMedium = rWrt.GetWriter().GetMedia();
+    if ( pMedium )
+        bRelUrl = pMedium->IsRemote() ? aSaveOpt.IsSaveRelINet() : aSaveOpt.IsSaveRelFSys();
+    return bRelUrl;
+}
+
+OUString SwBasicEscherEx::GetBasePath()
+{
+    OUString sDocUrl;
+    SfxMedium * pMedium = rWrt.GetWriter().GetMedia();
+    if (pMedium)
+    {
+        const SfxItemSet* pPItemSet = pMedium->GetItemSet();
+        if( pPItemSet )
+        {
+            const SfxStringItem* pPItem = dynamic_cast< const SfxStringItem* >( pPItemSet->GetItem( SID_FILE_NAME ) );
+            if ( pPItem )
+                sDocUrl = pPItem->GetValue();
+        }
+    }
+
+    return sDocUrl.copy(0, sDocUrl.lastIndexOf('/') + 1);
+}
+
+OUString SwBasicEscherEx::BuildFileName(sal_uInt16& rnLevel, bool& rbRel, const OUString& rUrl)
+{
+    OUString aDosName( INetURLObject( rUrl ).getFSysPath( INetURLObject::FSYS_DOS ) );
+    rnLevel = 0;
+    rbRel = IsRelUrl();
+
+    if (rbRel)
+    {
+        // try to convert to relative file name
+        OUString aTmpName( aDosName );
+        aDosName = INetURLObject::GetRelURL( GetBasePath(), rUrl,
+        INetURLObject::WAS_ENCODED, INetURLObject::DECODE_WITH_CHARSET );
+
+        if (aDosName.startsWith(INET_FILE_SCHEME))
+        {
+            // not converted to rel -> back to old, return absolute flag
+            aDosName = aTmpName;
+            rbRel = false;
+        }
+        else if (aDosName.startsWith("./"))
+        {
+            aDosName = aDosName.copy(2);
+        }
+        else
+        {
+            while (aDosName.startsWith("../"))
+            {
+                ++rnLevel;
+                aDosName = aDosName.copy(3);
+            }
+        }
+    }
+    return aDosName;
+}
+
+void SwBasicEscherEx::WriteHyperlinkWithinFly( SvMemoryStream& rStrm, const SwFmtURL* pINetFmtArg)
+{
+    if ( !pINetFmtArg ) return;
+
+    sal_uInt8 maGuidStdLink[ 16 ] ={
+        0xD0, 0xC9, 0xEA, 0x79, 0xF9, 0xBA, 0xCE, 0x11, 0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B };
+    sal_uInt8 maGuidUrlMoniker[ 16 ] = {
+        0xE0, 0xC9, 0xEA, 0x79, 0xF9, 0xBA, 0xCE, 0x11, 0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B };
+
+    sal_uInt8 maGuidFileMoniker[ 16 ] = {
+        0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 };
+    sal_uInt8 maGuidFileTail[] = {
+            0xFF, 0xFF, 0xAD, 0xDE, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+        };
+    //const sal_uInt18 WW8_ID_HLINK               = 0x01B8;
+    const sal_uInt32 WW8_HLINK_BODY             = 0x00000001;   /// Contains file link or URL.
+    const sal_uInt32 WW8_HLINK_ABS              = 0x00000002;   /// Absolute path.
+    //const sal_uInt32 WW8_HLINK_DESCR            = 0x00000014;   /// Description.
+    const sal_uInt32 WW8_HLINK_MARK             = 0x00000008;   /// Text mark.
+    const sal_uInt32 WW8_HLINK_FRAME            = 0x00000080;   /// Target frame.
+    //const sal_uInt32 WW8_HLINK_UNC              = 0x00000100;   /// UNC path.
+    SvMemoryStream tmpStrm;
+    OUString tmpTextMark;
+
+    OUString rUrl = pINetFmtArg->GetURL();
+    OUString rTarFrm = pINetFmtArg->GetTargetFrameName();
+    sal_uInt32          mnFlags = 0;
+
+    INetURLObject aUrlObj( rUrl );
+    const INetProtocol eProtocol = aUrlObj.GetProtocol();
+
+    //Target Frame
+    if (!rTarFrm.isEmpty())
+    {
+        SwWW8Writer::WriteLong(tmpStrm, rTarFrm.getLength()+1);
+        SwWW8Writer::WriteString16(tmpStrm, rTarFrm, false);
+
+        tmpStrm << sal_uInt16( 0 );
+
+        mnFlags |= WW8_HLINK_FRAME;
+    }
+
+    // file link or URL
+    if (eProtocol == INET_PROT_FILE || (eProtocol == INET_PROT_NOT_VALID && rUrl[0] != '#'))
+    {
+        sal_uInt16 nLevel;
+        bool bRel;
+        OUString aFileName( BuildFileName( nLevel, bRel, rUrl ));
+
+        if( !bRel )
+            mnFlags |= WW8_HLINK_ABS;
+
+        mnFlags |= WW8_HLINK_BODY;
+
+        tmpStrm.Write( maGuidFileMoniker,sizeof(maGuidFileMoniker) );
+        tmpStrm << nLevel;
+        SwWW8Writer::WriteLong(tmpStrm, aFileName.getLength()+1);
+        SwWW8Writer::WriteString8( tmpStrm, aFileName, true, RTL_TEXTENCODING_MS_1252 );
+        tmpStrm.Write( maGuidFileTail,sizeof(maGuidFileTail) );
+
+        //For UNICODE
+        SwWW8Writer::WriteLong(tmpStrm, 2*aFileName.getLength()+6);
+        SwWW8Writer::WriteLong(tmpStrm, 2*aFileName.getLength());
+        tmpStrm << sal_uInt16(0x0003);
+        SwWW8Writer::WriteString16(tmpStrm, aFileName, false);
+    }
+    else if( eProtocol != INET_PROT_NOT_VALID )
+    {
+        tmpStrm.Write( maGuidUrlMoniker,sizeof(maGuidUrlMoniker) );
+            SwWW8Writer::WriteLong(tmpStrm, 2*(rUrl.getLength()+1));
+
+            SwWW8Writer::WriteString16(tmpStrm, rUrl, true);
+            mnFlags |= WW8_HLINK_BODY | WW8_HLINK_ABS;
+    }
+    else if (rUrl[0] == '#' )
+    {
+        OUString aTextMark(rUrl.copy( 1 ));
+        aTextMark = aTextMark.replaceFirst(".", "!");
+        tmpTextMark = aTextMark;
+    }
+
+    if (tmpTextMark.isEmpty() && aUrlObj.HasMark())
+    {
+        tmpTextMark = aUrlObj.GetMark();
+    }
+
+    if (!tmpTextMark.isEmpty())
+    {
+        SwWW8Writer::WriteLong(tmpStrm, tmpTextMark.getLength()+1);
+            SwWW8Writer::WriteString16(tmpStrm, tmpTextMark, true);
+
+        mnFlags |= WW8_HLINK_MARK;
+    }
+
+    rStrm.Write( maGuidStdLink,16 );
+    rStrm  << sal_uInt32( 2 )
+           << mnFlags;
+    tmpStrm.Seek( STREAM_SEEK_TO_BEGIN );
+    sal_uInt32 nStrmPos = tmpStrm.Tell();
+    tmpStrm.Seek( STREAM_SEEK_TO_END );
+    sal_uInt32 nStrmSize = tmpStrm.Tell();
+    tmpStrm.Seek( nStrmPos );
+    sal_uInt32 nLen;
+    nLen = nStrmSize - nStrmPos;
+    if(nLen >0)
+    {
+        sal_uInt8* pBuffer = new sal_uInt8[ nLen ];
+        tmpStrm.Read(pBuffer, nLen);
+        rStrm.Write( pBuffer, nLen );
+        delete[] pBuffer;
+    }
+}
+void SwBasicEscherEx::PreWriteHyperlinkWithinFly(const SwFrmFmt& rFmt,EscherPropertyContainer& rPropOpt)
+{
+    const SfxPoolItem* pItem;
+    const SwAttrSet& rAttrSet = rFmt.GetAttrSet();
+    if (SFX_ITEM_SET == rAttrSet.GetItemState(RES_URL, true, &pItem))
+    {
+        const SwFmtURL *pINetFmt = dynamic_cast<const SwFmtURL*>(pItem);
+        if (pINetFmt && !pINetFmt->GetURL().isEmpty())
+        {
+            SvMemoryStream *rStrm = new SvMemoryStream ;
+            OUString tmpstr = pINetFmt->GetURL();
+            WriteHyperlinkWithinFly( *rStrm, pINetFmt );
+            sal_uInt8* pBuf = (sal_uInt8*) rStrm->GetData();
+            sal_uInt32 nSize = rStrm->Seek( STREAM_SEEK_TO_END );
+            rPropOpt.AddOpt( ESCHER_Prop_pihlShape, sal_True, nSize, pBuf, nSize );
+            sal_uInt32 nValue;
+            OUString aNamestr = pINetFmt->GetName();
+            if (!aNamestr.isEmpty())
+            {
+                rPropOpt.AddOpt(ESCHER_Prop_wzName, aNamestr );
+            }
+            if(rPropOpt.GetOpt( ESCHER_Prop_fPrint, nValue))
+            {
+                nValue|=0x03080008;
+                rPropOpt.AddOpt(ESCHER_Prop_fPrint, nValue );
+            }
+            else
+                rPropOpt.AddOpt(ESCHER_Prop_fPrint, 0x03080008 );
+        }
+    }
+}
 
 namespace
 {
@@ -1883,6 +2104,8 @@ sal_Int32 SwBasicEscherEx::WriteFlyFrameAttr(const SwFrmFmt& rFmt,
         rPropOpt.AddOpt( ESCHER_Prop_fPrint, 0x200020 );
     }
 
+    PreWriteHyperlinkWithinFly(rFmt,rPropOpt);
+
     return nLineWidth;
 }
 
@@ -1976,6 +2199,8 @@ sal_Int32 SwEscherEx::WriteFlyFrameAttr(const SwFrmFmt& rFmt, MSO_SPT eShapeType
         }
     }
 
+    PreWriteHyperlinkWithinFly(rFmt,rPropOpt);
+
     return nLineWidth;
 }
 
diff --git a/sw/source/filter/ww8/wrtww8.hxx b/sw/source/filter/ww8/wrtww8.hxx
index 4185437..2993fff 100644
--- a/sw/source/filter/ww8/wrtww8.hxx
+++ b/sw/source/filter/ww8/wrtww8.hxx
@@ -896,6 +896,8 @@ public:
 
     using StgWriter::Write;
     virtual sal_uLong Write( SwPaM&, SfxMedium&, const OUString* = 0 );
+    //Seems not an expected to provide method to access the private member
+    SfxMedium* GetMedia() { return mpMedium; }
 
 private:
     /// No copying.
diff --git a/sw/source/filter/ww8/ww8graf.cxx b/sw/source/filter/ww8/ww8graf.cxx
index d7ed633..911149e 100644
--- a/sw/source/filter/ww8/ww8graf.cxx
+++ b/sw/source/filter/ww8/ww8graf.cxx
@@ -89,6 +89,10 @@
 #include <editeng/editobj.hxx>
 #include <boost/scoped_ptr.hpp>
 #include <math.h>
+#include <fmturl.hxx>
+#include <svx/hlnkitem.hxx>
+#include <svl/whiter.hxx>
+#include "ww8par2.hxx"
 
 using ::editeng::SvxBorderLine;
 using namespace ::com::sun::star;
@@ -2572,6 +2576,39 @@ SwFrmFmt* SwWW8ImplReader::Read_GrafLayer( long nGrafAnchorCp )
     if (pRecord->bHidden)
         return 0;
 
+    if(pObject)
+    {
+        sal_uInt16 nCount = pObject ? pObject->GetUserDataCount() : 0;
+        if(nCount)
+        {
+            OUString lnName, aObjName, aTarFrm;
+            for (sal_uInt16 i = 0; i < nCount; i++ )
+            {
+                SdrObjUserData* pData = pObject->GetUserData( i );
+                if( pData && pData->GetInventor() == SW_DRAWLAYER
+                        && pData->GetId() == SW_UD_IMAPDATA)
+                {
+                    SwMacroInfo* macInf = dynamic_cast<SwMacroInfo*>(pData);
+                    if( macInf->GetShapeId() == pF->nSpId)
+                    {
+                        lnName = macInf->GetHlink();
+                        aObjName = macInf->GetName();
+                        aTarFrm = macInf->GetTarFrm();
+                        break;
+                    }
+                }
+            }
+            SwFmtURL* pFmtURL = new SwFmtURL();
+            pFmtURL->SetURL( lnName, false );
+            if (!aObjName.isEmpty())
+                pFmtURL->SetName(aObjName);
+            if (!aTarFrm.isEmpty())
+                pFmtURL->SetTargetFrameName(aTarFrm);
+            pFmtURL->SetMap(0);
+            aFlySet.Put(*pFmtURL);
+        }
+    }
+
     // If we are to be "below text" then we are not to be opaque
     // #i14045# MM If we are in a header or footer then make the object transparent
     // Not exactly like word but close enough for now
diff --git a/sw/source/filter/ww8/ww8par.cxx b/sw/source/filter/ww8/ww8par.cxx
index 577c6d5..0382873 100644
--- a/sw/source/filter/ww8/ww8par.cxx
+++ b/sw/source/filter/ww8/ww8par.cxx
@@ -113,6 +113,7 @@
 #endif
 #include <unotools/localfilehelper.hxx>
 
+#include <svx/hlnkitem.hxx>
 #include "WW8Sttbf.hxx"
 #include "WW8FibData.hxx"
 
@@ -132,6 +133,247 @@ using namespace nsHdFtFlags;
 
 using ::comphelper::MediaDescriptor;
 
+//#define VT_EMPTY            0
+//#define VT_I4               3
+//#define VT_LPSTR            30
+//#define VT_LPWSTR           31
+//#define VT_BLOB             65
+//#define VT_TYPEMASK         0xFFF
+/** Expands to a pointer behind the last element of a STATIC data array (like STL end()). */
+//#define STATIC_TABLE_END( array )   ((array)+STATIC_TABLE_SIZE(array))
+/** Expands to the size of a STATIC data array. */
+//#define STATIC_TABLE_SIZE( array )  (sizeof(array)/sizeof(*(array)))
+
+SwMacroInfo* GetMacroInfo( SdrObject* pObj, sal_Bool bCreate )             // static
+{
+    if ( pObj )
+    {
+        sal_uInt16 nCount = pObj->GetUserDataCount();
+        for( sal_uInt16 i = 0; i < nCount; i++ )
+        {
+            SdrObjUserData* pData = pObj->GetUserData( i );
+            if( pData && pData->GetInventor() == SW_DRAWLAYER
+                && pData->GetId() == SW_UD_IMAPDATA)
+            {
+                return dynamic_cast<SwMacroInfo*>(pData);
+            }
+        }
+        if ( bCreate )
+        {
+            SwMacroInfo* pData = new SwMacroInfo;
+            pObj->AppendUserData(pData);
+            return pData;
+        }
+    }
+
+    return 0;
+};
+
+void lclGetAbsPath(OUString& rPath, sal_uInt16 nLevel, SwDocShell* pDocShell)
+{
+    OUString aTmpStr;
+    while( nLevel )
+    {
+        aTmpStr += "../";
+        --nLevel;
+    }
+    if (!aTmpStr.isEmpty())
+        aTmpStr += rPath;
+    else
+        aTmpStr = rPath;
+
+    if (!aTmpStr.isEmpty())
+    {
+        bool bWasAbs = false;
+        rPath = pDocShell->GetMedium()->GetURLObject().smartRel2Abs( aTmpStr, bWasAbs ).GetMainURL( INetURLObject::NO_DECODE );
+        // full path as stored in SvxURLField must be encoded
+    }
+}
+
+void lclIgnoreString32( SvMemoryStream& rStrm, bool b16Bit )
+{
+    sal_uInt32 nChars(0);
+    rStrm >> nChars;
+    if( b16Bit )
+        nChars *= 2;
+    rStrm.SeekRel( nChars );
+}
+
+OUString SwWW8ImplReader::ReadRawUniString(SvMemoryStream& rStrm, sal_uInt16 nChars, bool b16Bit)
+{
+    // Fixed-size characters
+    const sal_uInt8 WW8_NUL_C                   = '\x00';       /// NUL chararcter.
+    const sal_uInt16 WW8_NUL                    = WW8_NUL_C;    /// NUL chararcter (unicode).
+    sal_Unicode         mcNulSubst = '\0';
+
+    sal_uInt16 nCharsLeft = nChars;
+    sal_Unicode* pcBuffer = new sal_Unicode[ nCharsLeft + 1 ];
+
+    sal_Unicode* pcUniChar = pcBuffer;
+    sal_Unicode* pcEndChar = pcBuffer + nCharsLeft;
+
+    if( b16Bit )
+    {
+        sal_uInt16 nReadChar;
+        for( ;  (pcUniChar < pcEndChar); ++pcUniChar )
+        {
+            rStrm >> (nReadChar);
+            (*pcUniChar) = (nReadChar == WW8_NUL) ? mcNulSubst : static_cast< sal_Unicode >( nReadChar );
+        }
+    }
+    else
+    {
+        sal_uInt8 nReadChar;
+        for( ; (pcUniChar < pcEndChar); ++pcUniChar )
+        {
+            rStrm >> nReadChar ;
+            (*pcUniChar) = (nReadChar == WW8_NUL_C) ? mcNulSubst : static_cast< sal_Unicode >( nReadChar );
+        }
+    }
+
+    *pcEndChar = '\0';
+    OUString aRet(pcBuffer);
+    delete[] pcBuffer;
+    return aRet;
+}
+
+void lclAppendString32(OUString& rString, SvMemoryStream& rStrm, sal_uInt32 nChars, bool b16Bit)
+{
+    sal_uInt16 nReadChars = ulimit_cast< sal_uInt16 >( nChars );
+    OUString urlStr = SwWW8ImplReader::ReadRawUniString( rStrm, nReadChars, b16Bit );
+    rString += urlStr;
+}
+
+void lclAppendString32(OUString& rString, SvMemoryStream& rStrm, bool b16Bit)
+{
+    sal_uInt32 nValue(0);
+    rStrm >> nValue;
+    lclAppendString32(rString, rStrm, nValue, b16Bit);
+}
+
+void SwWW8ImplReader::ReadEmbeddedData( SvMemoryStream& rStrm, SwDocShell* pDocShell, struct HyperLinksTable& hlStr)
+{
+    // (0x01B8) HLINK -------------------------------------------------------------
+    //const sal_uInt16 WW8_ID_HLINK               = 0x01B8;
+    const sal_uInt32 WW8_HLINK_BODY             = 0x00000001;   /// Contains file link or URL.
+    const sal_uInt32 WW8_HLINK_ABS              = 0x00000002;   /// Absolute path.
+    const sal_uInt32 WW8_HLINK_DESCR            = 0x00000014;   /// Description.
+    const sal_uInt32 WW8_HLINK_MARK             = 0x00000008;   /// Text mark.
+    const sal_uInt32 WW8_HLINK_FRAME            = 0x00000080;   /// Target frame.
+    const sal_uInt32 WW8_HLINK_UNC              = 0x00000100;   /// UNC path.
+
+    //sal_uInt8 maGuidStdLink[ 16 ] ={
+    //    0xD0, 0xC9, 0xEA, 0x79, 0xF9, 0xBA, 0xCE, 0x11, 0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B };
+
+    sal_uInt8 maGuidUrlMoniker[ 16 ] = {
+        0xE0, 0xC9, 0xEA, 0x79, 0xF9, 0xBA, 0xCE, 0x11, 0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B };
+
+    sal_uInt8 maGuidFileMoniker[ 16 ] = {
+        0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 };
+
+    sal_uInt8 aGuid[16];
+    sal_uInt32 nFlags(0);
+
+
+    rStrm.Read(aGuid, 16);
+    rStrm.SeekRel( 4 );
+    rStrm >> nFlags;
+
+    sal_uInt16 nLevel = 0;                  // counter for level to climb down in path
+    boost::scoped_ptr< OUString > xLongName;    // link / file name
+    boost::scoped_ptr< OUString > xShortName;   // 8.3-representation of file name
+    boost::scoped_ptr< OUString > xTextMark;    // text mark
+
+    // description (ignore)
+    if( ::get_flag( nFlags, WW8_HLINK_DESCR ) )
+        lclIgnoreString32( rStrm, true );
+
+    // target frame
+    if( ::get_flag( nFlags, WW8_HLINK_FRAME ) )
+    {
+        OUString sFrmName;
+        lclAppendString32(sFrmName, rStrm, true);
+        hlStr.tarFrm = sFrmName;
+    }
+
+        // UNC path
+    if( ::get_flag( nFlags, WW8_HLINK_UNC ) )
+    {
+        xLongName.reset( new OUString );
+        lclAppendString32( *xLongName, rStrm, true );
+        lclGetAbsPath( *xLongName, 0 , pDocShell);
+    }
+    // file link or URL
+    else if( ::get_flag( nFlags, WW8_HLINK_BODY ) )
+    {
+        rStrm.Read( aGuid, 16);
+
+        if( (memcmp(aGuid, maGuidFileMoniker, 16) == 0) )
+        {
+            rStrm >> nLevel;
+            xShortName.reset( new OUString );
+            lclAppendString32( *xShortName,rStrm, false );
+            rStrm.SeekRel( 24 );
+
+            sal_uInt32 nStrLen(0);
+            rStrm >> nStrLen;
+            if( nStrLen )
+            {
+                nStrLen = 0;
+                rStrm >> nStrLen;
+                nStrLen /= 2;
+                rStrm.SeekRel( 2 );
+                xLongName.reset( new OUString );
+                lclAppendString32( *xLongName, rStrm,nStrLen, true );
+                lclGetAbsPath( *xLongName, nLevel, pDocShell);
+            }
+            else
+                lclGetAbsPath( *xShortName, nLevel, pDocShell);
+        }
+        else if( (memcmp(aGuid, maGuidUrlMoniker, 16) == 0) )
+        {
+            sal_uInt32 nStrLen(0);
+            rStrm >> nStrLen;
+            nStrLen /= 2;
+            xLongName.reset( new OUString );
+            lclAppendString32( *xLongName,rStrm, nStrLen, true );
+            if( !::get_flag( nFlags, WW8_HLINK_ABS ) )
+                lclGetAbsPath( *xLongName, 0 ,pDocShell);
+        }
+        else
+        {
+            DBG_ERRORFILE( "WW8Hyperlink::ReadEmbeddedData - unknown content GUID" );
+        }
+    }
+
+    // text mark
+    if( ::get_flag( nFlags, WW8_HLINK_MARK ) )
+    {
+        xTextMark.reset( new OUString );
+        lclAppendString32( *xTextMark, rStrm, true );
+    }
+
+    if( !xLongName.get() && xShortName.get() )
+    {
+        xLongName.reset( new OUString );
+        *xLongName = xLongName->concat(*xShortName);
+    }
+    else if( !xLongName.get() && xTextMark.get() )
+        xLongName.reset( new OUString );
+
+    if( xLongName.get() )
+    {
+        if( xTextMark.get() )
+        {
+            if (xLongName->isEmpty())
+                *xTextMark = xTextMark->replace('!', '.');
+            *xLongName = xLongName->concat("#");
+            *xLongName = xLongName->concat(*xTextMark);
+        }
+        hlStr.hLinkAddr = *xLongName;
+    }
+}
+
 class BasicProjImportHelper
 {
     SwDocShell& mrDocShell;
@@ -256,6 +498,7 @@ Sttb::getStringAtIndex( sal_uInt32 index )
     if ( index < dataItems.size() )
         aRet = dataItems[ index ].data;
     return aRet;
+
 }
 
 SwMSDffManager::SwMSDffManager( SwWW8ImplReader& rRdr )
@@ -869,6 +1112,51 @@ SdrObject* SwMSDffManager::ProcessObj(SvStream& rSt,
             delete pImpRec;
     }
 
+    sal_uInt32 nBufferSize = GetPropertyValue( DFF_Prop_pihlShape );
+     if( (0 < nBufferSize) && (nBufferSize <= 0xFFFF) && SeekToContent( DFF_Prop_pihlShape, rSt ) )
+    {
+        SvMemoryStream aMemStream;
+        OUString aStrURL;
+        struct HyperLinksTable hlStr;
+        sal_uInt16 mnRawRecId,mnRawRecSize;
+        aMemStream << sal_uInt16( 0 ) << static_cast< sal_uInt16 >( nBufferSize );
+
+        // copy from DFF stream to memory stream
+        ::std::vector< sal_uInt8 > aBuffer( nBufferSize );
+        sal_uInt8* pnData = &aBuffer.front();
+        sal_uInt8 mnStreamSize;
+        if( pnData && rSt.Read( pnData, nBufferSize ) == nBufferSize )
+        {
+            aMemStream.Write( pnData, nBufferSize );
+            aMemStream.Seek( STREAM_SEEK_TO_END );
+            mnStreamSize = aMemStream.Tell();
+            aMemStream.Seek( STREAM_SEEK_TO_BEGIN );
+            bool bRet =  4 <= mnStreamSize;
+            if( bRet )
+                aMemStream >> mnRawRecId >> mnRawRecSize;
+            SwDocShell* pDocShell = rReader.mpDocShell;
+            if(pDocShell)
+            {
+                rReader.ReadEmbeddedData( aMemStream, pDocShell, hlStr);
+            }
+        }
+
+        if (pObj && !hlStr.hLinkAddr.isEmpty())
+        {
+            SwMacroInfo* pInfo = GetMacroInfo( pObj, true );
+            if( pInfo )
+            {
+                pInfo->SetShapeId( rObjData.nShapeId );
+                pInfo->SetHlink( hlStr.hLinkAddr );
+                if (!hlStr.tarFrm.isEmpty())
+                    pInfo->SetTarFrm( hlStr.tarFrm );
+                OUString aNameStr = GetPropertyString( DFF_Prop_wzName, rSt );
+                if (!aNameStr.isEmpty())
+                    pInfo->SetName( aNameStr );
+            }
+        }
+    }
+
     return pObj;
 }
 
@@ -5989,4 +6277,18 @@ namespace sw
     }
 }
 
+SwMacroInfo::SwMacroInfo() :
+    SdrObjUserData( SW_DRAWLAYER, SW_UD_IMAPDATA, 0 )
+{
+}
+
+SwMacroInfo::~SwMacroInfo()
+{
+}
+
+SdrObjUserData* SwMacroInfo::Clone( SdrObject* /*pObj*/ ) const
+{
+   return new SwMacroInfo( *this );
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/filter/ww8/ww8par.hxx b/sw/source/filter/ww8/ww8par.hxx
index 3580f28..ead9ef3 100644
--- a/sw/source/filter/ww8/ww8par.hxx
+++ b/sw/source/filter/ww8/ww8par.hxx
@@ -26,6 +26,10 @@
 #include <editeng/frmdir.hxx>
 #include <fltshell.hxx>
 
+#include <svx/svdobj.hxx>
+#define SW_DRAWLAYER 0x30334353
+#define SW_UD_IMAPDATA      2
+
 #include <vector>
 #include <stack>
 #include <deque>
@@ -458,6 +462,48 @@ private:
     SwWW8FltRefStack& operator=(const SwWW8FltRefStack&);
 };
 
+template< typename Type >
+inline bool get_flag( Type nBitField, Type nMask )
+{ return (nBitField & nMask) != 0; }
+
+template< typename ReturnType, typename Type >
+inline ReturnType ulimit_cast( Type nValue, ReturnType nMax )
+{ return static_cast< ReturnType >( ::std::min< Type >( nValue, nMax ) ); }
+
+
+template< typename ReturnType, typename Type >
+inline ReturnType ulimit_cast( Type nValue )
+{ return ulimit_cast( nValue, ::std::numeric_limits< ReturnType >::max() ); }
+
+class SwMacroInfo : public SdrObjUserData
+{
+public:
+    SwMacroInfo();
+    virtual ~SwMacroInfo();
+
+    virtual SdrObjUserData* Clone( SdrObject* pObj ) const;
+
+    void SetHlink( const OUString& rHlink ) { maHlink = rHlink; }
+    const OUString& GetHlink() const { return maHlink; }
+    void SetTarFrm( const OUString& rTarFrm ) { maTarFrm = rTarFrm; }
+    const OUString& GetTarFrm() const { return maTarFrm; }
+    void SetShapeId( const sal_Int32& rShapeId ) { mnShapeId = rShapeId; }
+    const sal_Int32& GetShapeId() const { return mnShapeId; }
+    void SetName( const OUString& rName ) { maNameStr = rName; }
+    const OUString& GetName() const { return maNameStr; }
+
+private:
+    sal_Int32 mnShapeId;
+    OUString maHlink;
+    OUString maNameStr;
+    OUString maTarFrm;
+};
+
+struct HyperLinksTable
+{
+    OUString hLinkAddr;
+    OUString tarFrm;
+};
 
 namespace sw
 {
@@ -1844,6 +1890,8 @@ public:     // eigentlich private, geht aber leider nur public
     rtl_TextEncoding GetCurrentCJKCharSet();
 
     void PostProcessAttrs();
+    static void ReadEmbeddedData(SvMemoryStream& rStrm, SwDocShell* pDocShell, struct HyperLinksTable& hlStr);
+    static OUString ReadRawUniString(SvMemoryStream& rStrm, sal_uInt16 nChars, bool b16Bit);
 };
 
 bool CanUseRemoteLink(const OUString &rGrfName);


More information about the Libreoffice-commits mailing list