summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@suse.com>2011-12-07 13:33:06 -0500
committerKohei Yoshida <kohei.yoshida@suse.com>2011-12-07 13:34:53 -0500
commitc8552bc97b9f860494bc45091936010d98fff1cb (patch)
treece168434d3ca683de91332ad1654a12f683045cf
parent5683109a4928ba3e083abfbd73e794a6784eba21 (diff)
fdo#43534: Partially support external refs in CELL function.
For now, only COL and ROW are supported. More on the way. Note that we can't support all the information types that we do for internal references.
-rw-r--r--sc/qa/unit/ucalc.cxx38
-rw-r--r--sc/source/core/inc/cellkeytranslator.hxx1
-rw-r--r--sc/source/core/inc/interpre.hxx3
-rw-r--r--sc/source/core/tool/cellkeytranslator.cxx7
-rw-r--r--sc/source/core/tool/interpr1.cxx49
-rw-r--r--sc/source/core/tool/interpr4.cxx20
6 files changed, 111 insertions, 7 deletions
diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index d6d9484f32b0..a4158c3e1bc5 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -672,6 +672,43 @@ void testFuncMATCH(ScDocument* pDoc)
}
}
+void testFuncCELL(ScDocument* pDoc)
+{
+ clearRange(pDoc, ScRange(0, 0, 0, 2, 20, 0)); // Clear A1:C21.
+
+ {
+ const char* pContent = "Some random text";
+ pDoc->SetString(2, 9, 0, rtl::OUString::createFromAscii(pContent)); // Set this value to C10.
+ double val = 1.2;
+ pDoc->SetValue(2, 0, 0, val); // Set numeric value to C1;
+
+ // We don't test: FILENAME, FORMAT, WIDTH, PROTECT, PREFIX
+ StrStrCheck aChecks[] = {
+ { "=CELL(\"COL\";C10)", "3" },
+ { "=CELL(\"ROW\";C10)", "10" },
+ { "=CELL(\"SHEET\";C10)", "1" },
+ { "=CELL(\"ADDRESS\";C10)", "$C$10" },
+ { "=CELL(\"CONTENTS\";C10)", pContent },
+ { "=CELL(\"COLOR\";C10)", "0" },
+ { "=CELL(\"TYPE\";C9)", "b" },
+ { "=CELL(\"TYPE\";C10)", "l" },
+ { "=CELL(\"TYPE\";C1)", "v" },
+ { "=CELL(\"PARENTHESES\";C10)", "0" }
+ };
+
+ for (size_t i = 0; i < SAL_N_ELEMENTS(aChecks); ++i)
+ pDoc->SetString(0, i, 0, rtl::OUString::createFromAscii(aChecks[i].pVal));
+ pDoc->CalcAll();
+
+ for (size_t i = 0; i < SAL_N_ELEMENTS(aChecks); ++i)
+ {
+ rtl::OUString aVal = pDoc->GetString(0, i, 0);
+ cout << "CELL: " << aVal << endl;
+ CPPUNIT_ASSERT_MESSAGE("Unexpected result for CELL", aVal.equalsAscii(aChecks[i].pRes));
+ }
+ }
+}
+
void Test::testCellFunctions()
{
rtl::OUString aTabName(RTL_CONSTASCII_USTRINGPARAM("foo"));
@@ -684,6 +721,7 @@ void Test::testCellFunctions()
testFuncCOUNTIF(m_pDoc);
testFuncVLOOKUP(m_pDoc);
testFuncMATCH(m_pDoc);
+ testFuncCELL(m_pDoc);
m_pDoc->DeleteTab(0);
}
diff --git a/sc/source/core/inc/cellkeytranslator.hxx b/sc/source/core/inc/cellkeytranslator.hxx
index 0ec2c36c5ef3..5a1b87752409 100644
--- a/sc/source/core/inc/cellkeytranslator.hxx
+++ b/sc/source/core/inc/cellkeytranslator.hxx
@@ -73,6 +73,7 @@ class ScCellKeywordTranslator
{
public:
static void transKeyword(String& rName, const ::com::sun::star::lang::Locale* pLocale = NULL, OpCode eOpCode = ocNone);
+ static void transKeyword(rtl::OUString& rName, const ::com::sun::star::lang::Locale* pLocale = NULL, OpCode eOpCode = ocNone);
~ScCellKeywordTranslator();
private:
diff --git a/sc/source/core/inc/interpre.hxx b/sc/source/core/inc/interpre.hxx
index 586a4ddb18e4..192c2e05e315 100644
--- a/sc/source/core/inc/interpre.hxx
+++ b/sc/source/core/inc/interpre.hxx
@@ -287,6 +287,8 @@ void PopDoubleRef(SCCOL& rCol1, SCROW &rRow1, SCTAB& rTab1,
bool bDontCheckForTableOp = false );
void PopExternalSingleRef(sal_uInt16& rFileId, String& rTabName, ScSingleRefData& rRef);
void PopExternalSingleRef(ScExternalRefCache::TokenRef& rToken, ScExternalRefCache::CellFormat* pFmt = NULL);
+void PopExternalSingleRef(sal_uInt16& rFileId, String& rTabName, ScSingleRefData& rRef,
+ ScExternalRefCache::TokenRef& rToken, ScExternalRefCache::CellFormat* pFmt = NULL);
void PopExternalDoubleRef(sal_uInt16& rFileId, String& rTabName, ScComplexRefData& rRef);
void PopExternalDoubleRef(ScExternalRefCache::TokenArrayRef& rArray);
void PopExternalDoubleRef(ScMatrixRef& rMat);
@@ -427,6 +429,7 @@ void ScIsNonString();
void ScIsLogical();
void ScType();
void ScCell();
+void ScCellExternal();
void ScIsRef();
void ScIsValue();
void ScIsFormula();
diff --git a/sc/source/core/tool/cellkeytranslator.cxx b/sc/source/core/tool/cellkeytranslator.cxx
index 9acd35cf3bdc..41fbe7782185 100644
--- a/sc/source/core/tool/cellkeytranslator.cxx
+++ b/sc/source/core/tool/cellkeytranslator.cxx
@@ -171,6 +171,13 @@ void ScCellKeywordTranslator::transKeyword(String& rName, const Locale* pLocale,
lclMatchKeyword(rName, spInstance->maStringNameMap, eOpCode, pLocale);
}
+void ScCellKeywordTranslator::transKeyword(rtl::OUString& rName, const Locale* pLocale, OpCode eOpCode)
+{
+ String aName = rName;
+ transKeyword(aName, pLocale, eOpCode);
+ rName = aName;
+}
+
ScCellKeywordTranslator::ScCellKeywordTranslator() :
maTransWrapper( ::comphelper::getProcessServiceFactory(),
i18n::TransliterationModules_LOWERCASE_UPPERCASE )
diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index 56719f40c0a5..2dd5d7a64979 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -2064,7 +2064,21 @@ void ScInterpreter::ScCell()
ScAddress aCellPos( aPos );
bool bError = false;
if( nParamCount == 2 )
+ {
+ switch (GetStackType())
+ {
+ case svExternalSingleRef:
+ case svExternalDoubleRef:
+ {
+ // Let's handle external reference separately...
+ ScCellExternal();
+ return;
+ }
+ default:
+ ;
+ }
bError = !PopDoubleRefOrSingleRef( aCellPos );
+ }
String aInfoType( GetString() );
if( bError || nGlobalError )
PushIllegalParameter();
@@ -2268,6 +2282,41 @@ void ScInterpreter::ScCell()
}
}
+void ScInterpreter::ScCellExternal()
+{
+ sal_uInt16 nFileId;
+ String aTabName;
+ ScSingleRefData aRef;
+ ScExternalRefCache::TokenRef pToken;
+ ScExternalRefCache::CellFormat aFmt;
+ PopExternalSingleRef(nFileId, aTabName, aRef, pToken, &aFmt);
+ if (nGlobalError)
+ {
+ PushIllegalParameter();
+ return;
+ }
+
+ rtl::OUString aInfoType = GetString();
+ if (nGlobalError)
+ {
+ PushIllegalParameter();
+ return;
+ }
+
+ SCCOL nCol;
+ SCROW nRow;
+ SCTAB nTab;
+ SingleRefToVars(aRef, nCol, nRow, nTab);
+
+ ScCellKeywordTranslator::transKeyword(aInfoType, ScGlobal::GetLocale(), ocCell);
+
+ if (aInfoType.equalsAscii("COL"))
+ PushInt(nCol + 1);
+ else if (aInfoType.equalsAscii("ROW"))
+ PushInt(nRow + 1);
+ else
+ PushIllegalParameter();
+}
void ScInterpreter::ScIsRef()
{
diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx
index 1bbad1cedf94..c3992053ce3a 100644
--- a/sc/source/core/tool/interpr4.cxx
+++ b/sc/source/core/tool/interpr4.cxx
@@ -1442,34 +1442,40 @@ void ScInterpreter::PopExternalSingleRef(sal_uInt16& rFileId, String& rTabName,
void ScInterpreter::PopExternalSingleRef(ScExternalRefCache::TokenRef& rToken, ScExternalRefCache::CellFormat* pFmt)
{
-
sal_uInt16 nFileId;
String aTabName;
ScSingleRefData aData;
- PopExternalSingleRef(nFileId, aTabName, aData);
+ PopExternalSingleRef(nFileId, aTabName, aData, rToken, pFmt);
+}
+
+void ScInterpreter::PopExternalSingleRef(
+ sal_uInt16& rFileId, String& rTabName, ScSingleRefData& rRef,
+ ScExternalRefCache::TokenRef& rToken, ScExternalRefCache::CellFormat* pFmt)
+{
+ PopExternalSingleRef(rFileId, rTabName, rRef);
if (nGlobalError)
return;
ScExternalRefManager* pRefMgr = pDok->GetExternalRefManager();
- const OUString* pFile = pRefMgr->getExternalFileName(nFileId);
+ const OUString* pFile = pRefMgr->getExternalFileName(rFileId);
if (!pFile)
{
SetError(errNoName);
return;
}
- if (aData.IsTabRel())
+ if (rRef.IsTabRel())
{
OSL_FAIL("ScCompiler::GetToken: external single reference must have an absolute table reference!");
SetError(errNoRef);
return;
}
- aData.CalcAbsIfRel(aPos);
- ScAddress aAddr(aData.nCol, aData.nRow, aData.nTab);
+ rRef.CalcAbsIfRel(aPos);
+ ScAddress aAddr(rRef.nCol, rRef.nRow, rRef.nTab);
ScExternalRefCache::CellFormat aFmt;
ScExternalRefCache::TokenRef xNew = pRefMgr->getSingleRefToken(
- nFileId, aTabName, aAddr, &aPos, NULL, &aFmt);
+ rFileId, rTabName, aAddr, &aPos, NULL, &aFmt);
if (!xNew)
{