Author: chengjh
Date: Fri Nov 30 02:09:14 2012
New Revision: 1415477

URL: http://svn.apache.org/viewvc?rev=1415477&view=rev
Log:
Fix issue #120927: 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,<[email protected]>
Found by: Yan Ji,<[email protected]>
Review by: Jian Hong Cheng,<[email protected]>           

Modified:
    openoffice/trunk/main/sw/source/filter/ww8/escher.hxx
    openoffice/trunk/main/sw/source/filter/ww8/wrtw8esh.cxx
    openoffice/trunk/main/sw/source/filter/ww8/wrtww8.hxx
    openoffice/trunk/main/sw/source/filter/ww8/ww8graf.cxx
    openoffice/trunk/main/sw/source/filter/ww8/ww8par.cxx
    openoffice/trunk/main/sw/source/filter/ww8/ww8par.hxx

Modified: openoffice/trunk/main/sw/source/filter/ww8/escher.hxx
URL: 
http://svn.apache.org/viewvc/openoffice/trunk/main/sw/source/filter/ww8/escher.hxx?rev=1415477&r1=1415476&r2=1415477&view=diff
==============================================================================
--- openoffice/trunk/main/sw/source/filter/ww8/escher.hxx (original)
+++ openoffice/trunk/main/sw/source/filter/ww8/escher.hxx Fri Nov 30 02:09:14 
2012
@@ -134,6 +134,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();
+    String GetBasePath();
+    String BuildFileName(sal_uInt16& rnLevel, bool& rbRel, const String& rUrl 
);
+    void WriteHyperlinkWithinFly( SvMemoryStream& rStrm, const SwFmtURL* 
pINetFmtArg);
+    void PreWriteHyperlinkWithinFly(const SwFrmFmt& 
rFmt,EscherPropertyContainer& rPropOpt);
+
 private:
     //No copying
     SwBasicEscherEx(const SwBasicEscherEx&);

Modified: openoffice/trunk/main/sw/source/filter/ww8/wrtw8esh.cxx
URL: 
http://svn.apache.org/viewvc/openoffice/trunk/main/sw/source/filter/ww8/wrtw8esh.cxx?rev=1415477&r1=1415476&r2=1415477&view=diff
==============================================================================
--- openoffice/trunk/main/sw/source/filter/ww8/wrtw8esh.cxx (original)
+++ openoffice/trunk/main/sw/source/filter/ww8/wrtw8esh.cxx Fri Nov 30 02:09:14 
2012
@@ -103,11 +103,232 @@
 // <--
 #include "WW8FFData.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 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;
