summaryrefslogtreecommitdiff
path: root/sc/source
diff options
context:
space:
mode:
Diffstat (limited to 'sc/source')
-rw-r--r--sc/source/core/data/conditio.cxx18
-rw-r--r--sc/source/core/data/documen2.cxx47
-rw-r--r--sc/source/core/data/documen4.cxx85
-rw-r--r--sc/source/core/data/document.cxx9
-rw-r--r--sc/source/core/data/dpobject.cxx5
-rw-r--r--sc/source/core/data/table1.cxx8
-rw-r--r--sc/source/core/data/table2.cxx46
-rw-r--r--sc/source/core/data/table4.cxx6
-rw-r--r--sc/source/core/inc/interpre.hxx1
-rw-r--r--sc/source/core/tool/interpr1.cxx76
-rw-r--r--sc/source/core/tool/interpr4.cxx79
-rw-r--r--sc/source/core/tool/rangenam.cxx17
-rw-r--r--sc/source/ui/app/inputwin.cxx15
-rw-r--r--sc/source/ui/dbgui/pvlaydlg.cxx13
-rw-r--r--sc/source/ui/docshell/dbdocfun.cxx19
-rw-r--r--sc/source/ui/docshell/docfunc.cxx9
-rw-r--r--sc/source/ui/docshell/externalrefmgr.cxx76
-rw-r--r--sc/source/ui/inc/dbdocfun.hxx2
-rw-r--r--sc/source/ui/inc/undoblk.hxx4
-rw-r--r--sc/source/ui/undo/undoblk3.cxx50
-rw-r--r--sc/source/ui/unoobj/datauno.cxx117
-rw-r--r--sc/source/ui/unoobj/docuno.cxx5
-rw-r--r--sc/source/ui/vba/excelvbahelper.cxx43
-rw-r--r--sc/source/ui/vba/excelvbahelper.hxx4
-rw-r--r--sc/source/ui/vba/vbarange.cxx29
-rw-r--r--sc/source/ui/view/viewfunc.cxx9
26 files changed, 505 insertions, 287 deletions
diff --git a/sc/source/core/data/conditio.cxx b/sc/source/core/data/conditio.cxx
index 40390816128b..2668893ed4d3 100644
--- a/sc/source/core/data/conditio.cxx
+++ b/sc/source/core/data/conditio.cxx
@@ -1270,7 +1270,8 @@ ScConditionalFormat::ScConditionalFormat(const ScConditionalFormat& r) :
pAreas( NULL ),
nKey( r.nKey ),
ppEntries( NULL ),
- nEntryCount( r.nEntryCount )
+ nEntryCount( r.nEntryCount ),
+ pRanges( NULL )
{
if (nEntryCount)
{
@@ -1281,7 +1282,8 @@ ScConditionalFormat::ScConditionalFormat(const ScConditionalFormat& r) :
ppEntries[i]->SetParent(this);
}
}
- pRanges = new ScRangeList( *r.pRanges );
+ if (r.pRanges)
+ pRanges = new ScRangeList( *r.pRanges );
}
ScConditionalFormat* ScConditionalFormat::Clone(ScDocument* pNewDoc) const
@@ -1320,10 +1322,16 @@ sal_Bool ScConditionalFormat::EqualEntries( const ScConditionalFormat& r ) const
if ( ! (*ppEntries[i] == *r.ppEntries[i]) )
return false;
- if( *pRanges != *r.pRanges )
- return false;
+ if (pRanges)
+ {
+ if (r.pRanges)
+ return *pRanges == *r.pRanges;
+ else
+ return false;
+ }
- return true;
+ // pRanges is NULL, which means r.pRanges must be NULL.
+ return r.pRanges.Is() == false;
}
void ScConditionalFormat::AddRangeInfo( const ScRangeListRef& rRanges )
diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx
index 2188a458a855..756990e681bc 100644
--- a/sc/source/core/data/documen2.cxx
+++ b/sc/source/core/data/documen2.cxx
@@ -1130,53 +1130,6 @@ void ScDocument::SetError( SCCOL nCol, SCROW nRow, SCTAB nTab, const sal_uInt16
pTab[nTab]->SetError( nCol, nRow, nError );
}
-namespace {
-
-bool eraseUnusedSharedName(ScRangeName* pRangeName, ScTable* pTab[], sal_uInt16 nLevel)
-{
- if (!pRangeName)
- return false;
-
- ScRangeName::iterator itr = pRangeName->begin(), itrEnd = pRangeName->end();
- for (; itr != itrEnd; ++itr)
- {
- if (!itr->HasType(RT_SHARED))
- continue;
-
- String aName;
- itr->GetName(aName);
- aName.Erase(0, 6); // !!! vgl. Table4, FillFormula !!
- sal_uInt16 nInd = static_cast<sal_uInt16>(aName.ToInt32());
- if (nInd > nLevel)
- continue;
-
- sal_uInt16 nIndex = itr->GetIndex();
-
- bool bInUse = false;
- for (SCTAB j = 0; !bInUse && (j <= MAXTAB); ++j)
- {
- if (pTab[j])
- bInUse = pTab[j]->IsRangeNameInUse(0, 0, MAXCOL-1, MAXROW-1, nIndex);
- }
- if (!bInUse)
- {
- pRangeName->erase(itr);
- return true;
- }
- }
- return false;
-}
-
-}
-
-void ScDocument::EraseNonUsedSharedNames(sal_uInt16 nLevel)
-{
- if (!pRangeName)
- return;
- while (eraseUnusedSharedName(pRangeName, pTab, nLevel))
- ;
-}
-
// ----------------------------------------------------------------------------
void ScDocument::SetConsolidateDlgData( const ScConsolidateParam* pData )
diff --git a/sc/source/core/data/documen4.cxx b/sc/source/core/data/documen4.cxx
index 1958bf721a4c..b9c79e1c9ebf 100644
--- a/sc/source/core/data/documen4.cxx
+++ b/sc/source/core/data/documen4.cxx
@@ -296,42 +296,71 @@ void ScDocument::InsertTableOp(const ScTabOpParam& rParam, // Mehrfachopera
pTab[i]->PutCell( j, k, aRefCell.CloneWithoutNote( *this, ScAddress( j, k, i ), SC_CLONECELL_STARTLISTENING ) );
}
+namespace {
+
+bool setCacheTableReferenced(ScToken& rToken, ScExternalRefManager& rRefMgr)
+{
+ switch (rToken.GetType())
+ {
+ case svExternalSingleRef:
+ return rRefMgr.setCacheTableReferenced(
+ rToken.GetIndex(), rToken.GetString(), 1);
+ case svExternalDoubleRef:
+ {
+ const ScComplexRefData& rRef = rToken.GetDoubleRef();
+ size_t nSheets = rRef.Ref2.nTab - rRef.Ref1.nTab + 1;
+ return rRefMgr.setCacheTableReferenced(
+ rToken.GetIndex(), rToken.GetString(), nSheets);
+ }
+ case svExternalName:
+ /* TODO: external names aren't supported yet, but would
+ * have to be marked as well, if so. Mechanism would be
+ * different. */
+ DBG_ERRORFILE("ScDocument::MarkUsedExternalReferences: implement the svExternalName case!");
+ default:
+ ;
+ }
+ return false;
+}
+
+}
+
bool ScDocument::MarkUsedExternalReferences( ScTokenArray & rArr )
{
+ if (!rArr.GetLen())
+ return false;
+
+ ScExternalRefManager* pRefMgr = NULL;
+ rArr.Reset();
+ ScToken* t = NULL;
bool bAllMarked = false;
- if (rArr.GetLen())
+ while (!bAllMarked && (t = static_cast<ScToken*>(rArr.GetNextReferenceOrName())) != NULL)
{
- ScExternalRefManager* pRefMgr = NULL;
- rArr.Reset();
- ScToken* t;
- while (!bAllMarked && (t = static_cast<ScToken*>(rArr.GetNextReferenceOrName())) != NULL)
+ if (t->IsExternalRef())
+ {
+ if (!pRefMgr)
+ pRefMgr = GetExternalRefManager();
+
+ bAllMarked = setCacheTableReferenced(*t, *pRefMgr);
+ }
+ else if (t->GetType() == svIndex)
{
- if (t->IsExternalRef())
+ // this is a named range. Check if the range contains an external
+ // reference.
+ ScRangeData* pRangeData = GetRangeName()->findByIndex(t->GetIndex());
+ if (!pRangeData)
+ continue;
+
+ ScTokenArray* pArray = pRangeData->GetCode();
+ for (t = static_cast<ScToken*>(pArray->First()); t; t = static_cast<ScToken*>(pArray->Next()))
{
+ if (!t->IsExternalRef())
+ continue;
+
if (!pRefMgr)
pRefMgr = GetExternalRefManager();
- switch (t->GetType())
- {
- case svExternalSingleRef:
- bAllMarked = pRefMgr->setCacheTableReferenced(
- t->GetIndex(), t->GetString(), 1);
- break;
- case svExternalDoubleRef:
- {
- const ScComplexRefData& rRef = t->GetDoubleRef();
- size_t nSheets = rRef.Ref2.nTab - rRef.Ref1.nTab + 1;
- bAllMarked = pRefMgr->setCacheTableReferenced(
- t->GetIndex(), t->GetString(), nSheets);
- }
- break;
- case svExternalName:
- /* TODO: external names aren't supported yet, but would
- * have to be marked as well, if so. Mechanism would be
- * different. */
- DBG_ERRORFILE("ScDocument::MarkUsedExternalReferences: implement the svExternalName case!");
- break;
- default: break;
- }
+
+ bAllMarked = setCacheTableReferenced(*t, *pRefMgr);
}
}
}
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 8d236383dac2..b8f026503dc4 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -5422,7 +5422,14 @@ void ScDocument::SetSubTotalCellsDirty(const ScRange& rDirtyRange)
void ScDocument::EnableUndo( bool bVal )
{
- GetUndoManager()->EnableUndo(bVal);
+ // The undo manager increases lock count every time undo is disabled.
+ // Because of this, we shouldn't disable undo unless it's currently
+ // enabled, or else re-enabling it may not actually re-enable undo unless
+ // the lock count becomes zero.
+
+ if (bVal != GetUndoManager()->IsUndoEnabled())
+ GetUndoManager()->EnableUndo(bVal);
+
mbUndoEnabled = bVal;
}
diff --git a/sc/source/core/data/dpobject.cxx b/sc/source/core/data/dpobject.cxx
index 9589fe838f7a..7f5abef802ea 100644
--- a/sc/source/core/data/dpobject.cxx
+++ b/sc/source/core/data/dpobject.cxx
@@ -2445,6 +2445,11 @@ void ScDPCollection::NameCaches::removeCache(const OUString& rName)
ScDPCollection::DBType::DBType(sal_Int32 nSdbType, const OUString& rDBName, const OUString& rCommand) :
mnSdbType(nSdbType), maDBName(rDBName), maCommand(rCommand) {}
+bool ScDPCollection::DBType::less::operator() (const DBType& left, const DBType& right) const
+{
+ return left < right;
+}
+
ScDPCollection::DBCaches::DBCaches(ScDocument* pDoc) : mpDoc(pDoc) {}
const ScDPCache* ScDPCollection::DBCaches::getCache(sal_Int32 nSdbType, const OUString& rDBName, const OUString& rCommand)
diff --git a/sc/source/core/data/table1.cxx b/sc/source/core/data/table1.cxx
index d4c194676471..554a22773dd6 100644
--- a/sc/source/core/data/table1.cxx
+++ b/sc/source/core/data/table1.cxx
@@ -1696,6 +1696,8 @@ void ScTable::SetRepeatColRange( const ScRange* pNew )
if (IsStreamValid())
SetStreamValid(false);
+
+ InvalidatePageBreaks();
}
void ScTable::SetRepeatRowRange( const ScRange* pNew )
@@ -1704,6 +1706,8 @@ void ScTable::SetRepeatRowRange( const ScRange* pNew )
if (IsStreamValid())
SetStreamValid(false);
+
+ InvalidatePageBreaks();
}
void ScTable::ClearPrintRanges()
@@ -1713,6 +1717,8 @@ void ScTable::ClearPrintRanges()
if (IsStreamValid())
SetStreamValid(false);
+
+ InvalidatePageBreaks();
}
void ScTable::AddPrintRange( const ScRange& rNew )
@@ -1723,6 +1729,8 @@ void ScTable::AddPrintRange( const ScRange& rNew )
if (IsStreamValid())
SetStreamValid(false);
+
+ InvalidatePageBreaks();
}
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index 646be060b6a9..c5e2c7644085 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -157,18 +157,17 @@ void ScTable::InsertRow( SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCSIZE
if (!maRowManualBreaks.empty())
{
- std::set<SCROW>::reverse_iterator rit = maRowManualBreaks.rbegin();
- while (rit != maRowManualBreaks.rend())
- {
- SCROW nRow = *rit;
- if (nRow < nStartRow)
- break; // while
- else
- {
- maRowManualBreaks.erase( (++rit).base());
- maRowManualBreaks.insert( static_cast<SCROW>( nRow + nSize));
- }
- }
+ // Copy all breaks up to nStartRow (non-inclusive).
+ ::std::set<SCROW>::iterator itr1 = maRowManualBreaks.lower_bound(nStartRow);
+ ::std::set<SCROW> aNewBreaks(maRowManualBreaks.begin(), itr1);
+
+ // Copy all breaks from nStartRow (inclusive) to the last element,
+ // but add nSize to each value.
+ ::std::set<SCROW>::iterator itr2 = maRowManualBreaks.end();
+ for (; itr1 != itr2; ++itr1)
+ aNewBreaks.insert(static_cast<SCROW>(*itr1 + nSize));
+
+ maRowManualBreaks.swap(aNewBreaks);
}
}
@@ -208,14 +207,21 @@ void ScTable::DeleteRow( SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCSIZE
if (!maRowManualBreaks.empty())
{
- std::set<SCROW>::iterator it = maRowManualBreaks.upper_bound( static_cast<SCROW>( nStartRow + nSize - 1));
- maRowManualBreaks.erase( maRowManualBreaks.lower_bound( nStartRow), it);
- while (it != maRowManualBreaks.end())
- {
- SCROW nRow = *it;
- maRowManualBreaks.erase( it++);
- maRowManualBreaks.insert( static_cast<SCROW>( nRow - nSize));
- }
+ // Erase all manual breaks between nStartRow and nStartRow + nSize - 1 (inclusive).
+ std::set<SCROW>::iterator itr1 = maRowManualBreaks.lower_bound(nStartRow);
+ std::set<SCROW>::iterator itr2 = maRowManualBreaks.upper_bound(static_cast<SCROW>(nStartRow + nSize - 1));
+ maRowManualBreaks.erase(itr1, itr2);
+
+ // Copy all breaks from the 1st element up to nStartRow to the new container.
+ itr1 = maRowManualBreaks.lower_bound(nStartRow);
+ ::std::set<SCROW> aNewBreaks(maRowManualBreaks.begin(), itr1);
+
+ // Copy all breaks from nStartRow to the last element, but subtract each value by nSize.
+ itr2 = maRowManualBreaks.end();
+ for (; itr1 != itr2; ++itr1)
+ aNewBreaks.insert(static_cast<SCROW>(*itr1 - nSize));
+
+ maRowManualBreaks.swap(aNewBreaks);
}
}
diff --git a/sc/source/core/data/table4.cxx b/sc/source/core/data/table4.cxx
index 55b4da849665..edba012fadd1 100644
--- a/sc/source/core/data/table4.cxx
+++ b/sc/source/core/data/table4.cxx
@@ -1576,17 +1576,11 @@ void ScTable::Fill( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
ScProgress aProgress( pDocument->GetDocumentShell(),
ScGlobal::GetRscString(STR_FILL_SERIES_PROGRESS), nProgCount );
- bSharedNameInserted = false;
-
if (eFillCmd == FILL_AUTO)
FillAuto(nCol1, nRow1, nCol2, nRow2, nFillCount, eFillDir, aProgress);
else
FillSeries(nCol1, nRow1, nCol2, nRow2, nFillCount, eFillDir,
eFillCmd, eFillDateCmd, nStepValue, nMaxValue, 0, sal_True, aProgress);
-
- if (bSharedNameInserted) // Wurde Shared-Name eingefuegt?
- pDocument->GetRangeName()->SetSharedMaxIndex(
- pDocument->GetRangeName()->GetSharedMaxIndex()+1); // dann hochzaehlen
}
diff --git a/sc/source/core/inc/interpre.hxx b/sc/source/core/inc/interpre.hxx
index ce59c16ffa20..7caee7518f8b 100644
--- a/sc/source/core/inc/interpre.hxx
+++ b/sc/source/core/inc/interpre.hxx
@@ -316,6 +316,7 @@ void PopExternalSingleRef(ScExternalRefCache::TokenRef& rToken, ScExternalRefCac
void PopExternalDoubleRef(sal_uInt16& rFileId, String& rTabName, ScComplexRefData& rRef);
void PopExternalDoubleRef(ScExternalRefCache::TokenArrayRef& rArray);
void PopExternalDoubleRef(ScMatrixRef& rMat);
+void GetExternalDoubleRef(sal_uInt16 nFileId, const String& rTabName, const ScComplexRefData& aData, ScExternalRefCache::TokenArrayRef& rArray);
sal_Bool PopDoubleRefOrSingleRef( ScAddress& rAdr );
void PopDoubleRefPushMatrix();
// If MatrixFormula: convert formula::svDoubleRef to svMatrix, create JumpMatrix.
diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index 476eb6ef2cb0..c4a8cdd346cd 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -810,6 +810,38 @@ double ScInterpreter::Compare()
}
}
break;
+ case svExternalSingleRef:
+ {
+ ScMatrixRef pMat = GetMatrix();
+ if (!pMat)
+ {
+ SetError( errIllegalParameter);
+ break;
+ }
+
+ SCSIZE nC, nR;
+ pMat->GetDimensions(nC, nR);
+ if (!nC || !nR)
+ {
+ SetError( errIllegalParameter);
+ break;
+ }
+ if (pMat->IsEmpty(0, 0))
+ aComp.bEmpty[i] = true;
+ else if (pMat->IsString(0, 0))
+ {
+ *aComp.pVal[i] = pMat->GetString(0, 0);
+ aComp.bVal[i] = false;
+ }
+ else
+ {
+ aComp.nVal[i] = pMat->GetDouble(0, 0);
+ aComp.bVal[i] = true;
+ }
+ }
+ break;
+ case svExternalDoubleRef:
+ // TODO: Find out how to handle this...
default:
SetError( errIllegalParameter);
break;
@@ -2908,8 +2940,10 @@ void ScInterpreter::ScMin( sal_Bool bTextAsZero )
}
break;
case svMatrix :
+ case svExternalSingleRef:
+ case svExternalDoubleRef:
{
- ScMatrixRef pMat = PopMatrix();
+ ScMatrixRef pMat = GetMatrix();
if (pMat)
{
SCSIZE nC, nR;
@@ -3029,8 +3063,10 @@ void ScInterpreter::ScMax( sal_Bool bTextAsZero )
}
break;
case svMatrix :
+ case svExternalSingleRef:
+ case svExternalDoubleRef:
{
- ScMatrixRef pMat = PopMatrix();
+ ScMatrixRef pMat = GetMatrix();
if (pMat)
{
nFuncFmtType = NUMBERFORMAT_NUMBER;
@@ -4603,7 +4639,9 @@ void ScInterpreter::ScCountIf()
}
}
break;
- case svMatrix :
+ case svMatrix:
+ case svExternalSingleRef:
+ case svExternalDoubleRef:
{
ScMatValType nType = GetDoubleOrStringFromMatrix( fVal,
rString);
@@ -4648,23 +4686,25 @@ void ScInterpreter::ScCountIf()
nTab2 = nTab1;
break;
case svMatrix:
+ case svExternalSingleRef:
+ case svExternalDoubleRef:
+ {
+ pQueryMatrix = GetMatrix();
+ if (!pQueryMatrix)
{
- pQueryMatrix = PopMatrix();
- if (!pQueryMatrix)
- {
- PushIllegalParameter();
- return;
- }
- nCol1 = 0;
- nRow1 = 0;
- nTab1 = 0;
- SCSIZE nC, nR;
- pQueryMatrix->GetDimensions( nC, nR);
- nCol2 = static_cast<SCCOL>(nC - 1);
- nRow2 = static_cast<SCROW>(nR - 1);
- nTab2 = 0;
+ PushIllegalParameter();
+ return;
}
- break;
+ nCol1 = 0;
+ nRow1 = 0;
+ nTab1 = 0;
+ SCSIZE nC, nR;
+ pQueryMatrix->GetDimensions( nC, nR);
+ nCol2 = static_cast<SCCOL>(nC - 1);
+ nRow2 = static_cast<SCROW>(nR - 1);
+ nTab2 = 0;
+ }
+ break;
default:
PushIllegalParameter();
return ;
diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx
index 1c7ecdd33c78..bfe5b6b632ac 100644
--- a/sc/source/core/tool/interpr4.cxx
+++ b/sc/source/core/tool/interpr4.cxx
@@ -1519,6 +1519,28 @@ void ScInterpreter::PopExternalDoubleRef(ScExternalRefCache::TokenArrayRef& rArr
if (nGlobalError)
return;
+ GetExternalDoubleRef(nFileId, aTabName, aData, rArray);
+ if (nGlobalError)
+ return;
+}
+
+void ScInterpreter::PopExternalDoubleRef(ScMatrixRef& rMat)
+{
+ ScExternalRefCache::TokenArrayRef pArray;
+ PopExternalDoubleRef(pArray);
+ if (nGlobalError)
+ return;
+
+ // For now, we only support single range data for external
+ // references, which means the array should only contain a
+ // single matrix token.
+ ScToken* p = static_cast<ScToken*>(pArray->First());
+ rMat = p->GetMatrix();
+}
+
+void ScInterpreter::GetExternalDoubleRef(
+ sal_uInt16 nFileId, const String& rTabName, const ScComplexRefData& rData, ScExternalRefCache::TokenArrayRef& rArray)
+{
ScExternalRefManager* pRefMgr = pDok->GetExternalRefManager();
const String* pFile = pRefMgr->getExternalFileName(nFileId);
if (!pFile)
@@ -1526,18 +1548,19 @@ void ScInterpreter::PopExternalDoubleRef(ScExternalRefCache::TokenArrayRef& rArr
SetError(errNoName);
return;
}
- if (aData.Ref1.IsTabRel() || aData.Ref2.IsTabRel())
+ if (rData.Ref1.IsTabRel() || rData.Ref2.IsTabRel())
{
OSL_FAIL("ScCompiler::GetToken: external double reference must have an absolute table reference!");
SetError(errNoRef);
return;
}
+ ScComplexRefData aData(rData);
aData.CalcAbsIfRel(aPos);
ScRange aRange(aData.Ref1.nCol, aData.Ref1.nRow, aData.Ref1.nTab,
aData.Ref2.nCol, aData.Ref2.nRow, aData.Ref2.nTab);
ScExternalRefCache::TokenArrayRef pArray = pRefMgr->getDoubleRefTokens(
- nFileId, aTabName, aRange, &aPos);
+ nFileId, rTabName, aRange, &aPos);
if (!pArray)
{
@@ -1562,20 +1585,6 @@ void ScInterpreter::PopExternalDoubleRef(ScExternalRefCache::TokenArrayRef& rArr
rArray = pArray;
}
-void ScInterpreter::PopExternalDoubleRef(ScMatrixRef& rMat)
-{
- ScExternalRefCache::TokenArrayRef pArray;
- PopExternalDoubleRef(pArray);
- if (nGlobalError)
- return;
-
- // For now, we only support single range data for external
- // references, which means the array should only contain a
- // single matrix token.
- ScToken* p = static_cast<ScToken*>(pArray->First());
- rMat = p->GetMatrix();
-}
-
sal_Bool ScInterpreter::PopDoubleRefOrSingleRef( ScAddress& rAdr )
{
RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PopDoubleRefOrSingleRef" );
@@ -1643,6 +1652,7 @@ bool ScInterpreter::ConvertMatrixParameters()
case svDouble:
case svString:
case svSingleRef:
+ case svExternalSingleRef:
case svMissing:
case svError:
case svEmptyCell:
@@ -1700,6 +1710,35 @@ bool ScInterpreter::ConvertMatrixParameters()
}
}
break;
+ case svExternalDoubleRef:
+ {
+ ScParameterClassification::Type eType =
+ ScParameterClassification::GetParameterType( pCur, nParams - i);
+ if (eType == ScParameterClassification::Array)
+ {
+ sal_uInt16 nFileId = p->GetIndex();
+ const String& rTabName = p->GetString();
+ const ScComplexRefData& rRef = static_cast<ScToken*>(p)->GetDoubleRef();
+ ScExternalRefCache::TokenArrayRef pArray;
+ GetExternalDoubleRef(nFileId, rTabName, rRef, pArray);
+ if (nGlobalError)
+ break;
+
+ ScToken* pTemp = static_cast<ScToken*>(pArray->First());
+ if (!pTemp)
+ break;
+
+ ScMatrixRef pMat = pTemp->GetMatrix();
+ if (pMat)
+ {
+ ScToken* pNew = new ScMatrixToken( pMat);
+ pNew->IncRef();
+ pStack[ sp - i ] = pNew;
+ p->DecRef(); // p may be dead now!
+ }
+ }
+ }
+ break;
case svRefList:
{
ScParameterClassification::Type eType =
@@ -2350,13 +2389,9 @@ ScMatValType ScInterpreter::GetDoubleOrStringFromMatrix( double& rDouble,
ScMatrixRef pMat;
StackVar eType = GetStackType();
- if (eType == svExternalDoubleRef)
- {
- PopExternalDoubleRef(pMat);
- }
- else if (eType == svMatrix)
+ if (eType == svExternalDoubleRef || eType == svExternalSingleRef || eType == svMatrix)
{
- pMat = PopMatrix();
+ pMat = GetMatrix();
}
else
{
diff --git a/sc/source/core/tool/rangenam.cxx b/sc/source/core/tool/rangenam.cxx
index 440a9598e59e..df5f43617ae1 100644
--- a/sc/source/core/tool/rangenam.cxx
+++ b/sc/source/core/tool/rangenam.cxx
@@ -729,11 +729,10 @@ void ScRangeName::copyLocalNames(const TabNameMap& rNames, TabNameCopyMap& rCopy
}
}
-ScRangeName::ScRangeName() :
- mnSharedMaxIndex(0) {}
+ScRangeName::ScRangeName() {}
ScRangeName::ScRangeName(const ScRangeName& r) :
- maData(r.maData), mnSharedMaxIndex(r.mnSharedMaxIndex) {}
+ maData(r.maData) {}
const ScRangeData* ScRangeName::findByRange(const ScRange& rRange) const
{
@@ -806,16 +805,6 @@ void ScRangeName::UpdateGrow(const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY)
itr->UpdateGrow(rArea, nGrowX, nGrowY);
}
-sal_uInt16 ScRangeName::GetSharedMaxIndex()
-{
- return mnSharedMaxIndex;
-}
-
-void ScRangeName::SetSharedMaxIndex(sal_uInt16 nInd)
-{
- mnSharedMaxIndex = nInd;
-}
-
ScRangeName::const_iterator ScRangeName::begin() const
{
return maData.begin();
@@ -886,7 +875,7 @@ void ScRangeName::clear()
bool ScRangeName::operator== (const ScRangeName& r) const
{
- return maData == r.maData && mnSharedMaxIndex == r.mnSharedMaxIndex;
+ return maData == r.maData;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/app/inputwin.cxx b/sc/source/ui/app/inputwin.cxx
index c03799aa6ffe..8cb3d6e136e8 100644
--- a/sc/source/ui/app/inputwin.cxx
+++ b/sc/source/ui/app/inputwin.cxx
@@ -1533,7 +1533,7 @@ ScNameInputType lcl_GetInputType( const String& rText )
sal_Int32 nNumeric;
if ( aRange.Parse( rText, pDoc, eConv ) & SCA_VALID )
- eRet = SC_NAME_INPUT_NAMEDRANGE;
+ eRet = SC_NAME_INPUT_RANGE;
else if ( aAddress.Parse( rText, pDoc, eConv ) & SCA_VALID )
eRet = SC_NAME_INPUT_CELL;
else if ( aRangeUtil.MakeRangeFromName( rText, pDoc, nTab, aRange, RUTL_NAMES, eConv ) )
@@ -1697,11 +1697,14 @@ void ScPosWnd::DoEnter()
else
{
// for all selection types, excecute the SID_CURRENTCELL slot.
- // Note that SID_CURRENTCELL always expects address to be
- // in Calc A1 format. Convert the text.
- ScRange aRange;
- aRange.ParseAny(aText, pDoc, pDoc->GetAddressConvention());
- aRange.Format(aText, SCR_ABS_3D, pDoc, ::formula::FormulaGrammar::CONV_OOO);
+ if (eType == SC_NAME_INPUT_CELL || eType == SC_NAME_INPUT_RANGE)
+ {
+ // Note that SID_CURRENTCELL always expects address to
+ // be in Calc A1 format. Convert the text.
+ ScRange aRange;
+ aRange.ParseAny(aText, pDoc, pDoc->GetAddressConvention());
+ aRange.Format(aText, SCR_ABS_3D, pDoc, ::formula::FormulaGrammar::CONV_OOO);
+ }
SfxStringItem aPosItem( SID_CURRENTCELL, aText );
SfxBoolItem aUnmarkItem( FN_PARAM_1, sal_True ); // remove existing selection
diff --git a/sc/source/ui/dbgui/pvlaydlg.cxx b/sc/source/ui/dbgui/pvlaydlg.cxx
index f280af43f7e0..fa063bcf7ab8 100644
--- a/sc/source/ui/dbgui/pvlaydlg.cxx
+++ b/sc/source/ui/dbgui/pvlaydlg.cxx
@@ -1450,11 +1450,24 @@ void ScDPLayoutDlg::UpdateSrcRange()
switch (eSrcType)
{
case SRC_REF:
+ {
// data source is a range reference.
if (inSheet.GetSourceRange() == aNewRange)
// new range is identical to the current range. Nothing to do.
return;
inSheet.SetSourceRange(aNewRange);
+ sal_uLong nError = inSheet.CheckSourceRange();
+ if (nError)
+ {
+ // The error number corresponds with string ID for the error
+ // message. In the future we should display the error message
+ // somewhere in the dialog to let the user know of the reason
+ // for error.
+ aEdInPos.SetRefValid(false);
+ aBtnOk.Disable();
+ return;
+ }
+ }
break;
case SRC_NAME:
// data source is a range name.
diff --git a/sc/source/ui/docshell/dbdocfun.cxx b/sc/source/ui/docshell/dbdocfun.cxx
index 8991706293a1..8fde7e29e57a 100644
--- a/sc/source/ui/docshell/dbdocfun.cxx
+++ b/sc/source/ui/docshell/dbdocfun.cxx
@@ -255,7 +255,7 @@ sal_Bool ScDBDocFunc::ModifyDBData( const ScDBData& rNewData, sal_Bool /* bApi *
// -----------------------------------------------------------------
-sal_Bool ScDBDocFunc::RepeatDB( const String& rDBName, sal_Bool bRecord, sal_Bool bApi )
+sal_Bool ScDBDocFunc::RepeatDB( const String& rDBName, sal_Bool bRecord, sal_Bool bApi, bool bIsUnnamed, SCTAB aTab )
{
//! auch fuer ScDBFunc::RepeatDB benutzen!
@@ -263,12 +263,21 @@ sal_Bool ScDBDocFunc::RepeatDB( const String& rDBName, sal_Bool bRecord, sal_Boo
ScDocument* pDoc = rDocShell.GetDocument();
if (bRecord && !pDoc->IsUndoEnabled())
bRecord = false;
- ScDBCollection* pColl = pDoc->GetDBCollection();
- sal_uInt16 nIndex;
- if ( pColl && pColl->SearchName( rDBName, nIndex ) )
+ ScDBData* pDBData = NULL;
+ if (bIsUnnamed)
{
- ScDBData* pDBData = (*pColl)[nIndex];
+ pDBData = pDoc->GetAnonymousDBData( aTab );
+ }
+ else
+ {
+ sal_uInt16 nIndex;
+ ScDBCollection* pColl = pDoc->GetDBCollection();
+ if ( pColl && pColl->SearchName( rDBName, nIndex ) )
+ pDBData = (*pColl)[nIndex];
+ }
+ if ( pDBData )
+ {
ScQueryParam aQueryParam;
pDBData->GetQueryParam( aQueryParam );
sal_Bool bQuery = aQueryParam.GetEntry(0).bDoQuery;
diff --git a/sc/source/ui/docshell/docfunc.cxx b/sc/source/ui/docshell/docfunc.cxx
index c9d600f34d9c..62ced922b01f 100644
--- a/sc/source/ui/docshell/docfunc.cxx
+++ b/sc/source/ui/docshell/docfunc.cxx
@@ -4023,8 +4023,7 @@ sal_Bool ScDocFunc::FillSimple( const ScRange& rRange, const ScMarkData* pTabMar
{
rDocShell.GetUndoManager()->AddUndoAction(
new ScUndoAutoFill( &rDocShell, aDestArea, aSourceArea, pUndoDoc, aMark,
- eDir, FILL_SIMPLE, FILL_DAY, MAXDOUBLE, 1.0, 1e307,
- pDoc->GetRangeName()->GetSharedMaxIndex()+1 ) );
+ eDir, FILL_SIMPLE, FILL_DAY, MAXDOUBLE, 1.0, 1e307) );
}
rDocShell.PostPaintGridAll();
@@ -4143,8 +4142,7 @@ sal_Bool ScDocFunc::FillSeries( const ScRange& rRange, const ScMarkData* pTabMar
{
rDocShell.GetUndoManager()->AddUndoAction(
new ScUndoAutoFill( &rDocShell, aDestArea, aSourceArea, pUndoDoc, aMark,
- eDir, eCmd, eDateCmd, fStart, fStep, fMax,
- pDoc->GetRangeName()->GetSharedMaxIndex()+1 ) );
+ eDir, eCmd, eDateCmd, fStart, fStep, fMax) );
}
bSuccess = sal_True;
@@ -4271,8 +4269,7 @@ sal_Bool ScDocFunc::FillAuto( ScRange& rRange, const ScMarkData* pTabMark, FillD
{
rDocShell.GetUndoManager()->AddUndoAction(
new ScUndoAutoFill( &rDocShell, aDestArea, aSourceArea, pUndoDoc, aMark,
- eDir, eCmd, eDateCmd, MAXDOUBLE, fStep, fMax,
- pDoc->GetRangeName()->GetSharedMaxIndex()+1 ) );
+ eDir, eCmd, eDateCmd, MAXDOUBLE, fStep, fMax) );
}
rDocShell.PostPaintGridAll();
diff --git a/sc/source/ui/docshell/externalrefmgr.cxx b/sc/source/ui/docshell/externalrefmgr.cxx
index f9de3e8c0c48..1bfdc8b5b88f 100644
--- a/sc/source/ui/docshell/externalrefmgr.cxx
+++ b/sc/source/ui/docshell/externalrefmgr.cxx
@@ -74,6 +74,7 @@ using ::rtl::OUString;
using ::std::vector;
using ::std::find;
using ::std::find_if;
+using ::std::remove_if;
using ::std::distance;
using ::std::pair;
using ::std::list;
@@ -85,7 +86,7 @@ using namespace formula;
namespace {
-class TabNameSearchPredicate : public unary_function<bool, ScExternalRefCache::TableName>
+class TabNameSearchPredicate : public unary_function<ScExternalRefCache::TableName, bool>
{
public:
explicit TabNameSearchPredicate(const String& rSearchName) :
@@ -201,6 +202,56 @@ private:
ScDocument* mpDoc;
};
+/**
+ * Check whether a named range contains an external reference to a
+ * particular document.
+ */
+bool hasRefsToSrcDoc(ScRangeData& rData, sal_uInt16 nFileId)
+{
+ ScTokenArray* pArray = rData.GetCode();
+ if (!pArray)
+ return false;
+
+ pArray->Reset();
+ ScToken* p = static_cast<ScToken*>(pArray->GetNextReference());
+ for (; p; p = static_cast<ScToken*>(pArray->GetNextReference()))
+ {
+ if (!p->IsExternalRef())
+ continue;
+
+ if (p->GetIndex() == nFileId)
+ return true;
+ }
+ return false;
+}
+
+class EraseRangeByIterator : unary_function<ScRangeName::iterator, void>
+{
+ ScRangeName& mrRanges;
+public:
+ EraseRangeByIterator(ScRangeName& rRanges) : mrRanges(rRanges) {}
+ void operator() (const ScRangeName::iterator& itr)
+ {
+ mrRanges.erase(itr);
+ }
+};
+
+/**
+ * Remove all named ranges that contain references to specified source
+ * document.
+ */
+void removeRangeNamesBySrcDoc(ScRangeName& rRanges, sal_uInt16 nFileId)
+{
+ ScRangeName::iterator itr = rRanges.begin(), itrEnd = rRanges.end();
+ vector<ScRangeName::iterator> v;
+ for (; itr != itrEnd; ++itr)
+ {
+ if (hasRefsToSrcDoc(*itr, nFileId))
+ v.push_back(itr);
+ }
+ for_each(v.begin(), v.end(), EraseRangeByIterator(rRanges));
+}
+
}
// ============================================================================
@@ -2358,9 +2409,14 @@ void lcl_removeByFileId(sal_uInt16 nFileId, MapContainer& rMap)
{
typename MapContainer::iterator itr = rMap.find(nFileId);
if (itr != rMap.end())
+ {
+ // Close this document shell.
+ itr->second.maShell->DoClose();
rMap.erase(itr);
+ }
}
+
void ScExternalRefManager::refreshNames(sal_uInt16 nFileId)
{
maRefCache.clearCache(nFileId);
@@ -2389,6 +2445,21 @@ void ScExternalRefManager::breakLink(sal_uInt16 nFileId)
maRefCells.erase(nFileId);
}
+ // Remove all named ranges that reference this document.
+
+ // Global named ranges.
+ ScRangeName* pRanges = mpDoc->GetRangeName();
+ if (pRanges)
+ removeRangeNamesBySrcDoc(*pRanges, nFileId);
+
+ // Sheet-local named ranges.
+ for (SCTAB i = 0, n = mpDoc->GetTableCount(); i < n; ++i)
+ {
+ pRanges = mpDoc->GetRangeName(i);
+ if (pRanges)
+ removeRangeNamesBySrcDoc(*pRanges, nFileId);
+ }
+
lcl_removeByFileId(nFileId, maDocShells);
if (maDocShells.empty())
@@ -2528,6 +2599,9 @@ void ScExternalRefManager::purgeStaleSrcDocument(sal_Int32 nTimeOut)
sal_Int32 nSinceLastAccess = (Time() - itr->second.maLastAccess).GetTime();
if (nSinceLastAccess < nTimeOut)
aNewDocShells.insert(*itr);
+ else
+ // Timed out. Let's close this.
+ itr->second.maShell->DoClose();
}
maDocShells.swap(aNewDocShells);
diff --git a/sc/source/ui/inc/dbdocfun.hxx b/sc/source/ui/inc/dbdocfun.hxx
index 132eb9a3750b..11b2ce27ef62 100644
--- a/sc/source/ui/inc/dbdocfun.hxx
+++ b/sc/source/ui/inc/dbdocfun.hxx
@@ -114,7 +114,7 @@ public:
sal_Bool RenameDBRange( const String& rOld, const String& rNew, sal_Bool bApi );
sal_Bool ModifyDBData( const ScDBData& rNewData, sal_Bool bApi ); // Name unveraendert
- sal_Bool RepeatDB( const String& rDBName, sal_Bool bRecord, sal_Bool bApi );
+ sal_Bool RepeatDB( const String& rDBName, sal_Bool bRecord, sal_Bool bApi, bool bIsUnnamed=false, SCTAB aTab = 0);
sal_Bool DataPilotUpdate( ScDPObject* pOldObj, const ScDPObject* pNewObj,
sal_Bool bRecord, sal_Bool bApi, sal_Bool bAllowMove = false );
diff --git a/sc/source/ui/inc/undoblk.hxx b/sc/source/ui/inc/undoblk.hxx
index d8617490219a..16fc7591ac08 100644
--- a/sc/source/ui/inc/undoblk.hxx
+++ b/sc/source/ui/inc/undoblk.hxx
@@ -421,8 +421,7 @@ public:
ScDocument* pNewUndoDoc, const ScMarkData& rMark,
FillDir eNewFillDir,
FillCmd eNewFillCmd, FillDateCmd eNewFillDateCmd,
- double fNewStartValue, double fNewStepValue, double fNewMaxValue,
- sal_uInt16 nMaxShIndex );
+ double fNewStartValue, double fNewStepValue, double fNewMaxValue );
virtual ~ScUndoAutoFill();
virtual void Undo();
@@ -444,7 +443,6 @@ private:
double fMaxValue;
sal_uLong nStartChangeAction;
sal_uLong nEndChangeAction;
- sal_uInt16 nMaxSharedIndex;
void SetChangeTrack();
};
diff --git a/sc/source/ui/undo/undoblk3.cxx b/sc/source/ui/undo/undoblk3.cxx
index 446e3dede1c6..45ea822f2090 100644
--- a/sc/source/ui/undo/undoblk3.cxx
+++ b/sc/source/ui/undo/undoblk3.cxx
@@ -602,8 +602,7 @@ ScUndoAutoFill::ScUndoAutoFill( ScDocShell* pNewDocShell,
const ScRange& rRange, const ScRange& rSourceArea,
ScDocument* pNewUndoDoc, const ScMarkData& rMark,
FillDir eNewFillDir, FillCmd eNewFillCmd, FillDateCmd eNewFillDateCmd,
- double fNewStartValue, double fNewStepValue, double fNewMaxValue,
- sal_uInt16 nMaxShIndex )
+ double fNewStartValue, double fNewStepValue, double fNewMaxValue )
//
: ScBlockUndo( pNewDocShell, rRange, SC_UNDO_AUTOHEIGHT ),
//
@@ -615,8 +614,7 @@ ScUndoAutoFill::ScUndoAutoFill( ScDocShell* pNewDocShell,
eFillDateCmd ( eNewFillDateCmd ),
fStartValue ( fNewStartValue ),
fStepValue ( fNewStepValue ),
- fMaxValue ( fNewMaxValue ),
- nMaxSharedIndex ( nMaxShIndex)
+ fMaxValue ( fNewMaxValue )
{
SetChangeTrack();
}
@@ -626,7 +624,6 @@ ScUndoAutoFill::ScUndoAutoFill( ScDocShell* pNewDocShell,
ScUndoAutoFill::~ScUndoAutoFill()
{
- pDocShell->GetDocument()->EraseNonUsedSharedNames(nMaxSharedIndex);
delete pUndoDoc;
}
@@ -649,26 +646,6 @@ void ScUndoAutoFill::SetChangeTrack()
nStartChangeAction = nEndChangeAction = 0;
}
-namespace {
-
-bool eraseNameContaining(ScRangeName& rNames, const rtl::OUString& rCriteria)
-{
- ScRangeName::iterator itr = rNames.begin(), itrEnd = rNames.end();
- for (; itr != itrEnd; ++itr)
- {
- rtl::OUString aRName = itr->GetName();
- if (aRName.indexOf(rCriteria) >= 0)
- {
- // Criteria found. Erase this.
- rNames.erase(itr);
- return true;
- }
- }
- return false;
-}
-
-}
-
void ScUndoAutoFill::Undo()
{
BeginUndo();
@@ -698,29 +675,6 @@ void ScUndoAutoFill::Undo()
if (pViewShell)
pViewShell->CellContentChanged();
-// Shared-Names loeschen
-// Falls Undo ins Dokument gespeichert
-// => automatisches Loeschen am Ende
-// umarbeiten!!
-
- String aName = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("___SC_"));
- aName += String::CreateFromInt32(nMaxSharedIndex);
- aName += '_';
- ScRangeName* pRangeName = pDoc->GetRangeName();
- bool bHasFound = false;
- // Remove all range names that contain ___SC_...
- while (true)
- {
- bool bErased = eraseNameContaining(*pRangeName, aName);
- if (bErased)
- bHasFound = true;
- else
- break;
- }
-
- if (bHasFound)
- pRangeName->SetSharedMaxIndex(pRangeName->GetSharedMaxIndex()-1);
-
ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
if ( pChangeTrack )
pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
diff --git a/sc/source/ui/unoobj/datauno.cxx b/sc/source/ui/unoobj/datauno.cxx
index f5f2ab6071d0..a1ee63dc8b26 100644
--- a/sc/source/ui/unoobj/datauno.cxx
+++ b/sc/source/ui/unoobj/datauno.cxx
@@ -57,6 +57,7 @@
#include "docsh.hxx"
#include "dbdocfun.hxx"
#include "unonames.hxx"
+#include "globalnames.hxx"
#include "globstr.hrc"
#include "convuno.hxx"
#include "hints.hxx"
@@ -1607,7 +1608,18 @@ void ScDataPilotFilterDescriptor::PutData( const ScQueryParam& rParam )
ScDatabaseRangeObj::ScDatabaseRangeObj(ScDocShell* pDocSh, const String& rNm) :
pDocShell( pDocSh ),
aName( rNm ),
- aPropSet( lcl_GetDBRangePropertyMap() )
+ aPropSet( lcl_GetDBRangePropertyMap() ),
+ bIsUnnamed(false)
+{
+ pDocShell->GetDocument()->AddUnoObject(*this);
+}
+
+ScDatabaseRangeObj::ScDatabaseRangeObj(ScDocShell* pDocSh, const SCTAB nTab) :
+ pDocShell( pDocSh ),
+ aName(RTL_CONSTASCII_USTRINGPARAM(STR_DB_LOCAL_NONAME)),
+ aPropSet( lcl_GetDBRangePropertyMap() ),
+ bIsUnnamed(true),
+ aTab( nTab )
{
pDocShell->GetDocument()->AddUnoObject(*this);
}
@@ -1641,12 +1653,19 @@ ScDBData* ScDatabaseRangeObj::GetDBData_Impl() const
ScDBData* pRet = NULL;
if (pDocShell)
{
- ScDBCollection* pNames = pDocShell->GetDocument()->GetDBCollection();
- if (pNames)
+ if (bIsUnnamed)
{
- sal_uInt16 nPos = 0;
- if (pNames->SearchName( aName, nPos ))
- pRet = (*pNames)[nPos];
+ pRet = pDocShell->GetDocument()->GetAnonymousDBData(aTab);
+ }
+ else
+ {
+ ScDBCollection* pNames = pDocShell->GetDocument()->GetDBCollection();
+ if (pNames)
+ {
+ sal_uInt16 nPos = 0;
+ if (pNames->SearchName( aName, nPos ))
+ pRet = (*pNames)[nPos];
+ }
}
}
return pRet;
@@ -1889,7 +1908,7 @@ void SAL_CALL ScDatabaseRangeObj::refresh() throw(uno::RuntimeException)
// interne Operationen (sort, query, subtotal) nur, wenn kein Fehler
if (bContinue)
- aFunc.RepeatDB( pData->GetName(), sal_True, sal_True );
+ aFunc.RepeatDB( pData->GetName(), true, true, bIsUnnamed, aTab );
}
}
@@ -2079,7 +2098,7 @@ uno::Any SAL_CALL ScDatabaseRangeObj::getPropertyValue( const rtl::OUString& aPr
{
// all database ranges except "unnamed" are user defined
ScUnoHelpFunctions::SetBoolInAny( aRet,
- ( pData->GetName() != ScGlobal::GetRscString(STR_DB_NONAME) ) );
+ ( pData->GetName() != String(RTL_CONSTASCII_USTRINGPARAM(STR_DB_LOCAL_NONAME)) ) );
}
else if ( aString.EqualsAscii( SC_UNO_LINKDISPBIT ) )
{
@@ -2354,8 +2373,90 @@ sal_Bool SAL_CALL ScDatabaseRangesObj::hasByName( const rtl::OUString& aName )
//------------------------------------------------------------------------
+ScUnnamedDatabaseRangesObj::ScUnnamedDatabaseRangesObj(ScDocShell* pDocSh) :
+ pDocShell( pDocSh )
+{
+ pDocShell->GetDocument()->AddUnoObject(*this);
+}
+
+ScUnnamedDatabaseRangesObj::~ScUnnamedDatabaseRangesObj()
+{
+ if (pDocShell)
+ pDocShell->GetDocument()->RemoveUnoObject(*this);
+}
+
+void ScUnnamedDatabaseRangesObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ // Referenz-Update interessiert hier nicht
+
+ if ( rHint.ISA( SfxSimpleHint ) &&
+ ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
+ {
+ pDocShell = NULL; // ungueltig geworden
+ }
+}
+
+// XUnnamedDatabaseRanges
+
+void ScUnnamedDatabaseRangesObj::setByTable( const table::CellRangeAddress& aRange )
+ throw( uno::RuntimeException,
+ lang::IndexOutOfBoundsException )
+{
+ SolarMutexGuard aGuard;
+ bool bDone = false;
+ if (pDocShell)
+ {
+ if ( pDocShell->GetDocument()->GetTableCount() <= aRange.Sheet )
+ throw lang::IndexOutOfBoundsException();
+ ScDBDocFunc aFunc(*pDocShell);
+ String aString(RTL_CONSTASCII_USTRINGPARAM(STR_DB_LOCAL_NONAME));
+ ScRange aUnnamedRange( (SCCOL)aRange.StartColumn, (SCROW)aRange.StartRow, aRange.Sheet,
+ (SCCOL)aRange.EndColumn, (SCROW)aRange.EndRow, aRange.Sheet );
+ bDone = aFunc.AddDBRange( aString, aUnnamedRange, sal_True );
+ }
+ if (!bDone)
+ throw uno::RuntimeException(); // no other exceptions specified
+}
+uno::Any ScUnnamedDatabaseRangesObj::getByTable( const sal_Int32 nTab )
+ throw(uno::RuntimeException,
+ lang::IndexOutOfBoundsException,
+ container::NoSuchElementException)
+{
+ SolarMutexGuard aGuard;
+ if (pDocShell)
+ {
+ if ( pDocShell->GetDocument()->GetTableCount() <= nTab )
+ throw lang::IndexOutOfBoundsException();
+ uno::Reference<sheet::XDatabaseRange> xRange( new ScDatabaseRangeObj(pDocShell, (SCTAB) nTab) );
+ if (xRange.is())
+ return uno::makeAny(xRange);
+ else
+ throw container::NoSuchElementException();
+ }
+ else
+ throw uno::RuntimeException();
+}
+
+sal_Bool ScUnnamedDatabaseRangesObj::hasByTable( sal_Int32 nTab )
+ throw (uno::RuntimeException,
+ lang::IndexOutOfBoundsException)
+{
+ SolarMutexGuard aGuard;
+ if (pDocShell)
+ {
+ if (pDocShell->GetDocument()->GetTableCount() <= nTab)
+ throw lang::IndexOutOfBoundsException();
+ if (pDocShell->GetDocument()->GetAnonymousDBData((SCTAB) nTab))
+ return true;
+ return false;
+ }
+ else
+ return false;
+}
+
+//------------------------------------------------------------------------
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/unoobj/docuno.cxx b/sc/source/ui/unoobj/docuno.cxx
index e84f6756757e..15673f35c0b8 100644
--- a/sc/source/ui/unoobj/docuno.cxx
+++ b/sc/source/ui/unoobj/docuno.cxx
@@ -56,6 +56,7 @@
#include <com/sun/star/util/Date.hpp>
#include <com/sun/star/sheet/XNamedRanges.hpp>
#include <com/sun/star/sheet/XLabelRanges.hpp>
+#include <com/sun/star/sheet/XUnnamedDatabaseRanges.hpp>
#include <com/sun/star/i18n/XForbiddenCharacters.hpp>
#include <com/sun/star/script/XLibraryContainer.hpp>
#include <com/sun/star/lang/XInitialization.hpp>
@@ -1780,6 +1781,10 @@ uno::Any SAL_CALL ScModelObj::getPropertyValue( const rtl::OUString& aPropertyNa
{
aRet <<= uno::Reference<sheet::XDatabaseRanges>(new ScDatabaseRangesObj( pDocShell ));
}
+ else if ( aString.EqualsAscii( SC_UNO_UNNAMEDDBRNG ) )
+ {
+ aRet <<= uno::Reference<sheet::XUnnamedDatabaseRanges>(new ScUnnamedDatabaseRangesObj(pDocShell));
+ }
else if ( aString.EqualsAscii( SC_UNO_COLLABELRNG ) )
{
aRet <<= uno::Reference<sheet::XLabelRanges>(new ScLabelRangesObj( pDocShell, sal_True ));
diff --git a/sc/source/ui/vba/excelvbahelper.cxx b/sc/source/ui/vba/excelvbahelper.cxx
index d98f1ac7ee1e..cbf30eba603d 100644
--- a/sc/source/ui/vba/excelvbahelper.cxx
+++ b/sc/source/ui/vba/excelvbahelper.cxx
@@ -66,36 +66,33 @@ GetDataBaseRanges( ScDocShell* pShell ) throw ( uno::RuntimeException )
return xDBRanges;
}
+uno::Reference< sheet::XUnnamedDatabaseRanges >
+GetUnnamedDataBaseRanges( ScDocShell* pShell ) throw ( uno::RuntimeException )
+{
+ uno::Reference< frame::XModel > xModel;
+ if ( pShell )
+ xModel.set( pShell->GetModel(), uno::UNO_QUERY_THROW );
+ uno::Reference< beans::XPropertySet > xModelProps( xModel, uno::UNO_QUERY_THROW );
+ uno::Reference< sheet::XUnnamedDatabaseRanges > xUnnamedDBRanges( xModelProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("UnnamedDatabaseRanges") ) ), uno::UNO_QUERY_THROW );
+ return xUnnamedDBRanges;
+}
+
// returns the XDatabaseRange for the autofilter on sheet (nSheet)
// also populates sName with the name of range
uno::Reference< sheet::XDatabaseRange >
-GetAutoFiltRange( ScDocShell* pShell, sal_Int16 nSheet, rtl::OUString& sName ) throw ( uno::RuntimeException )
+GetAutoFiltRange( ScDocShell* pShell, sal_Int16 nSheet ) throw ( uno::RuntimeException )
{
- uno::Reference< container::XIndexAccess > xIndexAccess( GetDataBaseRanges( pShell ), uno::UNO_QUERY_THROW );
+ uno::Reference< sheet::XUnnamedDatabaseRanges > xUnnamedDBRanges( GetUnnamedDataBaseRanges( pShell ), uno::UNO_QUERY_THROW );
uno::Reference< sheet::XDatabaseRange > xDataBaseRange;
- table::CellRangeAddress dbAddress;
- for ( sal_Int32 index=0; index < xIndexAccess->getCount(); ++index )
+ if (xUnnamedDBRanges->hasByTable( nSheet ) )
{
- uno::Reference< sheet::XDatabaseRange > xDBRange( xIndexAccess->getByIndex( index ), uno::UNO_QUERY_THROW );
- uno::Reference< container::XNamed > xNamed( xDBRange, uno::UNO_QUERY_THROW );
- // autofilters work weirdly with openoffice, unnamed is the default
- // named range which is used to create an autofilter, but
- // its also possible that another name could be used
- // this also causes problems when an autofilter is created on
- // another sheet
- // ( but.. you can use any named range )
- dbAddress = xDBRange->getDataArea();
- if ( dbAddress.Sheet == nSheet )
+ uno::Reference< sheet::XDatabaseRange > xDBRange( xUnnamedDBRanges->getByTable( nSheet ) , uno::UNO_QUERY_THROW );
+ sal_Bool bHasAuto = false;
+ uno::Reference< beans::XPropertySet > xProps( xDBRange, uno::UNO_QUERY_THROW );
+ xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("AutoFilter") ) ) >>= bHasAuto;
+ if ( bHasAuto )
{
- sal_Bool bHasAuto = false;
- uno::Reference< beans::XPropertySet > xProps( xDBRange, uno::UNO_QUERY_THROW );
- xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("AutoFilter") ) ) >>= bHasAuto;
- if ( bHasAuto )
- {
- sName = xNamed->getName();
- xDataBaseRange=xDBRange;
- break;
- }
+ xDataBaseRange=xDBRange;
}
}
return xDataBaseRange;
diff --git a/sc/source/ui/vba/excelvbahelper.hxx b/sc/source/ui/vba/excelvbahelper.hxx
index 9befc1548357..1cc0546a4fd7 100644
--- a/sc/source/ui/vba/excelvbahelper.hxx
+++ b/sc/source/ui/vba/excelvbahelper.hxx
@@ -32,6 +32,7 @@
#include "docsh.hxx"
#include <com/sun/star/sheet/XDatabaseRanges.hpp>
#include <com/sun/star/sheet/XDatabaseRange.hpp>
+#include <com/sun/star/sheet/XUnnamedDatabaseRanges.hpp>
#include <com/sun/star/table/XCellRange.hpp>
#include <com/sun/star/sheet/XSheetCellRangeContainer.hpp>
#include <com/sun/star/sheet/XSpreadsheet.hpp>
@@ -65,8 +66,9 @@ formula::FormulaGrammar::Grammar GetFormulaGrammar( ScDocument* pDoc, const ScAd
void CompileExcelFormulaToODF( ScDocument* pDoc, const String& rOldFormula, String& rNewFormula );
void CompileODFFormulaToExcel( ScDocument* pDoc, const String& rOldFormula, String& rNewFormula, const formula::FormulaGrammar::Grammar eGrammar );
css::uno::Reference< css::sheet::XDatabaseRanges > GetDataBaseRanges( ScDocShell* pShell ) throw ( css::uno::RuntimeException );
+css::uno::Reference< css::sheet::XUnnamedDatabaseRanges > GetUnnamedDataBaseRanges( ScDocShell* pShell ) throw ( css::uno::RuntimeException );
-css::uno::Reference< css::sheet::XDatabaseRange > GetAutoFiltRange( ScDocShell* pShell, sal_Int16 nSheet, rtl::OUString& sName ) throw ( css::uno::RuntimeException );
+css::uno::Reference< css::sheet::XDatabaseRange > GetAutoFiltRange( ScDocShell* pShell, sal_Int16 nSheet ) throw ( css::uno::RuntimeException );
css::uno::Reference< ooo::vba::XHelperInterface > getUnoSheetModuleObj( const css::uno::Reference< css::sheet::XSpreadsheet >& xSheet ) throw ( css::uno::RuntimeException );
css::uno::Reference< ooo::vba::XHelperInterface > getUnoSheetModuleObj( const css::uno::Reference< css::sheet::XSheetCellRangeContainer >& xRanges ) throw ( css::uno::RuntimeException );
css::uno::Reference< ooo::vba::XHelperInterface > getUnoSheetModuleObj( const css::uno::Reference< css::table::XCellRange >& xRange ) throw ( css::uno::RuntimeException );
diff --git a/sc/source/ui/vba/vbarange.cxx b/sc/source/ui/vba/vbarange.cxx
index df750a774ad4..9c199423abd0 100644
--- a/sc/source/ui/vba/vbarange.cxx
+++ b/sc/source/ui/vba/vbarange.cxx
@@ -39,6 +39,7 @@
#include <com/sun/star/script/vba/XVBAEventProcessor.hpp>
#include <com/sun/star/sheet/XDatabaseRange.hpp>
#include <com/sun/star/sheet/XDatabaseRanges.hpp>
+#include <com/sun/star/sheet/XUnnamedDatabaseRanges.hpp>
#include <com/sun/star/sheet/XGoalSeek.hpp>
#include <com/sun/star/sheet/XSheetOperation.hpp>
#include <com/sun/star/sheet/CellFlags.hpp>
@@ -4334,20 +4335,10 @@ ScVbaRange::ApplicationRange( const uno::Reference< uno::XComponentContext >& xC
// Helper functions for AutoFilter
ScDBData* lcl_GetDBData_Impl( ScDocShell* pDocShell, sal_Int16 nSheet )
{
- rtl::OUString sName;
- excel::GetAutoFiltRange( pDocShell, nSheet, sName );
- OSL_TRACE("lcl_GetDBData_Impl got autofilter range %s for sheet %d",
- rtl::OUStringToOString( sName, RTL_TEXTENCODING_UTF8 ).getStr() , nSheet );
ScDBData* pRet = NULL;
if (pDocShell)
{
- ScDBCollection* pNames = pDocShell->GetDocument()->GetDBCollection();
- if (pNames)
- {
- sal_uInt16 nPos = 0;
- if (pNames->SearchName( sName , nPos ))
- pRet = (*pNames)[nPos];
- }
+ pRet = pDocShell->GetDocument()->GetAnonymousDBData(nSheet);
}
return pRet;
}
@@ -4501,8 +4492,7 @@ ScVbaRange::AutoFilter( const uno::Any& Field, const uno::Any& Criteria1, const
sal_Int16 nSheet = thisAddress.Sheet;
ScDocShell* pShell = getScDocShell();
sal_Bool bHasAuto = false;
- rtl::OUString sAutofiltRangeName;
- uno::Reference< sheet::XDatabaseRange > xDataBaseRange = excel::GetAutoFiltRange( pShell, nSheet, sAutofiltRangeName );
+ uno::Reference< sheet::XDatabaseRange > xDataBaseRange = excel::GetAutoFiltRange( pShell, nSheet );
if ( xDataBaseRange.is() )
bHasAuto = true;
@@ -4549,16 +4539,13 @@ ScVbaRange::AutoFilter( const uno::Any& Field, const uno::Any& Criteria1, const
}
}
- uno::Reference< sheet::XDatabaseRanges > xDBRanges = excel::GetDataBaseRanges( pShell );
+ uno::Reference< sheet::XUnnamedDatabaseRanges > xDBRanges = excel::GetUnnamedDataBaseRanges( pShell );
if ( xDBRanges.is() )
{
- rtl::OUString sGenName( RTL_CONSTASCII_USTRINGPARAM("VBA_Autofilter_") );
- sGenName += rtl::OUString::valueOf( static_cast< sal_Int32 >( nSheet ) );
- OSL_TRACE("Going to add new autofilter range.. name %s",
- rtl::OUStringToOString( sGenName, RTL_TEXTENCODING_UTF8 ).getStr() , nSheet );
- if ( !xDBRanges->hasByName( sGenName ) )
- xDBRanges->addNewByName( sGenName, autoFiltAddress );
- xDataBaseRange.set( xDBRanges->getByName( sGenName ), uno::UNO_QUERY_THROW );
+ OSL_TRACE("Going to add new autofilter range.. sheet %i", nSheet );
+ if ( !xDBRanges->hasByTable( nSheet ) )
+ xDBRanges->setByTable( autoFiltAddress );
+ xDataBaseRange.set( xDBRanges->getByTable(nSheet ), uno::UNO_QUERY_THROW );
}
if ( !xDataBaseRange.is() )
throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Failed to find the autofilter placeholder range" ) ), uno::Reference< uno::XInterface >() );
diff --git a/sc/source/ui/view/viewfunc.cxx b/sc/source/ui/view/viewfunc.cxx
index 2918410d0923..cc85ef7b7137 100644
--- a/sc/source/ui/view/viewfunc.cxx
+++ b/sc/source/ui/view/viewfunc.cxx
@@ -97,10 +97,13 @@ static void lcl_PostRepaintCondFormat( const ScConditionalFormat *pCondFmt, ScDo
{
if( pCondFmt )
{
- const ScRangeListRef& aRanges = pCondFmt->GetRangeInfo();
- size_t nCount = aRanges->size();
+ const ScRangeListRef& xRanges = pCondFmt->GetRangeInfo();
+ if (!xRanges)
+ return;
+
+ size_t nCount = xRanges->size();
for( size_t n = 0 ; n < nCount; n++ )
- pDocSh->PostPaint( *((*aRanges)[n]), PAINT_ALL );
+ pDocSh->PostPaint( *((*xRanges)[n]), PAINT_ALL );
}
}