21#include <com/sun/star/util/DateTime.hpp>
22#include <com/sun/star/sheet/GeneralFunction2.hpp>
24#include <tools/datetime.hxx>
47 return sheet::GeneralFunction_SUM;
49 return sheet::GeneralFunction_AUTO;
51 return sheet::GeneralFunction_COUNT;
53 return sheet::GeneralFunction_COUNTNUMS;
55 return sheet::GeneralFunction_PRODUCT;
57 return sheet::GeneralFunction_AVERAGE;
59 return sheet::GeneralFunction_MAX;
61 return sheet::GeneralFunction_MIN;
63 return sheet::GeneralFunction_STDEV;
65 return sheet::GeneralFunction_STDEVP;
67 return sheet::GeneralFunction_VAR;
69 return sheet::GeneralFunction_VARP;
70 return sheet::GeneralFunction_NONE;
134 sal_Int16 eFunction )
192 std::u16string_view rString )
195 return sheet::DataPilotFieldOrientation_COLUMN;
197 return sheet::DataPilotFieldOrientation_ROW;
199 return sheet::DataPilotFieldOrientation_PAGE;
201 return sheet::DataPilotFieldOrientation_DATA;
202 return sheet::DataPilotFieldOrientation_HIDDEN;
206 const sheet::DataPilotFieldOrientation eOrientation )
209 switch( eOrientation )
211 case sheet::DataPilotFieldOrientation_HIDDEN:
214 case sheet::DataPilotFieldOrientation_COLUMN:
217 case sheet::DataPilotFieldOrientation_ROW:
220 case sheet::DataPilotFieldOrientation_PAGE:
223 case sheet::DataPilotFieldOrientation_DATA:
318 OUStringBuffer sBuffer(
sFormula.getLength());
319 bool bInQuotationMarks(
false);
323 for ( ;
p < pStop; ++
p)
327 bInQuotationMarks = !bInQuotationMarks;
328 if (bInQuotationMarks)
330 else if ((c !=
'.') ||
331 !((chPrevious ==
':') || (chPrevious ==
' ') || (chPrevious ==
'=')))
336 sFormula = sBuffer.makeStringAndClear();
348enum ScXMLConditionTokenType
350 XML_COND_TYPE_KEYWORD,
351 XML_COND_TYPE_COMPARISON,
352 XML_COND_TYPE_FUNCTION0,
353 XML_COND_TYPE_FUNCTION1,
354 XML_COND_TYPE_FUNCTION2
357struct ScXMLConditionInfo
360 ScXMLConditionTokenType
meType;
361 sheet::ValidationType meValidation;
362 sheet::ConditionOperator meOperator;
363 const char* mpcIdentifier;
364 sal_Int32 mnIdentLength;
367const ScXMLConditionInfo spConditionInfos[] =
369 {
XML_COND_AND, XML_COND_TYPE_KEYWORD, sheet::ValidationType_ANY, sheet::ConditionOperator_NONE, RTL_CONSTASCII_STRINGPARAM(
"and" ) },
370 {
XML_COND_CELLCONTENT, XML_COND_TYPE_COMPARISON, sheet::ValidationType_ANY, sheet::ConditionOperator_NONE, RTL_CONSTASCII_STRINGPARAM(
"cell-content" ) },
371 {
XML_COND_ISBETWEEN, XML_COND_TYPE_FUNCTION2, sheet::ValidationType_ANY, sheet::ConditionOperator_BETWEEN, RTL_CONSTASCII_STRINGPARAM(
"cell-content-is-between" ) },
372 {
XML_COND_ISNOTBETWEEN, XML_COND_TYPE_FUNCTION2, sheet::ValidationType_ANY, sheet::ConditionOperator_NOT_BETWEEN, RTL_CONSTASCII_STRINGPARAM(
"cell-content-is-not-between" ) },
373 {
XML_COND_ISWHOLENUMBER, XML_COND_TYPE_FUNCTION0, sheet::ValidationType_WHOLE, sheet::ConditionOperator_NONE, RTL_CONSTASCII_STRINGPARAM(
"cell-content-is-whole-number" ) },
374 {
XML_COND_ISDECIMALNUMBER, XML_COND_TYPE_FUNCTION0, sheet::ValidationType_DECIMAL, sheet::ConditionOperator_NONE, RTL_CONSTASCII_STRINGPARAM(
"cell-content-is-decimal-number" ) },
375 {
XML_COND_ISDATE, XML_COND_TYPE_FUNCTION0, sheet::ValidationType_DATE, sheet::ConditionOperator_NONE, RTL_CONSTASCII_STRINGPARAM(
"cell-content-is-date" ) },
376 {
XML_COND_ISTIME, XML_COND_TYPE_FUNCTION0, sheet::ValidationType_TIME, sheet::ConditionOperator_NONE, RTL_CONSTASCII_STRINGPARAM(
"cell-content-is-time" ) },
377 {
XML_COND_ISINLIST, XML_COND_TYPE_FUNCTION1, sheet::ValidationType_LIST, sheet::ConditionOperator_EQUAL, RTL_CONSTASCII_STRINGPARAM(
"cell-content-is-in-list" ) },
378 {
XML_COND_TEXTLENGTH, XML_COND_TYPE_COMPARISON, sheet::ValidationType_TEXT_LEN, sheet::ConditionOperator_NONE, RTL_CONSTASCII_STRINGPARAM(
"cell-content-text-length" ) },
379 {
XML_COND_TEXTLENGTH_ISBETWEEN, XML_COND_TYPE_FUNCTION2, sheet::ValidationType_TEXT_LEN, sheet::ConditionOperator_BETWEEN, RTL_CONSTASCII_STRINGPARAM(
"cell-content-text-length-is-between" ) },
380 {
XML_COND_TEXTLENGTH_ISNOTBETWEEN, XML_COND_TYPE_FUNCTION2, sheet::ValidationType_TEXT_LEN, sheet::ConditionOperator_NOT_BETWEEN, RTL_CONSTASCII_STRINGPARAM(
"cell-content-text-length-is-not-between" ) },
381 {
XML_COND_ISTRUEFORMULA, XML_COND_TYPE_FUNCTION1, sheet::ValidationType_CUSTOM, sheet::ConditionOperator_FORMULA, RTL_CONSTASCII_STRINGPARAM(
"is-true-formula" ) }
386 while( (rpcString < pcEnd) && (*rpcString <=
' ') ) ++rpcString;
391 lclSkipWhitespace( rpcString, pcEnd );
395 while( (rpcString < pcEnd) && (((*rpcString >=
'a') && (*rpcString <=
'z')) || (*rpcString ==
'-')) ) ++rpcString;
396 sal_Int32
nLength =
static_cast< sal_Int32
>( rpcString - pcIdStart );
400 for(
auto const &rInfo : spConditionInfos)
401 if((nLength == rInfo.mnIdentLength)
402 && (::rtl_ustr_ascii_shortenedCompare_WithLength(pcIdStart, nLength, rInfo.mpcIdentifier, nLength) == 0) )
408sheet::ConditionOperator lclGetConditionOperator(
const sal_Unicode*& rpcString,
const sal_Unicode* pcEnd )
411 if( (rpcString + 1 < pcEnd) && (rpcString[ 1 ] ==
'=') )
413 sheet::ConditionOperator eOperator = sheet::ConditionOperator_NONE;
416 case '!': eOperator = sheet::ConditionOperator_NOT_EQUAL;
break;
417 case '<': eOperator = sheet::ConditionOperator_LESS_EQUAL;
break;
418 case '>': eOperator = sheet::ConditionOperator_GREATER_EQUAL;
break;
420 if( eOperator != sheet::ConditionOperator_NONE )
428 if( rpcString < pcEnd )
430 sheet::ConditionOperator eOperator = sheet::ConditionOperator_NONE;
433 case '=': eOperator = sheet::ConditionOperator_EQUAL;
break;
434 case '<': eOperator = sheet::ConditionOperator_LESS;
break;
435 case '>': eOperator = sheet::ConditionOperator_GREATER;
break;
437 if( eOperator != sheet::ConditionOperator_NONE )
444 return sheet::ConditionOperator_NONE;
463 if( rpcString < pcEnd )
465 sal_Int32
nLength =
static_cast< sal_Int32
>( pcEnd - rpcString );
466 sal_Int32 nNextQuote = ::rtl_ustr_indexOfChar_WithLength( rpcString, nLength, cQuoteChar );
467 if( nNextQuote >= 0 )
468 rpcString += nNextQuote;
490 while( rpcString < pcEnd )
492 if( *rpcString == cEndChar )
496 case '(': lclSkipExpression( ++rpcString, pcEnd,
')' );
break;
497 case '{': lclSkipExpression( ++rpcString, pcEnd,
'}' );
break;
498 case '"': lclSkipExpressionString( ++rpcString, pcEnd,
'"' );
break;
499 case '\'': lclSkipExpressionString( ++rpcString, pcEnd,
'\'' );
break;
501 if( rpcString < pcEnd ) ++rpcString;
527 if( (rpcString < pcEnd) && (*rpcString ==
'(') )
529 lclSkipWhitespace( ++rpcString, pcEnd );
530 if( (rpcString < pcEnd) && (*rpcString ==
')') )
545 if( (nStartIndex < 0) || (nStartIndex >= rAttribute.getLength()) )
return;
549 const sal_Unicode* pcString = pcBegin + nStartIndex;
550 const sal_Unicode* pcEnd = pcBegin + rAttribute.getLength();
551 const ScXMLConditionInfo* pCondInfo = lclGetConditionInfo( pcString, pcEnd );
557 rParseResult.
meOperator = pCondInfo->meOperator;
559 switch( pCondInfo->meType )
561 case XML_COND_TYPE_KEYWORD:
563 rParseResult.
meToken = pCondInfo->meToken;
566 case XML_COND_TYPE_COMPARISON:
568 if( lclSkipEmptyParentheses( pcString, pcEnd ) )
570 rParseResult.
meOperator = lclGetConditionOperator( pcString, pcEnd );
571 if( rParseResult.
meOperator != sheet::ConditionOperator_NONE )
573 lclSkipWhitespace( pcString, pcEnd );
574 if( pcString < pcEnd )
576 rParseResult.
meToken = pCondInfo->meToken;
578 rParseResult.
maOperand1 = OUString( pcString,
static_cast< sal_Int32
>( pcEnd - pcString ) );
584 case XML_COND_TYPE_FUNCTION0:
586 if( lclSkipEmptyParentheses( pcString, pcEnd ) )
587 rParseResult.
meToken = pCondInfo->meToken;
590 case XML_COND_TYPE_FUNCTION1:
592 if( (pcString < pcEnd) && (*pcString ==
'(') )
596 rParseResult.
meToken = pCondInfo->meToken;
600 case XML_COND_TYPE_FUNCTION2:
602 if( (pcString < pcEnd) && (*pcString ==
'(') )
609 rParseResult.
meToken = pCondInfo->meToken;
614 rParseResult.
mnEndIndex =
static_cast< sal_Int32
>( pcString - pcBegin );
621 lclSkipExpression( rpcString, pcEnd, cEndChar );
622 if( rpcString < pcEnd )
624 aExp = OUString( pcExpStart,
static_cast< sal_Int32
>( rpcString - pcExpStart ) ).trim();
@ XML_COND_ISNOTBETWEEN
The 'cell-content-is-between' token.
@ XML_COND_ISTIME
The 'cell-content-is-date' token.
@ XML_COND_AND
Token not recognized.
@ XML_COND_CELLCONTENT
The 'and' token.
@ XML_COND_TEXTLENGTH
The 'cell-content-is-in-list' token.
@ XML_COND_TEXTLENGTH_ISBETWEEN
The 'cell-content-text-length' token.
@ XML_COND_ISTRUEFORMULA
The 'cell-content-text-length-is-not-between' token.
@ XML_COND_ISWHOLENUMBER
The 'cell-content-is-not-between' token.
@ XML_COND_ISINLIST
The 'cell-content-is-time' token.
@ XML_COND_ISBETWEEN
The 'cell-content' token.
@ XML_COND_ISDATE
The 'cell-content-is-decimal-number' token.
@ XML_COND_ISDECIMALNUMBER
The 'cell-content-is-whole-number' token.
@ XML_COND_TEXTLENGTH_ISNOTBETWEEN
The 'cell-content-text-length-is-between' token.
css::util::DateTime GetUNODateTime() const
ScDocument * GetDocument() const
static void AssignString(OUString &rString, const OUString &rNewStr, bool bAppendStr, sal_Unicode cSeparator=' ')
helper methods
static ScSubTotalFunc GetSubTotalFuncFromString(std::u16string_view rString)
static OUString GetStringFromOrientation(const css::sheet::DataPilotFieldOrientation eOrientation)
static OUString GetStringFromFunction(const sal_Int16 eFunction)
static void ConvertDateTimeToString(const DateTime &aDateTime, OUStringBuffer &sDate)
static css::sheet::GeneralFunction GetFunctionFromString(std::u16string_view rString)
static void ConvertCellRangeAddress(OUString &sFormula)
static css::sheet::DataPilotFieldOrientation GetOrientationFromString(std::u16string_view rString)
static ScDocument * GetScDocument(const css::uno::Reference< css::frame::XModel > &xModel)
static bool GetDetOpTypeFromString(ScDetOpType &rDetOpType, std::u16string_view rString)
static OUString GetStringFromDetObjType(const ScDetectiveObjType eObjType)
static ScGeneralFunction GetFunctionFromString2(std::u16string_view rString)
static OUString GetStringFromDetOpType(const ScDetOpType eOpType)
static ScDetectiveObjType GetDetObjTypeFromString(std::u16string_view rString)
static void convertDateTime(OUStringBuffer &rBuffer, const css::util::DateTime &rDateTime, sal_Int16 const *pTimeZoneOffset, bool bAddTimeIf0AM=false)
ScGeneralFunction
the css::sheet::GeneralFunction enum is extended by constants in GeneralFunction2,...
@ AVERAGE
average of all numerical values is calculated.
@ PRODUCT
product of all numerical values is calculated.
@ MAX
maximum value of all numerical values is calculated.
@ COUNT
all values, including non-numerical values, are counted.
@ VARP
variance is calculated based on the entire population.
@ SUM
sum of all numerical values is calculated.
@ STDEVP
standard deviation is calculated based on the entire population.
@ MEDIAN
median of all numerical values is calculated.
@ COUNTNUMS
numerical values are counted.
@ NONE
nothing is calculated.
@ MIN
minimum value of all numerical values is calculated.
@ VAR
variance is calculated based on a sample.
@ AUTO
function is determined automatically.
@ STDEV
standard deviation is calculated based on a sample.
@ SUBTOTAL_FUNC_SELECTION_COUNT
void parseCondition(ScXMLConditionParseResult &rParseResult, const OUString &rAttribute, sal_Int32 nStartIndex)
Parses the next condition in a 'condition' attribute value of e.g.
OUString getExpression(const sal_Unicode *&rpcString, const sal_Unicode *pcEnd, sal_Unicode cEndChar)
bool IsXMLToken(std::u16string_view rString, enum XMLTokenEnum eToken)
const OUString & GetXMLToken(enum XMLTokenEnum eToken)
Result of an attempt to parse a single condition in a 'condition' attribute value of e....
OUString maOperand2
First operand of the token or comparison value.
css::sheet::ValidationType meValidation
The leading condition token.
OUString maOperand1
A comparison operator if existing.
css::sheet::ConditionOperator meOperator
A data validation type if existing.
sal_Int32 mnEndIndex
Second operand of 'between' conditions.
ScXMLConditionToken meToken
Reference< XModel > xModel