You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openoffice.apache.org by ch...@apache.org on 2012/11/30 03:09:15 UTC

svn commit: r1415477 - in /openoffice/trunk/main/sw/source/filter/ww8: escher.hxx wrtw8esh.cxx wrtww8.hxx ww8graf.cxx ww8par.cxx ww8par.hxx

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,<ka...@gmail.com>
Found by: Yan Ji,<ya...@gmail.com>
Review by: Jian Hong Cheng,<ch...@apache.org>           

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);