22#include <rtl/math.hxx>
24#include <osl/diagnose.h>
26#include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp>
27#include <com/sun/star/i18n/CalendarDisplayIndex.hpp>
35OUString getTwoDigitString(sal_Int32 nValue)
37 OUString aRet = OUString::number( nValue );
38 if ( aRet.getLength() < 2 )
43void appendDateStr(OUStringBuffer& rBuffer,
double fValue,
SvNumberFormatter* pFormatter)
48 rBuffer.append(aString);
51OUString getSpecialDateName(
double fValue,
bool bFirst,
SvNumberFormatter* pFormatter)
54 aBuffer.append( bFirst ?
'<' :
'>' );
55 appendDateStr(aBuffer, fValue, pFormatter);
56 return aBuffer.makeStringAndClear();
75 sal_Int32
n = rName.getLength();
83 for (;
p != pStart; --
p, ++nDupCount)
97 OUStringBuffer
aBuf(rOriginal);
98 for (
size_t i = 0;
i < nDupCount; ++
i)
101 return aBuf.makeStringAndClear();
106 double fStart,
double fEnd)
109 return getSpecialDateName(fStart,
true, pFormatter);
111 return getSpecialDateName(fEnd,
false, pFormatter);
115 case sheet::DataPilotFieldGroupBy::YEARS:
116 return OUString::number(
nValue);
117 case sheet::DataPilotFieldGroupBy::QUARTERS:
119 case css::sheet::DataPilotFieldGroupBy::MONTHS:
121 i18n::CalendarDisplayIndex::MONTH, sal_Int16(
nValue-1), 0);
122 case sheet::DataPilotFieldGroupBy::DAYS:
134 case sheet::DataPilotFieldGroupBy::HOURS:
137 return getTwoDigitString(
nValue);
140 case sheet::DataPilotFieldGroupBy::MINUTES:
141 case sheet::DataPilotFieldGroupBy::SECONDS:
147 OSL_FAIL(
"invalid date part");
150 return "FIXME: unhandled value";
155 if (fValue < rInfo.
mfStart && !rtl::math::approxEqual(fValue, rInfo.
mfStart))
156 return -std::numeric_limits<double>::infinity();
158 if (fValue > rInfo.
mfEnd && !rtl::math::approxEqual(fValue, rInfo.
mfEnd))
159 return std::numeric_limits<double>::infinity();
161 double fDiff = fValue - rInfo.
mfStart;
162 double fDiv = rtl::math::approxFloor( fDiff / rInfo.
mfStep );
165 if (rtl::math::approxEqual(fGroupStart, rInfo.
mfEnd) &&
166 !rtl::math::approxEqual(fGroupStart, rInfo.
mfStart))
190void lcl_AppendDateStr( OUStringBuffer& rBuffer,
double fValue,
SvNumberFormatter* pFormatter )
195 rBuffer.append( aString );
198OUString lcl_GetSpecialNumGroupName(
double fValue,
bool bFirst,
sal_Unicode cDecSeparator,
201 OSL_ENSURE( cDecSeparator != 0,
"cDecSeparator not initialized" );
204 aBuffer.append( bFirst ?
'<' :
'>' );
206 lcl_AppendDateStr( aBuffer, fValue, pFormatter );
208 rtl::math::doubleToUStringBuffer( aBuffer, fValue, rtl_math_StringFormat_Automatic,
209 rtl_math_DecimalPlaces_Max, cDecSeparator,
true );
210 return aBuffer.makeStringAndClear();
213OUString lcl_GetNumGroupName(
217 OSL_ENSURE( cDecSep != 0,
"cDecSeparator not initialized" );
219 double fStep = rInfo.
mfStep;
220 double fEndValue = fStartValue + fStep;
236 fEndValue = rInfo.
mfEnd;
242 lcl_AppendDateStr( aBuffer, fStartValue, pFormatter );
244 lcl_AppendDateStr( aBuffer, fEndValue, pFormatter );
248 rtl::math::doubleToUStringBuffer( aBuffer, fStartValue, rtl_math_StringFormat_Automatic,
249 rtl_math_DecimalPlaces_Max, cDecSep,
true );
251 rtl::math::doubleToUStringBuffer( aBuffer, fEndValue, rtl_math_StringFormat_Automatic,
252 rtl_math_DecimalPlaces_Max, cDecSep,
true );
255 return aBuffer.makeStringAndClear();
263 if ( fValue < rInfo.
mfStart && !rtl::math::approxEqual( fValue, rInfo.
mfStart ) )
264 return lcl_GetSpecialNumGroupName( rInfo.
mfStart,
true, cDecSep, rInfo.
mbDateValues, pFormatter );
266 if ( fValue > rInfo.
mfEnd && !rtl::math::approxEqual( fValue, rInfo.
mfEnd ) )
267 return lcl_GetSpecialNumGroupName( rInfo.
mfEnd,
false, cDecSep, rInfo.
mbDateValues, pFormatter );
269 double fDiff = fValue - rInfo.
mfStart;
270 double fDiv = rtl::math::approxFloor( fDiff / rInfo.
mfStep );
273 if ( rtl::math::approxEqual( fGroupStart, rInfo.
mfEnd ) &&
274 !rtl::math::approxEqual( fGroupStart, rInfo.
mfStart ) )
280 return lcl_GetSpecialNumGroupName( rInfo.
mfEnd,
false, cDecSep, rInfo.
mbDateValues, pFormatter );
284 return lcl_GetNumGroupName(fGroupStart, rInfo, cDecSep, pFormatter);
296 if (fValue < pInfo->mfStart && !rtl::math::approxEqual(fValue, pInfo->
mfStart))
298 if (fValue > pInfo->
mfEnd && !rtl::math::approxEqual(fValue, pInfo->
mfEnd))
302 sal_Int32 nResult = 0;
304 if (nDatePart == sheet::DataPilotFieldGroupBy::HOURS ||
305 nDatePart == sheet::DataPilotFieldGroupBy::MINUTES ||
306 nDatePart == sheet::DataPilotFieldGroupBy::SECONDS)
311 sal_uInt16 nHour, nMinute, nSecond;
312 double fFractionOfSecond;
317 case sheet::DataPilotFieldGroupBy::HOURS:
320 case sheet::DataPilotFieldGroupBy::MINUTES:
323 case sheet::DataPilotFieldGroupBy::SECONDS:
331 aDate.
AddDays(::rtl::math::approxFloor(fValue));
335 case css::sheet::DataPilotFieldGroupBy::YEARS:
338 case css::sheet::DataPilotFieldGroupBy::QUARTERS:
339 nResult = 1 + (aDate.
GetMonth() - 1) / 3;
341 case css::sheet::DataPilotFieldGroupBy::MONTHS:
344 case css::sheet::DataPilotFieldGroupBy::DAYS:
347 nResult = (aDate - aYearStart) + 1;
356 OSL_FAIL(
"invalid date part");
372 STR_FUN_TEXT_PRODUCT,
OUString getDisplayName(sal_Int16 nCalendarDisplayIndex, sal_Int16 nIdx, sal_Int16 nNameType) const
void AddDays(sal_Int32 nAddDays)
sal_Int16 GetYear() const
sal_uInt16 GetMonth() const
const OUString & getTimeSep() const
const OUString & getQuarterAbbreviation(sal_Int16 nQuarter) const
static const sal_Int32 DateFirst
static const sal_Int32 DateLast
static sal_uInt8 getDuplicateIndex(const OUString &rName)
Get a duplicate index in case the dimension is a duplicate.
static SC_DLLPUBLIC OUString getDateGroupName(sal_Int32 nDatePart, sal_Int32 nValue, SvNumberFormatter *pFormatter, double fStart, double fEnd)
static SC_DLLPUBLIC OUString getSourceDimensionName(std::u16string_view rName)
static sal_Int32 getDatePartValue(double fValue, const ScDPNumGroupInfo *pInfo, sal_Int32 nDatePart, const SvNumberFormatter *pFormatter)
static bool isDuplicateDimension(std::u16string_view rName)
static OUString getNumGroupName(double fValue, const ScDPNumGroupInfo &rInfo, sal_Unicode cDecSep, SvNumberFormatter *pFormatter)
static SC_DLLPUBLIC ScSubTotalFunc toSubTotalFunc(ScGeneralFunction eGenFunc)
static SC_DLLPUBLIC OUString createDuplicateDimensionName(const OUString &rOriginal, size_t nDupCount)
static SC_DLLPUBLIC OUString getDisplayedMeasureName(const OUString &rName, ScSubTotalFunc eFunc)
static double getNumGroupStartValue(double fValue, const ScDPNumGroupInfo &rInfo)
static SC_DLLPUBLIC LanguageType eLnge
static SC_DLLPUBLIC const LocaleDataWrapper & getLocaleData()
static CalendarWrapper & GetCalendar()
const sal_uInt16 SC_DP_LEAPYEAR
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.
#define SAL_N_ELEMENTS(arr)
OString stripEnd(const OString &rIn, char c)
constexpr bool ends_with(std::basic_string_view< charT, traits > sv, std::basic_string_view< charT, traits > x) noexcept
OUString ScResId(TranslateId aId)
std::unique_ptr< char[]> aBuffer