aboutsummaryrefslogtreecommitdiff
path: root/extension/src/LoadLocalisation.cpp
blob: b660435128aea13d5dd2dc0ef874fdc113d7a8c6 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#include "LoadLocalisation.hpp"

#include <godot_cpp/classes/dir_access.hpp>
#include <godot_cpp/classes/file_access.hpp>
#include <godot_cpp/classes/translation_server.hpp>
#include <godot_cpp/variant/utility_functions.hpp>

using namespace godot;
using namespace OpenVic;

LoadLocalisation* LoadLocalisation::singleton = nullptr;

void LoadLocalisation::_bind_methods() {
   ClassDB::bind_method(D_METHOD("load_file", "file_path", "locale"), &LoadLocalisation::load_file);
   ClassDB::bind_method(D_METHOD("load_locale_dir", "dir_path", "locale"), &LoadLocalisation::load_locale_dir);
   ClassDB::bind_method(D_METHOD("load_localisation_dir", "dir_path"), &LoadLocalisation::load_localisation_dir);
}

LoadLocalisation* LoadLocalisation::get_singleton() {
   return singleton;
}

LoadLocalisation::LoadLocalisation() {
   ERR_FAIL_COND(singleton != nullptr);
   singleton = this;
}

LoadLocalisation::~LoadLocalisation() {
   ERR_FAIL_COND(singleton != this);
   singleton = nullptr;
}

Error LoadLocalisation::_load_file_into_translation(String const& file_path, Ref<Translation> translation) {
   const Ref<FileAccess> file = FileAccess::open(file_path, FileAccess::ModeFlags::READ);
   Error err = FileAccess::get_open_error();
   if (err != OK || file.is_null()) {
      UtilityFunctions::push_error("Failed to load localisation file: ", file_path);
      return err == OK ? FAILED : err;
   }
   int line_number = 0;
   while (!file->eof_reached()) {
      PackedStringArray line = file->get_csv_line();
      line_number++;
      if (line.size() < 2 || line[0].is_empty() || line[1].is_empty()) {
         if (!line[0].is_empty()) {
            UtilityFunctions::push_warning("Key \"", line[0], "\" missing value on line ", line_number, " in file: ", file_path);
            err = FAILED;
         } else if (line.size() >= 2 && !line[1].is_empty()) {
            UtilityFunctions::push_warning("Value \"", line[1], "\" missing key on line ", line_number, " in file: ", file_path);
            err = FAILED;
         }
         continue;
      }
      translation->add_message(line[0], line[1].c_unescape());
   }
   return err;
}

Ref<Translation> LoadLocalisation::_get_translation(String const& locale) {
   TranslationServer* server = TranslationServer::get_singleton();
   Ref<Translation> translation = server->get_translation_object(locale);
   if (translation.is_null() || translation->get_locale() != locale) {
      translation.instantiate();
      translation->set_locale(locale);
      server->add_translation(translation);
   }
   return translation;
}

Error LoadLocalisation::load_file(String const& file_path, String const& locale) {
   return _load_file_into_translation(file_path, _get_translation(locale));
}

/* REQUIREMENTS
 * FS-18, FS-24, FS-25
 */
Error LoadLocalisation::load_locale_dir(String const& dir_path, String const& locale) {
   if (!DirAccess::dir_exists_absolute(dir_path)) {
      UtilityFunctions::push_error("Locale directory does not exist: ", dir_path);
      return FAILED;
   }
   Ref<Translation> translation = _get_translation(locale);
   Error err = OK;
   for (String const& file_name : DirAccess::get_files_at(dir_path)) {
      if (file_name.get_extension().to_lower() == "csv") {
         String file_path = dir_path.path_join(file_name);
         if (_load_file_into_translation(file_path, translation) != OK)
            err = FAILED;
      }
   }
   return err;
}

/* REQUIREMENTS
 * FS-23
 */
Error LoadLocalisation::load_localisation_dir(String const& dir_path) {
   if(!DirAccess::dir_exists_absolute(dir_path)) {
      UtilityFunctions::push_error("Localisation directory does not exist: ", dir_path);
      return FAILED;
   }
   TranslationServer* server = TranslationServer::get_singleton();
   Error err = OK;
   for (String const& locale_name : DirAccess::get_directories_at(dir_path)) {
      if (locale_name != server->standardize_locale(locale_name))
         UtilityFunctions::push_error("Invalid locale directory name: ", locale_name);
      else if (load_locale_dir(dir_path.path_join(locale_name), locale_name) == OK)
         continue;
      err = FAILED;
   }
   return err;
}