+}
+
+String SwBasicEscherEx::GetBasePath()
+{
+       String sDocUrl;
+       String sBasePath;
+       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();
+               }
+       }
+       
+       sBasePath = sDocUrl.Copy( 0, sDocUrl.SearchBackward( '/' ) + 1 );
+       return sBasePath;
+
+}
+
+String SwBasicEscherEx::BuildFileName(sal_uInt16& rnLevel, bool& rbRel, const 
String& rUrl )
+{
+       String aDosName( INetURLObject( rUrl ).getFSysPath( 
INetURLObject::FSYS_DOS ) );
+       rnLevel = 0;
+       rbRel = IsRelUrl();
+
+       if( rbRel )
+       {
+                // try to convert to relative file name
+               String aTmpName( aDosName );
+               aDosName = INetURLObject::GetRelURL( GetBasePath(), rUrl,
+               INetURLObject::WAS_ENCODED, INetURLObject::DECODE_WITH_CHARSET 
);
+
+               if( aDosName.SearchAscii( INET_FILE_SCHEME ) == 0 )
+               {
+                       // not converted to rel -> back to old, return absolute 
flag
+                       aDosName = aTmpName;
+                       rbRel = false;
+               }
+              else if( aDosName.SearchAscii( "./" ) == 0 )
+              {
+                   aDosName.Erase( 0, 2 );
+              }
+              else
+              {
+                   while( aDosName.SearchAndReplaceAscii( "../", 
String::EmptyString() ) == 0 )
+                       ++rnLevel;
+              }
+       }
+       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_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.
+       SvMemoryStream tmpStrm;
+       String tmpTextMark;
+       
+       String rUrl = pINetFmtArg->GetURL();
+       String rTarFrm = pINetFmtArg->GetTargetFrameName();
+       sal_uInt32          mnFlags = 0;
+
+       INetURLObject aUrlObj( rUrl );
+       const INetProtocol eProtocol = aUrlObj.GetProtocol();
+
+       //Target Frame
+       if( rTarFrm.Len() > 0 )
+       {               
+               SwWW8Writer::WriteLong( tmpStrm, rTarFrm.Len()+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.GetChar( 0 ) != '#') )
+       {
+               sal_uInt16 nLevel;
+               bool bRel;
+               String 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.Len()+1);
+               SwWW8Writer::WriteString8( tmpStrm, aFileName, true, 
RTL_TEXTENCODING_MS_1252 );
+               tmpStrm.Write( maGuidFileTail,sizeof(maGuidFileTail) );
+
+               //For UNICODE
+               SwWW8Writer::WriteLong( tmpStrm, 2*aFileName.Len()+6);
+               SwWW8Writer::WriteLong( tmpStrm, 2*aFileName.Len());
+               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.Len()+1));
+
+               SwWW8Writer::WriteString16(tmpStrm, rUrl, true);
+               mnFlags |= WW8_HLINK_BODY | WW8_HLINK_ABS;
+       }
+       else if( rUrl.GetChar( 0 ) == '#' )
+       {
+               String aTextMark( rUrl.Copy( 1 ) );
+               aTextMark.SearchAndReplace( '.', '!' );
+               sal_uInt8 tmpLen = aTextMark.Len();
+               tmpTextMark = aTextMark;
+       }
+       
+       if( tmpTextMark.Len() == 0 && aUrlObj.HasMark() )
+       {
+               tmpTextMark = aUrlObj.GetMark();
+       }
+
+       if( tmpTextMark.Len()>0 )
+       {
+               SwWW8Writer::WriteLong( tmpStrm, tmpTextMark.Len()+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().Len()>0)
+               {
+                       SvMemoryStream *rStrm = new SvMemoryStream ; 
+                       String 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;
+                       String aNamestr = pINetFmt->GetName();
+                       if(aNamestr.Len()>0)
+                       {
+                               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 
);
+               }                               
+       }
+}
 
 //#110185# get a part fix for this type of element
 bool WW8Export::MiserableFormFieldExportHack(const SwFrmFmt& rFrmFmt)
@@ -1842,6 +2063,8 @@ sal_Int32 SwBasicEscherEx::WriteFlyFrame
     {
         rPropOpt.AddOpt( ESCHER_Prop_fPrint, 0x200020 );
     }
+       
+       PreWriteHyperlinkWithinFly(rFmt,rPropOpt);      
 
     return nLineWidth;
 }
@@ -1936,6 +2159,8 @@ sal_Int32 SwEscherEx::WriteFlyFrameAttr(
         }
     }
 
+       PreWriteHyperlinkWithinFly(rFmt,rPropOpt);      
+
     return nLineWidth;
 }
 

Modified: openoffice/trunk/main/sw/source/filter/ww8/wrtww8.hxx
URL: 
http://svn.apache.org/viewvc/openoffice/trunk/main/sw/source/filter/ww8/wrtww8.hxx?rev=1415477&r1=1415476&r2=1415477&view=diff
==============================================================================
--- openoffice/trunk/main/sw/source/filter/ww8/wrtww8.hxx (original)
+++ openoffice/trunk/main/sw/source/filter/ww8/wrtww8.hxx Fri Nov 30 02:09:14 
2012
@@ -901,6 +901,8 @@ public:
 
     using StgWriter::Write;
     virtual sal_uLong Write( SwPaM&, SfxMedium&, const String* = 0 );
