ooo-build r15230 - in branches/ooo-build-3-0-1: . patches/dev300



Author: kyoshida
Date: Wed Jan 28 22:34:15 2009
New Revision: 15230
URL: http://svn.gnome.org/viewvc/ooo-build?rev=15230&view=rev

Log:
2009-01-28  Kohei Yoshida  <kyoshida novell com>

	* patches/dev300/calc-external-defined-names-empty-cells.diff: put the 
	right fix to deal with out-of-bound external references on a cached
	sheet.


Modified:
   branches/ooo-build-3-0-1/ChangeLog
   branches/ooo-build-3-0-1/patches/dev300/calc-external-defined-names-empty-cells.diff

Modified: branches/ooo-build-3-0-1/patches/dev300/calc-external-defined-names-empty-cells.diff
==============================================================================
--- branches/ooo-build-3-0-1/patches/dev300/calc-external-defined-names-empty-cells.diff	(original)
+++ branches/ooo-build-3-0-1/patches/dev300/calc-external-defined-names-empty-cells.diff	Wed Jan 28 22:34:15 2009
@@ -1,24 +1,288 @@
+diff --git sc/inc/externalrefmgr.hxx sc/inc/externalrefmgr.hxx
+index fa2bd9e..e16d192 100644
+--- sc/inc/externalrefmgr.hxx
++++ sc/inc/externalrefmgr.hxx
+@@ -72,7 +72,7 @@ private:
+     ScExternalRefLink(); // disabled
+     ScExternalRefLink(const ScExternalRefLink&); // disabled
+ 
+-    DECL_LINK(EndEditHdl, void*);
++    DECL_LINK( ExternalRefEndEditHdl, ::sfx2::SvBaseLink* );
+ 
+     sal_uInt16  mnFileId;
+     String      maFilterName;
+@@ -149,16 +149,14 @@ public:
+      *
+      * @param nFileId file ID of an external document
+      * @param rTabName sheet name
+-     * @param nRow
+      * @param nCol
++     * @param nRow
+      *
+-     * @return pointer to the token instance in the cache.  <i>The caller does
+-     *         not need to delete this instance since its life cycle is
+-     *         managed by this class.</i>
++     * @return pointer to the token instance in the cache. 
+      */
+     ScExternalRefCache::TokenRef getCellData(
+-        sal_uInt16 nFileId, const String& rTabName, SCROW nRow, SCCOL nCol, 
+-        sal_uInt32* pnFmtIndex = NULL);
++        sal_uInt16 nFileId, const String& rTabName, SCCOL nCol, SCROW nRow,
++        bool bEmptyCellOnNull, sal_uInt32* pnFmtIndex = NULL);
+ 
+     /**
+      * Get a cached cell range data.
+@@ -167,7 +165,8 @@ public:
+      *         manage the life cycle of the returned instance</i>, which is
+      *         guaranteed if the TokenArrayRef is properly used..
+      */
+-    ScExternalRefCache::TokenArrayRef getCellRangeData(sal_uInt16 nFileId, const String& rTabName, const ScRange& rRange);
++    ScExternalRefCache::TokenArrayRef getCellRangeData(
++        sal_uInt16 nFileId, const String& rTabName, const ScRange& rRange, bool bEmptyCellOnNull);
+ 
+     ScExternalRefCache::TokenArrayRef getRangeNameTokens(sal_uInt16 nFileId, const String& rName);
+     void setRangeNameTokens(sal_uInt16 nFileId, const String& rName, TokenArrayRef pArray);
+@@ -294,7 +293,7 @@ private:
+     };
+ 
+     typedef ::std::hash_map<sal_uInt16, SrcShell>           DocShellMap;
+-    typedef ::std::hash_set<sal_uInt16>                     LinkedDocSet;
++    typedef ::std::hash_map<sal_uInt16, bool>               LinkedDocMap;
+ 
+     typedef ::std::hash_map<sal_uInt16, RefCells>           RefCellMap;
+     typedef ::std::hash_map<sal_uInt16, SvNumberFormatterMergeMap> NumFmtMap;
+@@ -338,7 +337,12 @@ public:
+      * XCT/CRN records.
+      *
+      * @param nFileId file ID
+-     * @param rTabName table name
++     * @param rTabName table name 
++     * @param bCreateNew if true, create a new table instance if it's not 
++     *                   already present.  If false, it returns NULL if the
++     *                   specified table's cache doesn't exist.
++     * @param pnIndex if non-NULL pointer is passed, it stores the internal 
++     *                index of a cache table instance.
+      *
+      * @return shared_ptr to the cache table instance
+      */
+@@ -410,6 +414,7 @@ public:
+     const String* getRealTableName(sal_uInt16 nFileId, const String& rTabName) const;
+     const String* getRealRangeName(sal_uInt16 nFileId, const String& rRangeName) const;
+     void refreshNames(sal_uInt16 nFileId);
++    void breakLink(sal_uInt16 nFileId);
+     void switchSrcFile(sal_uInt16 nFileId, const String& rNewFile);
+ 
+     void setRelativeFileName(sal_uInt16 nFileId, const String& rRelUrl);
+@@ -424,7 +429,6 @@ public:
+      */
+     void setFilterData(sal_uInt16 nFileId, const String& rFilterName, const String& rOptions);
+ 
+-    void removeSrcDocument(sal_uInt16 nFileId, bool bBreakLink);
+     void clear();
+ 
+     bool hasExternalData() const;
+@@ -503,7 +507,7 @@ private:
+     DocShellMap maDocShells;
+ 
+     /** list of source documents that are managed by the link manager. */
+-    LinkedDocSet maLinkedDocs;
++    LinkedDocMap maLinkedDocs;
+ 
+     /**
+      * List of referencing cells that may contain external names.  There is
 diff --git sc/source/ui/docshell/externalrefmgr.cxx sc/source/ui/docshell/externalrefmgr.cxx
-index ae5015d..d3f770b 100644
+index 9dcb2cc..bb39ff5 100644
 --- sc/source/ui/docshell/externalrefmgr.cxx
 +++ sc/source/ui/docshell/externalrefmgr.cxx
-@@ -161,7 +161,8 @@ ScExternalRefCache::TokenRef ScExternalRefCache::Table::getCell(SCCOL nCol, SCRO
-     if (itrTable == maRows.end())
-     {
-         // this table doesn't have the specified row.
--        return TokenRef();
-+        TokenRef p(new ScEmptyCellToken(false, false));
-+        return p;
+@@ -290,7 +290,8 @@ const String* ScExternalRefCache::getRealRangeName(sal_uInt16 nFileId, const Str
+ }
+ 
+ ScExternalRefCache::TokenRef ScExternalRefCache::getCellData(
+-    sal_uInt16 nFileId, const String& rTabName, SCROW nRow, SCCOL nCol, sal_uInt32* pnFmtIndex)
++    sal_uInt16 nFileId, const String& rTabName, SCCOL nCol, SCROW nRow, 
++    bool bEmptyCellOnNull, sal_uInt32* pnFmtIndex)
+ {
+     DocDataType::const_iterator itrDoc = maDocs.find(nFileId);
+     if (itrDoc == maDocs.end())
+@@ -314,10 +315,15 @@ ScExternalRefCache::TokenRef ScExternalRefCache::getCellData(
+         // the table data is not instantiated yet.
+         return TokenRef();
      }
+-    return pTableData->getCell(nCol, nRow, pnFmtIndex);
++
++    TokenRef pToken = pTableData->getCell(nCol, nRow, pnFmtIndex);
++    if (!pToken && bEmptyCellOnNull)
++        pToken.reset(new ScEmptyCellToken(false, false));
++    return pToken;
+ }
+ 
+-ScExternalRefCache::TokenArrayRef ScExternalRefCache::getCellRangeData(sal_uInt16 nFileId, const String& rTabName, const ScRange& rRange)
++ScExternalRefCache::TokenArrayRef ScExternalRefCache::getCellRangeData(
++    sal_uInt16 nFileId, const String& rTabName, const ScRange& rRange, bool bEmptyCellOnNull)
+ {
+     DocDataType::iterator itrDoc = maDocs.find(nFileId);
+     if (itrDoc == maDocs.end())
+@@ -366,9 +372,14 @@ ScExternalRefCache::TokenArrayRef ScExternalRefCache::getCellRangeData(sal_uInt1
+         {
+             for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
+             {
+-                ScToken* pToken = pTab->getCell(nCol, nRow).get();
++                TokenRef pToken = pTab->getCell(nCol, nRow);
+                 if (!pToken)
+-                    return TokenArrayRef();
++                {
++                    if (bEmptyCellOnNull)
++                        pToken.reset(new ScEmptyCellToken(false, false));
++                    else
++                        return TokenArrayRef();
++                }
+ 
+                 SCSIZE nC = nCol - nCol1, nR = nRow - nRow1;
+                 switch (pToken->GetType())
+@@ -724,7 +735,7 @@ ScExternalRefLink::~ScExternalRefLink()
+ void ScExternalRefLink::Closed()
+ {
+     ScExternalRefManager* pMgr = mpDoc->GetExternalRefManager();
+-    pMgr->removeSrcDocument(mnFileId, true);
++    pMgr->breakLink(mnFileId);
+ }
+ 
+ void ScExternalRefLink::DataChanged(const String& /*rMimeType*/, const Any& /*rValue*/)
+@@ -754,7 +765,7 @@ void ScExternalRefLink::DataChanged(const String& /*rMimeType*/, const Any& /*rV
  
-     const RowDataType& rRowData = itrTable->second;
-@@ -169,7 +170,8 @@ ScExternalRefCache::TokenRef ScExternalRefCache::Table::getCell(SCCOL nCol, SCRO
-     if (itrRow == rRowData.end())
+ void ScExternalRefLink::Edit(Window* pParent, const Link& /*rEndEditHdl*/)
+ {
+-    SvBaseLink::Edit(pParent, LINK(this, ScExternalRefLink, EndEditHdl));
++    SvBaseLink::Edit(pParent, LINK(this, ScExternalRefLink, ExternalRefEndEditHdl));
+ }
+ 
+ void ScExternalRefLink::SetDoReferesh(bool b)
+@@ -762,7 +773,7 @@ void ScExternalRefLink::SetDoReferesh(bool b)
+     mbDoRefresh = b;
+ }
+ 
+-IMPL_LINK(ScExternalRefLink, EndEditHdl, void*, EMPTYARG)
++IMPL_LINK( ScExternalRefLink, ExternalRefEndEditHdl, ::sfx2::SvBaseLink*, EMPTYARG )
+ {
+     return 0;
+ }
+@@ -1226,7 +1237,7 @@ ScExternalRefCache::TokenRef ScExternalRefManager::getSingleRefToken(
+     // Check if the given table name and the cell position is cached.
+     sal_uInt32 nFmtIndex = 0;
+     ScExternalRefCache::TokenRef pToken = maRefCache.getCellData(
+-        nFileId, rTabName, rCell.Row(), rCell.Col(), &nFmtIndex);
++        nFileId, rTabName, rCell.Col(), rCell.Row(), false, &nFmtIndex);
+     if (pToken)
      {
-         // this row doesn't have the specified column.
--        return TokenRef();
-+        TokenRef p(new ScEmptyCellToken(false, false));
-+        return p;
+         if (pFmt)
+@@ -1246,7 +1257,12 @@ ScExternalRefCache::TokenRef ScExternalRefManager::getSingleRefToken(
+     ScDocument* pSrcDoc = getSrcDocument(nFileId);
+     if (!pSrcDoc)
+     {
+-        return ScExternalRefCache::TokenRef();
++        // Source document is not reachable.  Try to get data from the cache 
++        // once again, but this time treat a non-cached cell as an empty cell
++        // as long as the table itself is cached.
++        pToken = maRefCache.getCellData(
++            nFileId, rTabName, rCell.Col(), rCell.Row(), true, &nFmtIndex);
++        return pToken;
      }
  
-     const Cell& rCell = itrRow->second;
+     ScBaseCell* pCell = NULL;
+@@ -1295,13 +1311,18 @@ ScExternalRefCache::TokenArrayRef ScExternalRefManager::getDoubleRefTokens(sal_u
+     maybeLinkExternalFile(nFileId);
+ 
+     // Check if the given table name and the cell position is cached.
+-    ScExternalRefCache::TokenArrayRef p = maRefCache.getCellRangeData(nFileId, rTabName, rRange);
++    ScExternalRefCache::TokenArrayRef p = maRefCache.getCellRangeData(nFileId, rTabName, rRange, false);
+     if (p.get())
+         return p;
+ 
+     ScDocument* pSrcDoc = getSrcDocument(nFileId);
+     if (!pSrcDoc)
+-        return ScExternalRefCache::TokenArrayRef();
++    {
++        // Source document is not reachable.  Try to get data from the cache 
++        // once again, but this time treat non-cached cells as empty cells as
++        // long as the table itself is cached.
++        return maRefCache.getCellRangeData(nFileId, rTabName, rRange, true);
++    }
+ 
+     SCTAB nTab1;
+     if (!pSrcDoc->GetTable(rTabName, nTab1))
+@@ -1431,7 +1452,7 @@ void ScExternalRefManager::refreshAllRefCells(sal_uInt16 nFileId)
+ 
+     // Repainting the grid also repaints the texts, but is there a better way
+     // to refresh texts?
+-    pVShell->Invalidate(FID_TAB_TOGGLE_GRID);
++    pVShell->Invalidate(FID_REPAINT);
+     pVShell->PaintGrid();
+ }
+ 
+@@ -1595,7 +1616,7 @@ bool ScExternalRefManager::isFileLoadable(const String& rFile) const
+ void ScExternalRefManager::maybeLinkExternalFile(sal_uInt16 nFileId)
+ {
+     if (maLinkedDocs.count(nFileId))
+-        // file alerady linked.
++        // file alerady linked, or the link has been broken.
+         return;
+ 
+     // Source document not linked yet.  Link it now.
+@@ -1614,7 +1635,7 @@ void ScExternalRefManager::maybeLinkExternalFile(sal_uInt16 nFileId)
+     pLink->Update();
+     pLink->SetDoReferesh(true);
+ 
+-    maLinkedDocs.insert(nFileId);
++    maLinkedDocs.insert(LinkedDocMap::value_type(nFileId, true));
+ }
+ 
+ bool ScExternalRefManager::compileTokensByCell(const ScAddress& rCell)
+@@ -1735,12 +1756,28 @@ static void lcl_removeByFileId(sal_uInt16 nFileId, MapContainer& rMap)
+ 
+ void ScExternalRefManager::refreshNames(sal_uInt16 nFileId)
+ {
+-    removeSrcDocument(nFileId, false);
++    maRefCache.clearCache(nFileId);
++    lcl_removeByFileId(nFileId, maDocShells);
++
++    if (maDocShells.empty())
++        maSrcDocTimer.Stop();
+ 
+     // Update all cells containing names from this source document.
+     refreshAllRefCells(nFileId);
+ }
+ 
++void ScExternalRefManager::breakLink(sal_uInt16 nFileId)
++{
++    lcl_removeByFileId(nFileId, maDocShells);
++
++    if (maDocShells.empty())
++        maSrcDocTimer.Stop();
++
++    LinkedDocMap::iterator itr = maLinkedDocs.find(nFileId);
++    if (itr != maLinkedDocs.end())
++        itr->second = false;
++}
++
+ void ScExternalRefManager::switchSrcFile(sal_uInt16 nFileId, const String& rNewFile)
+ {
+     maSrcFiles[nFileId].maFileName = rNewFile;
+@@ -1763,18 +1800,6 @@ void ScExternalRefManager::setFilterData(sal_uInt16 nFileId, const String& rFilt
+     maSrcFiles[nFileId].maFilterOptions = rOptions;
+ }
+ 
+-void ScExternalRefManager::removeSrcDocument(sal_uInt16 nFileId, bool bBreakLink)
+-{
+-    maRefCache.clearCache(nFileId);
+-    lcl_removeByFileId(nFileId, maDocShells);
+-
+-    if (bBreakLink)
+-        maLinkedDocs.erase(nFileId);
+-
+-    if (maDocShells.empty())
+-        maSrcDocTimer.Stop();
+-}
+-
+ void ScExternalRefManager::clear()
+ {
+     DocShellMap::iterator itrEnd = maDocShells.end();



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