From 3b5ee26d2c27b9fb8d3836c470832fc81cda721f Mon Sep 17 00:00:00 2001 From: Eike Rathke Date: Tue, 22 Nov 2011 14:29:35 +0100 Subject: added partitive case month names * Locale data: * nominative (nouns) month names always given in element * optional genitive case month names in element, following the element; if not given take nominative names * optional partitive case month names in element, following the element, or following the element if the element is not present; if not given take genitive case names, or nominative if genitive names aren't defined * currently known partitive case matters in Finnish locales * Rules for use of nominative / genitive / partitive case month names in number formatter: * no day of month (D or DD) present in format code => MMM or MMMM display nominative month name (noun) * day of month (D or DD) after MMM or MMMM => genitive name * no genitive names defined => nominative names * day of month (D or DD) before MMM or MMMM => partitive name * no partitive names defined => genitive names * no genitive names defined => nominative names --- i18npool/inc/calendarImpl.hxx | 1 + i18npool/inc/calendar_gregorian.hxx | 1 + i18npool/source/calendar/calendarImpl.cxx | 10 ++ i18npool/source/calendar/calendar_gregorian.cxx | 23 ++++ i18npool/source/localedata/LocaleNode.cxx | 48 +++++++++ i18npool/source/localedata/data/locale.dtd | 12 ++- i18npool/source/localedata/localedata.cxx | 12 ++- offapi/com/sun/star/i18n/Calendar2.idl | 17 ++- offapi/com/sun/star/i18n/CalendarDisplayCode.idl | 95 ++++++++++------- offapi/com/sun/star/i18n/CalendarDisplayIndex.idl | 25 +++-- offapi/com/sun/star/i18n/XCalendar3.idl | 6 ++ svl/inc/svl/zformat.hxx | 23 ++-- svl/source/numbers/zforfind.cxx | 28 +++++ svl/source/numbers/zforfind.hxx | 2 + svl/source/numbers/zformat.cxx | 123 ++++++++++++++-------- unotools/inc/unotools/calendarwrapper.hxx | 1 + unotools/source/i18n/calendarwrapper.cxx | 21 ++++ 17 files changed, 341 insertions(+), 107 deletions(-) diff --git a/i18npool/inc/calendarImpl.hxx b/i18npool/inc/calendarImpl.hxx index da69ef886a5a..c71800619864 100644 --- a/i18npool/inc/calendarImpl.hxx +++ b/i18npool/inc/calendarImpl.hxx @@ -90,6 +90,7 @@ public: virtual com::sun::star::uno::Sequence < CalendarItem2 > SAL_CALL getDays2() throw(com::sun::star::uno::RuntimeException); virtual com::sun::star::uno::Sequence < CalendarItem2 > SAL_CALL getMonths2() throw(com::sun::star::uno::RuntimeException); virtual com::sun::star::uno::Sequence < CalendarItem2 > SAL_CALL getGenitiveMonths2() throw(com::sun::star::uno::RuntimeException); + virtual com::sun::star::uno::Sequence < CalendarItem2 > SAL_CALL getPartitiveMonths2() throw(com::sun::star::uno::RuntimeException); //XServiceInfo virtual rtl::OUString SAL_CALL getImplementationName() throw(com::sun::star::uno::RuntimeException); diff --git a/i18npool/inc/calendar_gregorian.hxx b/i18npool/inc/calendar_gregorian.hxx index 42d7599d59d6..03e4e8161d93 100644 --- a/i18npool/inc/calendar_gregorian.hxx +++ b/i18npool/inc/calendar_gregorian.hxx @@ -89,6 +89,7 @@ public: virtual com::sun::star::uno::Sequence < CalendarItem2 > SAL_CALL getDays2() throw(com::sun::star::uno::RuntimeException); virtual com::sun::star::uno::Sequence < CalendarItem2 > SAL_CALL getMonths2() throw(com::sun::star::uno::RuntimeException); virtual com::sun::star::uno::Sequence < CalendarItem2 > SAL_CALL getGenitiveMonths2() throw(com::sun::star::uno::RuntimeException); + virtual com::sun::star::uno::Sequence < CalendarItem2 > SAL_CALL getPartitiveMonths2() throw(com::sun::star::uno::RuntimeException); //XServiceInfo virtual rtl::OUString SAL_CALL getImplementationName() throw(com::sun::star::uno::RuntimeException); diff --git a/i18npool/source/calendar/calendarImpl.cxx b/i18npool/source/calendar/calendarImpl.cxx index aebc1d5accdc..3c6d10c56260 100644 --- a/i18npool/source/calendar/calendarImpl.cxx +++ b/i18npool/source/calendar/calendarImpl.cxx @@ -322,6 +322,16 @@ CalendarImpl::getGenitiveMonths2() throw(RuntimeException) } +Sequence< CalendarItem2 > SAL_CALL +CalendarImpl::getPartitiveMonths2() throw(RuntimeException) +{ + if (xCalendar.is()) + return xCalendar->getPartitiveMonths2(); + else + throw ERROR ; +} + + sal_Bool SAL_CALL CalendarImpl::isValid() throw(RuntimeException) { diff --git a/i18npool/source/calendar/calendar_gregorian.cxx b/i18npool/source/calendar/calendar_gregorian.cxx index 23e95220b25b..703c847866f6 100644 --- a/i18npool/source/calendar/calendar_gregorian.cxx +++ b/i18npool/source/calendar/calendar_gregorian.cxx @@ -850,6 +850,9 @@ static sal_Int32 SAL_CALL DisplayCode2FieldIndex(sal_Int32 nCalendarDisplayCode) case CalendarDisplayCode::SHORT_GENITIVE_MONTH_NAME: case CalendarDisplayCode::LONG_GENITIVE_MONTH_NAME: case CalendarDisplayCode::NARROW_GENITIVE_MONTH_NAME: + case CalendarDisplayCode::SHORT_PARTITIVE_MONTH_NAME: + case CalendarDisplayCode::LONG_PARTITIVE_MONTH_NAME: + case CalendarDisplayCode::NARROW_PARTITIVE_MONTH_NAME: return CalendarFieldIndex::MONTH; case CalendarDisplayCode::SHORT_YEAR: case CalendarDisplayCode::LONG_YEAR: @@ -945,6 +948,13 @@ Calendar_gregorian::getGenitiveMonths2() throw(RuntimeException) } +Sequence< CalendarItem2 > SAL_CALL +Calendar_gregorian::getPartitiveMonths2() throw(RuntimeException) +{ + return aCalendar.PartitiveMonths; +} + + OUString SAL_CALL Calendar_gregorian::getDisplayName( sal_Int16 displayIndex, sal_Int16 idx, sal_Int16 nameType ) throw(RuntimeException) { @@ -977,6 +987,13 @@ Calendar_gregorian::getDisplayName( sal_Int16 displayIndex, sal_Int16 idx, sal_I else if (nameType == 2) aStr = aCalendar.GenitiveMonths[idx].NarrowName; else throw ERROR; break; + case CalendarDisplayIndex::PARTITIVE_MONTH: + if( idx >= aCalendar.PartitiveMonths.getLength() ) throw ERROR; + if (nameType == 0) aStr = aCalendar.PartitiveMonths[idx].AbbrevName; + else if (nameType == 1) aStr = aCalendar.PartitiveMonths[idx].FullName; + else if (nameType == 2) aStr = aCalendar.PartitiveMonths[idx].NarrowName; + else throw ERROR; + break; case CalendarDisplayIndex::ERA: if( idx >= aCalendar.Eras.getLength() ) throw ERROR; if (nameType == 0) aStr = aCalendar.Eras[idx].AbbrevName; @@ -1069,6 +1086,12 @@ Calendar_gregorian::getDisplayString( sal_Int32 nCalendarDisplayCode, sal_Int16 return getDisplayName(CalendarDisplayIndex::GENITIVE_MONTH, value, 1); case CalendarDisplayCode::NARROW_GENITIVE_MONTH_NAME: return getDisplayName(CalendarDisplayIndex::GENITIVE_MONTH, value, 2); + case CalendarDisplayCode::SHORT_PARTITIVE_MONTH_NAME: + return getDisplayName(CalendarDisplayIndex::PARTITIVE_MONTH, value, 0); + case CalendarDisplayCode::LONG_PARTITIVE_MONTH_NAME: + return getDisplayName(CalendarDisplayIndex::PARTITIVE_MONTH, value, 1); + case CalendarDisplayCode::NARROW_PARTITIVE_MONTH_NAME: + return getDisplayName(CalendarDisplayIndex::PARTITIVE_MONTH, value, 2); case CalendarDisplayCode::SHORT_ERA: return getDisplayName(CalendarDisplayIndex::ERA, value, 0); case CalendarDisplayCode::LONG_ERA: diff --git a/i18npool/source/localedata/LocaleNode.cxx b/i18npool/source/localedata/LocaleNode.cxx index fac4583ad4ec..8d7d1a30c6ed 100644 --- a/i18npool/source/localedata/LocaleNode.cxx +++ b/i18npool/source/localedata/LocaleNode.cxx @@ -1204,6 +1204,7 @@ void LCCalendarNode::generateCode (const OFileWriter &of) const sal_Int16 * nbOfDays = new sal_Int16[nbOfCalendars]; sal_Int16 * nbOfMonths = new sal_Int16[nbOfCalendars]; sal_Int16 * nbOfGenitiveMonths = new sal_Int16[nbOfCalendars]; + sal_Int16 * nbOfPartitiveMonths = new sal_Int16[nbOfCalendars]; sal_Int16 * nbOfEras = new sal_Int16[nbOfCalendars]; sal_Int16 j; sal_Int16 i; @@ -1322,6 +1323,42 @@ void LCCalendarNode::generateCode (const OFileWriter &of) const } ++nChild; + // Generate partitive Months of Year + // Optional, if not present fall back to genitive months, or nominative + // months (nouns) if that isn't present either. + if (!calNode->getChildAt(nChild)->getName().equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "PartitiveMonths"))) + --nChild; + LocaleNode * partitiveMonthsNode = NULL; + ref_name = calNode->getChildAt(nChild)->getAttr().getValueByName("ref"); + if (ref_name.getLength() > 0 && i > 0) { + for (j = 0; j < i; j++) { + str = getChildAt(j)->getAttr().getValueByName("unoid"); + if (str.equals(ref_name)) + partitiveMonthsNode = getChildAt(j)->getChildAt(1); + } + } + if (ref_name.getLength() > 0 && partitiveMonthsNode == NULL) { + of.writeParameter("partitiveMonthRef", OUString(RTL_CONSTASCII_USTRINGPARAM("ref")), i); + of.writeParameter("partitiveMonthRefName", ref_name, i); + nbOfPartitiveMonths[i] = 0; + } else { + if (partitiveMonthsNode == NULL) + partitiveMonthsNode = calNode -> getChildAt(nChild); + nbOfPartitiveMonths[i] = sal::static_int_cast( partitiveMonthsNode->getNumberOfChildren() ); + if (bGregorian && nbOfPartitiveMonths[i] != 12) + incErrorInt( "A Gregorian calendar must have 12 partitive months, this one has %d", nbOfPartitiveMonths[i]); + elementTag = "partitiveMonth"; + for (j = 0; j < nbOfPartitiveMonths[i]; j++) { + LocaleNode *currNode = partitiveMonthsNode -> getChildAt(j); + OUString partitiveMonthID( currNode->getChildAt(0)->getValue()); + of.writeParameter("partitiveMonthID", partitiveMonthID, i, j); + if (j == 0 && bGregorian && !partitiveMonthID.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM( "jan"))) + incError( "First partitive month of a year of a Gregorian calendar must be jan"); + lcl_writeAbbrFullNarrNames( of, currNode, elementTag, i, j); + } + } + ++nChild; + // Generate Era name LocaleNode * erasNode = NULL; ref_name = calNode -> getChildAt(nChild) ->getAttr().getValueByName("ref"); @@ -1411,6 +1448,14 @@ void LCCalendarNode::generateCode (const OFileWriter &of) const of.writeInt(nbOfGenitiveMonths[i]); of.writeAsciiString("};\n"); + of.writeAsciiString("static const sal_Unicode nbOfPartitiveMonths[] = {"); + for(i = 0; i < nbOfCalendars - 1; i++) { + of.writeInt(nbOfPartitiveMonths[i]); + of.writeAsciiString(", "); + }; + of.writeInt(nbOfPartitiveMonths[i]); + of.writeAsciiString("};\n"); + of.writeAsciiString("static const sal_Unicode nbOfEras[] = {"); for(i = 0; i < nbOfCalendars - 1; i++) { of.writeInt(nbOfEras[i]); @@ -1424,6 +1469,7 @@ void LCCalendarNode::generateCode (const OFileWriter &of) const of.writeAsciiString("\tnbOfDays,\n"); of.writeAsciiString("\tnbOfMonths,\n"); of.writeAsciiString("\tnbOfGenitiveMonths,\n"); + of.writeAsciiString("\tnbOfPartitiveMonths,\n"); of.writeAsciiString("\tnbOfEras,\n"); for(i = 0; i < nbOfCalendars; i++) { of.writeAsciiString("\tcalendarID"); @@ -1435,6 +1481,7 @@ void LCCalendarNode::generateCode (const OFileWriter &of) const lcl_writeAbbrFullNarrArrays( of, nbOfDays[i], "day", i, true); lcl_writeAbbrFullNarrArrays( of, nbOfMonths[i], "month", i, true); lcl_writeAbbrFullNarrArrays( of, nbOfGenitiveMonths[i], "genitiveMonth", i, true); + lcl_writeAbbrFullNarrArrays( of, nbOfPartitiveMonths[i], "partitiveMonth", i, true); lcl_writeAbbrFullNarrArrays( of, nbOfEras[i], "era", i, false /*noNarrow*/); of.writeAsciiString("\tstartDayOfWeek");of.writeInt(i); of.writeAsciiString(",\n"); of.writeAsciiString("\tminimalDaysInFirstWeek");of.writeInt(i); of.writeAsciiString(",\n"); @@ -1446,6 +1493,7 @@ void LCCalendarNode::generateCode (const OFileWriter &of) const delete []nbOfDays; delete []nbOfMonths; delete []nbOfGenitiveMonths; + delete []nbOfPartitiveMonths; delete []nbOfEras; } diff --git a/i18npool/source/localedata/data/locale.dtd b/i18npool/source/localedata/data/locale.dtd index ac0cfa739aff..ff88bfdbcf69 100644 --- a/i18npool/source/localedata/data/locale.dtd +++ b/i18npool/source/localedata/data/locale.dtd @@ -254,7 +254,7 @@ - + + + + + + diff --git a/i18npool/source/localedata/localedata.cxx b/i18npool/source/localedata/localedata.cxx index 66a5b9325f02..c759ffe0877b 100644 --- a/i18npool/source/localedata/localedata.cxx +++ b/i18npool/source/localedata/localedata.cxx @@ -494,8 +494,9 @@ oslGenericFunction SAL_CALL lcl_LookupTableHelper::getFunctionSymbolByName( #define REF_DAYS 0 #define REF_MONTHS 1 #define REF_GMONTHS 2 -#define REF_ERAS 3 -#define REF_OFFSET_COUNT 4 +#define REF_PMONTHS 3 +#define REF_ERAS 4 +#define REF_OFFSET_COUNT 5 Sequence< CalendarItem2 > &LocaleData::getCalendarItemByName(const OUString& name, const Locale& rLocale, const Sequence< Calendar2 >& calendarsSeq, sal_Int16 item) @@ -538,6 +539,8 @@ Sequence< CalendarItem2 > &LocaleData::getCalendarItemByName(const OUString& nam return ref_cal.Months; case REF_GMONTHS: return ref_cal.GenitiveMonths; + case REF_PMONTHS: + return ref_cal.PartitiveMonths; default: OSL_FAIL( "LocaleData::getCalendarItemByName: unhandled REF_* case"); // fallthru @@ -569,6 +572,7 @@ Sequence< CalendarItem2 > LocaleData::getCalendarItems( case REF_DAYS: case REF_MONTHS: case REF_GMONTHS: + case REF_PMONTHS: for (sal_Int16 j = 0; j < nSize; ++j, ++pItem) { CalendarItem2 item( allCalendars[rnOffset], allCalendars[rnOffset+1], @@ -620,13 +624,15 @@ LocaleData::getAllCalendars2( const Locale& rLocale ) throw(RuntimeException) rLocale, calendarsSeq); Sequence< CalendarItem2 > gmonths = getCalendarItems( allCalendars, offset, REF_GMONTHS, i, rLocale, calendarsSeq); + Sequence< CalendarItem2 > pmonths = getCalendarItems( allCalendars, offset, REF_PMONTHS, i, + rLocale, calendarsSeq); Sequence< CalendarItem2 > eras = getCalendarItems( allCalendars, offset, REF_ERAS, i, rLocale, calendarsSeq); OUString startOfWeekDay(allCalendars[offset]); offset++; sal_Int16 minimalDaysInFirstWeek = allCalendars[offset][0]; offset++; - Calendar2 aCalendar(days, months, gmonths, eras, startOfWeekDay, + Calendar2 aCalendar(days, months, gmonths, pmonths, eras, startOfWeekDay, minimalDaysInFirstWeek, defaultCalendar, calendarID); calendarsSeq[i] = aCalendar; } diff --git a/offapi/com/sun/star/i18n/Calendar2.idl b/offapi/com/sun/star/i18n/Calendar2.idl index c06667883574..0e1d9cc6640c 100644 --- a/offapi/com/sun/star/i18n/Calendar2.idl +++ b/offapi/com/sun/star/i18n/Calendar2.idl @@ -42,11 +42,15 @@ module com { module sun { module star { module i18n { XLocaleData3::getAllCalendars2().

Similar to - Calendar this provides - an additional member with a sequence of possessive (genitive case) - month names for locales that use them, for example Slavic locales. - If a locale does not provide the possessive form, the names are - identical to the nouns in Calendar::Months

+ Calendar this provides + additional members with a sequence of possessive (genitive case) and + partitive case month names for locales that use them, for example + Slavic locales. If a locale does not provide the possessive form in + GenitiveMonths, the names are identical to the + nominative case nouns in Calendar::Months. If a + locale does not provide the partitive case in + PartitiveMonths, the names are identical to + GenititiveMonths.

The sequences are of type CalendarItem2 instead of @@ -70,6 +74,9 @@ published struct Calendar2 /// The months of the year in possessive genitive case. sequence< CalendarItem2 > GenitiveMonths; + /// The months of the year in partitive case. + sequence< CalendarItem2 > PartitiveMonths; + /// The possible eras. sequence< CalendarItem2 > Eras; diff --git a/offapi/com/sun/star/i18n/CalendarDisplayCode.idl b/offapi/com/sun/star/i18n/CalendarDisplayCode.idl index e7ce30c798f1..258408096a86 100644 --- a/offapi/com/sun/star/i18n/CalendarDisplayCode.idl +++ b/offapi/com/sun/star/i18n/CalendarDisplayCode.idl @@ -47,66 +47,81 @@ module com { module sun { module star { module i18n { */ published constants CalendarDisplayCode { - /// Day of month, one or two digits, no leading zero. - const long SHORT_DAY = 1; - /// Day of month, two digits, with leading zero. - const long LONG_DAY = 2; - /// Day of week, abbreviated name. - const long SHORT_DAY_NAME = 3; - /// Day of week, full name. - const long LONG_DAY_NAME = 4; - - /// Month of year, one or two digits, no leading zero. - const long SHORT_MONTH = 5; - /// Month of year, with leading zero. - const long LONG_MONTH = 6; - /// Full month name. - const long SHORT_MONTH_NAME = 7; - /// Abbreviated month name. - const long LONG_MONTH_NAME = 8; - - /// Year, two digits. - const long SHORT_YEAR = 9; - /// Year, four digits. - const long LONG_YEAR = 10; - /// Full era name, for example, "Before Christ" or "Anno Dominus". - const long SHORT_ERA = 11; - /// Abbreviated era name, for example, BC or AD. - const long LONG_ERA = 12; - /// Combined short year and era, order depends on locale/calendar. - const long SHORT_YEAR_AND_ERA = 13; - /// Combined full year and era, order depends on locale/calendar. - const long LONG_YEAR_AND_ERA = 14; - - /// Short quarter, for example, "Q1" - const long SHORT_QUARTER = 15; - /// Long quarter, for example, "1st quarter" - const long LONG_QUARTER = 16; + /// Day of month, one or two digits, no leading zero. + const long SHORT_DAY = 1; + /// Day of month, two digits, with leading zero. + const long LONG_DAY = 2; + /// Day of week, abbreviated name. + const long SHORT_DAY_NAME = 3; + /// Day of week, full name. + const long LONG_DAY_NAME = 4; + + /// Month of year, one or two digits, no leading zero. + const long SHORT_MONTH = 5; + /// Month of year, with leading zero. + const long LONG_MONTH = 6; + /// Abbreviated month name. + const long SHORT_MONTH_NAME = 7; + /// Full month name. + const long LONG_MONTH_NAME = 8; + + /// Year, two digits. + const long SHORT_YEAR = 9; + /// Year, four digits. + const long LONG_YEAR = 10; + /// Abbreviated era name, for example, BC or AD. + const long SHORT_ERA = 11; + /// Full era name, for example, "Before Christ" or "Anno Dominus". + const long LONG_ERA = 12; + /// Combined short year and era, order depends on locale/calendar. + const long SHORT_YEAR_AND_ERA = 13; + /// Combined full year and era, order depends on locale/calendar. + const long LONG_YEAR_AND_ERA = 14; + + /// Short quarter, for example, "Q1" + const long SHORT_QUARTER = 15; + /// Long quarter, for example, "1st quarter" + const long LONG_QUARTER = 16; /** Abbreviated possessive genitive case month name. @since LibreOffice 3.5 */ - const long SHORT_GENITIVE_MONTH_NAME = 17; + const long SHORT_GENITIVE_MONTH_NAME = 17; /** Full possessive genitive case month name. @since LibreOffice 3.5 */ - const long LONG_GENITIVE_MONTH_NAME = 18; + const long LONG_GENITIVE_MONTH_NAME = 18; /** Narrow possessive genitive case month name. @since LibreOffice 3.5 */ - const long NARROW_GENITIVE_MONTH_NAME = 19; + const long NARROW_GENITIVE_MONTH_NAME = 19; + + /** Abbreviated partitive case month name. + @since LibreOffice 3.5 + */ + const long SHORT_PARTITIVE_MONTH_NAME = 20; + + /** Full partitive case month name. + @since LibreOffice 3.5 + */ + const long LONG_PARTITIVE_MONTH_NAME = 21; + + /** Narrow partitive case month name. + @since LibreOffice 3.5 + */ + const long NARROW_PARTITIVE_MONTH_NAME = 22; /** Day of week, narrow name. @since LibreOffice 3.5 */ - const long NARROW_DAY_NAME = 20; + const long NARROW_DAY_NAME = 23; /** Narrow month name. @since LibreOffice 3.5 */ - const long NARROW_MONTH_NAME = 21; + const long NARROW_MONTH_NAME = 24; }; diff --git a/offapi/com/sun/star/i18n/CalendarDisplayIndex.idl b/offapi/com/sun/star/i18n/CalendarDisplayIndex.idl index 777f9fa36144..b419b12ecfec 100644 --- a/offapi/com/sun/star/i18n/CalendarDisplayIndex.idl +++ b/offapi/com/sun/star/i18n/CalendarDisplayIndex.idl @@ -41,20 +41,25 @@ module com { module sun { module star { module i18n { published constants CalendarDisplayIndex { /// name of an AM/PM value - const short AM_PM = 0; - /// name of a day of week - const short DAY = 1; - /// name of a month - const short MONTH = 2; - /// name of a year (if used for a specific calendar) - const short YEAR = 3; - /// name of an era, like BC/AD - const short ERA = 4; + const short AM_PM = 0; + /// name of a day of week + const short DAY = 1; + /// name of a month + const short MONTH = 2; + /// name of a year (if used for a specific calendar) + const short YEAR = 3; + /// name of an era, like BC/AD + const short ERA = 4; /** name of a possessive genitive case month @since LibreOffice 3.5 */ - const short GENITIVE_MONTH = 5; + const short GENITIVE_MONTH = 5; + + /** name of a partitive case month + @since LibreOffice 3.5 + */ + const short PARTITIVE_MONTH = 6; }; //============================================================================= diff --git a/offapi/com/sun/star/i18n/XCalendar3.idl b/offapi/com/sun/star/i18n/XCalendar3.idl index 2ffe25b627a1..6bd7ef96992b 100644 --- a/offapi/com/sun/star/i18n/XCalendar3.idl +++ b/offapi/com/sun/star/i18n/XCalendar3.idl @@ -75,6 +75,12 @@ published interface XCalendar3 : com::sun::star::i18n::XExtendedCalendar */ sequence< CalendarItem2 > getGenitiveMonths2(); + //------------------------------------------------------------------------ + /** returns a sequence of CalendarItem2 describing the + partitive case month names. + */ + sequence< CalendarItem2 > getPartitiveMonths2(); + }; //============================================================================= diff --git a/svl/inc/svl/zformat.hxx b/svl/inc/svl/zformat.hxx index 1ad50d704a15..659b9304c7c0 100644 --- a/svl/inc/svl/zformat.hxx +++ b/svl/inc/svl/zformat.hxx @@ -476,14 +476,25 @@ private: SVL_DLLPRIVATE bool ImpIsOtherCalendar( const ImpSvNumFor& rNumFor ) const; - /** Whether to use possessive genitive case month name instead of noun. + /** Whether to use possessive genitive case month name, or partitive case + month name, instead of nominative name (noun). + @param io_nState - 0: execute check, set to 1 if true is returned, set to 2 if false - is returned
- 1: don't execute check, return true
- 2: don't execute check, return false
+ 0: execute check
+ set to 1 if nominative case is returned,
+ set to 2 if genitive case is returned,
+ set to 3 if partitive case is returned
+ 1: don't execute check, return nominative case
+ 2: don't execute check, return genitive case
+ 3: don't execute check, return partitive case
+ + @param eCodeType + a NfKeywordIndex, must designate a month type code + + @returns one of com::sun::star::i18n::CalendarDisplayCode values + according to eCodeType and the check executed (or passed). */ - SVL_DLLPRIVATE bool ImpUseGenitiveMonth( int & io_nState, const ImpSvNumFor& rNumFor ) const; + SVL_DLLPRIVATE sal_Int32 ImpUseMonthCase( int & io_nState, const ImpSvNumFor& rNumFor, NfKeywordIndex eCodeType ) const; #ifdef THE_FUTURE SVL_DLLPRIVATE bool ImpSwitchToSpecifiedCalendar( String& rOrgCalendar, diff --git a/svl/source/numbers/zforfind.cxx b/svl/source/numbers/zforfind.cxx index 3fa6908b1d4f..cfad6e2b7483 100644 --- a/svl/source/numbers/zforfind.cxx +++ b/svl/source/numbers/zforfind.cxx @@ -87,6 +87,8 @@ ImpSvNumberInputScan::ImpSvNumberInputScan( SvNumberFormatter* pFormatterP ) pUpperAbbrevMonthText( NULL ), pUpperGenitiveMonthText( NULL ), pUpperGenitiveAbbrevMonthText( NULL ), + pUpperPartitiveMonthText( NULL ), + pUpperPartitiveAbbrevMonthText( NULL ), pUpperDayText( NULL ), pUpperAbbrevDayText( NULL ), eScannedType( NUMBERFORMAT_UNDEFINED ), @@ -111,6 +113,8 @@ ImpSvNumberInputScan::~ImpSvNumberInputScan() delete [] pUpperAbbrevMonthText; delete [] pUpperGenitiveMonthText; delete [] pUpperGenitiveAbbrevMonthText; + delete [] pUpperPartitiveMonthText; + delete [] pUpperPartitiveAbbrevMonthText; delete [] pUpperDayText; delete [] pUpperAbbrevDayText; } @@ -573,6 +577,18 @@ short ImpSvNumberInputScan::GetMonth( const String& rString, xub_StrLen& nPos ) res = sal::static_int_cast< short >(-(i+1)); // negative break; // for } + else if ( StringContains( pUpperPartitiveMonthText[i], rString, nPos ) ) + { // partitive full names + nPos = nPos + pUpperPartitiveMonthText[i].Len(); + res = i+1; + break; // for + } + else if ( StringContains( pUpperPartitiveAbbrevMonthText[i], rString, nPos ) ) + { // partitive abbreviated + nPos = nPos + pUpperPartitiveAbbrevMonthText[i].Len(); + res = sal::static_int_cast< short >(-(i+1)); // negative + break; // for + } else if ( StringContains( pUpperMonthText[i], rString, nPos ) ) { // noun full names nPos = nPos + pUpperMonthText[i].Len(); @@ -2455,6 +2471,18 @@ void ImpSvNumberInputScan::InitText() pUpperGenitiveAbbrevMonthText[j] = pChrCls->upper( xElems[j].AbbrevName ); } + delete [] pUpperPartitiveMonthText; + delete [] pUpperPartitiveAbbrevMonthText; + xElems = pCal->getPartitiveMonths(); + nElems = xElems.getLength(); + pUpperPartitiveMonthText = new String[nElems]; + pUpperPartitiveAbbrevMonthText = new String[nElems]; + for ( j=0; jupper( xElems[j].FullName ); + pUpperPartitiveAbbrevMonthText[j] = pChrCls->upper( xElems[j].AbbrevName ); + } + delete [] pUpperDayText; delete [] pUpperAbbrevDayText; xElems = pCal->getDays(); diff --git a/svl/source/numbers/zforfind.hxx b/svl/source/numbers/zforfind.hxx index 158a4564a28d..c8a6d29ba5f5 100644 --- a/svl/source/numbers/zforfind.hxx +++ b/svl/source/numbers/zforfind.hxx @@ -75,6 +75,8 @@ private: String* pUpperAbbrevMonthText; // Array of month names, abbreviated, uppercase String* pUpperGenitiveMonthText; // Array of genitive month names, uppercase String* pUpperGenitiveAbbrevMonthText; // Array of genitive month names, abbreviated, uppercase + String* pUpperPartitiveMonthText; // Array of partitive month names, uppercase + String* pUpperPartitiveAbbrevMonthText; // Array of partitive month names, abbreviated, uppercase String* pUpperDayText; // Array of day of week names, uppercase String* pUpperAbbrevDayText; // Array of day of week names, abbreviated, uppercase String aUpperCurrSymbol; // Currency symbol, uppercase diff --git a/svl/source/numbers/zformat.cxx b/svl/source/numbers/zformat.cxx index c4315d3a007d..e4c347b77660 100644 --- a/svl/source/numbers/zformat.cxx +++ b/svl/source/numbers/zformat.cxx @@ -2946,28 +2946,79 @@ bool SvNumberformat::ImpGetTimeOutput(double fNumber, /** If a day of month occurs within the format, the month name is in possessive - genitive case. + genitive case if the day follows the month, and partitive case if the day + precedes the month. If there is no day of month the nominative case (noun) + is returned. */ -bool SvNumberformat::ImpUseGenitiveMonth( int & io_nState, const ImpSvNumFor& rNumFor ) const +sal_Int32 SvNumberformat::ImpUseMonthCase( int & io_nState, const ImpSvNumFor& rNumFor, NfKeywordIndex eCodeType ) const { - if (io_nState) - return io_nState == 1; - - const ImpSvNumberformatInfo& rInfo = rNumFor.Info(); - const sal_uInt16 nAnz = rNumFor.GetCount(); - sal_uInt16 i; - for ( i = 0; i < nAnz; i++ ) + using namespace ::com::sun::star::i18n; + if (!io_nState) { - switch ( rInfo.nTypeArray[i] ) + io_nState = 1; + bool bMonthSeen = false; + const ImpSvNumberformatInfo& rInfo = rNumFor.Info(); + const sal_uInt16 nCount = rNumFor.GetCount(); + for ( sal_uInt16 i = 0; i < nCount && io_nState == 1; ++i ) { - case NF_KEY_D : - case NF_KEY_DD : - io_nState = 1; - return true; + switch ( rInfo.nTypeArray[i] ) + { + case NF_KEY_D : + case NF_KEY_DD : + io_nState = (bMonthSeen ? 2 : 3); // and end loop + break; + case NF_KEY_MMM: + case NF_KEY_MMMM: + case NF_KEY_MMMMM: + bMonthSeen = true; + break; + } } } - io_nState = 2; - return false; + switch (io_nState) + { + case 1: + // no day of month + switch (eCodeType) + { + case NF_KEY_MMM: + return CalendarDisplayCode::SHORT_MONTH_NAME; + case NF_KEY_MMMM: + return CalendarDisplayCode::LONG_MONTH_NAME; + case NF_KEY_MMMMM: + return CalendarDisplayCode::NARROW_MONTH_NAME; + default: + ; // nothing + } + case 2: + // day of month follows month (the month's 17th) + switch (eCodeType) + { + case NF_KEY_MMM: + return CalendarDisplayCode::SHORT_GENITIVE_MONTH_NAME; + case NF_KEY_MMMM: + return CalendarDisplayCode::LONG_GENITIVE_MONTH_NAME; + case NF_KEY_MMMMM: + return CalendarDisplayCode::NARROW_GENITIVE_MONTH_NAME; + default: + ; // nothing + } + case 3: + // day of month precedes month (17 of month) + switch (eCodeType) + { + case NF_KEY_MMM: + return CalendarDisplayCode::SHORT_PARTITIVE_MONTH_NAME; + case NF_KEY_MMMM: + return CalendarDisplayCode::LONG_PARTITIVE_MONTH_NAME; + case NF_KEY_MMMMM: + return CalendarDisplayCode::NARROW_PARTITIVE_MONTH_NAME; + default: + ; // nothing + } + } + OSL_FAIL( "ImpUseMonthCase: should not be reached"); + return CalendarDisplayCode::LONG_MONTH_NAME; } @@ -3130,7 +3181,7 @@ bool SvNumberformat::ImpGetDateOutput(double fNumber, double fDiff = DateTime(*(rScan.GetNullDate())) - rCal.getEpochStart(); fNumber += fDiff; rCal.setLocalDateTime( fNumber ); - int nUseGenitiveMonth = 0; // not decided yet + int nUseMonthCase = 0; // not decided yet String aOrgCalendar; // empty => not changed yet double fOrgDateTime; bool bOtherCalendar = ImpIsOtherCalendar( NumFor[nIx] ); @@ -3183,22 +3234,16 @@ bool SvNumberformat::ImpGetDateOutput(double fNumber, CalendarDisplayCode::LONG_MONTH, nNatNum ); break; case NF_KEY_MMM: // MMM - OutString += rCal.getDisplayString( - (ImpUseGenitiveMonth( nUseGenitiveMonth, NumFor[nIx]) ? - CalendarDisplayCode::SHORT_GENITIVE_MONTH_NAME : - CalendarDisplayCode::SHORT_MONTH_NAME), nNatNum ); + OutString += rCal.getDisplayString( ImpUseMonthCase( + nUseMonthCase, NumFor[nIx], static_cast(rInfo.nTypeArray[i])), nNatNum); break; case NF_KEY_MMMM: // MMMM - OutString += rCal.getDisplayString( - (ImpUseGenitiveMonth( nUseGenitiveMonth, NumFor[nIx]) ? - CalendarDisplayCode::LONG_GENITIVE_MONTH_NAME : - CalendarDisplayCode::LONG_MONTH_NAME), nNatNum ); + OutString += rCal.getDisplayString( ImpUseMonthCase( + nUseMonthCase, NumFor[nIx], static_cast(rInfo.nTypeArray[i])), nNatNum); break; case NF_KEY_MMMMM: // MMMMM - OutString += rCal.getDisplayString( - (ImpUseGenitiveMonth( nUseGenitiveMonth, NumFor[nIx]) ? - CalendarDisplayCode::NARROW_GENITIVE_MONTH_NAME : - CalendarDisplayCode::NARROW_MONTH_NAME), nNatNum ); + OutString += rCal.getDisplayString( ImpUseMonthCase( + nUseMonthCase, NumFor[nIx], static_cast(rInfo.nTypeArray[i])), nNatNum); break; case NF_KEY_Q: // Q OutString += rCal.getDisplayString( @@ -3345,7 +3390,7 @@ bool SvNumberformat::ImpGetDateTimeOutput(double fNumber, } rCal.setLocalDateTime( fNumber ); - int nUseGenitiveMonth = 0; // not decided yet + int nUseMonthCase = 0; // not decided yet String aOrgCalendar; // empty => not changed yet double fOrgDateTime; bool bOtherCalendar = ImpIsOtherCalendar( NumFor[nIx] ); @@ -3512,22 +3557,16 @@ bool SvNumberformat::ImpGetDateTimeOutput(double fNumber, CalendarDisplayCode::LONG_MONTH, nNatNum ); break; case NF_KEY_MMM: // MMM - OutString += rCal.getDisplayString( - (ImpUseGenitiveMonth( nUseGenitiveMonth, NumFor[nIx]) ? - CalendarDisplayCode::SHORT_GENITIVE_MONTH_NAME : - CalendarDisplayCode::SHORT_MONTH_NAME), nNatNum ); + OutString += rCal.getDisplayString( ImpUseMonthCase( + nUseMonthCase, NumFor[nIx], static_cast(rInfo.nTypeArray[i])), nNatNum); break; case NF_KEY_MMMM: // MMMM - OutString += rCal.getDisplayString( - (ImpUseGenitiveMonth( nUseGenitiveMonth, NumFor[nIx]) ? - CalendarDisplayCode::LONG_GENITIVE_MONTH_NAME : - CalendarDisplayCode::LONG_MONTH_NAME), nNatNum ); + OutString += rCal.getDisplayString( ImpUseMonthCase( + nUseMonthCase, NumFor[nIx], static_cast(rInfo.nTypeArray[i])), nNatNum); break; case NF_KEY_MMMMM: // MMMMM - OutString += rCal.getDisplayString( - (ImpUseGenitiveMonth( nUseGenitiveMonth, NumFor[nIx]) ? - CalendarDisplayCode::NARROW_GENITIVE_MONTH_NAME : - CalendarDisplayCode::NARROW_MONTH_NAME), nNatNum ); + OutString += rCal.getDisplayString( ImpUseMonthCase( + nUseMonthCase, NumFor[nIx], static_cast(rInfo.nTypeArray[i])), nNatNum); break; case NF_KEY_Q: // Q OutString += rCal.getDisplayString( diff --git a/unotools/inc/unotools/calendarwrapper.hxx b/unotools/inc/unotools/calendarwrapper.hxx index cc67696d0439..bab43e9522e4 100644 --- a/unotools/inc/unotools/calendarwrapper.hxx +++ b/unotools/inc/unotools/calendarwrapper.hxx @@ -112,6 +112,7 @@ public: ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::CalendarItem2 > getDays() const; ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::CalendarItem2 > getMonths() const; ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::CalendarItem2 > getGenitiveMonths() const; + ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::CalendarItem2 > getPartitiveMonths() const; // convenience methods diff --git a/unotools/source/i18n/calendarwrapper.cxx b/unotools/source/i18n/calendarwrapper.cxx index 6d7aa4bea94e..a128c33e968f 100644 --- a/unotools/source/i18n/calendarwrapper.cxx +++ b/unotools/source/i18n/calendarwrapper.cxx @@ -632,4 +632,25 @@ String CalendarWrapper::getDisplayString( sal_Int32 nCalendarDisplayCode, sal_In return ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::CalendarItem2 > (0); } + +::com::sun::star::uno::Sequence< ::com::sun::star::i18n::CalendarItem2 > CalendarWrapper::getPartitiveMonths() const +{ + try + { + if ( xC.is() ) + return xC->getPartitiveMonths2(); + } + catch ( Exception& e ) + { +#ifdef DBG_UTIL + ByteString aMsg( "getPartitiveMonths: Exception caught\n" ); + aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 ); + DBG_ERRORFILE( aMsg.GetBuffer() ); +#else + (void)e; +#endif + } + return ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::CalendarItem2 > (0); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ -- cgit