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:
parent
56d454f45a
commit
947a842bad
10 changed files with 202 additions and 3 deletions
|
@ -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.
|
||||
|
|
|
@ -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"
|
||||
>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
137
src/strftime.cpp
Normal 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
31
src/strftime.hpp
Normal 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
|
Loading…
Add table
Reference in a new issue