diff options
author | Kohei Yoshida <kohei.yoshida@suse.com> | 2011-10-04 21:59:17 -0400 |
---|---|---|
committer | Kohei Yoshida <kohei.yoshida@suse.com> | 2011-10-04 21:59:17 -0400 |
commit | 0e1de41755fd3e9f9e1c42edb7285e64aff07218 (patch) | |
tree | 5a7de17fccf5ed68eb0c757bd34004a904983532 | |
parent | 74feb347fd5a0267f774f76968f8f3403421b17f (diff) |
bnc#719887: Encode virtual paths to local volume correctly.
When exporting to xls, we weren't encoding the so-called virtual paths
(used for recording external workbook paths etc) correctly when the
external docs were located under the same drive as the referencing doc.
This patch fixes this.
-rw-r--r-- | sc/source/filter/excel/xehelper.cxx | 120 |
1 files changed, 41 insertions, 79 deletions
diff --git a/sc/source/filter/excel/xehelper.cxx b/sc/source/filter/excel/xehelper.cxx index f36d318951f0..f6f482137978 100644 --- a/sc/source/filter/excel/xehelper.cxx +++ b/sc/source/filter/excel/xehelper.cxx @@ -902,106 +902,67 @@ void XclExpHFConverter::AppendPortion( const EditTextObject* pTextObj, sal_Unico namespace { -/** Converts the file URL passed in rUrl to a URL in DOS notation (local or UNC). - @param rUrl (in/out-param) In: URL to convert; Out: Converted URL in DOS notation. - @param rBasePath Base path for relative URLs. - @param bSaveRelUrl Converts to a relative URL, using rBasePath. - @return True = Conversion successful, rUrl contains converted file URL. */ -bool lclConvertToDos( String& rUrl, const String& rBasePath, bool bSaveRelUrl ) -{ - String aDosUrl( INetURLObject( rUrl ).getFSysPath( INetURLObject::FSYS_DOS ) ); - bool bRet = (aDosUrl.Len() > 0); - if( bRet && bSaveRelUrl ) - { - // try to convert to relative path - String aDosBase( INetURLObject( rBasePath ).getFSysPath( INetURLObject::FSYS_DOS ) ); - if( aDosBase.Len() ) - { - xub_StrLen nPos; - - // --- 1st step: delete equal subdirectories --- - - // special handling for UNC - xub_StrLen nStartSearch = aDosBase.EqualsAscii( "\\\\", 0, 2 ) ? 2 : 0; - bool bEqualBase = false; - bool bLoop = true; - while( bLoop && ((nPos = aDosBase.Search( '\\', nStartSearch )) != STRING_NOTFOUND) ) - { - bLoop = (sal_True == aDosBase.Equals( aDosUrl, 0, nPos + 1 )); - if( bLoop ) - { - aDosBase.Erase( 0, nPos + 1 ); - aDosUrl.Erase( 0, nPos + 1 ); - nStartSearch = 0; - bEqualBase = true; - } - } - - // --- 2nd step: add parent directory levels --- - - if( bEqualBase ) - { - while( (nPos = aDosBase.Search( '\\' )) != STRING_NOTFOUND ) - { - aDosBase.Erase( 0, nPos + 1 ); - aDosUrl.InsertAscii( "..\\", 0 ); - } - } - } - rUrl = aDosUrl; - } - return bRet; -} - /** Encodes special parts of the URL, i.e. directory separators and volume names. @param pTableName Pointer to a table name to be encoded in this URL, or 0. */ -void lclEncodeDosUrl( XclBiff eBiff, String& rUrl, const rtl::OUString* pTableName = 0 ) +rtl::OUString lclEncodeDosUrl( + XclBiff eBiff, const rtl::OUString& rUrl, const rtl::OUString& rBase, const rtl::OUString* pTableName) { - if( rUrl.Len() ) + rtl::OUStringBuffer aBuf; + + if (!rUrl.isEmpty()) { - String aOldUrl( rUrl ); - rUrl = EXC_URLSTART_ENCODED; + rtl::OUString aOldUrl = rUrl; + aBuf.append(EXC_URLSTART_ENCODED); - if( (aOldUrl.Len() > 2) && aOldUrl.EqualsAscii( "\\\\", 0, 2 ) ) + if (aOldUrl.getLength() > 2 && aOldUrl.copy(0,2).equalsAscii("\\\\")) { // UNC - rUrl.Append( EXC_URL_DOSDRIVE ).Append( '@' ); - aOldUrl.Erase( 0, 2 ); + aBuf.append(EXC_URL_DOSDRIVE).append(sal_Unicode('@')); + aOldUrl = aOldUrl.copy(2); } - else if( (aOldUrl.Len() > 2) && aOldUrl.EqualsAscii( ":\\", 1, 2 ) ) + else if (aOldUrl.getLength() > 2 && aOldUrl.copy(1,2).equalsAscii(":\\")) { // drive letter - rUrl.Append( EXC_URL_DOSDRIVE ).Append( aOldUrl.GetChar( 0 ) ); - aOldUrl.Erase( 0, 3 ); + sal_Unicode cThisDrive = rBase.isEmpty() ? ' ' : rBase.getStr()[0]; + sal_Unicode cDrive = aOldUrl.getStr()[0]; + if (cThisDrive == cDrive) + // This document and the referenced document are under the same drive. + aBuf.append(EXC_URL_DRIVEROOT); + else + aBuf.append(EXC_URL_DOSDRIVE).append(cDrive); + aOldUrl = aOldUrl.copy(3); } // directories - xub_StrLen nPos; - while( (nPos = aOldUrl.Search( '\\' )) != STRING_NOTFOUND ) + sal_Int32 nPos = -1; + while((nPos = aOldUrl.indexOf('\\')) != -1) { - if( aOldUrl.EqualsAscii( "..", 0, 2 ) ) - rUrl.Append( EXC_URL_PARENTDIR ); // parent dir + if (aOldUrl.copy(0,2).equalsAscii("..")) + // parent dir (NOTE: the MS-XLS spec doesn't mention this, and + // Excel seems confused by this token). + aBuf.append(EXC_URL_PARENTDIR); else - rUrl.Append( aOldUrl.GetBuffer(), nPos ).Append( EXC_URL_SUBDIR ); - aOldUrl.Erase( 0, nPos + 1 ); + aBuf.append(aOldUrl.copy(0,nPos)).append(EXC_URL_SUBDIR); + + aOldUrl = aOldUrl.copy(nPos + 1); } // file name - if( pTableName ) // enclose file name in brackets if table name follows - rUrl.Append( '[' ).Append( aOldUrl ).Append( ']' ); + if (pTableName) // enclose file name in brackets if table name follows + aBuf.append(sal_Unicode('[')).append(aOldUrl).append(sal_Unicode(']')); else - rUrl.Append( aOldUrl ); + aBuf.append(aOldUrl); } else // empty URL -> self reference { switch( eBiff ) { case EXC_BIFF5: - rUrl = pTableName ? EXC_URLSTART_SELFENCODED : EXC_URLSTART_SELF; + aBuf.append(pTableName ? EXC_URLSTART_SELFENCODED : EXC_URLSTART_SELF); break; case EXC_BIFF8: - OSL_ENSURE( pTableName, "lclEncodeDosUrl - sheet name required for BIFF8" ); - rUrl = EXC_URLSTART_SELF; + DBG_ASSERT( pTableName, "lclEncodeDosUrl - sheet name required for BIFF8" ); + aBuf.append(EXC_URLSTART_SELF); break; default: DBG_ERROR_BIFF(); @@ -1009,8 +970,10 @@ void lclEncodeDosUrl( XclBiff eBiff, String& rUrl, const rtl::OUString* pTableNa } // table name - if( pTableName ) - rUrl.Append(String(*pTableName)); + if (pTableName) + aBuf.append(*pTableName); + + return aBuf.makeStringAndClear(); } } // namespace @@ -1019,10 +982,9 @@ void lclEncodeDosUrl( XclBiff eBiff, String& rUrl, const rtl::OUString* pTableNa String XclExpUrlHelper::EncodeUrl( const XclExpRoot& rRoot, const String& rAbsUrl, const rtl::OUString* pTableName ) { - String aDosUrl( rAbsUrl ); - if( !aDosUrl.Len() || lclConvertToDos( aDosUrl, rRoot.GetBasePath(), rRoot.IsRelUrl() ) ) - lclEncodeDosUrl( rRoot.GetBiff(), aDosUrl, pTableName ); - return aDosUrl; + rtl::OUString aDosUrl = INetURLObject(rAbsUrl).getFSysPath(INetURLObject::FSYS_DOS); + rtl::OUString aDosBase = INetURLObject(rRoot.GetBasePath()).getFSysPath(INetURLObject::FSYS_DOS); + return lclEncodeDosUrl(rRoot.GetBiff(), aDosUrl, aDosBase, pTableName); } String XclExpUrlHelper::EncodeDde( const String& rApplic, const String rTopic ) |