ooo-build r13646 - in trunk: . patches/dev300



Author: kyoshida
Date: Thu Aug 21 02:43:12 2008
New Revision: 13646
URL: http://svn.gnome.org/viewvc/ooo-build?rev=13646&view=rev

Log:
2008-08-20  Kohei Yoshida  <kyoshida novell com>

	* patches/dev300/calc-external-defined-names.diff: more progress on ods
	file import/export.  fixed breakage on link failure on import, correct
	export of xlink:href values for the external ref caches, and several 
	parser fix on file/sheet names with single quotes in them.


Modified:
   trunk/ChangeLog
   trunk/patches/dev300/calc-external-defined-names.diff

Modified: trunk/patches/dev300/calc-external-defined-names.diff
==============================================================================
--- trunk/patches/dev300/calc-external-defined-names.diff	(original)
+++ trunk/patches/dev300/calc-external-defined-names.diff	Thu Aug 21 02:43:12 2008
@@ -207,10 +207,10 @@
  
 diff --git sc/inc/externalrefmgr.hxx sc/inc/externalrefmgr.hxx
 new file mode 100644
-index 0000000..82f694d
+index 0000000..46d691d
 --- /dev/null
 +++ sc/inc/externalrefmgr.hxx
-@@ -0,0 +1,373 @@
+@@ -0,0 +1,382 @@
 +/*************************************************************************
 + *
 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -495,6 +495,7 @@
 +     */
 +    ScTokenArray* getRangeNameTokens(sal_uInt16 nFileId, const String& rName, const ScAddress* pCurPos = NULL);
 +
++    const String& getOwnDocumentName() const;
 +    bool isOwnDocument(const String& rFile) const;
 +
 +    /** 
@@ -531,6 +532,13 @@
 +
 +    bool hasExternalData() const;
 +
++    /** 
++     * Re-generates relative names for all stored source files.  This is 
++     * necessary when exporting to an ods document, to ensure that all source 
++     * files have their respective relative names for xlink:href export.
++     */
++    void resetSrcFileData();
++
 +private:
 +    ScExternalRefManager();
 +    ScExternalRefManager(const ScExternalRefManager&); 
@@ -540,7 +548,8 @@
 +    void insertReferencingCell(sal_uInt16 nFileId, const ScAddress& rCell);
 +
 +    ScDocument* getSrcDocument(sal_uInt16 nFileId);
-+    SfxObjectShellRef loadSrcDocument(sal_uInt16 nFileId, const String& rFile, String& rFilter);
++    SfxObjectShellRef loadSrcDocument(sal_uInt16 nFileId, String& rFilter);
++    bool isFileLoadable(const String& rFile) const;
 +
 +    void maybeLinkExternalFile(sal_uInt16 nFileId);
 +
