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 <caol...@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 <chen...@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 <chen...@apache.org> Date: Mon Dec 3 06:47:16 2012 +0000 Revise un-necessary checking.. Patch by: chengjh,<chen...@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 <chen...@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,<kangjane2...@gmail.com> Found by: Yan Ji,<yanji...@gmail.com> Review by: Jian Hong Cheng,<chen...@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);
_______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits