summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEike Rathke <erack@redhat.com>2015-06-26 15:12:46 +0200
committerEike Rathke <erack@redhat.com>2015-06-26 15:19:52 +0200
commit0c8778ce1df92ca3bc2a8dd2f64568fb257e9e39 (patch)
treebdcb65537d59d4f126feb00ce77aa02766d1688d
parent198b5aac12751e7f64e398935313077d8c412a8b (diff)
tdf#44419 allow A:A and 1:1 references also in Calc A1 and ODF syntax
They still get displayed as A1:A1048576 and A1:AMJ1 but are accepted as input. Change-Id: I6a44ce56767695af874e9f5122501a4c7925b0d6
-rw-r--r--sc/source/core/tool/address.cxx46
1 files changed, 42 insertions, 4 deletions
diff --git a/sc/source/core/tool/address.cxx b/sc/source/core/tool/address.cxx
index 18087a445197..dbcfb15c38dc 100644
--- a/sc/source/core/tool/address.cxx
+++ b/sc/source/core/tool/address.cxx
@@ -1031,14 +1031,21 @@ static sal_uInt16 lcl_ScRange_Parse_XL_A1( ScRange& r,
/**
@param p pointer to null-terminated sal_Unicode string
+ @param rRawRes returns SCA_... flags without the final check for full
+ validity that is applied to the return value, with which
+ two addresses that form a column or row singleton range,
+ e.g. A:A or 1:1, can be detected. Used in
+ lcl_ScRange_Parse_OOo().
@param pRange pointer to range where rAddr effectively is *pRange->aEnd,
used in conjunction with pExtInfo to determine the tab span
of a 3D reference.
*/
static sal_uInt16 lcl_ScAddress_Parse_OOo( const sal_Unicode* p, ScDocument* pDoc, ScAddress& rAddr,
+ sal_uInt16& rRawRes,
ScAddress::ExternalInfo* pExtInfo = NULL, ScRange* pRange = NULL )
{
sal_uInt16 nRes = 0;
+ rRawRes = 0;
OUString aDocName; // the pure Document Name
OUString aTab;
bool bExtDoc = false;
@@ -1263,6 +1270,8 @@ static sal_uInt16 lcl_ScAddress_Parse_OOo( const sal_Unicode* p, ScDocument* pDo
}
}
+ rRawRes |= nRes;
+
if ( !(nRes & SCA_VALID_ROW) && (nRes & SCA_VALID_COL)
&& !( (nRes & SCA_TAB_3D) && (nRes & SCA_VALID_TAB)) )
{ // no Row, no Tab, but Col => DM (...), B (...) et al
@@ -1309,7 +1318,8 @@ static sal_uInt16 lcl_ScAddress_Parse ( const sal_Unicode* p, ScDocument* pDoc,
default :
case formula::FormulaGrammar::CONV_OOO:
{
- return lcl_ScAddress_Parse_OOo( p, pDoc, rAddr, pExtInfo, NULL );
+ sal_uInt16 nRawRes = 0;
+ return lcl_ScAddress_Parse_OOo( p, pDoc, rAddr, nRawRes, pExtInfo, NULL );
}
}
}
@@ -1460,10 +1470,35 @@ static sal_uInt16 lcl_ScRange_Parse_OOo( ScRange& rRange,
OUStringBuffer aTmp(r);
aTmp[nPos] = 0;
const sal_Unicode* p = aTmp.getStr();
- if( (nRes1 = lcl_ScAddress_Parse_OOo( p, pDoc, rRange.aStart, pExtInfo, NULL ) ) != 0 )
+ sal_uInt16 nRawRes1 = 0;
+ if (((nRes1 = lcl_ScAddress_Parse_OOo( p, pDoc, rRange.aStart, nRawRes1, pExtInfo, NULL)) != 0) ||
+ ((nRawRes1 & (SCA_VALID_COL | SCA_VALID_ROW)) && (nRawRes1 & SCA_VALID_TAB)))
{
rRange.aEnd = rRange.aStart; // sheet must be initialized identical to first sheet
- if ( (nRes2 = lcl_ScAddress_Parse_OOo( p + nPos+ 1, pDoc, rRange.aEnd, pExtInfo, &rRange ) ) != 0 )
+ sal_uInt16 nRawRes2 = 0;
+ nRes2 = lcl_ScAddress_Parse_OOo( p + nPos+ 1, pDoc, rRange.aEnd, nRawRes2, pExtInfo, &rRange);
+ if (!((nRes1 & SCA_VALID) && (nRes2 & SCA_VALID)) &&
+ // If not fully valid addresses, check if both have a valid
+ // column or row, and both have valid (or omitted) sheet references.
+ (nRawRes1 & (SCA_VALID_COL | SCA_VALID_ROW)) && (nRawRes1 & SCA_VALID_TAB) &&
+ (nRawRes2 & (SCA_VALID_COL | SCA_VALID_ROW)) && (nRawRes2 & SCA_VALID_TAB) &&
+ // Both must be column XOR row references, A:A or 1:1 but not A:1 or 1:A
+ ((nRawRes1 & (SCA_VALID_COL | SCA_VALID_ROW)) == (nRawRes2 & (SCA_VALID_COL | SCA_VALID_ROW))))
+ {
+ nRes1 = nRawRes1 | SCA_VALID;
+ nRes2 = nRawRes2 | SCA_VALID;
+ if (nRawRes1 & SCA_VALID_COL)
+ {
+ rRange.aStart.SetRow(0);
+ rRange.aEnd.SetRow(MAXROW);
+ }
+ else
+ {
+ rRange.aStart.SetCol(0);
+ rRange.aEnd.SetCol(MAXCOL);
+ }
+ }
+ if (nRes1 && nRes2)
{
// PutInOrder / Justify
sal_uInt16 nMask, nBits1, nBits2;
@@ -1503,7 +1538,10 @@ static sal_uInt16 lcl_ScRange_Parse_OOo( ScRange& rRange,
nRes2 |= SCA_TAB_ABSOLUTE;
}
else
- nRes1 = 0; // keine Tokens aus halben Sachen
+ {
+ // Don't leave around valid half references.
+ nRes1 = nRes2 = 0;
+ }
}
}
nRes1 = ( ( nRes1 | nRes2 ) & SCA_VALID )