@@ -840,7 +849,7 @@
  {
      if (pLinkManager)
 diff --git sc/source/core/tool/address.cxx sc/source/core/tool/address.cxx
-index 2cb5dce..c1906dd 100644
+index 2cb5dce..e518b27 100644
 --- sc/source/core/tool/address.cxx
 +++ sc/source/core/tool/address.cxx
 @@ -35,6 +35,7 @@
@@ -851,7 +860,57 @@
  
  #include "globstr.hrc"
  #include <sal/alloca.h>
-@@ -102,10 +103,7 @@ sal_Unicode_strtol ( const sal_Unicode*  p,
+@@ -68,6 +69,49 @@ void ScAddress::Details::SetPos ( const ScDocument* pDoc,
+ 
+ #include <iostream>
+ 
++/** 
++ * Parse from the opening single quote to the closing single quote.  Inside 
++ * the quotes, a single quote character is encoded by double single-quote 
++ * characters. 
++ *
++ * @param p pointer to the first character to begin parsing. 
++ * @param rName (reference) parsed name within the quotes.  If the name is 
++ *              empty, either the parsing failed or it's an empty quote.
++ * 
++ * @return pointer to the character immediately after the closing single 
++ *         quote.
++ */
++static const sal_Unicode* lcl_ParseQuotedName( const sal_Unicode* p, String& rName )
++{
++    rName.Erase();
++    if (*p != '\'')
++        return p;
++
++    const sal_Unicode* pStart = p;
++    sal_Unicode cPrev = 0;
++    for (++p; *p; ++p)
++    {
++        if (*p == '\'')
++        {
++            if (cPrev == '\'')
++            {    
++                // double single-quote equals one single quote.
++                rName += *p;
++                cPrev = 0;
++                continue;
++            }
++        }
++        else if (cPrev == '\'')
++            // We are past the closing quote.  We're done!
++            return p;
++        else
++            rName += *p;
++        cPrev = *p;
++    }
++    rName.Erase();
++    return pStart;
++}
++
+ static long int
+ sal_Unicode_strtol ( const sal_Unicode*  p,
+                      const sal_Unicode** pEnd )
+@@ -102,31 +146,18 @@ sal_Unicode_strtol ( const sal_Unicode*  p,
  // Returns NULL if the string should be a sheet name, but is invalid
  // Returns a pointer to the first character after the sheet name
  static const sal_Unicode *
@@ -863,7 +922,30 @@
                        String& rExternTabName,
                        bool allow_3d )
  {
-@@ -190,26 +188,7 @@ lcl_XL_ParseSheetRef( const sal_Unicode *start,
+     String aTabName;
+-    SCTAB  nTab = 0;
+     const sal_Unicode *p = start;
+ 
+     //pAddr->SetTab( 0 );
+     if( *p == '\'' ) // XL only seems to use single quotes for sheet names
+     {
+-        for( p++; *p ; )
+-        {
+-            if( *p == '\'' )
+-            {
+-                if( p[1] != '\'' )  // end quote
+-                    break;
+-                p++;    // 2 quotes in a row are a quote in a the name
+-            }
+-            aTabName += *p++;
+-        }
+-        if( *p++ != '\'' )
++        p = lcl_ParseQuotedName(p, aTabName);
++        if (!aTabName.Len())
+             return NULL;
+     }
+     else
+@@ -190,26 +221,7 @@ lcl_XL_ParseSheetRef( const sal_Unicode *start,
          aTabName.Append( start, sal::static_int_cast<xub_StrLen>( p - start ) );
      }
  
@@ -891,7 +973,7 @@
      return p;
  }
  
-@@ -227,39 +206,66 @@ lcl_ScRange_Parse_XL_Header( ScRange& r,
+@@ -227,39 +239,33 @@ lcl_ScRange_Parse_XL_Header( ScRange& r,
      // Is this an external reference ?
      rStartTabName.Erase();
      rEndTabName.Erase();
@@ -911,44 +993,13 @@
 +        if (*p == '\'')
          {
 -            for( const sal_Unicode cQuote = *p++; *p && *p != cQuote ; )
-+            sal_Unicode cPrev;
-+            String aDocName;
-+            for (++p; *p; ++p)
-             {
+-            {
 -                if( *p == '\\' && p[1] )
 -                    p++;
 -                rExternDocName += *p++;
-+                if (*p == '\'')
-+                {
-+                    if (cPrev == '\'')
-+                        // two successive single quote is treated as a single 
-+                        // valid character.
-+                        aDocName += *p;
-+                }
-+                else if (*p == ']')
-+                {
-+                    if (cPrev == '\'')
-+                    {
-+                        // Success!
-+                        rExternDocName = aDocName;
-+                        break;
-+                    }
-+                    else
-+                        return start;
-+                }
-+                else
-+                {
-+                    // any other character
-+                    if (aDocName.Len() > 0 && cPrev == '\'')
-+                        // unless it's the 3rd character, a normal character 
-+                        // following immediately a single quote is invalid.
-+                        return start;
-+                    aDocName += *p;
-+                }
-+                cPrev = *p;
-             }
-+
-+            if (!*p)
+-            }
++            p = lcl_ParseQuotedName(p, rExternDocName);
++            if (!*p || *p != ']' || !rExternDocName.Len())
 +                return start;
          }
          else
@@ -1070,7 +1121,7 @@
 +    if (aExternDocName.Len() > 0)
 +    {
 +        ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager();
-+        if (!pRefMgr->isOwnDocument(aExternDocName))
++        if (pExtInfo && !pRefMgr->isOwnDocument(aExternDocName))
 +        {
 +            pExtInfo->mbExternal = true;
 +            pExtInfo->maTabName = aStartTabName;
@@ -1139,7 +1190,7 @@
 +    if (aExternDocName.Len() > 0)
 +    {
 +        ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager();
-+        if (!pRefMgr->isOwnDocument(aExternDocName))
++        if (pExtInfo && !pRefMgr->isOwnDocument(aExternDocName))
 +        {
 +            pExtInfo->mbExternal = true;
 +            pExtInfo->maTabName = aStartTabName;
@@ -1196,7 +1247,7 @@
  
      if ( *tmp2 != 0 )
      {
-@@ -708,20 +722,19 @@ lcl_ScRange_Parse_XL_A1( ScRange& r,
+@@ -708,45 +722,31 @@ lcl_ScRange_Parse_XL_A1( ScRange& r,
      }
  
      nFlags |= (nFlags2 << 4);
@@ -1213,15 +1264,80 @@
  {
      USHORT  nRes = 0;
      String  aDocName;       // der pure Dokumentenname
-     String  aDocTab;        // zusammengesetzt fuer Table
+-    String  aDocTab;        // zusammengesetzt fuer Table
      String  aTab;
      BOOL    bExtDoc = FALSE;
 -    BOOL    bNeedExtTab = FALSE;
 +    const ScAddress aCurPos(rAddr);
  
-     // Lets see if this is a reference to something in an external file.
-     // A Documentname is always quoted and has a trailing #
-@@ -795,35 +808,11 @@ lcl_ScAddress_Parse_OOo( BOOL& bExternal, const sal_Unicode* p,
+-    // Lets see if this is a reference to something in an external file.
+-    // A Documentname is always quoted and has a trailing #
+-    if ( *p == '\'' && ScGlobal::UnicodeStrChr( p, SC_COMPILER_FILE_TAB_SEP ) )
++    // Lets see if this is a reference to something in an external file.  A
++    // document name is always quoted and has a trailing #.
++    if (*p == '\'')
+     {
+-        const sal_Unicode *pStart = p;   
+-        BOOL bQuote = TRUE;         // A Documentname is always quoted
+-        aDocTab += *p++;
+-        while ( bQuote && *p )
+-        {
+-            if ( *p == '\'' && *(p-1) != '\\' )
+-                bQuote = FALSE;
+-            else if( !(*p == '\\' && *(p+1) == '\'') )
+-                aDocName += *p;     // An escaped Quote in the Documentname
+-            aDocTab += *p++;
+-        }
+-        aDocTab += *p;              // den SC_COMPILER_FILE_TAB_SEP mitnehmen
+-        if( *p++ == SC_COMPILER_FILE_TAB_SEP )
+-            bExtDoc = TRUE;
++        const sal_Unicode* pStart = p;
++        p = lcl_ParseQuotedName(p, aDocName);
++        if (*p++ == SC_COMPILER_FILE_TAB_SEP)
++            bExtDoc = true;
+         else
+-        {
+-            // It wasn't a document after all, reset and continue as normal
++            // This is not a document name.  Perhaps a quoted relative table 
++            // name.
+             p = pStart;
+-            aDocTab = String();
+-        }
+     }
+ 
+     SCCOL   nCol = 0;
+@@ -762,25 +762,11 @@ lcl_ScAddress_Parse_OOo( BOOL& bExternal, const sal_Unicode* p,
+         if (*p == '$')
+             nRes |= SCA_TAB_ABSOLUTE, p++;
+ 
+-        // Tokens that start at ' can have anything in them until a final '
+-        // but '' marks an escaped '
+-        // We've earlier guaranteed that a string containing '' will be
+-        // surrounded by '
+-        if( *p == '\'' )
+-        {
+-            ++p;
+-            while (*p)
+-            {
+-                if (*p == '\'')
+-                {
+-                    if ( (*(p+1) != '\'') )
+-                        break;
+-                    else
+-                        *p++;
+-                }
+-                aTab += *p++;
+-            }
+-        }
++        if (*p == '\'')
++            // Tokens that start at ' can have anything in them until a final
++            // ' but '' marks an escaped '.  We've earlier guaranteed that a
++            // string containing '' will be surrounded by '.
++            p = lcl_ParseQuotedName(p, aTab);
+ 
+         while (*p)
+         {
+@@ -795,35 +781,11 @@ lcl_ScAddress_Parse_OOo( BOOL& bExternal, const sal_Unicode* p,
          }
          if( *p++ != '.' )
              nBits = 0;
@@ -1261,7 +1377,7 @@
          }
          else
              nBits = 0;
-@@ -884,16 +873,32 @@ lcl_ScAddress_Parse_OOo( BOOL& bExternal, const sal_Unicode* p,
+@@ -884,16 +846,31 @@ lcl_ScAddress_Parse_OOo( BOOL& bExternal, const sal_Unicode* p,
          if( !nBits )
              p = q;
      }
@@ -1274,7 +1390,6 @@
 +        ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager();
 +        pRefMgr->convertToAbsName(aDocName);
 +
-+        // TODO: Do we need to check if the document exists before going further?
 +        if (!pRefMgr->isOwnDocument(aDocName))
          {
 -            nRes |= SCA_VALID_TAB;
@@ -1300,7 +1415,7 @@
      if ( !(nRes & SCA_VALID_ROW) && (nRes & SCA_VALID_COL)
              && !( (nRes & SCA_TAB_3D) && (nRes & SCA_VALID_TAB)) )
      {   // keine Row, keine Tab, aber Col => DM (...), B (...) o.ae.
-@@ -912,9 +917,8 @@ lcl_ScAddress_Parse_OOo( BOOL& bExternal, const sal_Unicode* p,
+@@ -912,9 +889,8 @@ lcl_ScAddress_Parse_OOo( BOOL& bExternal, const sal_Unicode* p,
  }
  
  static USHORT
@@ -1312,7 +1427,7 @@
  {
      if( !*p )
          return 0;
-@@ -924,20 +928,20 @@ lcl_ScAddress_Parse ( BOOL& bExternal, const sal_Unicode* p,
+@@ -924,20 +900,20 @@ lcl_ScAddress_Parse ( BOOL& bExternal, const sal_Unicode* p,
      default :
      case ScAddress::CONV_OOO:
          {
@@ -1336,7 +1451,7 @@
              rAddr = r.aStart;
              return nFlags;
          }
-@@ -949,9 +953,8 @@ bool ConvertSingleRef( ScDocument* pDoc, const String& rRefString,
+@@ -949,9 +925,8 @@ bool ConvertSingleRef( ScDocument* pDoc, const String& rRefString,
                         SCTAB nDefTab, ScRefAddress& rRefAddress,
                         const ScAddress::Details& rDetails )
  {
@@ -1347,7 +1462,7 @@
      if( nRes & SCA_VALID )
      {
          rRefAddress.Set( aAddr,
-@@ -988,10 +991,9 @@ bool ConvertDoubleRef( ScDocument* pDoc, const String& rRefString, SCTAB nDefTab
+@@ -988,10 +963,9 @@ bool ConvertDoubleRef( ScDocument* pDoc, const String& rRefString, SCTAB nDefTab
  
  
  USHORT ScAddress::Parse( const String& r, ScDocument* pDoc,
@@ -1360,7 +1475,7 @@
  }
  
  
-@@ -1060,7 +1062,7 @@ void ScRange::ExtendTo( const ScRange& rRange )
+@@ -1060,7 +1034,7 @@ void ScRange::ExtendTo( const ScRange& rRange )
  }
  
  static USHORT
@@ -1369,7 +1484,7 @@
  {
      USHORT nRes1 = 0, nRes2 = 0;
      xub_StrLen nTmp = 0;
-@@ -1073,13 +1075,12 @@ lcl_ScRange_Parse_OOo( ScRange &aRange, const String& r, ScDocument* pDoc )
+@@ -1073,13 +1047,12 @@ lcl_ScRange_Parse_OOo( ScRange &aRange, const String& r, ScDocument* pDoc )
          String aTmp( r );
          sal_Unicode* p = aTmp.GetBufferAccess();
          p[ nPos ] = 0;
@@ -1386,7 +1501,7 @@
                      nRes2 &= ~SCA_VALID_TAB;    // #REF!
                  else
                  {
-@@ -1132,7 +1133,7 @@ lcl_ScRange_Parse_OOo( ScRange &aRange, const String& r, ScDocument* pDoc )
+@@ -1132,7 +1105,7 @@ lcl_ScRange_Parse_OOo( ScRange &aRange, const String& r, ScDocument* pDoc )
  }
  
  USHORT ScRange::Parse( const String& r, ScDocument* pDoc,
@@ -1395,7 +1510,7 @@
  {
      if ( r.Len() <= 0 )
          return 0;
-@@ -1141,13 +1142,13 @@ USHORT ScRange::Parse( const String& r, ScDocument* pDoc,
+@@ -1141,13 +1114,13 @@ USHORT ScRange::Parse( const String& r, ScDocument* pDoc,
      {
      default :
      case ScAddress::CONV_OOO:
@@ -3542,7 +3657,7 @@
  
  
 diff --git sc/source/filter/excel/xeformula.cxx sc/source/filter/excel/xeformula.cxx
-index 3db8da7..f9f87c2 100644
+index 3db8da7..947b4ce 100644
 --- sc/source/filter/excel/xeformula.cxx
 +++ sc/source/filter/excel/xeformula.cxx
 @@ -42,6 +42,11 @@
@@ -3611,7 +3726,7 @@
      switch( eTokType )
      {
          case svUnknown:     mbOk = false;                           break;
-@@ -1248,6 +1286,133 @@ void XclExpFmlaCompImpl::ProcessExternal( const XclExpTokenData& rTokData, sal_u
+@@ -1248,6 +1286,131 @@ void XclExpFmlaCompImpl::ProcessExternal( const XclExpTokenData& rTokData, sal_u
          ProcessFunction( rTokData, nExpClass );
  }
  
@@ -3645,7 +3760,6 @@
 +            XclAddress aXclPos(ScAddress::UNINITIALIZED);
 +            ConvertRefData(aRef, aXclPos, false, false, false);
 +
-+            const String* pFile = pRefMgr->getExternalFileName(nFileId);
 +            sal_uInt16 nExtSheet, nFirstSBTab, nLastSBTab;
 +            mpLinkMgr->FindExtSheet(nFileId, rTabName, 1, nExtSheet, nFirstSBTab, nLastSBTab, GetNewRefLogEntry());
 +            sal_uInt8 nBaseId = lclIsRefDel2D(aRef) ? EXC_TOKID_REFERR3D : EXC_TOKID_REF3D;
@@ -3683,7 +3797,6 @@
 +            mpLinkMgr->StoreCellRange(nFileId, rTabName, aRef);
 +            XclRange aXclRange(ScAddress::UNINITIALIZED);
 +            ConvertRefData(aRef, aXclRange, false);
-+            const String* pFile = pRefMgr->getExternalFileName(nFileId);
 +            sal_uInt16 nExtSheet, nFirstSBTab, nLastSBTab;
 +            sal_uInt16 nTabSpan = r2.nTab - r1.nTab + 1;
 +            mpLinkMgr->FindExtSheet(nFileId, rTabName, nTabSpan, nExtSheet, nFirstSBTab, nLastSBTab, GetNewRefLogEntry());
@@ -3745,7 +3858,7 @@
  void XclExpFmlaCompImpl::ProcessFunction( const XclExpTokenData& rTokData, sal_uInt8 nExpClass )
  {
      OpCode eOpCode = rTokData.GetOpCode();
-@@ -1623,32 +1788,6 @@ void XclExpFmlaCompImpl::AppendTrailingParam( XclExpFuncData& rFuncData )
+@@ -1623,32 +1786,6 @@ void XclExpFmlaCompImpl::AppendTrailingParam( XclExpFuncData& rFuncData )
      }
  }
  
@@ -4672,7 +4785,7 @@
  {
      mxImpl->Save( rStrm );
 diff --git sc/source/filter/excel/xilink.cxx sc/source/filter/excel/xilink.cxx
-index 01932a5..2c50c2b 100644
+index 01932a5..ab4c08b 100644
 --- sc/source/filter/excel/xilink.cxx
 +++ sc/source/filter/excel/xilink.cxx
 @@ -38,6 +38,13 @@
@@ -5041,9 +5154,12 @@
  }
  
  bool XclImpLinkManagerImpl::IsSelfRef( sal_uInt16 nXtiIndex ) const
-@@ -570,8 +613,8 @@ bool XclImpLinkManagerImpl::GetScTabRange(
+@@ -568,10 +611,10 @@ bool XclImpLinkManagerImpl::GetScTabRange(
+ {
+     if( const XclImpXti* pXti = maXtiList.GetObject( nXtiIndex ) )
      {
-         if( const XclImpSupbook* pSupbook = maSupbookList.GetObject( pXti->mnSupbook ) )
+-        if( const XclImpSupbook* pSupbook = maSupbookList.GetObject( pXti->mnSupbook ) )
++        if (maSupbookList.GetObject(pXti->mnSupbook))
          {
 -            rnFirstScTab = pSupbook->GetScTabNum( pXti->mnSBTabFirst );
 -            rnLastScTab = pSupbook->GetScTabNum( pXti->mnSBTabLast );
@@ -5938,7 +6054,7 @@
  //------------------------------------------------------------------
  
 diff --git sc/source/filter/xml/xmlexprt.cxx sc/source/filter/xml/xmlexprt.cxx
-index 52f5145..2d173a5 100644
+index 52f5145..92dea13 100644
 --- sc/source/filter/xml/xmlexprt.cxx
 +++ sc/source/filter/xml/xmlexprt.cxx
 @@ -68,6 +68,7 @@
@@ -6343,7 +6459,7 @@
  				}
  				if (getExportFlags() & EXPORT_MASTERSTYLES)
  				{
-@@ -3316,6 +3336,182 @@ void ScXMLExport::WriteNamedExpressions(const com::sun::star::uno::Reference <co
+@@ -3316,6 +3336,183 @@ void ScXMLExport::WriteNamedExpressions(const com::sun::star::uno::Reference <co
  	}
  }
  
@@ -6353,6 +6469,7 @@
 +        return;
 +
 +    ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager();
++    pRefMgr->resetSrcFileData();
 +    sal_uInt16 nCount = pRefMgr->getCachedFileCount();
 +    for (sal_uInt16 nFileId = 0; nFileId < nCount; ++nFileId)
 +    {
@@ -7051,7 +7168,7 @@
 +
 +#endif
 diff --git sc/source/filter/xml/xmlimprt.cxx sc/source/filter/xml/xmlimprt.cxx
-index 47b26b9..3541e45 100644
+index 47b26b9..eb74c99 100644
 --- sc/source/filter/xml/xmlimprt.cxx
 +++ sc/source/filter/xml/xmlimprt.cxx
 @@ -104,6 +104,7 @@
@@ -7095,7 +7212,7 @@
 +    { XML_NAMESPACE_OFFICE, XML_TIME_VALUE,                     XML_TOK_TABLE_ROW_CELL_ATTR_TIME_VALUE              },
 +    { XML_NAMESPACE_OFFICE, XML_STRING_VALUE,                   XML_TOK_TABLE_ROW_CELL_ATTR_STRING_VALUE            },
 +    { XML_NAMESPACE_OFFICE, XML_BOOLEAN_VALUE,                  XML_TOK_TABLE_ROW_CELL_ATTR_BOOLEAN_VALUE           },
-+    { XML_NAMESPACE_OFFICE, XML_FORMULA,                        XML_TOK_TABLE_ROW_CELL_ATTR_FORMULA                 },
++    { XML_NAMESPACE_TABLE,  XML_FORMULA,                        XML_TOK_TABLE_ROW_CELL_ATTR_FORMULA                 },
 +    { XML_NAMESPACE_OFFICE, XML_CURRENCY,                       XML_TOK_TABLE_ROW_CELL_ATTR_CURRENCY                },
 +    XML_TOKEN_MAP_END
  };
@@ -7228,7 +7345,7 @@
  extern const XMLPropertyMapEntry aXMLScColumnStylesProperties[];
  extern const XMLPropertyMapEntry aXMLScRowStylesProperties[];
 diff --git sc/source/filter/xml/xmltabi.cxx sc/source/filter/xml/xmltabi.cxx
-index 4a0f83e..fcfb281 100644
+index 4a0f83e..264901d 100644
 --- sc/source/filter/xml/xmltabi.cxx
 +++ sc/source/filter/xml/xmltabi.cxx
 @@ -40,6 +40,7 @@
@@ -7247,7 +7364,7 @@
  
  #include <xmloff/xmltkmap.hxx>
  #include <xmloff/nmspmap.hxx>
-@@ -63,6 +65,78 @@
+@@ -63,6 +65,77 @@
  using namespace com::sun::star;
  using namespace xmloff::token;
  
@@ -7267,6 +7384,8 @@
 +{
 +    // 'file:///path/to/file.ods'#MySheet
 +    // 'file:///path/to/file.ods'#MySheet with space
++    // 'file:///path/to/file's.ods'#Sheet (Notice the quote in the file name.
++    //  That's allowed.)
 +
 +    static const sal_Unicode aPrefix[] = {
 +        '\'', 'f', 'i', 'l', 'e', ':', '/', '/'
@@ -7287,17 +7406,14 @@
 +            if (c != aPrefix[i])
 +                return false;
 +        }
-+        else if (c == '\'')
-+        {
-+            if (!bInUrl)
-+                return false;
-+            bInUrl = false;
-+            rUrl = aUrlBuf.makeStringAndClear();
-+        }
 +        else if (c == '#')
 +        {
 +            if (cPrev != '\'')
 +                return false;
++
++            rUrl = aUrlBuf.makeStringAndClear();
++            rUrl = rUrl.copy(0, rUrl.getLength()-1); // remove the trailing single-quote.
++            bInUrl = false;
 +        }
 +        else if (bInUrl)
 +            aUrlBuf.append(c);
@@ -7326,7 +7442,7 @@
  //------------------------------------------------------------------
  
  ScXMLTableContext::ScXMLTableContext( ScXMLImport& rImport,
-@@ -73,6 +147,7 @@ ScXMLTableContext::ScXMLTableContext( ScXMLImport& rImport,
+@@ -73,6 +146,7 @@ ScXMLTableContext::ScXMLTableContext( ScXMLImport& rImport,
  									  const sal_Bool bTempIsSubTable,
  									  const sal_Int32 nSpannedCols) :
  	SvXMLImportContext( rImport, nPrfx, rLName ),
@@ -7334,7 +7450,7 @@
  	bStartFormPage(sal_False),
      bPrintEntireSheet(sal_True)
  {
-@@ -117,7 +192,26 @@ ScXMLTableContext::ScXMLTableContext( ScXMLImport& rImport,
+@@ -117,7 +191,26 @@ ScXMLTableContext::ScXMLTableContext( ScXMLImport& rImport,
                      break;
  			}
  		}
@@ -7362,7 +7478,7 @@
  	}
  	else
  	{
-@@ -134,10 +228,30 @@ SvXMLImportContext *ScXMLTableContext::CreateChildContext( USHORT nPrefix,
+@@ -134,10 +227,30 @@ SvXMLImportContext *ScXMLTableContext::CreateChildContext( USHORT nPrefix,
  											const ::com::sun::star::uno::Reference<
  									  	::com::sun::star::xml::sax::XAttributeList>& xAttrList )
  {
@@ -7395,7 +7511,7 @@
  	{
  	case XML_TOK_TABLE_COL_GROUP:
  		pContext = new ScXMLTableColsContext( GetScImport(), nPrefix,
-@@ -195,6 +309,8 @@ SvXMLImportContext *ScXMLTableContext::CreateChildContext( USHORT nPrefix,
+@@ -195,6 +308,8 @@ SvXMLImportContext *ScXMLTableContext::CreateChildContext( USHORT nPrefix,
  			pContext = GetScImport().GetFormImport()->createOfficeFormsContext( GetScImport(), nPrefix, rLName );
  		}
  		break;
@@ -7471,10 +7587,10 @@
  
 diff --git sc/source/ui/docshell/externalrefmgr.cxx sc/source/ui/docshell/externalrefmgr.cxx
 new file mode 100644
-index 0000000..5648cf1
+index 0000000..25266aa
 --- /dev/null
 +++ sc/source/ui/docshell/externalrefmgr.cxx
-@@ -0,0 +1,1267 @@
+@@ -0,0 +1,1328 @@
 +/*************************************************************************
 + *
 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -7536,7 +7652,9 @@
 +#include "svtools/smplhint.hxx"
 +#include "svtools/itemset.hxx"
 +#include "svtools/stritem.hxx"
++#include "svtools/urihelper.hxx"
 +#include "svx/linkmgr.hxx"
++#include "tools/urlobj.hxx"
 +#include "unotools/ucbhelper.hxx"
 +
 +#include <memory>
@@ -7544,6 +7662,7 @@
 +
 +using ::std::auto_ptr;
 +using ::com::sun::star::uno::Any;
++using ::rtl::OUString;
 +using ::std::vector;
 +using ::std::find;
 +using ::std::distance;
@@ -8423,7 +8542,7 @@
 +
 +    String aFilter;
 +    SrcShell aSrcDoc;
-+    aSrcDoc.maShell = loadSrcDocument(nFileId, *pFile, aFilter);
++    aSrcDoc.maShell = loadSrcDocument(nFileId, aFilter);
 +    if (!aSrcDoc.maShell.Is())
 +    {
 +        // source document could not be loaded.
@@ -8457,21 +8576,47 @@
 +    return pSrcDoc;
 +}
 +
-+SfxObjectShellRef ScExternalRefManager::loadSrcDocument(sal_uInt16 nFileId, const String& rFile, String& rFilter)
++SfxObjectShellRef ScExternalRefManager::loadSrcDocument(sal_uInt16 nFileId, String& rFilter)
 +{
-+    // First, make sure the file actually exists at the specified URL.
-+    if (!utl::UCBContentHelper::Exists(rFile) || utl::UCBContentHelper::IsFolder(rFile))
-+        // Either the specified file doesn't exist, or it's a folder.
++    const SrcFileData* pFileData = getExternalFileData(nFileId);
++    if (!pFileData)
 +        return NULL;
 +
-+    if (isOwnDocument(rFile))
-+        // Don't load itself.  That would be asking for trouble.
-+        return NULL;
++    String aFile = pFileData->maFileName;
++    if (!isFileLoadable(aFile))
++    {
++        // The original file path is not loadable.  Try the relative path.  
++        // Note that the path is relative to the content.xml substream which
++        // is one-level higher than the file itself.
++
++        if (!pFileData->maRelativeName.Len())
++            return NULL;
++
++        INetURLObject aBaseURL(getOwnDocumentName());
++        aBaseURL.insertName(OUString::createFromAscii("content.xml"));
++        bool bWasAbs = false;
++        aFile = aBaseURL.smartRel2Abs(pFileData->maRelativeName, bWasAbs).GetMainURL(INetURLObject::NO_DECODE);
++        if (!isFileLoadable(aFile))
++            // Ok, I've tried both paths but no success.  Bail out.
++            return NULL;
++    }
 +
 +    String aOptions;
-+    ScDocumentLoader::GetFilterName(rFile, rFilter, aOptions, true, false);
++    ScDocumentLoader::GetFilterName(aFile, rFilter, aOptions, true, false);
 +    const SfxFilter* pFilter = ScDocShell::Factory().GetFilterContainer()->GetFilter4FilterName(rFilter);
 +
++    if (!pFileData->maRelativeName.Len())
++    {
++        // Generate a relative file path.
++        INetURLObject aBaseURL(getOwnDocumentName());
++        aBaseURL.insertName(OUString::createFromAscii("content.xml"));
++
++        String aStr = URIHelper::simpleNormalizedMakeRelative(
++            aBaseURL.GetMainURL(INetURLObject::NO_DECODE), aFile);
++
++        setRelativeFileName(nFileId, aStr);
++    }
++
 +    // Update the filter data now that we are loading it again.
 +    setFilterData(nFileId, rFilter, aOptions);
 +
@@ -8479,7 +8624,7 @@
 +    if (aOptions.Len())
 +        pSet->Put(SfxStringItem(SID_FILE_FILTEROPTIONS, aOptions));
 +
-+    auto_ptr<SfxMedium> pMedium(new SfxMedium(rFile, STREAM_STD_READ, false, pFilter, pSet));
++    auto_ptr<SfxMedium> pMedium(new SfxMedium(aFile, STREAM_STD_READ, false, pFilter, pSet));
 +    if (pMedium->GetError() != ERRCODE_NONE)
 +        return NULL;
 +
@@ -8504,6 +8649,17 @@
 +    return aRef;
 +}
 +
++bool ScExternalRefManager::isFileLoadable(const String& rFile) const
++{
++    if (isOwnDocument(rFile))
++        return false;
++
++    if (utl::UCBContentHelper::IsFolder(rFile))
++        return false;
++
++    return utl::UCBContentHelper::Exists(rFile);
++}
++
 +void ScExternalRefManager::maybeLinkExternalFile(sal_uInt16 nFileId)
 +{
 +    if (maLinkedDocs.count(nFileId))
@@ -8568,18 +8724,23 @@
 +    return true;
 +}
 +
-+bool ScExternalRefManager::isOwnDocument(const String& rFile) const
++const String& ScExternalRefManager::getOwnDocumentName() const
 +{
 +    SfxObjectShell* pShell = mpDoc->GetDocumentShell();
 +    if (!pShell)
 +        // This should not happen!
-+        return true;
++        return EMPTY_STRING;
 +
 +    SfxMedium* pMed = pShell->GetMedium();
 +    if (!pMed)
-+        return false;
++        return EMPTY_STRING;
 +
-+    return pMed->GetName().Equals(rFile);
++    return pMed->GetName();
++}
++
++bool ScExternalRefManager::isOwnDocument(const String& rFile) const
++{
++    return getOwnDocumentName().Equals(rFile);
 +}
 +
 +void ScExternalRefManager::convertToAbsName(String& rFile) const
@@ -8717,6 +8878,22 @@
 +    return !maSrcFiles.empty();
 +}
 +
++void ScExternalRefManager::resetSrcFileData()
++{
++    INetURLObject aBaseURL(getOwnDocumentName());
++    aBaseURL.insertName(OUString::createFromAscii("content.xml"));
++    String aBaseUrlStr = aBaseURL.GetMainURL(INetURLObject::NO_DECODE);
++    for (vector<SrcFileData>::iterator itr = maSrcFiles.begin(), itrEnd = maSrcFiles.end();
++          itr != itrEnd; ++itr)
++    {
++        if (!itr->maRelativeName.Len())
++        {
++            itr->maRelativeName = URIHelper::simpleNormalizedMakeRelative(
++                aBaseUrlStr, itr->maFileName);
++        }
++    }
++}
++
 +void ScExternalRefManager::purgeStaleSrcDocument(sal_Int32 nTimeOut)
 +{
 +    DocShellMap aNewDocShells;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]