+       //Seems not an expected to provide method to access the private member
+       SfxMedium* GetMedia(){ return mpMedium;};
 
 private:
     /// No copying.

Modified: openoffice/trunk/main/sw/source/filter/ww8/ww8graf.cxx
URL: 
http://svn.apache.org/viewvc/openoffice/trunk/main/sw/source/filter/ww8/ww8graf.cxx?rev=1415477&r1=1415476&r2=1415477&view=diff
==============================================================================
--- openoffice/trunk/main/sw/source/filter/ww8/ww8graf.cxx (original)
+++ openoffice/trunk/main/sw/source/filter/ww8/ww8graf.cxx Fri Nov 30 02:09:14 
2012
@@ -99,6 +99,11 @@
 
 #include <math.h>
 
+#include <fmturl.hxx>
+#include <svx/hlnkitem.hxx>
+#include <svl/whiter.hxx>
+#include "ww8par2.hxx"
+
 using namespace ::com::sun::star;
 using namespace sw::types;
 using namespace sw::util;
@@ -2728,6 +2733,39 @@ SwFrmFmt* SwWW8ImplReader::Read_GrafLaye
     if (pRecord->bHidden)
         return 0;
 
+       if(pObject)
+       {
+               sal_uInt16 nCount = pObject ? pObject->GetUserDataCount() : 0;
+               if(nCount)
+               {
+                       String 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.Len() > 0)
+                               pFmtURL->SetName(aObjName);
+                       if(aTarFrm.Len()>0)
+                               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

Modified: openoffice/trunk/main/sw/source/filter/ww8/ww8par.cxx
URL: 
http://svn.apache.org/viewvc/openoffice/trunk/main/sw/source/filter/ww8/ww8par.cxx?rev=1415477&r1=1415476&r2=1415477&view=diff
==============================================================================
--- openoffice/trunk/main/sw/source/filter/ww8/ww8par.cxx (original)
+++ openoffice/trunk/main/sw/source/filter/ww8/ww8par.cxx Fri Nov 30 02:09:14 
2012
@@ -141,7 +141,7 @@
 #include <iostream>
 #include <dbgoutsw.hxx>
 #endif
-
+#include <svx/hlnkitem.hxx>
 #include "WW8Sttbf.hxx"
 #include "WW8FibData.hxx"
 #define MM_250 1417             // WW-Default fuer Hor. Seitenraender: 2.5 cm
@@ -152,6 +152,247 @@ using namespace sw::util;
 using namespace sw::types;
 using namespace nsHdFtFlags;
 
+#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->InsertUserData( pData, 0 );
+                       return pData;
+               }
+       }
+       
+       return 0;
+};
+
+void lclGetAbsPath( String& rPath, sal_uInt16 nLevel, SwDocShell* pDocShell)
+{
+       String aTmpStr;
+       while( nLevel )
+       {
+               aTmpStr.AppendAscii( "../" );
+               --nLevel;
+       }
+       if(aTmpStr.Len())
+               aTmpStr += rPath;
+       else
+               aTmpStr = rPath;
+
+       if(aTmpStr.Len())
+       {
+               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;
+       rStrm >> nChars;
+       if( b16Bit )
+               nChars *= 2;
+       rStrm.SeekRel( nChars );
+}
+
+String 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).
+       String aRet;
+       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';
+       aRet.Append( pcBuffer );
+       delete[] pcBuffer;
+       return aRet;
+}
+
+void lclAppendString32( String& rString, SvMemoryStream& rStrm, sal_uInt32 
nChars, bool b16Bit )
+{
+       sal_uInt16 nReadChars = ulimit_cast< sal_uInt16 >( nChars );
+       String urlStr = SwWW8ImplReader::ReadRawUniString( rStrm, nReadChars, 
b16Bit );
+       rString.Append( urlStr );
+}
+
+void lclAppendString32( String& rString, SvMemoryStream& rStrm, bool b16Bit )
+{
+       sal_uInt32 nValue;
+       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 = new sal_uInt8[ 16 ];
+       sal_uInt32 nFlags;
+
+
+       rStrm.Read( aGuid, 16);
+       rStrm.SeekRel( 4 );
+       rStrm >> nFlags;
+
+       sal_uInt16 nLevel = 0;                  // counter for level to climb 
down in path
+       ::std::auto_ptr< String > xLongName;    // link / file name
+       ::std::auto_ptr< String > xShortName;   // 8.3-representation of file 
name
+       ::std::auto_ptr< String > xTextMark;    // text mark
+
+       // description (ignore)
+       if( ::get_flag( nFlags, WW8_HLINK_DESCR ) )
+               lclIgnoreString32( rStrm, true );
+
+       // target frame
+       if( ::get_flag( nFlags, WW8_HLINK_FRAME ) )
+       {       
+               ::std::auto_ptr< String > FrmName;
+               FrmName.reset( new String );
+               lclAppendString32(*FrmName , rStrm , true);
+               hlStr.tarFrm = *FrmName;
+       }
+
+       // UNC path
+       if( ::get_flag( nFlags, WW8_HLINK_UNC ) )
+       {
+               xLongName.reset( new String );
+               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 String );
+                       lclAppendString32( *xShortName,rStrm, false );
+                       rStrm.SeekRel( 24 );
+
+                       sal_uInt32 nStrLen;
+                       rStrm >> nStrLen;
+                       if( nStrLen )
+                       {
+                               rStrm >> nStrLen;
+                               nStrLen /= 2;       
+                                               rStrm.SeekRel( 2 );
+                               xLongName.reset( new String );
+                               lclAppendString32( *xLongName, rStrm,nStrLen, 
true );
+                               lclGetAbsPath( *xLongName, nLevel, pDocShell);
+                       }
+                       else
+                               lclGetAbsPath( *xShortName, nLevel, pDocShell);
+               }
+               else    if( (memcmp(aGuid, maGuidUrlMoniker, 16) == 0) )
+               {
+                       sal_uInt32 nStrLen;
+                       rStrm >> nStrLen;
+                       nStrLen /= 2;       
+                       xLongName.reset( new String );
+                       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 String );
+               lclAppendString32( *xTextMark, rStrm, true );
+       }
+
+       DBG_ASSERT( rStrm.GetRecLeft() == 0, "WW8Hyperlink::ReadEmbeddedData - 
record size mismatch" );
+
+       if( !xLongName.get() && xShortName.get() )
+       {
+               xLongName.reset( new String );
+               xLongName->Append(*xShortName);
+       }
+       else if( !xLongName.get() && xTextMark.get() )
+               xLongName.reset( new String );
+
+       if( xLongName.get() )
+       {
+               if( xTextMark.get() )
+               {
+                       if( xLongName->Len() == 0 )
+                               xTextMark->SearchAndReplaceAll( '!', '.' );
+                       xLongName->Append( '#' );
+                       xLongName->Append( *xTextMark );
+               }
+               hlStr.hLinkAddr = *xLongName;           
+       }
+}
 
 SwMSDffManager::SwMSDffManager( SwWW8ImplReader& rRdr )
     : SvxMSDffManager(*rRdr.pTableStream, rRdr.GetBaseURL(), 
rRdr.pWwFib->fcDggInfo,
@@ -752,6 +993,51 @@ SdrObject* SwMSDffManager::ProcessObj(Sv
                        delete pImpRec;
        }
 
+       sal_uInt32 nBufferSize = GetPropertyValue( DFF_Prop_pihlShape );
+        if( (0 < nBufferSize) && (nBufferSize <= 0xFFFF) && SeekToContent( 
DFF_Prop_pihlShape, rSt ) )
+       {
+               SvMemoryStream aMemStream;
+               String 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.Len() > 0)
+               {
+                       SwMacroInfo* pInfo = GetMacroInfo( pObj, true );
+                       if( pInfo )
+                       {
+                               pInfo->SetShapeId( rObjData.nShapeId );
+                               pInfo->SetHlink( hlStr.hLinkAddr );
+                               if(hlStr.tarFrm.Len() > 0)
+                                       pInfo->SetTarFrm( hlStr.tarFrm );
+                               String aNameStr = GetPropertyString( 
DFF_Prop_wzName, rSt );
+                               if(aNameStr.Len() > 0)
+                                       pInfo->SetName( aNameStr );
+                       }                               
+               }
+       }       
+       
        return pObj;
 }
 
@@ -5424,3 +5710,20 @@ namespace sw
 }
 
 /* vi:set tabstop=4 shiftwidth=4 expandtab: */
+
+SwMacroInfo::SwMacroInfo() :
+    SdrObjUserData( SW_DRAWLAYER, SW_UD_IMAPDATA, 0 )
+{
+}
+
+SwMacroInfo::~SwMacroInfo()
+{
+}
+
+SdrObjUserData* SwMacroInfo::Clone( SdrObject* /*pObj*/ ) const
+{
+   return new SwMacroInfo( *this );
+}
+
+
+

Modified: openoffice/trunk/main/sw/source/filter/ww8/ww8par.hxx
URL: 
http://svn.apache.org/viewvc/openoffice/trunk/main/sw/source/filter/ww8/ww8par.hxx?rev=1415477&r1=1415476&r2=1415477&view=diff
==============================================================================
--- openoffice/trunk/main/sw/source/filter/ww8/ww8par.hxx (original)
+++ openoffice/trunk/main/sw/source/filter/ww8/ww8par.hxx Fri Nov 30 02:09:14 
2012
@@ -31,6 +31,10 @@
 #include <editeng/frmdir.hxx>
 #include <fltshell.hxx>         // fuer den Attribut Stack
 
+#include <svx/svdobj.hxx>
+#define SW_DRAWLAYER 0x30334353
+#define SW_UD_IMAPDATA         2
+
 #include <vector>
 #include <stack>
 #include <deque>
