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