[Libreoffice-commits] core.git: Branch 'libreoffice-7-2' - 2 commits - include/vcl vcl/source
Eike Rathke (via logerrit)
logerrit at kemper.freedesktop.org
Mon Jul 5 21:41:10 UTC 2021
include/vcl/toolkit/field.hxx | 2
vcl/source/control/field2.cxx | 147 ++++++++++++++++++++++++++++++++----------
2 files changed, 115 insertions(+), 34 deletions(-)
New commits:
commit ccc48da9f9de2c93c01b9571f98221ff2eb07275
Author: Eike Rathke <erack at redhat.com>
AuthorDate: Mon Jul 5 18:37:37 2021 +0200
Commit: Eike Rathke <erack at redhat.com>
CommitDate: Mon Jul 5 23:40:53 2021 +0200
DateFormatter: make TextToDate() long date calendar aware, tdf#125035
Using number formatter to display long date now can generate any
arbitrary date string in any calendar known to the locale. Cope
with non-default non-Gregorian calendars when parsing such string
back to a date and convert to Gregorian for the calendar widget.
This currently relies on month names being different between
calendars, which isn't fail-proof but at least works for the ar_DZ
Hijri->Gregorian case.
A better approach would be to remember the calendar used in the
number formatter output, but that's not available (yet?).
Change-Id: I829655275de4d1983b7e453624efca967b16a3bd
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/118449
Reviewed-by: Eike Rathke <erack at redhat.com>
Tested-by: Jenkins
(cherry picked from commit 28859cd06cc699708bb43cb5e4ac7077d3a10f5b)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/118428
diff --git a/vcl/source/control/field2.cxx b/vcl/source/control/field2.cxx
index 6ed04e3a16ee..033905250b12 100644
--- a/vcl/source/control/field2.cxx
+++ b/vcl/source/control/field2.cxx
@@ -36,6 +36,7 @@
#include <svdata.hxx>
#include <com/sun/star/i18n/XCharacterClassification.hpp>
+#include <com/sun/star/i18n/CalendarFieldIndex.hdl>
#include <unotools/localedatawrapper.hxx>
#include <unotools/calendarwrapper.hxx>
@@ -1201,20 +1202,83 @@ static bool ImplCutMonthName( OUString& rStr, std::u16string_view _rLookupMonthN
return index >= 0;
}
-static sal_uInt16 ImplCutMonthFromString( OUString& rStr, const CalendarWrapper& rCalendarWrapper )
+static sal_uInt16 ImplGetMonthFromCalendarItem( OUString& rStr, const uno::Sequence< i18n::CalendarItem2 >& rMonths )
{
- // search for a month' name
- for ( sal_uInt16 i=1; i <= 12; i++ )
+ const sal_uInt16 nMonths = rMonths.getLength();
+ for (sal_uInt16 i=0; i < nMonths; ++i)
{
- OUString aMonthName = rCalendarWrapper.getMonths()[i-1].FullName;
// long month name?
- if ( ImplCutMonthName( rStr, aMonthName ) )
- return i;
+ if ( ImplCutMonthName( rStr, rMonths[i].FullName ) )
+ return i+1;
// short month name?
- OUString aAbbrevMonthName = rCalendarWrapper.getMonths()[i-1].AbbrevName;
- if ( ImplCutMonthName( rStr, aAbbrevMonthName ) )
- return i;
+ if ( ImplCutMonthName( rStr, rMonths[i].AbbrevName ) )
+ return i+1;
+ }
+ return 0;
+}
+
+static sal_uInt16 ImplCutMonthFromString( OUString& rStr, OUString& rCalendarName,
+ const LocaleDataWrapper& rLocaleData, const CalendarWrapper& rCalendarWrapper )
+{
+ const OUString aDefaultCalendarName( rCalendarWrapper.getUniqueID());
+ rCalendarName = aDefaultCalendarName;
+
+ // Search for a month name of the loaded default calendar.
+ const uno::Sequence< i18n::CalendarItem2 > aMonths = rCalendarWrapper.getMonths();
+ sal_uInt16 nMonth = ImplGetMonthFromCalendarItem( rStr, aMonths);
+ if (nMonth > 0)
+ return nMonth;
+
+ // And also possessive genitive and partitive month names.
+ const uno::Sequence< i18n::CalendarItem2 > aGenitiveMonths = rCalendarWrapper.getGenitiveMonths();
+ if (aGenitiveMonths != aMonths)
+ {
+ nMonth = ImplGetMonthFromCalendarItem( rStr, aGenitiveMonths);
+ if (nMonth > 0)
+ return nMonth;
+ }
+ const uno::Sequence< i18n::CalendarItem2 > aPartitiveMonths = rCalendarWrapper.getPartitiveMonths();
+ if (aPartitiveMonths != aMonths)
+ {
+ nMonth = ImplGetMonthFromCalendarItem( rStr, aPartitiveMonths);
+ if (nMonth > 0)
+ return nMonth;
+ }
+
+ // Check if there are more calendars and try them if so, as the long date
+ // format is obtained from the number formatter this is possible (e.g.
+ // ar_DZ "[~hijri] ...")
+ const uno::Sequence< i18n::Calendar2 > aCalendars = rLocaleData.getAllCalendars();
+ if (aCalendars.getLength() > 1)
+ {
+ for (const auto& rCalendar : aCalendars)
+ {
+ if (rCalendar.Name != aDefaultCalendarName)
+ {
+ rCalendarName = rCalendar.Name;
+
+ nMonth = ImplGetMonthFromCalendarItem( rStr, rCalendar.Months);
+ if (nMonth > 0)
+ return nMonth;
+
+ if (rCalendar.Months != rCalendar.GenitiveMonths)
+ {
+ nMonth = ImplGetMonthFromCalendarItem( rStr, rCalendar.GenitiveMonths);
+ if (nMonth > 0)
+ return nMonth;
+ }
+
+ if (rCalendar.Months != rCalendar.PartitiveMonths)
+ {
+ nMonth = ImplGetMonthFromCalendarItem( rStr, rCalendar.PartitiveMonths);
+ if (nMonth > 0)
+ return nMonth;
+ }
+
+ rCalendarName = aDefaultCalendarName;
+ }
+ }
}
return ImplCutNumberFromString( rStr );
@@ -1251,26 +1315,50 @@ bool DateFormatter::TextToDate(const OUString& rStr, Date& rDate, ExtDateFieldFo
if ( eDateOrder == ExtDateFieldFormat::SystemLong )
{
+ OUString aCalendarName;
DateOrder eFormat = rLocaleDataWrapper.getLongDateOrder();
switch( eFormat )
{
case DateOrder::MDY:
- nMonth = ImplCutMonthFromString( aStr, rCalendarWrapper );
+ nMonth = ImplCutMonthFromString( aStr, aCalendarName, rLocaleDataWrapper, rCalendarWrapper );
nDay = ImplCutNumberFromString( aStr );
nYear = ImplCutNumberFromString( aStr );
break;
case DateOrder::DMY:
nDay = ImplCutNumberFromString( aStr );
- nMonth = ImplCutMonthFromString( aStr, rCalendarWrapper );
+ nMonth = ImplCutMonthFromString( aStr, aCalendarName, rLocaleDataWrapper, rCalendarWrapper );
nYear = ImplCutNumberFromString( aStr );
break;
case DateOrder::YMD:
default:
nYear = ImplCutNumberFromString( aStr );
- nMonth = ImplCutMonthFromString( aStr, rCalendarWrapper );
+ nMonth = ImplCutMonthFromString( aStr, aCalendarName, rLocaleDataWrapper, rCalendarWrapper );
nDay = ImplCutNumberFromString( aStr );
break;
}
+ if (aCalendarName != "gregorian")
+ {
+ // Calendar widget is Gregorian, convert date.
+ // Need full date.
+ bError = !nDay || !nMonth || !nYear;
+ if (!bError)
+ {
+ CalendarWrapper aCW( rLocaleDataWrapper.getComponentContext());
+ aCW.loadCalendar( aCalendarName, rLocaleDataWrapper.getLoadedLanguageTag().getLocale());
+ aCW.setDateTime(0.5); // get rid of current time, set some day noon
+ aCW.setValue( i18n::CalendarFieldIndex::DAY_OF_MONTH, nDay);
+ aCW.setValue( i18n::CalendarFieldIndex::MONTH, nMonth - 1);
+ aCW.setValue( i18n::CalendarFieldIndex::YEAR, nYear);
+ bError = !aCW.isValid();
+ if (!bError)
+ {
+ Date aDate = aCW.getEpochStart() + aCW.getDateTime();
+ nYear = aDate.GetYear();
+ nMonth = aDate.GetMonth();
+ nDay = aDate.GetDay();
+ }
+ }
+ }
}
else
{
commit e8b1f2197776a08ac0b3d7e9a754c3e92327345a
Author: Eike Rathke <erack at redhat.com>
AuthorDate: Mon Jul 5 14:24:27 2021 +0200
Commit: Eike Rathke <erack at redhat.com>
CommitDate: Mon Jul 5 23:40:33 2021 +0200
Pass Formatter::StaticFormatter also from weld:DateFormatter, tdf#125035
Change-Id: I8e6b0e581b9522fb04225fc945e579406a4be208
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/118438
Reviewed-by: Eike Rathke <erack at redhat.com>
Tested-by: Jenkins
(cherry picked from commit 0335a319c5662f0b849a2231e48338dfeb6aa845)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/118427
diff --git a/include/vcl/toolkit/field.hxx b/include/vcl/toolkit/field.hxx
index d6ae05f51fc5..1eb55fabfd29 100644
--- a/include/vcl/toolkit/field.hxx
+++ b/include/vcl/toolkit/field.hxx
@@ -417,7 +417,7 @@ protected:
SAL_DLLPRIVATE bool ImplAllowMalformedInput() const;
public:
- static OUString FormatDate(const Date& rNewDate, ExtDateFieldFormat eFormat, const LocaleDataWrapper& rLocaleData, CalendarWrapper& rCalendarWrapper, const Formatter::StaticFormatter* pStaticFormatter = nullptr);
+ static OUString FormatDate(const Date& rNewDate, ExtDateFieldFormat eFormat, const LocaleDataWrapper& rLocaleData, const Formatter::StaticFormatter& rStaticFormatter);
static bool TextToDate(const OUString& rStr, Date& rTime, ExtDateFieldFormat eFormat, const LocaleDataWrapper& rLocaleDataWrapper, const CalendarWrapper& rCalendarWrapper);
static int GetDateArea(ExtDateFieldFormat eFormat, const OUString& rText, int nCursor, const LocaleDataWrapper& rLocaleDataWrapper);
diff --git a/vcl/source/control/field2.cxx b/vcl/source/control/field2.cxx
index 603415672f38..6ed04e3a16ee 100644
--- a/vcl/source/control/field2.cxx
+++ b/vcl/source/control/field2.cxx
@@ -1388,8 +1388,8 @@ namespace
}
OUString DateFormatter::FormatDate(const Date& rDate, ExtDateFieldFormat eExtFormat,
- const LocaleDataWrapper& rLocaleData, CalendarWrapper& rCalendarWrapper,
- const Formatter::StaticFormatter* pStaticFormatter)
+ const LocaleDataWrapper& rLocaleData,
+ const Formatter::StaticFormatter& rStaticFormatter)
{
bool bShowCentury = false;
switch (eExtFormat)
@@ -1439,22 +1439,16 @@ OUString DateFormatter::FormatDate(const Date& rDate, ExtDateFieldFormat eExtFor
{
case ExtDateFieldFormat::SystemLong:
{
- /* TODO: adapt all callers to pass a StaticFormatter. */
- if (!pStaticFormatter)
- return rLocaleData.getLongDate( rDate, rCalendarWrapper, !bShowCentury );
- else
- {
- SvNumberFormatter* pFormatter = *pStaticFormatter;
- const LanguageTag aFormatterLang( pFormatter->GetLanguageTag());
- const sal_uInt32 nIndex = pFormatter->GetFormatIndex( NF_DATE_SYSTEM_LONG,
- rLocaleData.getLanguageTag().getLanguageType(false));
- OUString aStr;
- const Color* pCol;
- pFormatter->GetOutputString( rDate - pFormatter->GetNullDate(), nIndex, aStr, &pCol);
- // Reset to what other uses may expect.
- pFormatter->ChangeIntl( aFormatterLang.getLanguageType(false));
- return aStr;
- }
+ SvNumberFormatter* pFormatter = rStaticFormatter;
+ const LanguageTag aFormatterLang( pFormatter->GetLanguageTag());
+ const sal_uInt32 nIndex = pFormatter->GetFormatIndex( NF_DATE_SYSTEM_LONG,
+ rLocaleData.getLanguageTag().getLanguageType(false));
+ OUString aStr;
+ const Color* pCol;
+ pFormatter->GetOutputString( rDate - pFormatter->GetNullDate(), nIndex, aStr, &pCol);
+ // Reset to what other uses may expect.
+ pFormatter->ChangeIntl( aFormatterLang.getLanguageType(false));
+ return aStr;
}
case ExtDateFieldFormat::ShortDDMMYY:
case ExtDateFieldFormat::ShortDDMMYYYY:
@@ -1499,8 +1493,7 @@ OUString DateFormatter::FormatDate(const Date& rDate, ExtDateFieldFormat eExtFor
OUString DateFormatter::ImplGetDateAsText( const Date& rDate ) const
{
- return DateFormatter::FormatDate(rDate, GetExtDateFormat(), ImplGetLocaleDataWrapper(),
- GetCalendarWrapper(), &maStaticFormatter);
+ return DateFormatter::FormatDate(rDate, GetExtDateFormat(), ImplGetLocaleDataWrapper(), maStaticFormatter);
}
static void ImplDateIncrementDay( Date& rDate, bool bUp )
@@ -2219,7 +2212,7 @@ namespace weld
OUString DateFormatter::FormatNumber(int nValue) const
{
const LocaleDataWrapper& rLocaleData = Application::GetSettings().GetLocaleDataWrapper();
- return ::DateFormatter::FormatDate(Date(nValue), m_eFormat, rLocaleData, GetCalendarWrapper());
+ return ::DateFormatter::FormatDate(Date(nValue), m_eFormat, rLocaleData, m_aStaticFormatter);
}
IMPL_LINK_NOARG(DateFormatter, FormatOutputHdl, LinkParamNone*, bool)
More information about the Libreoffice-commits
mailing list