Path: blob/master/editor/translations/editor_translation_parser.cpp
9896 views
/**************************************************************************/1/* editor_translation_parser.cpp */2/**************************************************************************/3/* This file is part of: */4/* GODOT ENGINE */5/* https://godotengine.org */6/**************************************************************************/7/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */8/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */9/* */10/* Permission is hereby granted, free of charge, to any person obtaining */11/* a copy of this software and associated documentation files (the */12/* "Software"), to deal in the Software without restriction, including */13/* without limitation the rights to use, copy, modify, merge, publish, */14/* distribute, sublicense, and/or sell copies of the Software, and to */15/* permit persons to whom the Software is furnished to do so, subject to */16/* the following conditions: */17/* */18/* The above copyright notice and this permission notice shall be */19/* included in all copies or substantial portions of the Software. */20/* */21/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */22/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */23/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */24/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */25/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */26/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */27/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */28/**************************************************************************/2930#include "editor_translation_parser.h"3132#include "core/error/error_macros.h"33#include "core/object/script_language.h"34#include "core/templates/hash_set.h"3536EditorTranslationParser *EditorTranslationParser::singleton = nullptr;3738Error EditorTranslationParserPlugin::parse_file(const String &p_path, Vector<Vector<String>> *r_translations) {39TypedArray<PackedStringArray> ret;4041if (GDVIRTUAL_CALL(_parse_file, p_path, ret)) {42// Copy over entries directly.43for (const PackedStringArray translation : ret) {44r_translations->push_back(translation);45}4647return OK;48}4950#ifndef DISABLE_DEPRECATED51TypedArray<String> ids;52TypedArray<Array> ids_ctx_plural;5354if (GDVIRTUAL_CALL(_parse_file_bind_compat_99297, p_path, ids, ids_ctx_plural)) {55// Add user's extracted translatable messages.56for (int i = 0; i < ids.size(); i++) {57r_translations->push_back({ ids[i] });58}5960// Add user's collected translatable messages with context or plurals.61for (int i = 0; i < ids_ctx_plural.size(); i++) {62Array arr = ids_ctx_plural[i];63ERR_FAIL_COND_V_MSG(arr.size() != 3, ERR_INVALID_DATA, "Array entries written into `msgids_context_plural` in `_parse_file` method should have the form [\"message\", \"context\", \"plural message\"]");6465r_translations->push_back({ arr[0], arr[1], arr[2] });66}67return OK;68}69#endif // DISABLE_DEPRECATED7071ERR_PRINT("Custom translation parser plugin's \"_parse_file\" is undefined.");72return ERR_UNAVAILABLE;73}7475void EditorTranslationParserPlugin::get_recognized_extensions(List<String> *r_extensions) const {76Vector<String> extensions;77if (GDVIRTUAL_CALL(_get_recognized_extensions, extensions)) {78for (int i = 0; i < extensions.size(); i++) {79r_extensions->push_back(extensions[i]);80}81} else {82ERR_PRINT("Custom translation parser plugin's \"func get_recognized_extensions()\" is undefined.");83}84}8586void EditorTranslationParserPlugin::_bind_methods() {87GDVIRTUAL_BIND(_parse_file, "path");88GDVIRTUAL_BIND(_get_recognized_extensions);8990#ifndef DISABLE_DEPRECATED91GDVIRTUAL_BIND_COMPAT(_parse_file_bind_compat_99297, "path", "msgids", "msgids_context_plural");92#endif93}9495/////////////////////////9697void EditorTranslationParser::get_recognized_extensions(List<String> *r_extensions) const {98HashSet<String> extensions;99List<String> temp;100for (int i = 0; i < standard_parsers.size(); i++) {101standard_parsers[i]->get_recognized_extensions(&temp);102}103for (int i = 0; i < custom_parsers.size(); i++) {104custom_parsers[i]->get_recognized_extensions(&temp);105}106// Remove duplicates.107for (const String &E : temp) {108extensions.insert(E);109}110for (const String &E : extensions) {111r_extensions->push_back(E);112}113}114115bool EditorTranslationParser::can_parse(const String &p_extension) const {116List<String> extensions;117get_recognized_extensions(&extensions);118for (const String &extension : extensions) {119if (p_extension == extension) {120return true;121}122}123return false;124}125126Ref<EditorTranslationParserPlugin> EditorTranslationParser::get_parser(const String &p_extension) const {127// Consider user-defined parsers first.128for (int i = 0; i < custom_parsers.size(); i++) {129List<String> temp;130custom_parsers[i]->get_recognized_extensions(&temp);131for (const String &E : temp) {132if (E == p_extension) {133return custom_parsers[i];134}135}136}137138for (int i = 0; i < standard_parsers.size(); i++) {139List<String> temp;140standard_parsers[i]->get_recognized_extensions(&temp);141for (const String &E : temp) {142if (E == p_extension) {143return standard_parsers[i];144}145}146}147148WARN_PRINT("No translation parser available for \"" + p_extension + "\" extension.");149150return nullptr;151}152153void EditorTranslationParser::add_parser(const Ref<EditorTranslationParserPlugin> &p_parser, ParserType p_type) {154if (p_type == ParserType::STANDARD) {155standard_parsers.push_back(p_parser);156} else if (p_type == ParserType::CUSTOM) {157custom_parsers.push_back(p_parser);158}159}160161void EditorTranslationParser::remove_parser(const Ref<EditorTranslationParserPlugin> &p_parser, ParserType p_type) {162if (p_type == ParserType::STANDARD) {163standard_parsers.erase(p_parser);164} else if (p_type == ParserType::CUSTOM) {165custom_parsers.erase(p_parser);166}167}168169void EditorTranslationParser::clean_parsers() {170standard_parsers.clear();171custom_parsers.clear();172}173174EditorTranslationParser *EditorTranslationParser::get_singleton() {175if (!singleton) {176singleton = memnew(EditorTranslationParser);177}178return singleton;179}180181EditorTranslationParser::~EditorTranslationParser() {182memdelete(singleton);183singleton = nullptr;184}185186187