Translatable months and weekdays. Missing am/pm designations.

A simple std::strftime wrapper was introduced, which takes care of date
translations when needed. I.e. if correct locale is not available, or
locale in use does not support am/pm designations.
This commit is contained in:
Andrius Silinskas 2013-09-30 08:10:32 +01:00
parent 56d454f45a
commit 947a842bad
10 changed files with 202 additions and 3 deletions

View file

@ -53,6 +53,10 @@ Version 1.11.6+dev:
* Updated translations: British English, German, Greek, Indonesian,
Lithuanian, Portuguese, Vietnamese
* Improved internationalization of notifications on Windows and OS X.
* Introduced translations for months and weekdays, which are used when user
does not have locale installed.
* Show am/pm designations, if required, even when locale doesn't support
them.
* Lua API:
* Added scroll_to_leader field (read/write) to wesnoth.sides table
elements.

View file

@ -19446,6 +19446,14 @@
RelativePath="..\..\src\statistics_dialog.hpp"
>
</File>
<File
RelativePath="..\..\src\strftime.cpp"
>
</File>
<File
RelativePath="..\..\src\strftime.hpp"
>
</File>
<File
RelativePath="..\..\src\team.cpp"
>

View file

@ -811,6 +811,7 @@ set(wesnoth-main_SRC
storyscreen/interface.cpp
storyscreen/part.cpp
storyscreen/render.cpp
strftime.cpp
team.cpp
terrain_filter.cpp
tod_manager.cpp

View file

@ -478,6 +478,7 @@ wesnoth_sources = Split("""
storyscreen/interface.cpp
storyscreen/part.cpp
storyscreen/render.cpp
strftime.cpp
team.cpp
terrain_filter.cpp
tod_manager.cpp

View file

@ -40,6 +40,7 @@
#include "replay.hpp"
#include "resources.hpp"
#include "savegame.hpp"
#include "strftime.hpp"
#include "thread.hpp"
#include "unit_helper.hpp"
#include "unit_types.hpp"
@ -815,7 +816,7 @@ void save_preview_pane::draw_contents()
const savegame::save_info& save = (*info_)[index_];
tm* tm_l = localtime(&save.modified());
if (tm_l) {
const size_t res = strftime(time_buf,sizeof(time_buf),
const size_t res = util::strftime(time_buf,sizeof(time_buf),
(preferences::use_twelve_hour_clock_format() ? _("%a %b %d %I:%M %p %Y") : _("%a %b %d %H:%M %Y")),
tm_l);
if(res == 0) {
@ -932,7 +933,7 @@ std::string format_time_summary(time_t t)
}
char buf[40];
const size_t res = strftime(buf,sizeof(buf),format_string,&save_time);
const size_t res = util::strftime(buf,sizeof(buf),format_string,&save_time);
if(res == 0) {
buf[0] = 0;
}

View file

@ -65,6 +65,12 @@ bool language_def::operator== (const language_def& a) const
symbol_table string_table;
bool& time_locale_correct()
{
static bool result = true;
return result;
}
const t_string& symbol_table::operator[](const std::string& key) const
{
const utils::string_map::const_iterator i = strings_.find(key);
@ -184,6 +190,11 @@ static void wesnoth_setlocale(int category, std::string const &slocale,
}
WRN_G << "setlocale() failed for '" << slocale << "'.\n";
if (category == LC_TIME) {
time_locale_correct() = false;
}
#ifndef _WIN32
#ifndef __AMIGAOS4__
if(category == LC_MESSAGES) {
@ -208,6 +219,8 @@ void set_language(const language_def& locale)
std::transform(locale.localename.begin(),locale.localename.end(),locale_lc.begin(),tolower);
current_language = locale;
time_locale_correct() = true;
wesnoth_setlocale(LC_COLLATE, locale.localename, &locale.alternates);
wesnoth_setlocale(LC_TIME, locale.localename, &locale.alternates);
wesnoth_setlocale(LC_MESSAGES, locale.localename, &locale.alternates);

View file

@ -66,6 +66,8 @@ struct symbol_table
//displayed on screen.
extern symbol_table string_table;
bool& time_locale_correct();
//function which, given the main configuration object, will return
//a list of the translations of the game available.
std::vector<language_def> get_languages();

View file

@ -28,6 +28,7 @@
#include "play_controller.hpp"
#include "reports.hpp"
#include "resources.hpp"
#include "strftime.hpp"
#include "team.hpp"
#include "text.hpp"
#include "tod_manager.hpp"
@ -1459,7 +1460,7 @@ REPORT_GENERATOR(report_clock)
struct tm *lt = std::localtime(&t);
if (!lt) return report();
char temp[15];
size_t s = std::strftime(temp, 15,
size_t s = util::strftime(temp, 15,
(preferences::use_twelve_hour_clock_format() ? _("%I:%M %p") : _("%H:%M")),
lt);
return s ? text_report(temp) : report();

137
src/strftime.cpp Normal file
View file

@ -0,0 +1,137 @@
/*
Copyright (C) 2013 by Andrius Silinskas <silinskas.andrius@gmail.com>
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.
See the COPYING file for more details.
*/
#include "strftime.hpp"
#include "gettext.hpp"
#include "language.hpp"
#include <string>
namespace {
const char *wday_abbr[] = {N_("Sun"), N_("Mon"), N_("Tue"), N_("Wed"),
N_("Thu"), N_("Fri"), N_("Sat")};
const char *wday_full[] = {N_("Sunday"), N_("Monday"), N_("Tuesday"),
N_("Wednesday"), N_("Thursday"), N_("Friday"), N_("Saturday")};
const char *mon_abbr[] = {N_("Jan"), N_("Feb"), N_("Mar"), N_("Apr"),
N_("abbrev^May"), N_("Jun"), N_("Jul"), N_("Aug"), N_("Sep"), N_("Oct"),
N_("Nov"), N_("Dec")};
const char *mon_full[] = {N_("January"), N_("February"), N_("March"),
N_("April"), N_("May"), N_("June"), N_("July"), N_("August"),
N_("September"), N_("October"), N_("November"), N_("December")};
}
static std::string reformat(const std::string& format, const std::tm* time,
bool locale_correct, bool ampm_supported)
{
if (locale_correct && ampm_supported) {
return format;
}
std::string new_format;
for (std::string::const_iterator it = format.begin(); it != format.end();
++it) {
if (*it == '%') {
++it;
bool unrecognized = false;
if (!locale_correct) {
switch (*it) {
case 'a': // abbreviated weekday name
new_format += (time->tm_wday < 0 || time->tm_wday > 6) ?
"?" : sgettext(wday_abbr[time->tm_wday]);
continue;
case 'A': // full weekday name
new_format += (time->tm_wday < 0 || time->tm_wday > 6) ?
"?" : sgettext(wday_full[time->tm_wday]);
continue;
case 'b': // abbreviated month name
case 'h':
new_format += (time->tm_mon < 0 || time->tm_mon > 11) ?
"?" : sgettext(mon_abbr[time->tm_mon]);
continue;
case 'B': // full month name
new_format += (time->tm_mon < 0 || time->tm_mon > 11) ?
"?" : sgettext(mon_full[time->tm_mon]);
continue;
case 'c': // date and time
new_format += reformat(_("%a %b %e %H:%M:%S %Y"), time,
locale_correct, ampm_supported);
continue;
case '+': // date and time
new_format += reformat(_("%a %d %b %Y %H:%M:%S %z"),
time, locale_correct, ampm_supported);
continue;
default:
unrecognized = true;
}
}
if (!ampm_supported || !locale_correct) {
switch (*it) {
case 'p': // AM or PM designation
new_format += (time->tm_hour < 12 ? _("AM") : _("PM"));
continue;
case 'P': // am or pm designation
new_format += (time->tm_hour < 12 ? _("am") : _("pm"));
continue;
default:
unrecognized = true;
}
}
// Unrecognized format specifiers should be left
// for std::strftime to deal with them.
if (unrecognized) {
new_format += "%";
}
}
new_format += *it;
}
return new_format;
}
static bool locale_supports_ampm(const std::tm* time)
{
const unsigned buffer_size = 16;
char time_buffer[buffer_size] = {0};
size_t ret = std::strftime(time_buffer, buffer_size, "%p", time);
if (ret == 0) {
return false;
}
return true;
}
namespace util {
size_t strftime(char* str, size_t count, const char* format,
const std::tm* time)
{
bool ampm_supported = locale_supports_ampm(time);
const std::string f = reformat(format, time, time_locale_correct(),
ampm_supported);
return std::strftime(str, count, f.c_str(), time);
}
} // end namespace util

31
src/strftime.hpp Normal file
View file

@ -0,0 +1,31 @@
/*
Copyright (C) 2013 by Andrius Silinskas <silinskas.andrius@gmail.com>
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.
See the COPYING file for more details.
*/
#ifndef STRFTIME_HPP_INCLUDED
#define STRFTIME_HPP_INCLUDED
#include <ctime>
namespace util {
/*
* std::strftime wrapper to support date translations and
* add missing am/pm designations.
*/
size_t strftime(char* str, size_t count, const char* format,
const std::tm* time);
}
#endif