@@ -365,6 +369,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 rtl::OUString& rHlink ) { maHlink = 
rHlink; }
+    const rtl::OUString& GetHlink() const { return maHlink; }
+        void            SetTarFrm( const rtl::OUString& rTarFrm ) { maTarFrm = 
rTarFrm; }
+    const rtl::OUString& GetTarFrm() const { return maTarFrm; }
+       void            SetShapeId( const sal_uInt32& rShapeId ) { maShapeId = 
rShapeId; }
+    const sal_uInt32& GetShapeId() const { return maShapeId; }
+       void            SetName( const rtl::OUString& rName ) { maNameStr = 
rName; }
+       const rtl::OUString& GetName() const { return maNameStr; }
+
+private:
+    sal_uInt32   maShapeId;
+    rtl::OUString   maHlink;
+       rtl::OUString maNameStr;
+       rtl::OUString maTarFrm;
+};
+struct HyperLinksTable
+{
+       String hLinkAddr;
+       String tarFrm;
+};
 
 namespace sw
 {
@@ -1667,6 +1713,8 @@ public:     // eigentlich private, geht 
     CharSet GetCurrentCJKCharSet();
 
     void PostProcessAttrs();
+       static void       ReadEmbeddedData(SvMemoryStream& rStrm, SwDocShell* 
pDocShell ,struct HyperLinksTable& hlStr);
+       static String ReadRawUniString( SvMemoryStream& rStrm,sal_uInt16 
nChars, bool b16Bit );
 };
 
 bool CanUseRemoteLink(const String &rGrfName);


Reply via email to