Kaydet (Commit) c8552bc9 authored tarafından Kohei Yoshida's avatar Kohei Yoshida

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.
üst 5683109a
...@@ -672,6 +672,43 @@ void testFuncMATCH(ScDocument* pDoc) ...@@ -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() void Test::testCellFunctions()
{ {
rtl::OUString aTabName(RTL_CONSTASCII_USTRINGPARAM("foo")); rtl::OUString aTabName(RTL_CONSTASCII_USTRINGPARAM("foo"));
...@@ -684,6 +721,7 @@ void Test::testCellFunctions() ...@@ -684,6 +721,7 @@ void Test::testCellFunctions()
testFuncCOUNTIF(m_pDoc); testFuncCOUNTIF(m_pDoc);
testFuncVLOOKUP(m_pDoc); testFuncVLOOKUP(m_pDoc);
testFuncMATCH(m_pDoc); testFuncMATCH(m_pDoc);
testFuncCELL(m_pDoc);
m_pDoc->DeleteTab(0); m_pDoc->DeleteTab(0);
} }
......
...@@ -73,6 +73,7 @@ class ScCellKeywordTranslator ...@@ -73,6 +73,7 @@ class ScCellKeywordTranslator
{ {
public: public:
static void transKeyword(String& rName, const ::com::sun::star::lang::Locale* pLocale = NULL, OpCode eOpCode = ocNone); 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(); ~ScCellKeywordTranslator();
private: private:
......
...@@ -287,6 +287,8 @@ void PopDoubleRef(SCCOL& rCol1, SCROW &rRow1, SCTAB& rTab1, ...@@ -287,6 +287,8 @@ void PopDoubleRef(SCCOL& rCol1, SCROW &rRow1, SCTAB& rTab1,
bool bDontCheckForTableOp = false ); bool bDontCheckForTableOp = false );
void PopExternalSingleRef(sal_uInt16& rFileId, String& rTabName, ScSingleRefData& rRef); void PopExternalSingleRef(sal_uInt16& rFileId, String& rTabName, ScSingleRefData& rRef);
void PopExternalSingleRef(ScExternalRefCache::TokenRef& rToken, ScExternalRefCache::CellFormat* pFmt = NULL); 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(sal_uInt16& rFileId, String& rTabName, ScComplexRefData& rRef);
void PopExternalDoubleRef(ScExternalRefCache::TokenArrayRef& rArray); void PopExternalDoubleRef(ScExternalRefCache::TokenArrayRef& rArray);
void PopExternalDoubleRef(ScMatrixRef& rMat); void PopExternalDoubleRef(ScMatrixRef& rMat);
...@@ -427,6 +429,7 @@ void ScIsNonString(); ...@@ -427,6 +429,7 @@ void ScIsNonString();
void ScIsLogical(); void ScIsLogical();
void ScType(); void ScType();
void ScCell(); void ScCell();
void ScCellExternal();
void ScIsRef(); void ScIsRef();
void ScIsValue(); void ScIsValue();
void ScIsFormula(); void ScIsFormula();
......
...@@ -171,6 +171,13 @@ void ScCellKeywordTranslator::transKeyword(String& rName, const Locale* pLocale, ...@@ -171,6 +171,13 @@ void ScCellKeywordTranslator::transKeyword(String& rName, const Locale* pLocale,
lclMatchKeyword(rName, spInstance->maStringNameMap, eOpCode, 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() : ScCellKeywordTranslator::ScCellKeywordTranslator() :
maTransWrapper( ::comphelper::getProcessServiceFactory(), maTransWrapper( ::comphelper::getProcessServiceFactory(),
i18n::TransliterationModules_LOWERCASE_UPPERCASE ) i18n::TransliterationModules_LOWERCASE_UPPERCASE )
......
...@@ -2064,7 +2064,21 @@ void ScInterpreter::ScCell() ...@@ -2064,7 +2064,21 @@ void ScInterpreter::ScCell()
ScAddress aCellPos( aPos ); ScAddress aCellPos( aPos );
bool bError = false; bool bError = false;
if( nParamCount == 2 ) if( nParamCount == 2 )
{
switch (GetStackType())
{
case svExternalSingleRef:
case svExternalDoubleRef:
{
// Let's handle external reference separately...
ScCellExternal();
return;
}
default:
;
}
bError = !PopDoubleRefOrSingleRef( aCellPos ); bError = !PopDoubleRefOrSingleRef( aCellPos );
}
String aInfoType( GetString() ); String aInfoType( GetString() );
if( bError || nGlobalError ) if( bError || nGlobalError )
PushIllegalParameter(); PushIllegalParameter();
...@@ -2268,6 +2282,41 @@ void ScInterpreter::ScCell() ...@@ -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() void ScInterpreter::ScIsRef()
{ {
......
...@@ -1442,34 +1442,40 @@ void ScInterpreter::PopExternalSingleRef(sal_uInt16& rFileId, String& rTabName, ...@@ -1442,34 +1442,40 @@ void ScInterpreter::PopExternalSingleRef(sal_uInt16& rFileId, String& rTabName,
void ScInterpreter::PopExternalSingleRef(ScExternalRefCache::TokenRef& rToken, ScExternalRefCache::CellFormat* pFmt) void ScInterpreter::PopExternalSingleRef(ScExternalRefCache::TokenRef& rToken, ScExternalRefCache::CellFormat* pFmt)
{ {
sal_uInt16 nFileId; sal_uInt16 nFileId;
String aTabName; String aTabName;
ScSingleRefData aData; 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) if (nGlobalError)
return; return;
ScExternalRefManager* pRefMgr = pDok->GetExternalRefManager(); ScExternalRefManager* pRefMgr = pDok->GetExternalRefManager();
const OUString* pFile = pRefMgr->getExternalFileName(nFileId); const OUString* pFile = pRefMgr->getExternalFileName(rFileId);
if (!pFile) if (!pFile)
{ {
SetError(errNoName); SetError(errNoName);
return; return;
} }
if (aData.IsTabRel()) if (rRef.IsTabRel())
{ {
OSL_FAIL("ScCompiler::GetToken: external single reference must have an absolute table reference!"); OSL_FAIL("ScCompiler::GetToken: external single reference must have an absolute table reference!");
SetError(errNoRef); SetError(errNoRef);
return; return;
} }
aData.CalcAbsIfRel(aPos); rRef.CalcAbsIfRel(aPos);
ScAddress aAddr(aData.nCol, aData.nRow, aData.nTab); ScAddress aAddr(rRef.nCol, rRef.nRow, rRef.nTab);
ScExternalRefCache::CellFormat aFmt; ScExternalRefCache::CellFormat aFmt;
ScExternalRefCache::TokenRef xNew = pRefMgr->getSingleRefToken( ScExternalRefCache::TokenRef xNew = pRefMgr->getSingleRefToken(
nFileId, aTabName, aAddr, &aPos, NULL, &aFmt); rFileId, rTabName, aAddr, &aPos, NULL, &aFmt);
if (!xNew) if (!xNew)
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment