added partitive case month names

* Locale data:
  * nominative (nouns) month names always given in <MonthsOfYear>
    element
  * optional genitive case month names in <GenitiveMonths> element,
    following the <MonthsOfYear> element; if not given take nominative
    names
  * optional partitive case month names in <PartitiveMonths> element,
    following the <GenitiveMonths> element, or following the
    <MonthsOfYear> element if the <GenitiveMonths> 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
This commit is contained in:
Eike Rathke
2011-11-22 14:29:35 +01:00
parent 734bfe16bd
commit 3b5ee26d2c
17 changed files with 338 additions and 104 deletions

View File

@@ -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 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 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 getGenitiveMonths2() throw(com::sun::star::uno::RuntimeException);
virtual com::sun::star::uno::Sequence < CalendarItem2 > SAL_CALL getPartitiveMonths2() throw(com::sun::star::uno::RuntimeException);
//XServiceInfo //XServiceInfo
virtual rtl::OUString SAL_CALL getImplementationName() throw(com::sun::star::uno::RuntimeException); virtual rtl::OUString SAL_CALL getImplementationName() throw(com::sun::star::uno::RuntimeException);

View File

@@ -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 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 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 getGenitiveMonths2() throw(com::sun::star::uno::RuntimeException);
virtual com::sun::star::uno::Sequence < CalendarItem2 > SAL_CALL getPartitiveMonths2() throw(com::sun::star::uno::RuntimeException);
//XServiceInfo //XServiceInfo
virtual rtl::OUString SAL_CALL getImplementationName() throw(com::sun::star::uno::RuntimeException); virtual rtl::OUString SAL_CALL getImplementationName() throw(com::sun::star::uno::RuntimeException);

View File

@@ -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 sal_Bool SAL_CALL
CalendarImpl::isValid() throw(RuntimeException) CalendarImpl::isValid() throw(RuntimeException)
{ {

View File

@@ -850,6 +850,9 @@ static sal_Int32 SAL_CALL DisplayCode2FieldIndex(sal_Int32 nCalendarDisplayCode)
case CalendarDisplayCode::SHORT_GENITIVE_MONTH_NAME: case CalendarDisplayCode::SHORT_GENITIVE_MONTH_NAME:
case CalendarDisplayCode::LONG_GENITIVE_MONTH_NAME: case CalendarDisplayCode::LONG_GENITIVE_MONTH_NAME:
case CalendarDisplayCode::NARROW_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; return CalendarFieldIndex::MONTH;
case CalendarDisplayCode::SHORT_YEAR: case CalendarDisplayCode::SHORT_YEAR:
case CalendarDisplayCode::LONG_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 OUString SAL_CALL
Calendar_gregorian::getDisplayName( sal_Int16 displayIndex, sal_Int16 idx, sal_Int16 nameType ) throw(RuntimeException) 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 if (nameType == 2) aStr = aCalendar.GenitiveMonths[idx].NarrowName;
else throw ERROR; else throw ERROR;
break; 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: case CalendarDisplayIndex::ERA:
if( idx >= aCalendar.Eras.getLength() ) throw ERROR; if( idx >= aCalendar.Eras.getLength() ) throw ERROR;
if (nameType == 0) aStr = aCalendar.Eras[idx].AbbrevName; 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); return getDisplayName(CalendarDisplayIndex::GENITIVE_MONTH, value, 1);
case CalendarDisplayCode::NARROW_GENITIVE_MONTH_NAME: case CalendarDisplayCode::NARROW_GENITIVE_MONTH_NAME:
return getDisplayName(CalendarDisplayIndex::GENITIVE_MONTH, value, 2); 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: case CalendarDisplayCode::SHORT_ERA:
return getDisplayName(CalendarDisplayIndex::ERA, value, 0); return getDisplayName(CalendarDisplayIndex::ERA, value, 0);
case CalendarDisplayCode::LONG_ERA: case CalendarDisplayCode::LONG_ERA:

View File

@@ -1204,6 +1204,7 @@ void LCCalendarNode::generateCode (const OFileWriter &of) const
sal_Int16 * nbOfDays = new sal_Int16[nbOfCalendars]; sal_Int16 * nbOfDays = new sal_Int16[nbOfCalendars];
sal_Int16 * nbOfMonths = new sal_Int16[nbOfCalendars]; sal_Int16 * nbOfMonths = new sal_Int16[nbOfCalendars];
sal_Int16 * nbOfGenitiveMonths = 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 * nbOfEras = new sal_Int16[nbOfCalendars];
sal_Int16 j; sal_Int16 j;
sal_Int16 i; sal_Int16 i;
@@ -1322,6 +1323,42 @@ void LCCalendarNode::generateCode (const OFileWriter &of) const
} }
++nChild; ++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<sal_Int16>( 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 <MonthID>jan</MonthID>");
lcl_writeAbbrFullNarrNames( of, currNode, elementTag, i, j);
}
}
++nChild;
// Generate Era name // Generate Era name
LocaleNode * erasNode = NULL; LocaleNode * erasNode = NULL;
ref_name = calNode -> getChildAt(nChild) ->getAttr().getValueByName("ref"); ref_name = calNode -> getChildAt(nChild) ->getAttr().getValueByName("ref");
@@ -1411,6 +1448,14 @@ void LCCalendarNode::generateCode (const OFileWriter &of) const
of.writeInt(nbOfGenitiveMonths[i]); of.writeInt(nbOfGenitiveMonths[i]);
of.writeAsciiString("};\n"); 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[] = {"); of.writeAsciiString("static const sal_Unicode nbOfEras[] = {");
for(i = 0; i < nbOfCalendars - 1; i++) { for(i = 0; i < nbOfCalendars - 1; i++) {
of.writeInt(nbOfEras[i]); of.writeInt(nbOfEras[i]);
@@ -1424,6 +1469,7 @@ void LCCalendarNode::generateCode (const OFileWriter &of) const
of.writeAsciiString("\tnbOfDays,\n"); of.writeAsciiString("\tnbOfDays,\n");
of.writeAsciiString("\tnbOfMonths,\n"); of.writeAsciiString("\tnbOfMonths,\n");
of.writeAsciiString("\tnbOfGenitiveMonths,\n"); of.writeAsciiString("\tnbOfGenitiveMonths,\n");
of.writeAsciiString("\tnbOfPartitiveMonths,\n");
of.writeAsciiString("\tnbOfEras,\n"); of.writeAsciiString("\tnbOfEras,\n");
for(i = 0; i < nbOfCalendars; i++) { for(i = 0; i < nbOfCalendars; i++) {
of.writeAsciiString("\tcalendarID"); 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, nbOfDays[i], "day", i, true);
lcl_writeAbbrFullNarrArrays( of, nbOfMonths[i], "month", i, true); lcl_writeAbbrFullNarrArrays( of, nbOfMonths[i], "month", i, true);
lcl_writeAbbrFullNarrArrays( of, nbOfGenitiveMonths[i], "genitiveMonth", 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*/); lcl_writeAbbrFullNarrArrays( of, nbOfEras[i], "era", i, false /*noNarrow*/);
of.writeAsciiString("\tstartDayOfWeek");of.writeInt(i); of.writeAsciiString(",\n"); of.writeAsciiString("\tstartDayOfWeek");of.writeInt(i); of.writeAsciiString(",\n");
of.writeAsciiString("\tminimalDaysInFirstWeek");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 []nbOfDays;
delete []nbOfMonths; delete []nbOfMonths;
delete []nbOfGenitiveMonths; delete []nbOfGenitiveMonths;
delete []nbOfPartitiveMonths;
delete []nbOfEras; delete []nbOfEras;
} }

View File

@@ -254,7 +254,7 @@
<!-- At least one Calendar element must be given if the RefLocale mechanism is not used! --> <!-- At least one Calendar element must be given if the RefLocale mechanism is not used! -->
<!ATTLIST LC_CALENDAR %RefLocale;> <!ATTLIST LC_CALENDAR %RefLocale;>
<!ELEMENT Calendar (DaysOfWeek, MonthsOfYear, GenitiveMonths*, Eras, StartDayOfWeek, MinimalDaysInFirstWeek) > <!ELEMENT Calendar (DaysOfWeek, MonthsOfYear, GenitiveMonths*, PartitiveMonths*, Eras, StartDayOfWeek, MinimalDaysInFirstWeek) >
<!ATTLIST Calendar %UNOModule;> <!ATTLIST Calendar %UNOModule;>
<!-- The unoid of a gregorian calendar MUST be lower case "gregorian", <!-- The unoid of a gregorian calendar MUST be lower case "gregorian",
calendars MUST match the names defined in the OASIS OpenDocument Format calendars MUST match the names defined in the OASIS OpenDocument Format
@@ -298,6 +298,16 @@
year, e.g. January in a Gregorian calendar. year, e.g. January in a Gregorian calendar.
--> -->
<!ELEMENT PartitiveMonths (Month*)>
<!-- Partitive case month names, for example in Finnish locales. The
element is optional, but if present all Month elements of a Calendar must
be given if the RefLocale mechanism is not used! If not present,
GenitiveMonths names will be used. -->
<!ATTLIST PartitiveMonths %RefLocale;>
<!-- Sequence of months is important, MUST start with the first month of a
year, e.g. January in a Gregorian calendar.
-->
<!ELEMENT Month (MonthID, DefaultAbbrvName, DefaultFullName, DefaultNarrowName*)> <!ELEMENT Month (MonthID, DefaultAbbrvName, DefaultFullName, DefaultNarrowName*)>
<!ELEMENT MonthID (#PCDATA)> <!ELEMENT MonthID (#PCDATA)>
<!-- Preferably the lower case abbreviated English name like jan for January. --> <!-- Preferably the lower case abbreviated English name like jan for January. -->

View File

@@ -494,8 +494,9 @@ oslGenericFunction SAL_CALL lcl_LookupTableHelper::getFunctionSymbolByName(
#define REF_DAYS 0 #define REF_DAYS 0
#define REF_MONTHS 1 #define REF_MONTHS 1
#define REF_GMONTHS 2 #define REF_GMONTHS 2
#define REF_ERAS 3 #define REF_PMONTHS 3
#define REF_OFFSET_COUNT 4 #define REF_ERAS 4
#define REF_OFFSET_COUNT 5
Sequence< CalendarItem2 > &LocaleData::getCalendarItemByName(const OUString& name, Sequence< CalendarItem2 > &LocaleData::getCalendarItemByName(const OUString& name,
const Locale& rLocale, const Sequence< Calendar2 >& calendarsSeq, sal_Int16 item) 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; return ref_cal.Months;
case REF_GMONTHS: case REF_GMONTHS:
return ref_cal.GenitiveMonths; return ref_cal.GenitiveMonths;
case REF_PMONTHS:
return ref_cal.PartitiveMonths;
default: default:
OSL_FAIL( "LocaleData::getCalendarItemByName: unhandled REF_* case"); OSL_FAIL( "LocaleData::getCalendarItemByName: unhandled REF_* case");
// fallthru // fallthru
@@ -569,6 +572,7 @@ Sequence< CalendarItem2 > LocaleData::getCalendarItems(
case REF_DAYS: case REF_DAYS:
case REF_MONTHS: case REF_MONTHS:
case REF_GMONTHS: case REF_GMONTHS:
case REF_PMONTHS:
for (sal_Int16 j = 0; j < nSize; ++j, ++pItem) for (sal_Int16 j = 0; j < nSize; ++j, ++pItem)
{ {
CalendarItem2 item( allCalendars[rnOffset], allCalendars[rnOffset+1], CalendarItem2 item( allCalendars[rnOffset], allCalendars[rnOffset+1],
@@ -620,13 +624,15 @@ LocaleData::getAllCalendars2( const Locale& rLocale ) throw(RuntimeException)
rLocale, calendarsSeq); rLocale, calendarsSeq);
Sequence< CalendarItem2 > gmonths = getCalendarItems( allCalendars, offset, REF_GMONTHS, i, Sequence< CalendarItem2 > gmonths = getCalendarItems( allCalendars, offset, REF_GMONTHS, i,
rLocale, calendarsSeq); rLocale, calendarsSeq);
Sequence< CalendarItem2 > pmonths = getCalendarItems( allCalendars, offset, REF_PMONTHS, i,
rLocale, calendarsSeq);
Sequence< CalendarItem2 > eras = getCalendarItems( allCalendars, offset, REF_ERAS, i, Sequence< CalendarItem2 > eras = getCalendarItems( allCalendars, offset, REF_ERAS, i,
rLocale, calendarsSeq); rLocale, calendarsSeq);
OUString startOfWeekDay(allCalendars[offset]); OUString startOfWeekDay(allCalendars[offset]);
offset++; offset++;
sal_Int16 minimalDaysInFirstWeek = allCalendars[offset][0]; sal_Int16 minimalDaysInFirstWeek = allCalendars[offset][0];
offset++; offset++;
Calendar2 aCalendar(days, months, gmonths, eras, startOfWeekDay, Calendar2 aCalendar(days, months, gmonths, pmonths, eras, startOfWeekDay,
minimalDaysInFirstWeek, defaultCalendar, calendarID); minimalDaysInFirstWeek, defaultCalendar, calendarID);
calendarsSeq[i] = aCalendar; calendarsSeq[i] = aCalendar;
} }

View File

@@ -42,11 +42,15 @@ module com { module sun { module star { module i18n {
<member>XLocaleData3::getAllCalendars2()</member>. <member>XLocaleData3::getAllCalendars2()</member>.
<p> Similar to <p> Similar to
<type scope="::com::sun::star::i18n">Calendar</type> this provides <type scope="::com::sun::star::i18n">Calendar</type> this provides
an additional member with a sequence of possessive (genitive case) additional members with a sequence of possessive (genitive case) and
month names for locales that use them, for example Slavic locales. partitive case month names for locales that use them, for example
If a locale does not provide the possessive form, the names are Slavic locales. If a locale does not provide the possessive form in
identical to the nouns in <member>Calendar::Months</member> </p> <member>GenitiveMonths</member>, the names are identical to the
nominative case nouns in <member>Calendar::Months</member>. If a
locale does not provide the partitive case in
<member>PartitiveMonths</member>, the names are identical to
<member>GenititiveMonths</member>. </p>
<p> The sequences are of type <p> The sequences are of type
<type scope="com::sun::star::i18n">CalendarItem2</type> instead of <type scope="com::sun::star::i18n">CalendarItem2</type> instead of
@@ -70,6 +74,9 @@ published struct Calendar2
/// The months of the year in possessive genitive case. /// The months of the year in possessive genitive case.
sequence< CalendarItem2 > GenitiveMonths; sequence< CalendarItem2 > GenitiveMonths;
/// The months of the year in partitive case.
sequence< CalendarItem2 > PartitiveMonths;
/// The possible eras. /// The possible eras.
sequence< CalendarItem2 > Eras; sequence< CalendarItem2 > Eras;

View File

@@ -47,66 +47,81 @@ module com { module sun { module star { module i18n {
*/ */
published constants CalendarDisplayCode published constants CalendarDisplayCode
{ {
/// Day of month, one or two digits, no leading zero. /// Day of month, one or two digits, no leading zero.
const long SHORT_DAY = 1; const long SHORT_DAY = 1;
/// Day of month, two digits, with leading zero. /// Day of month, two digits, with leading zero.
const long LONG_DAY = 2; const long LONG_DAY = 2;
/// Day of week, abbreviated name. /// Day of week, abbreviated name.
const long SHORT_DAY_NAME = 3; const long SHORT_DAY_NAME = 3;
/// Day of week, full name. /// Day of week, full name.
const long LONG_DAY_NAME = 4; const long LONG_DAY_NAME = 4;
/// Month of year, one or two digits, no leading zero. /// Month of year, one or two digits, no leading zero.
const long SHORT_MONTH = 5; const long SHORT_MONTH = 5;
/// Month of year, with leading zero. /// Month of year, with leading zero.
const long LONG_MONTH = 6; const long LONG_MONTH = 6;
/// Full month name. /// Abbreviated month name.
const long SHORT_MONTH_NAME = 7; const long SHORT_MONTH_NAME = 7;
/// Abbreviated month name. /// Full month name.
const long LONG_MONTH_NAME = 8; const long LONG_MONTH_NAME = 8;
/// Year, two digits. /// Year, two digits.
const long SHORT_YEAR = 9; const long SHORT_YEAR = 9;
/// Year, four digits. /// Year, four digits.
const long LONG_YEAR = 10; const long LONG_YEAR = 10;
/// Full era name, for example, "Before Christ" or "Anno Dominus". /// Abbreviated era name, for example, BC or AD.
const long SHORT_ERA = 11; const long SHORT_ERA = 11;
/// Abbreviated era name, for example, BC or AD. /// Full era name, for example, "Before Christ" or "Anno Dominus".
const long LONG_ERA = 12; const long LONG_ERA = 12;
/// Combined short year and era, order depends on locale/calendar. /// Combined short year and era, order depends on locale/calendar.
const long SHORT_YEAR_AND_ERA = 13; const long SHORT_YEAR_AND_ERA = 13;
/// Combined full year and era, order depends on locale/calendar. /// Combined full year and era, order depends on locale/calendar.
const long LONG_YEAR_AND_ERA = 14; const long LONG_YEAR_AND_ERA = 14;
/// Short quarter, for example, "Q1" /// Short quarter, for example, "Q1"
const long SHORT_QUARTER = 15; const long SHORT_QUARTER = 15;
/// Long quarter, for example, "1st quarter" /// Long quarter, for example, "1st quarter"
const long LONG_QUARTER = 16; const long LONG_QUARTER = 16;
/** Abbreviated possessive genitive case month name. /** Abbreviated possessive genitive case month name.
@since LibreOffice 3.5 @since LibreOffice 3.5
*/ */
const long SHORT_GENITIVE_MONTH_NAME = 17; const long SHORT_GENITIVE_MONTH_NAME = 17;
/** Full possessive genitive case month name. /** Full possessive genitive case month name.
@since LibreOffice 3.5 @since LibreOffice 3.5
*/ */
const long LONG_GENITIVE_MONTH_NAME = 18; const long LONG_GENITIVE_MONTH_NAME = 18;
/** Narrow possessive genitive case month name. /** Narrow possessive genitive case month name.
@since LibreOffice 3.5 @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. /** Day of week, narrow name.
@since LibreOffice 3.5 @since LibreOffice 3.5
*/ */
const long NARROW_DAY_NAME = 20; const long NARROW_DAY_NAME = 23;
/** Narrow month name. /** Narrow month name.
@since LibreOffice 3.5 @since LibreOffice 3.5
*/ */
const long NARROW_MONTH_NAME = 21; const long NARROW_MONTH_NAME = 24;
}; };

View File

@@ -41,20 +41,25 @@ module com { module sun { module star { module i18n {
published constants CalendarDisplayIndex published constants CalendarDisplayIndex
{ {
/// name of an AM/PM value /// name of an AM/PM value
const short AM_PM = 0; const short AM_PM = 0;
/// name of a day of week /// name of a day of week
const short DAY = 1; const short DAY = 1;
/// name of a month /// name of a month
const short MONTH = 2; const short MONTH = 2;
/// name of a year (if used for a specific calendar) /// name of a year (if used for a specific calendar)
const short YEAR = 3; const short YEAR = 3;
/// name of an era, like BC/AD /// name of an era, like BC/AD
const short ERA = 4; const short ERA = 4;
/** name of a possessive genitive case month /** name of a possessive genitive case month
@since LibreOffice 3.5 @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;
}; };
//============================================================================= //=============================================================================

View File

@@ -75,6 +75,12 @@ published interface XCalendar3 : com::sun::star::i18n::XExtendedCalendar
*/ */
sequence< CalendarItem2 > getGenitiveMonths2(); sequence< CalendarItem2 > getGenitiveMonths2();
//------------------------------------------------------------------------
/** returns a sequence of <type>CalendarItem2</type> describing the
partitive case month names.
*/
sequence< CalendarItem2 > getPartitiveMonths2();
}; };
//============================================================================= //=============================================================================

View File

@@ -476,14 +476,25 @@ private:
SVL_DLLPRIVATE bool ImpIsOtherCalendar( const ImpSvNumFor& rNumFor ) const; 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 @param io_nState
0: execute check, set to 1 if true is returned, set to 2 if false 0: execute check <br>
is returned <br> set to 1 if nominative case is returned, <br>
1: don't execute check, return true <br> set to 2 if genitive case is returned, <br>
2: don't execute check, return false <br> set to 3 if partitive case is returned <br>
1: don't execute check, return nominative case <br>
2: don't execute check, return genitive case <br>
3: don't execute check, return partitive case <br>
@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 #ifdef THE_FUTURE
SVL_DLLPRIVATE bool ImpSwitchToSpecifiedCalendar( String& rOrgCalendar, SVL_DLLPRIVATE bool ImpSwitchToSpecifiedCalendar( String& rOrgCalendar,

View File

@@ -87,6 +87,8 @@ ImpSvNumberInputScan::ImpSvNumberInputScan( SvNumberFormatter* pFormatterP )
pUpperAbbrevMonthText( NULL ), pUpperAbbrevMonthText( NULL ),
pUpperGenitiveMonthText( NULL ), pUpperGenitiveMonthText( NULL ),
pUpperGenitiveAbbrevMonthText( NULL ), pUpperGenitiveAbbrevMonthText( NULL ),
pUpperPartitiveMonthText( NULL ),
pUpperPartitiveAbbrevMonthText( NULL ),
pUpperDayText( NULL ), pUpperDayText( NULL ),
pUpperAbbrevDayText( NULL ), pUpperAbbrevDayText( NULL ),
eScannedType( NUMBERFORMAT_UNDEFINED ), eScannedType( NUMBERFORMAT_UNDEFINED ),
@@ -111,6 +113,8 @@ ImpSvNumberInputScan::~ImpSvNumberInputScan()
delete [] pUpperAbbrevMonthText; delete [] pUpperAbbrevMonthText;
delete [] pUpperGenitiveMonthText; delete [] pUpperGenitiveMonthText;
delete [] pUpperGenitiveAbbrevMonthText; delete [] pUpperGenitiveAbbrevMonthText;
delete [] pUpperPartitiveMonthText;
delete [] pUpperPartitiveAbbrevMonthText;
delete [] pUpperDayText; delete [] pUpperDayText;
delete [] pUpperAbbrevDayText; delete [] pUpperAbbrevDayText;
} }
@@ -573,6 +577,18 @@ short ImpSvNumberInputScan::GetMonth( const String& rString, xub_StrLen& nPos )
res = sal::static_int_cast< short >(-(i+1)); // negative res = sal::static_int_cast< short >(-(i+1)); // negative
break; // for 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 ) ) else if ( StringContains( pUpperMonthText[i], rString, nPos ) )
{ // noun full names { // noun full names
nPos = nPos + pUpperMonthText[i].Len(); nPos = nPos + pUpperMonthText[i].Len();
@@ -2455,6 +2471,18 @@ void ImpSvNumberInputScan::InitText()
pUpperGenitiveAbbrevMonthText[j] = pChrCls->upper( xElems[j].AbbrevName ); 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; j<nElems; j++ )
{
pUpperPartitiveMonthText[j] = pChrCls->upper( xElems[j].FullName );
pUpperPartitiveAbbrevMonthText[j] = pChrCls->upper( xElems[j].AbbrevName );
}
delete [] pUpperDayText; delete [] pUpperDayText;
delete [] pUpperAbbrevDayText; delete [] pUpperAbbrevDayText;
xElems = pCal->getDays(); xElems = pCal->getDays();

View File

@@ -75,6 +75,8 @@ private:
String* pUpperAbbrevMonthText; // Array of month names, abbreviated, uppercase String* pUpperAbbrevMonthText; // Array of month names, abbreviated, uppercase
String* pUpperGenitiveMonthText; // Array of genitive month names, uppercase String* pUpperGenitiveMonthText; // Array of genitive month names, uppercase
String* pUpperGenitiveAbbrevMonthText; // Array of genitive month names, abbreviated, 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* pUpperDayText; // Array of day of week names, uppercase
String* pUpperAbbrevDayText; // Array of day of week names, abbreviated, uppercase String* pUpperAbbrevDayText; // Array of day of week names, abbreviated, uppercase
String aUpperCurrSymbol; // Currency symbol, uppercase String aUpperCurrSymbol; // Currency symbol, uppercase

View File

@@ -2946,28 +2946,79 @@ bool SvNumberformat::ImpGetTimeOutput(double fNumber,
/** If a day of month occurs within the format, the month name is in possessive /** 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) using namespace ::com::sun::star::i18n;
return io_nState == 1; if (!io_nState)
const ImpSvNumberformatInfo& rInfo = rNumFor.Info();
const sal_uInt16 nAnz = rNumFor.GetCount();
sal_uInt16 i;
for ( i = 0; i < nAnz; i++ )
{ {
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 : switch ( rInfo.nTypeArray[i] )
case NF_KEY_DD : {
io_nState = 1; case NF_KEY_D :
return true; 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; switch (io_nState)
return false; {
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(); double fDiff = DateTime(*(rScan.GetNullDate())) - rCal.getEpochStart();
fNumber += fDiff; fNumber += fDiff;
rCal.setLocalDateTime( fNumber ); rCal.setLocalDateTime( fNumber );
int nUseGenitiveMonth = 0; // not decided yet int nUseMonthCase = 0; // not decided yet
String aOrgCalendar; // empty => not changed yet String aOrgCalendar; // empty => not changed yet
double fOrgDateTime; double fOrgDateTime;
bool bOtherCalendar = ImpIsOtherCalendar( NumFor[nIx] ); bool bOtherCalendar = ImpIsOtherCalendar( NumFor[nIx] );
@@ -3183,22 +3234,16 @@ bool SvNumberformat::ImpGetDateOutput(double fNumber,
CalendarDisplayCode::LONG_MONTH, nNatNum ); CalendarDisplayCode::LONG_MONTH, nNatNum );
break; break;
case NF_KEY_MMM: // MMM case NF_KEY_MMM: // MMM
OutString += rCal.getDisplayString( OutString += rCal.getDisplayString( ImpUseMonthCase(
(ImpUseGenitiveMonth( nUseGenitiveMonth, NumFor[nIx]) ? nUseMonthCase, NumFor[nIx], static_cast<NfKeywordIndex>(rInfo.nTypeArray[i])), nNatNum);
CalendarDisplayCode::SHORT_GENITIVE_MONTH_NAME :
CalendarDisplayCode::SHORT_MONTH_NAME), nNatNum );
break; break;
case NF_KEY_MMMM: // MMMM case NF_KEY_MMMM: // MMMM
OutString += rCal.getDisplayString( OutString += rCal.getDisplayString( ImpUseMonthCase(
(ImpUseGenitiveMonth( nUseGenitiveMonth, NumFor[nIx]) ? nUseMonthCase, NumFor[nIx], static_cast<NfKeywordIndex>(rInfo.nTypeArray[i])), nNatNum);
CalendarDisplayCode::LONG_GENITIVE_MONTH_NAME :
CalendarDisplayCode::LONG_MONTH_NAME), nNatNum );
break; break;
case NF_KEY_MMMMM: // MMMMM case NF_KEY_MMMMM: // MMMMM
OutString += rCal.getDisplayString( OutString += rCal.getDisplayString( ImpUseMonthCase(
(ImpUseGenitiveMonth( nUseGenitiveMonth, NumFor[nIx]) ? nUseMonthCase, NumFor[nIx], static_cast<NfKeywordIndex>(rInfo.nTypeArray[i])), nNatNum);
CalendarDisplayCode::NARROW_GENITIVE_MONTH_NAME :
CalendarDisplayCode::NARROW_MONTH_NAME), nNatNum );
break; break;
case NF_KEY_Q: // Q case NF_KEY_Q: // Q
OutString += rCal.getDisplayString( OutString += rCal.getDisplayString(
@@ -3345,7 +3390,7 @@ bool SvNumberformat::ImpGetDateTimeOutput(double fNumber,
} }
rCal.setLocalDateTime( fNumber ); rCal.setLocalDateTime( fNumber );
int nUseGenitiveMonth = 0; // not decided yet int nUseMonthCase = 0; // not decided yet
String aOrgCalendar; // empty => not changed yet String aOrgCalendar; // empty => not changed yet
double fOrgDateTime; double fOrgDateTime;
bool bOtherCalendar = ImpIsOtherCalendar( NumFor[nIx] ); bool bOtherCalendar = ImpIsOtherCalendar( NumFor[nIx] );
@@ -3512,22 +3557,16 @@ bool SvNumberformat::ImpGetDateTimeOutput(double fNumber,
CalendarDisplayCode::LONG_MONTH, nNatNum ); CalendarDisplayCode::LONG_MONTH, nNatNum );
break; break;
case NF_KEY_MMM: // MMM case NF_KEY_MMM: // MMM
OutString += rCal.getDisplayString( OutString += rCal.getDisplayString( ImpUseMonthCase(
(ImpUseGenitiveMonth( nUseGenitiveMonth, NumFor[nIx]) ? nUseMonthCase, NumFor[nIx], static_cast<NfKeywordIndex>(rInfo.nTypeArray[i])), nNatNum);
CalendarDisplayCode::SHORT_GENITIVE_MONTH_NAME :
CalendarDisplayCode::SHORT_MONTH_NAME), nNatNum );
break; break;
case NF_KEY_MMMM: // MMMM case NF_KEY_MMMM: // MMMM
OutString += rCal.getDisplayString( OutString += rCal.getDisplayString( ImpUseMonthCase(
(ImpUseGenitiveMonth( nUseGenitiveMonth, NumFor[nIx]) ? nUseMonthCase, NumFor[nIx], static_cast<NfKeywordIndex>(rInfo.nTypeArray[i])), nNatNum);
CalendarDisplayCode::LONG_GENITIVE_MONTH_NAME :
CalendarDisplayCode::LONG_MONTH_NAME), nNatNum );
break; break;
case NF_KEY_MMMMM: // MMMMM case NF_KEY_MMMMM: // MMMMM
OutString += rCal.getDisplayString( OutString += rCal.getDisplayString( ImpUseMonthCase(
(ImpUseGenitiveMonth( nUseGenitiveMonth, NumFor[nIx]) ? nUseMonthCase, NumFor[nIx], static_cast<NfKeywordIndex>(rInfo.nTypeArray[i])), nNatNum);
CalendarDisplayCode::NARROW_GENITIVE_MONTH_NAME :
CalendarDisplayCode::NARROW_MONTH_NAME), nNatNum );
break; break;
case NF_KEY_Q: // Q case NF_KEY_Q: // Q
OutString += rCal.getDisplayString( OutString += rCal.getDisplayString(

View File

@@ -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 > getDays() const;
::com::sun::star::uno::Sequence< ::com::sun::star::i18n::CalendarItem2 > getMonths() 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 > getGenitiveMonths() const;
::com::sun::star::uno::Sequence< ::com::sun::star::i18n::CalendarItem2 > getPartitiveMonths() const;
// convenience methods // convenience methods

View File

@@ -632,4 +632,25 @@ String CalendarWrapper::getDisplayString( sal_Int32 nCalendarDisplayCode, sal_In
return ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::CalendarItem2 > (0); 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: */ /* vim:set shiftwidth=4 softtabstop=4 expandtab: */