2014-02-10 02:10:30 +01:00
/**************************************************************************/
/* translation.cpp */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
2018-01-05 00:50:27 +01:00
2014-02-10 02:10:30 +01:00
# include "translation.h"
2024-01-30 21:03:28 +01:00
# include "translation.compat.inc"
2017-01-16 08:04:19 +01:00
2018-09-11 18:13:45 +02:00
# include "core/os/os.h"
2024-08-15 09:00:47 +02:00
# include "core/os/thread.h"
# include "core/string/translation_server.h"
2020-09-03 13:22:16 +02:00
2020-07-16 10:52:06 +02:00
Dictionary Translation : : _get_messages ( ) const {
Dictionary d ;
2021-08-09 22:13:42 +02:00
for ( const KeyValue < StringName , StringName > & E : translation_map ) {
d [ E . key ] = E . value ;
2014-02-10 02:10:30 +01:00
}
2020-07-16 10:52:06 +02:00
return d ;
}
2020-02-17 22:06:54 +01:00
Vector < String > Translation : : _get_message_list ( ) const {
2020-08-07 13:17:12 +02:00
Vector < String > msgs ;
msgs . resize ( translation_map . size ( ) ) ;
int idx = 0 ;
2021-08-09 22:13:42 +02:00
for ( const KeyValue < StringName , StringName > & E : translation_map ) {
msgs . set ( idx , E . key ) ;
2020-08-07 13:17:12 +02:00
idx + = 1 ;
2014-02-10 02:10:30 +01:00
}
2020-08-07 13:17:12 +02:00
return msgs ;
2020-07-16 10:52:06 +02:00
}
2014-02-10 02:10:30 +01:00
2022-11-09 13:45:21 +01:00
Vector < String > Translation : : get_translated_message_list ( ) const {
Vector < String > msgs ;
msgs . resize ( translation_map . size ( ) ) ;
int idx = 0 ;
for ( const KeyValue < StringName , StringName > & E : translation_map ) {
msgs . set ( idx , E . value ) ;
idx + = 1 ;
}
return msgs ;
}
2020-08-07 13:17:12 +02:00
void Translation : : _set_messages ( const Dictionary & p_messages ) {
List < Variant > keys ;
p_messages . get_key_list ( & keys ) ;
2021-07-24 15:46:25 +02:00
for ( const Variant & E : keys ) {
2021-07-16 05:45:57 +02:00
translation_map [ E ] = p_messages [ E ] ;
2020-07-16 10:52:06 +02:00
}
2014-02-10 02:10:30 +01:00
}
void Translation : : set_locale ( const String & p_locale ) {
2021-09-23 13:08:50 +02:00
locale = TranslationServer : : get_singleton ( ) - > standardize_locale ( p_locale ) ;
2017-06-28 22:00:18 +02:00
2023-06-27 14:21:31 +02:00
if ( Thread : : is_main_thread ( ) ) {
_notify_translation_changed_if_applies ( ) ;
} else {
// Avoid calling non-thread-safe functions here.
callable_mp ( this , & Translation : : _notify_translation_changed_if_applies ) . call_deferred ( ) ;
}
}
void Translation : : _notify_translation_changed_if_applies ( ) {
2022-08-08 00:52:20 +02:00
if ( OS : : get_singleton ( ) - > get_main_loop ( ) & & TranslationServer : : get_singleton ( ) - > get_loaded_locales ( ) . has ( get_locale ( ) ) ) {
2017-06-28 22:00:18 +02:00
OS : : get_singleton ( ) - > get_main_loop ( ) - > notification ( MainLoop : : NOTIFICATION_TRANSLATION_CHANGED ) ;
}
2014-02-10 02:10:30 +01:00
}
2020-07-16 10:52:06 +02:00
void Translation : : add_message ( const StringName & p_src_text , const StringName & p_xlated_text , const StringName & p_context ) {
2020-08-07 13:17:12 +02:00
translation_map [ p_src_text ] = p_xlated_text ;
2020-07-16 10:52:06 +02:00
}
2020-08-07 13:17:12 +02:00
void Translation : : add_plural_message ( const StringName & p_src_text , const Vector < String > & p_plural_xlated_texts , const StringName & p_context ) {
WARN_PRINT ( " Translation class doesn't handle plural messages. Calling add_plural_message() on a Translation instance is probably a mistake. \n Use a derived Translation class that handles plurals, such as TranslationPO class " ) ;
2020-12-15 13:04:21 +01:00
ERR_FAIL_COND_MSG ( p_plural_xlated_texts . is_empty ( ) , " Parameter vector p_plural_xlated_texts passed in is empty. " ) ;
2020-08-07 13:17:12 +02:00
translation_map [ p_src_text ] = p_plural_xlated_texts [ 0 ] ;
2020-07-16 10:52:06 +02:00
}
StringName Translation : : get_message ( const StringName & p_src_text , const StringName & p_context ) const {
2021-09-29 13:18:45 +02:00
StringName ret ;
if ( GDVIRTUAL_CALL ( _get_message , p_src_text , p_context , ret ) ) {
return ret ;
}
2020-08-07 13:17:12 +02:00
if ( p_context ! = StringName ( ) ) {
WARN_PRINT ( " Translation class doesn't handle context. Using context in get_message() on a Translation instance is probably a mistake. \n Use a derived Translation class that handles context, such as TranslationPO class " ) ;
2020-05-14 16:41:43 +02:00
}
2014-02-10 02:10:30 +01:00
2022-05-13 15:04:37 +02:00
HashMap < StringName , StringName > : : ConstIterator E = translation_map . find ( p_src_text ) ;
2020-08-07 13:17:12 +02:00
if ( ! E ) {
2020-07-16 10:52:06 +02:00
return StringName ( ) ;
}
2022-05-13 15:04:37 +02:00
return E - > value ;
2020-08-07 13:17:12 +02:00
}
2020-07-16 10:52:06 +02:00
2020-08-07 13:17:12 +02:00
StringName Translation : : get_plural_message ( const StringName & p_src_text , const StringName & p_plural_text , int p_n , const StringName & p_context ) const {
2021-09-29 13:18:45 +02:00
StringName ret ;
if ( GDVIRTUAL_CALL ( _get_plural_message , p_src_text , p_plural_text , p_n , p_context , ret ) ) {
return ret ;
}
2020-08-07 13:17:12 +02:00
WARN_PRINT ( " Translation class doesn't handle plural messages. Calling get_plural_message() on a Translation instance is probably a mistake. \n Use a derived Translation class that handles plurals, such as TranslationPO class " ) ;
return get_message ( p_src_text ) ;
2020-07-16 10:52:06 +02:00
}
void Translation : : erase_message ( const StringName & p_src_text , const StringName & p_context ) {
2020-08-07 13:17:12 +02:00
if ( p_context ! = StringName ( ) ) {
WARN_PRINT ( " Translation class doesn't handle context. Using context in erase_message() on a Translation instance is probably a mistake. \n Use a derived Translation class that handles context, such as TranslationPO class " ) ;
2020-07-16 10:52:06 +02:00
}
2020-08-07 13:17:12 +02:00
translation_map . erase ( p_src_text ) ;
2014-02-10 02:10:30 +01:00
}
void Translation : : get_message_list ( List < StringName > * r_messages ) const {
2021-08-09 22:13:42 +02:00
for ( const KeyValue < StringName , StringName > & E : translation_map ) {
r_messages - > push_back ( E . key ) ;
2014-02-10 02:10:30 +01:00
}
}
2014-08-02 03:10:38 +02:00
int Translation : : get_message_count ( ) const {
2020-08-07 13:17:12 +02:00
return translation_map . size ( ) ;
2020-05-19 15:46:49 +02:00
}
2014-08-02 03:10:38 +02:00
2014-02-10 02:10:30 +01:00
void Translation : : _bind_methods ( ) {
2017-02-13 12:47:24 +01:00
ClassDB : : bind_method ( D_METHOD ( " set_locale " , " locale " ) , & Translation : : set_locale ) ;
ClassDB : : bind_method ( D_METHOD ( " get_locale " ) , & Translation : : get_locale ) ;
2024-01-30 21:03:28 +01:00
ClassDB : : bind_method ( D_METHOD ( " add_message " , " src_message " , " xlated_message " , " context " ) , & Translation : : add_message , DEFVAL ( StringName ( ) ) ) ;
ClassDB : : bind_method ( D_METHOD ( " add_plural_message " , " src_message " , " xlated_messages " , " context " ) , & Translation : : add_plural_message , DEFVAL ( StringName ( ) ) ) ;
ClassDB : : bind_method ( D_METHOD ( " get_message " , " src_message " , " context " ) , & Translation : : get_message , DEFVAL ( StringName ( ) ) ) ;
ClassDB : : bind_method ( D_METHOD ( " get_plural_message " , " src_message " , " src_plural_message " , " n " , " context " ) , & Translation : : get_plural_message , DEFVAL ( StringName ( ) ) ) ;
ClassDB : : bind_method ( D_METHOD ( " erase_message " , " src_message " , " context " ) , & Translation : : erase_message , DEFVAL ( StringName ( ) ) ) ;
2017-02-13 12:47:24 +01:00
ClassDB : : bind_method ( D_METHOD ( " get_message_list " ) , & Translation : : _get_message_list ) ;
2022-11-09 13:45:21 +01:00
ClassDB : : bind_method ( D_METHOD ( " get_translated_message_list " ) , & Translation : : get_translated_message_list ) ;
2017-02-13 12:47:24 +01:00
ClassDB : : bind_method ( D_METHOD ( " get_message_count " ) , & Translation : : get_message_count ) ;
2022-08-08 14:18:26 +02:00
ClassDB : : bind_method ( D_METHOD ( " _set_messages " , " messages " ) , & Translation : : _set_messages ) ;
2017-02-13 12:47:24 +01:00
ClassDB : : bind_method ( D_METHOD ( " _get_messages " ) , & Translation : : _get_messages ) ;
2017-03-05 16:44:50 +01:00
2021-09-29 13:18:45 +02:00
GDVIRTUAL_BIND ( _get_plural_message , " src_message " , " src_plural_message " , " n " , " context " ) ;
GDVIRTUAL_BIND ( _get_message , " src_message " , " context " ) ;
2021-11-03 23:06:17 +01:00
ADD_PROPERTY ( PropertyInfo ( Variant : : DICTIONARY , " messages " , PROPERTY_HINT_NONE , " " , PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL ) , " _set_messages " , " _get_messages " ) ;
2017-02-12 01:11:37 +01:00
ADD_PROPERTY ( PropertyInfo ( Variant : : STRING , " locale " ) , " set_locale " , " get_locale " ) ;
2014-02-10 02:10:30 +01:00
}