Kaydet (Commit) 2c454f19 authored tarafından Eike Rathke's avatar Eike Rathke Kaydeden (comit) Andras Timar

TableRef: generate error for header-less column references, tdf#91278 related

... instead of using an arbitray first data record's string as column
name. We don't support header-less tables properly yet, so don't pretend
to.

Squashed 4 commits into one:

add optional ContainsHeader property

great we never had this :-(

(cherry picked from commit 6dddd1aa)

handle ContainsHeader property at database range

(cherry picked from commit ed497c01)

clear HasHeader at database range if table headerRowCount is 0

(cherry picked from commit 22c9977d)

TableRef: generate error for header-less column references, tdf#91278 related

... instead of using an arbitray first data record's string as column
name. We don't support header-less tables properly yet, so don't pretend
to.

(cherry picked from commit d7794792)

Change-Id: Id79b08ff9dfe42228ed7d6b27ad0c8cc29b1bfb0
f0d54ab1dee6c861b973dc490f6c4a1e11260546
1cf5b0ac3884320f39d439b6eecf0b39cdf6bc49
a42619ec800291b6617a61c8a89a2d54ef231cec
Reviewed-on: https://gerrit.libreoffice.org/17321Tested-by: 's avatarJenkins <ci@libreoffice.org>
Reviewed-by: 's avatarMarkus Mohrhard <markus.mohrhard@googlemail.com>
Tested-by: 's avatarMarkus Mohrhard <markus.mohrhard@googlemail.com>
üst 5ecb03be
...@@ -118,6 +118,13 @@ published service DatabaseRange ...@@ -118,6 +118,13 @@ published service DatabaseRange
@since LibreOffice 5.0 @since LibreOffice 5.0
*/ */
[optional, property] boolean TotalsRow; [optional, property] boolean TotalsRow;
/** specifies whether this range includes a top row of headers.
@since LibreOffice 5.0
*/
[optional, property] boolean ContainsHeader;
}; };
......
...@@ -3518,35 +3518,38 @@ bool ScCompiler::IsTableRefColumn( const OUString& rName ) const ...@@ -3518,35 +3518,38 @@ bool ScCompiler::IsTableRefColumn( const OUString& rName ) const
aRange.aEnd.SetTab( aRange.aStart.Tab()); aRange.aEnd.SetTab( aRange.aStart.Tab());
aRange.aEnd.SetRow( aRange.aStart.Row()); aRange.aEnd.SetRow( aRange.aStart.Row());
// Quite similar to IsColRowName() but limited to one row of headers. if (pDBData->HasHeader())
ScCellIterator aIter( pDoc, aRange);
for (bool bHas = aIter.first(); bHas; bHas = aIter.next())
{ {
CellType eType = aIter.getType(); // Quite similar to IsColRowName() but limited to one row of headers.
bool bOk = false; ScCellIterator aIter( pDoc, aRange);
if (eType == CELLTYPE_FORMULA) for (bool bHas = aIter.first(); bHas; bHas = aIter.next())
{ {
ScFormulaCell* pFC = aIter.getFormulaCell(); CellType eType = aIter.getType();
bOk = (pFC->GetCode()->GetCodeLen() > 0) && (pFC->aPos != aPos); bool bOk = false;
} if (eType == CELLTYPE_FORMULA)
else {
bOk = true; ScFormulaCell* pFC = aIter.getFormulaCell();
bOk = (pFC->GetCode()->GetCodeLen() > 0) && (pFC->aPos != aPos);
}
else
bOk = true;
if (bOk && aIter.hasString()) if (bOk && aIter.hasString())
{
OUString aStr = aIter.getString();
if (ScGlobal::GetpTransliteration()->isEqual( aStr, aName))
{ {
/* XXX NOTE: we could init the column as relative so copying a OUString aStr = aIter.getString();
* formula across columns would point to the relative column, if (ScGlobal::GetpTransliteration()->isEqual( aStr, aName))
* but do it absolute because: {
* a) it makes the reference work in named expressions without /* XXX NOTE: we could init the column as relative so copying a
* having to distinguish * formula across columns would point to the relative column,
* b) Excel does it the same. */ * but do it absolute because:
ScSingleRefData aRef; * a) it makes the reference work in named expressions without
aRef.InitAddress( aIter.GetPos()); * having to distinguish
maRawToken.SetSingleReference( aRef ); * b) Excel does it the same. */
return true; ScSingleRefData aRef;
aRef.InitAddress( aIter.GetPos());
maRawToken.SetSingleReference( aRef );
return true;
}
} }
} }
} }
...@@ -3558,11 +3561,26 @@ bool ScCompiler::IsTableRefColumn( const OUString& rName ) const ...@@ -3558,11 +3561,26 @@ bool ScCompiler::IsTableRefColumn( const OUString& rName ) const
sal_Int32 nOffset = pDBData->GetColumnNameOffset( aName); sal_Int32 nOffset = pDBData->GetColumnNameOffset( aName);
if (nOffset >= 0) if (nOffset >= 0)
{ {
ScSingleRefData aRef; if (pDBData->HasHeader())
ScAddress aAdr( aRange.aStart); {
aAdr.IncCol( nOffset); ScSingleRefData aRef;
aRef.InitAddress( aAdr); ScAddress aAdr( aRange.aStart);
maRawToken.SetSingleReference( aRef ); aAdr.IncCol( nOffset);
aRef.InitAddress( aAdr);
maRawToken.SetSingleReference( aRef );
}
else
{
/* TODO: this probably needs a new token type to hold offset and
* name, to be handled in HandleTableRef(). We can't use a
* reference token here because any reference would be wrong as
* there are no header cells to be referenced. However, it would
* only work as long as the ScDBData column names are not
* invalidated during document structure changes, otherwise
* recompiling the same formula could not resolve the name again.
* As long as this doesn't work generate an error. */
return false;
}
return true; return true;
} }
......
...@@ -94,6 +94,15 @@ void Table::finalizeImport() ...@@ -94,6 +94,15 @@ void Table::finalizeImport()
PropertySet aPropSet( xDatabaseRange ); PropertySet aPropSet( xDatabaseRange );
// Default HasHeader is true at ScDBData.
if (maModel.mnHeaderRows != 1)
{
SAL_WARN_IF( maModel.mnHeaderRows > 1, "sc.filter",
"Table HeaderRows > 1 not supported: " << maModel.mnHeaderRows);
if (maModel.mnHeaderRows == 0)
aPropSet.setProperty( PROP_ContainsHeader, false);
}
if (maModel.mnTotalsRows > 0) if (maModel.mnTotalsRows > 0)
{ {
SAL_WARN_IF( maModel.mnTotalsRows > 1, "sc.filter", SAL_WARN_IF( maModel.mnTotalsRows > 1, "sc.filter",
......
...@@ -123,6 +123,7 @@ static const SfxItemPropertyMapEntry* lcl_GetDBRangePropertyMap() ...@@ -123,6 +123,7 @@ static const SfxItemPropertyMapEntry* lcl_GetDBRangePropertyMap()
{OUString(SC_UNONAME_TOKENINDEX),0, cppu::UnoType<sal_Int32>::get(), beans::PropertyAttribute::READONLY, 0 }, {OUString(SC_UNONAME_TOKENINDEX),0, cppu::UnoType<sal_Int32>::get(), beans::PropertyAttribute::READONLY, 0 },
{OUString(SC_UNONAME_USEFLTCRT),0, cppu::UnoType<bool>::get(), 0, 0}, {OUString(SC_UNONAME_USEFLTCRT),0, cppu::UnoType<bool>::get(), 0, 0},
{OUString(SC_UNONAME_TOTALSROW),0, cppu::UnoType<bool>::get(), 0, 0}, {OUString(SC_UNONAME_TOTALSROW),0, cppu::UnoType<bool>::get(), 0, 0},
{OUString(SC_UNONAME_CONTHDR) ,0, cppu::UnoType<bool>::get(), 0, 0},
{ OUString(), 0, css::uno::Type(), 0, 0 } { OUString(), 0, css::uno::Type(), 0, 0 }
}; };
return aDBRangePropertyMap_Impl; return aDBRangePropertyMap_Impl;
...@@ -2085,6 +2086,8 @@ void SAL_CALL ScDatabaseRangeObj::setPropertyValue( ...@@ -2085,6 +2086,8 @@ void SAL_CALL ScDatabaseRangeObj::setPropertyValue(
} }
else if ( aString == SC_UNONAME_TOTALSROW ) else if ( aString == SC_UNONAME_TOTALSROW )
aNewData.SetTotals( ScUnoHelpFunctions::GetBoolFromAny( aValue ) ); aNewData.SetTotals( ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
else if ( aString == SC_UNONAME_CONTHDR )
aNewData.SetHeader( ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
else else
bDo = false; bDo = false;
...@@ -2170,6 +2173,12 @@ uno::Any SAL_CALL ScDatabaseRangeObj::getPropertyValue( const OUString& aPropert ...@@ -2170,6 +2173,12 @@ uno::Any SAL_CALL ScDatabaseRangeObj::getPropertyValue( const OUString& aPropert
ScUnoHelpFunctions::SetBoolInAny( aRet, bTotals ); ScUnoHelpFunctions::SetBoolInAny( aRet, bTotals );
} }
else if (aString == SC_UNONAME_CONTHDR )
{
bool bHeader(GetDBData_Impl()->HasHeader());
ScUnoHelpFunctions::SetBoolInAny( aRet, bHeader );
}
} }
return aRet; return aRet;
} }
......
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