36#include <unonames.hxx>
40#include <com/sun/star/chart/ChartAxisLabelPosition.hpp>
41#include <com/sun/star/chart/ChartAxisMarkPosition.hpp>
42#include <com/sun/star/chart/ChartAxisPosition.hpp>
43#include <com/sun/star/chart/TimeInterval.hpp>
44#include <com/sun/star/chart2/XAxis.hpp>
45#include <com/sun/star/chart2/AxisOrientation.hpp>
46#include <com/sun/star/chart2/AxisType.hpp>
48#include <osl/diagnose.h>
54#include <rtl/math.hxx>
58using ::com::sun::star::uno::Reference;
59using ::com::sun::star::chart::TimeInterval;
60using ::com::sun::star::chart::TimeIncrement;
76 return aAxisPropertyMap;
88 const awt::Size* pRefSize ) :
98 rPropertySet, rItemPool, rDrawModel,
115 pConv->FillItemSet( rOutItemSet );
123 bool bResult =
false;
126 bResult = pConv->ApplyItemSet( rItemSet ) || bResult;
141 ItemPropertyMapType::const_iterator aIt( rMap.find( nWhichId ));
143 if( aIt == rMap.end())
146 rOutProperty =(*aIt).second;
155 if( rAny >>= aValue )
165 const chart2::ScaleData& rScale(
m_xAxis->getScaleData() );
166 const chart2::IncrementData& rIncrement( rScale.IncrementData );
168 const TimeIncrement& rTimeIncrement( rScale.TimeIncrement );
169 bool bDateAxis = (rScale.AxisType == chart2::AxisType::DATE);
182 if( rScale.Maximum >>= fMax )
200 if( rScale.Minimum >>= fMin )
215 rOutItemSet.
Put(
SfxBoolItem( nWhichId, (rScale.Orientation == AxisOrientation_REVERSE) ));
228 TimeInterval aTimeInterval;
229 if( rTimeIncrement.MajorTimeInterval >>= aTimeInterval )
239 TimeInterval aTimeInterval;
240 if( rTimeIncrement.MajorTimeInterval >>= aTimeInterval )
247 double fDistance = 1.0;
248 if( rIncrement.Distance >>= fDistance )
261 ! ( rSubIncrements.hasElements() && rSubIncrements[0].IntervalCount.hasValue() )));
266 TimeInterval aTimeInterval;
267 if( rTimeIncrement.MinorTimeInterval >>= aTimeInterval )
277 TimeInterval aTimeInterval;
278 if( rTimeIncrement.MinorTimeInterval >>= aTimeInterval )
285 if( rSubIncrements.hasElements() && rSubIncrements[0].IntervalCount.hasValue())
288 *o3tl::doAccess<sal_Int32>(
289 rSubIncrements[0].IntervalCount) ));
305 !rTimeIncrement.TimeResolution.hasValue() ));
310 sal_Int32 nTimeResolution=0;
311 if( rTimeIncrement.TimeResolution >>= nTimeResolution )
326 double fOrigin = 0.0;
327 if( !(rScale.Origin >>= fOrigin) )
338 css::chart::ChartAxisPosition eAxisPos( css::chart::ChartAxisPosition_ZERO );
339 GetPropertySet()->getPropertyValue(
"CrossoverPosition" ) >>= eAxisPos;
340 rOutItemSet.
Put(
SfxInt32Item( nWhichId,
static_cast<sal_Int32
>(eAxisPos) ) );
362 sal_Int32 nFormatKey = ExplicitValueProvider::getExplicitNumberFormatKeyForAxis(
370 rOutItemSet.
Put(
SfxBoolItem(nWhichId, rScale.ShiftedCategoryPosition));
375 css::chart::ChartAxisLabelPosition
ePos( css::chart::ChartAxisLabelPosition_NEAR_AXIS );
383 css::chart::ChartAxisMarkPosition
ePos( css::chart::ChartAxisMarkPosition_AT_LABELS_AND_AXIS );
397 ::rtl::math::round( fVal * 100.0 )) ) ));
402 case SID_ATTR_NUMBERFORMAT_VALUE:
410 sal_Int32 nFormatKey = ExplicitValueProvider::getExplicitNumberFormatKeyForAxis(
418 case SID_ATTR_NUMBERFORMAT_SOURCE:
420 bool bLinkToSource =
true;
438 sal_Int32 nDimensionIndex=0; sal_Int32 nAxisIndex=0;
441 rOutItemSet.
Put(
SfxBoolItem( nWhichId, bChartTypeAllowsDateAxis ));
450 return (nAxisType == chart2::AxisType::DATE);
470 chart2::ScaleData aScale(
m_xAxis->getScaleData() );
472 bool bSetScale =
false;
473 bool bChangedOtherwise =
false;
482 aScale.Maximum.clear();
494 if( aScale.Maximum != aValue )
496 aScale.Maximum = aValue;
505 aScale.Minimum.clear();
517 if( aScale.Minimum != aValue )
519 aScale.Minimum = aValue;
532 if( ! bWasLogarithm )
552 bool bWasReverse = ( aScale.Orientation == AxisOrientation_REVERSE );
553 bool bNewReverse =
static_cast< const SfxBoolItem &
>(
555 if( bWasReverse != bNewReverse )
557 aScale.Orientation = bNewReverse ? AxisOrientation_REVERSE : AxisOrientation_MATHEMATICAL;
567 aScale.IncrementData.Distance.clear();
568 aScale.TimeIncrement.MajorTimeInterval.clear();
579 TimeInterval aTimeInterval;
580 aScale.TimeIncrement.MajorTimeInterval >>= aTimeInterval;
581 aValue >>= aTimeInterval.TimeUnit;
582 aScale.TimeIncrement.MajorTimeInterval <<= aTimeInterval;
596 if( aValue >>= fValue )
598 TimeInterval aTimeInterval;
599 aScale.TimeIncrement.MajorTimeInterval >>= aTimeInterval;
600 aTimeInterval.Number =
static_cast<sal_Int32
>(fValue);
601 aScale.TimeIncrement.MajorTimeInterval <<= aTimeInterval;
605 else if( aScale.IncrementData.Distance != aValue )
607 aScale.IncrementData.Distance = aValue;
617 if( aScale.IncrementData.SubIncrements.hasElements() &&
618 aScale.IncrementData.SubIncrements[0].IntervalCount.hasValue() )
620 aScale.IncrementData.SubIncrements.getArray()[0].IntervalCount.clear();
623 if( aScale.TimeIncrement.MinorTimeInterval.hasValue() )
625 aScale.TimeIncrement.MinorTimeInterval.clear();
637 TimeInterval aTimeInterval;
638 aScale.TimeIncrement.MinorTimeInterval >>= aTimeInterval;
639 aValue >>= aTimeInterval.TimeUnit;
640 aScale.TimeIncrement.MinorTimeInterval <<= aTimeInterval;
653 TimeInterval aTimeInterval;
654 aScale.TimeIncrement.MinorTimeInterval >>= aTimeInterval;
655 aValue >>= aTimeInterval.Number;
656 aScale.TimeIncrement.MinorTimeInterval <<= aTimeInterval;
659 else if( aScale.IncrementData.SubIncrements.hasElements() )
661 if( ! aScale.IncrementData.SubIncrements[0].IntervalCount.hasValue() ||
662 aScale.IncrementData.SubIncrements[0].IntervalCount != aValue )
664 OSL_ASSERT( aValue.getValueTypeClass() == uno::TypeClass_LONG );
665 aScale.IncrementData.SubIncrements.getArray()[0].IntervalCount = aValue;
675 aScale.TimeIncrement.TimeResolution.clear();
685 if( aScale.TimeIncrement.TimeResolution != aValue )
687 aScale.TimeIncrement.TimeResolution = aValue;
697 aScale.Origin.clear();
710 if( aScale.Origin != aValue )
712 aScale.Origin = aValue;
721 sal_Int32 nDimensionIndex=0;
722 sal_Int32 nAxisIndex=0;
726 if( xCrossingMainAxis.is() )
729 if( aValue >>= fValue )
731 xCrossingMainAxis->setPropertyValue(
"CrossoverPosition" ,
uno::Any( css::chart::ChartAxisPosition_VALUE ));
732 xCrossingMainAxis->setPropertyValue(
"CrossoverValue" ,
uno::Any( fValue ));
735 xCrossingMainAxis->setPropertyValue(
"CrossoverPosition" ,
uno::Any( css::chart::ChartAxisPosition_START ));
746 css::chart::ChartAxisPosition eAxisPos =
747 static_cast<css::chart::ChartAxisPosition
>(
static_cast< const SfxInt32Item &
>( rItemSet.
Get( nWhichId )).
GetValue());
749 css::chart::ChartAxisPosition eOldAxisPos( css::chart::ChartAxisPosition_ZERO );
750 bool bPropExisted = (
GetPropertySet()->getPropertyValue(
"CrossoverPosition" ) >>= eOldAxisPos );
752 if( !bPropExisted || ( eOldAxisPos != eAxisPos ))
755 bChangedOtherwise =
true;
758 if( eAxisPos==css::chart::ChartAxisPosition_START || eAxisPos==css::chart::ChartAxisPosition_END )
762 if( xParallelAxis.is() )
764 css::chart::ChartAxisPosition eOtherPos;
765 if( xParallelAxis->getPropertyValue(
"CrossoverPosition" ) >>= eOtherPos )
767 if( eOtherPos == eAxisPos )
769 css::chart::ChartAxisPosition eOppositePos =
770 (eAxisPos==css::chart::ChartAxisPosition_START)
771 ? css::chart::ChartAxisPosition_END
772 : css::chart::ChartAxisPosition_START;
773 xParallelAxis->setPropertyValue(
"CrossoverPosition" ,
uno::Any( eOppositePos ));
786 double fOldValue = 0.0;
787 bool bPropExisted = (
GetPropertySet()->getPropertyValue(
"CrossoverValue" ) >>= fOldValue );
789 if( !bPropExisted || ( fOldValue != fValue ))
792 bChangedOtherwise =
true;
799 sal_Int32 nDimensionIndex=0;
800 sal_Int32 nAxisIndex=0;
804 if( xCrossingMainAxis.is() )
806 ScaleData aCrossingScale( xCrossingMainAxis->getScaleData() );
807 aCrossingScale.Origin <<= fValue;
808 xCrossingMainAxis->setScaleData(aCrossingScale);
819 bool bOldValue = aScale.ShiftedCategoryPosition;
820 if (bOldValue != bNewValue)
822 aScale.ShiftedCategoryPosition = bNewValue;
830 css::chart::ChartAxisLabelPosition
ePos =
831 static_cast<css::chart::ChartAxisLabelPosition
>(
static_cast< const SfxInt32Item &
>( rItemSet.
Get( nWhichId )).
GetValue());
833 css::chart::ChartAxisLabelPosition eOldPos( css::chart::ChartAxisLabelPosition_NEAR_AXIS );
834 bool bPropExisted = (
GetPropertySet()->getPropertyValue(
"LabelPosition" ) >>= eOldPos );
836 if( !bPropExisted || ( eOldPos !=
ePos ))
839 bChangedOtherwise =
true;
842 if(
ePos==css::chart::ChartAxisLabelPosition_OUTSIDE_START ||
ePos==css::chart::ChartAxisLabelPosition_OUTSIDE_END )
846 if( xParallelAxis.is() )
848 css::chart::ChartAxisLabelPosition eOtherPos;
849 if( xParallelAxis->getPropertyValue(
"LabelPosition" ) >>= eOtherPos )
851 if( eOtherPos ==
ePos )
853 css::chart::ChartAxisLabelPosition eOppositePos =
854 (
ePos==css::chart::ChartAxisLabelPosition_OUTSIDE_START)
855 ? css::chart::ChartAxisLabelPosition_OUTSIDE_END
856 : css::chart::ChartAxisLabelPosition_OUTSIDE_START;
857 xParallelAxis->setPropertyValue(
"LabelPosition" ,
uno::Any( eOppositePos ));
868 css::chart::ChartAxisMarkPosition
ePos =
869 static_cast<css::chart::ChartAxisMarkPosition
>(
static_cast< const SfxInt32Item &
>( rItemSet.
Get( nWhichId )).
GetValue());
871 css::chart::ChartAxisMarkPosition eOldPos( css::chart::ChartAxisMarkPosition_AT_LABELS_AND_AXIS );
872 bool bPropExisted = (
GetPropertySet()->getPropertyValue(
"MarkPosition" ) >>= eOldPos );
874 if( !bPropExisted || ( eOldPos !=
ePos ))
877 bChangedOtherwise =
true;
885 double fOldVal = 0.0;
887 (
GetPropertySet()->getPropertyValue(
"TextRotation" ) >>= fOldVal );
889 if( ! bPropExisted || fOldVal != fVal )
892 bChangedOtherwise =
true;
897 case SID_ATTR_NUMBERFORMAT_VALUE:
901 bool bUseSourceFormat =
902 rItemSet.
Get( SID_ATTR_NUMBERFORMAT_SOURCE ).GetValue();
904 if( ! bUseSourceFormat )
906 sal_Int32 nFmt =
static_cast< sal_Int32
>(
914 bChangedOtherwise =
true;
921 case SID_ATTR_NUMBERFORMAT_SOURCE:
923 bool bUseSourceFormat =
930 bChangedOtherwise = (bUseSourceFormat == bNumberFormatIsSet);
931 if( bChangedOtherwise )
933 if( ! bUseSourceFormat )
936 if( aState == SfxItemState::SET )
938 sal_Int32 nFormatKey =
static_cast< sal_Int32
>(
939 rItemSet.
Get( SID_ATTR_NUMBERFORMAT_VALUE ).GetValue());
940 aValue <<= nFormatKey;
948 sal_Int32 nFormatKey = ExplicitValueProvider::getExplicitNumberFormatKeyForAxis(
951 aValue <<= nFormatKey;
963 aScale.AxisType = nNewAxisType;
971 bool bOldValue = aScale.AutoDateAxis;
972 if( bOldValue != bNewValue )
974 aScale.AutoDateAxis = bNewValue;
982 m_xAxis->setScaleData( aScale );
984 return (bSetScale || bChangedOtherwise);
css::chart::ChartAxisLabelPosition ePos
rtl::Reference<::chart::ChartModel > m_xChartDoc
constexpr TypedWhichId< SfxInt32Item > SCHATTR_AXIS_TICKS(SCHATTR_AXIS_POSITION_START)
constexpr TypedWhichId< SfxBoolItem > SCHATTR_AXIS_LABEL_BREAK(SCHATTR_AXIS_LABEL_START+3)
constexpr TypedWhichId< SfxBoolItem > SCHATTR_AXIS_AUTO_DATEAXIS(SCHATTR_AXIS_START+15)
constexpr TypedWhichId< SfxBoolItem > SCHATTR_AXIS_LABEL_OVERLAP(SCHATTR_AXIS_LABEL_START+2)
constexpr TypedWhichId< SfxBoolItem > SCHATTR_TEXT_STACKED(SCHATTR_TEXT_START+1)
constexpr TypedWhichId< SfxInt32Item > SCHATTR_AXIS_STEP_HELP(SCHATTR_AXIS_START+10)
constexpr TypedWhichId< SfxBoolItem > SCHATTR_AXIS_AUTO_MAX(SCHATTR_AXIS_START+4)
constexpr TypedWhichId< SvxChartTextOrderItem > SCHATTR_AXIS_LABEL_ORDER(SCHATTR_AXIS_LABEL_START+1)
constexpr TypedWhichId< SfxBoolItem > SCHATTR_AXIS_AUTO_STEP_MAIN(SCHATTR_AXIS_START+6)
constexpr TypedWhichId< SfxUInt32Item > SCHATTR_AXIS_CROSSING_MAIN_AXIS_NUMBERFORMAT(SCHATTR_AXIS_POSITION_START+4)
constexpr TypedWhichId< SfxBoolItem > SCHATTR_AXIS_AUTO_STEP_HELP(SCHATTR_AXIS_START+9)
constexpr TypedWhichId< SvxDoubleItem > SCHATTR_AXIS_MIN(SCHATTR_AXIS_START+3)
constexpr TypedWhichId< SfxBoolItem > SCHATTR_AXIS_REVERSE(SCHATTR_AXIS_START+1)
constexpr TypedWhichId< SfxInt32Item > SCHATTR_AXISTYPE(SCHATTR_AXIS_START)
constexpr TypedWhichId< SfxBoolItem > SCHATTR_AXIS_SHOWDESCR(SCHATTR_AXIS_LABEL_START)
constexpr TypedWhichId< SfxBoolItem > SCHATTR_AXIS_AUTO_MIN(SCHATTR_AXIS_START+2)
constexpr TypedWhichId< SfxBoolItem > SCHATTR_AXIS_SHIFTED_CATEGORY_POSITION(SCHATTR_AXIS_POSITION_START+5)
constexpr TypedWhichId< SvxDoubleItem > SCHATTR_AXIS_POSITION_VALUE(SCHATTR_AXIS_POSITION_START+3)
constexpr TypedWhichId< SvxDoubleItem > SCHATTR_AXIS_ORIGIN(SCHATTR_AXIS_START+18)
constexpr TypedWhichId< SfxInt32Item > SCHATTR_AXIS_HELP_TIME_UNIT(SCHATTR_AXIS_START+11)
constexpr TypedWhichId< SdrAngleItem > SCHATTR_TEXT_DEGREES(SCHATTR_TEXT_START)
constexpr TypedWhichId< SfxInt32Item > SCHATTR_AXIS_TIME_RESOLUTION(SCHATTR_AXIS_START+13)
constexpr TypedWhichId< SvxDoubleItem > SCHATTR_AXIS_STEP_MAIN(SCHATTR_AXIS_START+7)
constexpr TypedWhichId< SfxBoolItem > SCHATTR_AXIS_AUTO_ORIGIN(SCHATTR_AXIS_START+17)
constexpr TypedWhichId< SvxDoubleItem > SCHATTR_AXIS_MAX(SCHATTR_AXIS_START+5)
constexpr TypedWhichId< SfxBoolItem > SCHATTR_AXIS_ALLOW_DATEAXIS(SCHATTR_AXIS_START+16)
constexpr TypedWhichId< SfxInt32Item > SCHATTR_AXIS_HELPTICKS(SCHATTR_AXIS_POSITION_START+1)
constexpr TypedWhichId< SfxInt32Item > SCHATTR_AXIS_POSITION(SCHATTR_AXIS_POSITION_START+2)
constexpr TypedWhichId< SfxInt32Item > SCHATTR_AXIS_MAIN_TIME_UNIT(SCHATTR_AXIS_START+8)
constexpr TypedWhichId< SfxInt32Item > SCHATTR_AXIS_LABEL_POSITION(SCHATTR_AXIS_POSITION_START+6)
constexpr TypedWhichId< SfxBoolItem > SCHATTR_AXIS_LOGARITHM(SCHATTR_AXIS_START+14)
constexpr TypedWhichId< SfxBoolItem > SCHATTR_AXIS_AUTO_TIME_RESOLUTION(SCHATTR_AXIS_START+12)
constexpr TypedWhichId< SfxInt32Item > SCHATTR_AXIS_MARK_POSITION(SCHATTR_AXIS_POSITION_START+7)
const WhichRangesContainer nAxisWhichPairs(svl::Items< SCHATTR_TEXT_START, SCHATTR_TEXT_END, SCHATTR_AXIS_START, SCHATTR_AXIS_END, XATTR_LINE_FIRST, XATTR_LINE_LAST, EE_ITEMS_START, EE_ITEMS_END, SID_ATTR_NUMBERFORMAT_VALUE, SID_ATTR_NUMBERFORMAT_VALUE, SID_ATTR_NUMBERFORMAT_SOURCE, SID_ATTR_NUMBERFORMAT_SOURCE, SID_CHAR_DLG_PREVIEW_STRING, SID_CHAR_DLG_PREVIEW_STRING >)
SfxItemState GetItemState(sal_uInt16 nWhich, bool bSrchInParent=true, const SfxPoolItem **ppItem=nullptr) const
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
const SfxPoolItem & Get(sal_uInt16 nWhich, bool bSrchInParent=true) const
virtual bool QueryValue(css::uno::Any &rVal, sal_uInt8 nMemberId=0) const
static bool isLogarithmic(const css::uno::Reference< css::chart2::XScaling > &xScaling)
static rtl::Reference< ::chart::Axis > getCrossingMainAxis(const rtl::Reference< ::chart::Axis > &xAxis, const rtl::Reference< ::chart::BaseCoordinateSystem > &xCooSys)
static rtl::Reference< ::chart::BaseCoordinateSystem > getCoordinateSystemOfAxis(const rtl::Reference< ::chart::Axis > &xAxis, const rtl::Reference< ::chart::Diagram > &xDiagram)
static css::uno::Reference< css::chart2::XScaling > createLinearScaling()
static rtl::Reference< ::chart::Axis > getParallelAxis(const rtl::Reference< ::chart::Axis > &xAxis, const rtl::Reference< ::chart::Diagram > &xDiagram)
static rtl::Reference< ::chart::ChartType > getChartTypeByIndex(const rtl::Reference< ::chart::BaseCoordinateSystem > &xCooSys, sal_Int32 nIndex)
static bool getIndicesForAxis(const rtl::Reference< ::chart::Axis > &xAxis, const rtl::Reference< ::chart::BaseCoordinateSystem > &xCooSys, sal_Int32 &rOutDimensionIndex, sal_Int32 &rOutAxisIndex)
static css::uno::Reference< css::chart2::XScaling > createLogarithmicScaling(double fBase=10.0)
static bool isAxisPositioningEnabled()
static bool isSupportingDateAxis(const rtl::Reference< ::chart::ChartType > &xChartType, sal_Int32 nDimensionIndex)
rtl::Reference<::chart::Axis > m_xAxis
virtual const WhichRangesContainer & GetWhichPairs() const override
implement this method to provide an array of which-ranges
std::unique_ptr< ExplicitIncrementData > m_pExplicitIncrement
virtual bool ApplyItemSet(const SfxItemSet &rItemSet) override
applies all properties that are results of a conversion from all items in rItemSet to the internal XP...
virtual ~AxisItemConverter() override
AxisItemConverter(const css::uno::Reference< css::beans::XPropertySet > &rPropertySet, SfxItemPool &rItemPool, SdrModel &rDrawModel, const rtl::Reference<::chart::ChartModel > &xChartDoc, ExplicitScaleData const *pScale, ExplicitIncrementData const *pIncrement, const css::awt::Size *pRefSize)
rtl::Reference<::chart::ChartModel > m_xChartDoc
std::unique_ptr< ExplicitScaleData > m_pExplicitScale
std::vector< std::unique_ptr< ItemConverter > > m_aConverters
virtual void FillSpecialItem(sal_uInt16 nWhichId, SfxItemSet &rOutItemSet) const override
for items that can not be mapped directly to a property.
virtual bool GetItemProperty(tWhichIdType nWhichId, tPropertyNameWithMemberId &rOutProperty) const override
implement this method to return a Property object for a given which id.
virtual bool ApplySpecialItem(sal_uInt16 nWhichId, const SfxItemSet &rItemSet) override
for items that can not be mapped directly to a property.
virtual void FillItemSet(SfxItemSet &rOutItemSet) const override
applies all properties that can be mapped to items into the given item set.
This class serves for conversion between properties of an XPropertySet and SfxItems in SfxItemSets.
virtual void FillItemSet(SfxItemSet &rOutItemSet) const
applies all properties that can be mapped to items into the given item set.
std::pair< tPropertyNameType, tMemberIdType > tPropertyNameWithMemberId
const css::uno::Reference< css::beans::XPropertySet > & GetPropertySet() const
Returns the XPropertySet that was given in the CTOR and is used to apply items in ApplyItemSet().
virtual bool ApplyItemSet(const SfxItemSet &rItemSet)
applies all properties that are results of a conversion from all items in rItemSet to the internal XP...
static bool lcl_hasTimeIntervalValue(const uno::Any &rAny)
std::map< ItemConverter::tWhichIdType, std::pair< ItemConverter::tPropertyNameType, ItemConverter::tMemberIdType > > ItemPropertyMapType
static bool lcl_isDateAxis(const SfxItemSet &rItemSet)
static bool lcl_isAutoMajor(const SfxItemSet &rItemSet)
static bool lcl_isAutoMinor(const SfxItemSet &rItemSet)
OOO_DLLPUBLIC_CHARTTOOLS bool hasDoubleValue(const css::uno::Any &rAny)
bool getPropertyValue(ValueType &rValue, css::uno::Reference< css::beans::XPropertySet > const &xPropSet, OUString const &propName)
describes how tickmarks are positioned on the scale of an axis.
This structure contains the explicit values for a scale like Minimum and Maximum.
constexpr OUStringLiteral CHART_UNONAME_LINK_TO_SRC_NUMFMT
constexpr OUStringLiteral CHART_UNONAME_NUMFMT