diff --git a/addons/dialogic/Editor/Settings/CoreSettingsPages/csv_file.gd b/addons/dialogic/Editor/Settings/CoreSettingsPages/csv_file.gd index 3f8fb3a98..cafd28a37 100644 --- a/addons/dialogic/Editor/Settings/CoreSettingsPages/csv_file.gd +++ b/addons/dialogic/Editor/Settings/CoreSettingsPages/csv_file.gd @@ -89,11 +89,15 @@ func _read_file_into_lines() -> void: ## ## If this is the character name CSV file, use this method to ## take previously collected characters from other [class DialogicCsvFile]s. -func collect_lines_from_characters(characters: Dictionary) -> void: +func collect_lines_from_characters(characters: Dictionary, update_text: bool = false, text_dict: Dictionary = {}) -> void: for character: DialogicCharacter in characters.values(): # Add row for display names. var name_property := DialogicCharacter.TranslatedProperties.NAME var display_name_key: String = character.get_property_translation_key(name_property) + + if update_text and display_name_key in text_dict and text_dict[display_name_key]: + character.display_name = text_dict[display_name_key] + var line_value: String = character.display_name var array_line := PackedStringArray([display_name_key, line_value]) lines.append(array_line) @@ -104,6 +108,11 @@ func collect_lines_from_characters(characters: Dictionary) -> void: var nick_name_property := DialogicCharacter.TranslatedProperties.NICKNAMES var nickname_string: String = ",".join(nicknames) var nickname_name_line_key: String = character.get_property_translation_key(nick_name_property) + + if update_text and nickname_name_line_key in text_dict and text_dict[nickname_name_line_key]: + nickname_string = text_dict[nickname_name_line_key] + character.nicknames = nickname_string.split(",") + var nick_array_line := PackedStringArray([nickname_name_line_key, nickname_string]) lines.append(nick_array_line) @@ -226,11 +235,17 @@ func _sort_glossary_entry_property_keys(property_key_a: String, property_key_b: return value_a < value_b +# We use a space after the comma to make it easier to read. +var glossary_item_array_separator = ", " ## Collects properties from glossary entries from the given [param glossary] and ## adds them to the [member lines]. -func collect_lines_from_glossary(glossary: DialogicGlossary) -> void: - +func collect_lines_from_glossary(glossary: DialogicGlossary, update_text: bool = false, text_dict: Dictionary = {}) -> void: + + var entry_keys_to_replace : Dictionary = {} # "old entry key": "new entry key" + var aliases_to_remove : Array = [] + var aliases_to_add : Dictionary = {} # " "new alias": "entry key" + for glossary_value: Variant in glossary.entries.values(): if glossary_value is String: @@ -247,18 +262,17 @@ func collect_lines_from_glossary(glossary: DialogicGlossary) -> void: var entry_name_property: String = glossary_entry[DialogicGlossary.NAME_PROPERTY] - for entry_key: String in entry_property_keys: + for entry_property_key: String in entry_property_keys: # Ignore private keys. - if entry_key.begins_with(DialogicGlossary.PRIVATE_PROPERTY_PREFIX): + if entry_property_key.begins_with(DialogicGlossary.PRIVATE_PROPERTY_PREFIX): continue - var item_value: Variant = glossary_entry[entry_key] + var item_value: Variant = glossary_entry[entry_property_key] var item_value_str := "" if item_value is Array: var item_array := item_value as Array - # We use a space after the comma to make it easier to read. - item_value_str = " ,".join(item_array) + item_value_str = glossary_item_array_separator.join(item_array) elif not item_value is String or item_value.is_empty(): continue @@ -266,11 +280,55 @@ func collect_lines_from_glossary(glossary: DialogicGlossary) -> void: else: item_value_str = item_value - var glossary_csv_key := glossary._get_glossary_translation_key(entry_translation_id, entry_key) - - if (entry_key == DialogicGlossary.NAME_PROPERTY - or entry_key == DialogicGlossary.ALTERNATIVE_PROPERTY): - glossary.entries[glossary_csv_key] = entry_name_property + var glossary_csv_key := glossary._get_glossary_translation_key(entry_translation_id, entry_property_key) + + if update_text and glossary_csv_key in text_dict and text_dict[glossary_csv_key]: + + if entry_property_key == DialogicGlossary.ALTERNATIVE_PROPERTY: + aliases_to_remove.append_array(item_value) + var new_aliases_array = text_dict[glossary_csv_key].split(glossary_item_array_separator) as Array + + var new_aliases_array_dedup : Array = [] + + for alias in new_aliases_array: + + var new_alias = alias + # It's possible that translations of two words could lead to the same key, + # we add a suffix in this case to avoid any issues + while new_alias in aliases_to_add: + new_alias += " (duplicate)" + while new_alias in entry_keys_to_replace.values(): + new_alias += " (duplicate)" + + aliases_to_add[new_alias] = entry_name_property + + new_aliases_array_dedup.append(new_alias) + + item_value_str = glossary_item_array_separator.join(new_aliases_array_dedup) + glossary_entry[entry_property_key] = new_aliases_array_dedup + else: + item_value_str = text_dict[glossary_csv_key] + glossary_entry[entry_property_key] = text_dict[glossary_csv_key] + + if entry_property_key == DialogicGlossary.NAME_PROPERTY: + var new_entry_key : String = text_dict[glossary_csv_key] + + # It's possible that translations of two words could lead to the same key, + # we add a suffix in this case to avoid any issues + while new_entry_key in entry_keys_to_replace.values(): + new_entry_key += " (duplicate)" + while new_entry_key in aliases_to_add: + new_entry_key += " (duplicate)" + + entry_keys_to_replace[entry_name_property] = new_entry_key + + if (entry_property_key == DialogicGlossary.NAME_PROPERTY + or entry_property_key == DialogicGlossary.ALTERNATIVE_PROPERTY): + var entry_key = entry_name_property + if entry_key in entry_keys_to_replace: + entry_key = entry_keys_to_replace[entry_key] + + glossary.entries[glossary_csv_key] = entry_key var glossary_line := PackedStringArray([glossary_csv_key, item_value_str]) @@ -279,12 +337,29 @@ func collect_lines_from_glossary(glossary: DialogicGlossary) -> void: # New glossary item, if needed, add a separator. if add_separator: _append_empty() - + + + if update_text: + for old_entry_key in entry_keys_to_replace: + var new_entry_key = entry_keys_to_replace[old_entry_key] + glossary.replace_entry_key(old_entry_key, new_entry_key) + + for old_alias in aliases_to_remove: + glossary._remove_entry_alias(old_alias) + + for new_alias in aliases_to_add: + + var entry_key = aliases_to_add[new_alias] + + if entry_key in entry_keys_to_replace: + entry_key = entry_keys_to_replace[entry_key] + + glossary._add_entry_key_alias(entry_key, new_alias) ## Collects translatable events from the given [param timeline] and adds ## them to the [member lines]. -func collect_lines_from_timeline(timeline: DialogicTimeline) -> void: +func collect_lines_from_timeline(timeline: DialogicTimeline, update_text: bool = false, text_dict: Dictionary = {}) -> void: for event: DialogicEvent in timeline.events: if event.can_be_translated(): @@ -292,12 +367,19 @@ func collect_lines_from_timeline(timeline: DialogicTimeline) -> void: if event._translation_id.is_empty(): event.add_translation_id() event.update_text_version() + var properties: Array = event._get_translatable_properties() for property: String in properties: var line_key: String = event.get_property_translation_key(property) + + if update_text and line_key in text_dict and text_dict[line_key]: + event._set_property_original_translation(property, text_dict[line_key]) + event.update_text_version() + var line_value: String = event._get_property_original_translation(property) + var array_line := PackedStringArray([line_key, line_value]) lines.append(array_line) diff --git a/addons/dialogic/Editor/Settings/CoreSettingsPages/settings_translation.gd b/addons/dialogic/Editor/Settings/CoreSettingsPages/settings_translation.gd index d882ec7fd..14d858395 100644 --- a/addons/dialogic/Editor/Settings/CoreSettingsPages/settings_translation.gd +++ b/addons/dialogic/Editor/Settings/CoreSettingsPages/settings_translation.gd @@ -52,6 +52,9 @@ func _ready() -> void: %CollectTranslations.pressed.connect(collect_translations) %CollectTranslations.icon = get_theme_icon("File", "EditorIcons") + + %UseTextFromCsvFiles.pressed.connect(update_text_based_on_csv_files) + %UseTextFromCsvFiles.icon = get_theme_icon("TextFile", "EditorIcons") %TransRemove.pressed.connect(_on_erase_translations_pressed) %TransRemove.icon = get_theme_icon("Remove", "EditorIcons") @@ -62,6 +65,133 @@ func _ready() -> void: _verify_translation_file() +func get_csv_translation_files() -> Array: + var csv_files := [] + var translation_mode: TranslationModes = ProjectSettings.get_setting('dialogic/translation/file_mode', TranslationModes.PER_PROJECT) + + if translation_mode == TranslationModes.PER_TIMELINE: + + for timeline_path: String in DialogicResourceUtil.list_resources_of_type('.csv'): + + for file: String in DialogicUtil.listdir(timeline_path.get_base_dir()): + file = timeline_path.get_base_dir().path_join(file) + + if file.ends_with('.csv'): + + if not file in csv_files: + csv_files.append(file) + + if translation_mode == TranslationModes.PER_PROJECT: + var translation_folder: String = ProjectSettings.get_setting('dialogic/translation/translation_folder', 'res://') + + for file: String in DialogicUtil.listdir(translation_folder): + file = translation_folder.path_join(file) + + if file.ends_with('.csv'): + + if not file in csv_files: + csv_files.append(file) + + return csv_files + +func get_translations_from_csv_for_locale(file_path : StringName, locale : String) -> Dictionary: + var translations = {} + + var file = FileAccess.open(file_path, FileAccess.READ) + + if file: + var header = file.get_csv_line() + if locale in header: + var locale_index = header.find(locale) + while not file.eof_reached(): + var line = file.get_csv_line() + if line.size() > locale_index: + translations[line[0]] = line[locale_index] + + file.close() + + return translations + +func array_swap(array:Array, index_1:int, index_2:int) -> Array: + if array.size() > index_1 and array.size() > index_2: + var tmp = array[index_1] + array[index_1] = array[index_2] + array[index_2] = tmp + + return array + +func change_first_locale_in_csv_file(file_path : StringName, first_locale_key : String) -> void: + + var file = FileAccess.open(file_path, FileAccess.READ) + var lines = [] + + if file: + var header:Array = file.get_csv_line() + + if first_locale_key in header: + # If the locale exists, we move it to the first column + + var locale_index = header.find(first_locale_key) + + if locale_index <= 1: + # If it's already the first column we have nothing to do + # (and if it is the column zero, the file is not usable ...) + file.close() + return + + else: + array_swap(header, 1, locale_index) + lines.append(header) + + while not file.eof_reached(): + var line:Array = file.get_csv_line() + + while line.size() <= locale_index: + line.append("") + + array_swap(line, 1, locale_index) + + lines.append(line) + else: + # If the locale doesn't even exist, we create it + header.insert(1, first_locale_key) + lines.append(header) + + while not file.eof_reached(): + var line:Array = file.get_csv_line() + + line.insert(1, "") + lines.append(line) + + file.close() + + file = FileAccess.open(file_path, FileAccess.WRITE) + for line in lines: + file.store_csv_line(line) + + file.close() + + + + +## First retrieve all translations for default locale +## Update the CSV files if needed to make the default locale the first column +## Call the update_csv_files function with update_text set to true to put the retrieved translations +## for default locale in the timeline, character and gloassary files. +## +## If any translation is missing for selected default locale, it will use original text. +func update_text_based_on_csv_files() -> void: + var translation_files = get_csv_translation_files() + + var translations = {} + + for file in translation_files: + change_first_locale_in_csv_file(file, get_orig_locale()) + + for file in translation_files: + translations.merge(get_translations_from_csv_for_locale(file, get_orig_locale())) + + update_csv_files(true, translations) func _on_custom_action(action: String) -> void: if action == "generate_new": @@ -120,6 +250,7 @@ func _verify_translation_file() -> void: and DirAccess.dir_exists_absolute(translation_folder)) %UpdateCsvFiles.disabled = not valid_translation_folder + %UseTextFromCsvFiles.disabled = not valid_translation_folder var status_message := "" @@ -183,7 +314,9 @@ func _handle_glossary_translation( save_location_mode: SaveLocationModes, translation_mode: TranslationModes, translation_folder_path: String, - orig_locale: String) -> void: + orig_locale: String, + update_text: bool = false, + text_dict: Dictionary = {}) -> void: var glossary_csv: DialogicCsvFile = null var glossary_paths: Array = ProjectSettings.get_setting('dialogic/glossary/glossary_files', []) @@ -223,7 +356,7 @@ func _handle_glossary_translation( csv_data.updated_glossaries += 1 var glossary: DialogicGlossary = load(glossary_path) - glossary_csv.collect_lines_from_glossary(glossary) + glossary_csv.collect_lines_from_glossary(glossary, update_text, text_dict) glossary_csv.add_translation_keys_to_glossary(glossary) ResourceSaver.save(glossary) @@ -257,10 +390,18 @@ class CsvUpdateData: var new_glossary_entries := 0 var updated_glossary_entries := 0 +func get_orig_locale(): + + var orig_locale: String = ProjectSettings.get_setting('dialogic/translation/original_locale', '').strip_edges() + + if orig_locale.is_empty(): + orig_locale = ProjectSettings.get_setting('internationalization/locale/fallback') + + return orig_locale -func update_csv_files() -> void: +func update_csv_files(update_text: bool = false, text_dict: Dictionary = {}) -> void: _unique_locales = [] - var orig_locale: String = ProjectSettings.get_setting('dialogic/translation/original_locale', '').strip_edges() + var orig_locale: String = get_orig_locale() var save_location_mode: SaveLocationModes = ProjectSettings.get_setting('dialogic/translation/save_mode', SaveLocationModes.NEXT_TO_TIMELINE) var translation_mode: TranslationModes = ProjectSettings.get_setting('dialogic/translation/file_mode', TranslationModes.PER_PROJECT) var translation_folder_path: String = ProjectSettings.get_setting('dialogic/translation/translation_folder', 'res://') @@ -268,15 +409,16 @@ func update_csv_files() -> void: var csv_data := CsvUpdateData.new() - if orig_locale.is_empty(): - orig_locale = ProjectSettings.get_setting('internationalization/locale/fallback') - ProjectSettings.set_setting('dialogic/translation/intern/save_mode', save_location_mode) ProjectSettings.set_setting('dialogic/translation/intern/file_mode', translation_mode) ProjectSettings.set_setting('dialogic/translation/intern/translation_folder', translation_folder_path) var current_timeline := _close_active_timeline() + var current_character : Resource = null + if update_text: + current_character = _close_active_character() + var csv_per_project: DialogicCsvFile = null var per_project_csv_path := translation_folder_path.path_join(DEFAULT_TIMELINE_CSV_NAME) @@ -320,7 +462,7 @@ func update_csv_files() -> void: timeline.process() # Collect timeline into CSV. - csv_file.collect_lines_from_timeline(timeline) + csv_file.collect_lines_from_timeline(timeline, update_text, text_dict) # in case new translation_id's were added, we save the timeline again timeline.set_meta("timeline_not_saved", true) @@ -337,20 +479,27 @@ func update_csv_files() -> void: save_location_mode, translation_mode, translation_folder_path, - orig_locale + orig_locale, + update_text, + text_dict ) _handle_character_names( csv_data, orig_locale, translation_folder_path, - add_separator_lines + add_separator_lines, + update_text, + text_dict ) if translation_mode == TranslationModes.PER_PROJECT: csv_per_project.update_csv_file_on_disk() _silently_open_timeline(current_timeline) + + if update_text: + _silently_open_character(current_character) # Trigger reimport. find_parent('EditorView').plugin_reference.get_editor_interface().get_resource_filesystem().scan_sources() @@ -385,11 +534,13 @@ func _handle_character_names( csv_data: CsvUpdateData, original_locale: String, translation_folder_path: String, - add_separator_lines: bool) -> void: + add_separator_lines: bool, + update_text: bool = false, + text_dict: Dictionary = {}) -> void: var names_csv_path := translation_folder_path.path_join(DEFAULT_CHARACTER_CSV_NAME) var character_name_csv: DialogicCsvFile = DialogicCsvFile.new(names_csv_path, original_locale, - add_separator_lines + add_separator_lines, ) var all_characters := {} @@ -408,7 +559,7 @@ func _handle_character_names( ResourceSaver.save(character) - character_name_csv.collect_lines_from_characters(all_characters) + character_name_csv.collect_lines_from_characters(all_characters, update_text, text_dict) character_name_csv.update_csv_file_on_disk() @@ -642,6 +793,15 @@ func _close_active_timeline() -> Resource: return current_timeline +func _close_active_character() -> Resource: + var character_node: DialogicEditor = settings_editor.editors_manager.editors['CharacterEditor']['node'] + # We will close this character to ensure it will properly update. + # By saving this reference, we can open it again. + var current_character := character_node.current_resource + # Clean the current editor, this will also close the character. + settings_editor.editors_manager.clear_editor(character_node) + + return current_character ## Opens the timeline resource into the Dialogic Editor. ## If the timeline is null, does nothing. @@ -649,6 +809,11 @@ func _silently_open_timeline(timeline_to_open: Resource) -> void: if timeline_to_open != null: settings_editor.editors_manager.edit_resource(timeline_to_open, true, true) +## Opens the character resource into the Dialogic Editor. +## If the character is null, does nothing. +func _silently_open_character(character_to_open: Resource) -> void: + if character_to_open != null: + settings_editor.editors_manager.edit_resource(character_to_open, true, true) ## Checks [param locale] for unique locales that have not been added ## to the [_unique_locales] array yet. diff --git a/addons/dialogic/Editor/Settings/CoreSettingsPages/settings_translation.tscn b/addons/dialogic/Editor/Settings/CoreSettingsPages/settings_translation.tscn index eadce4ad3..0b586acf1 100644 --- a/addons/dialogic/Editor/Settings/CoreSettingsPages/settings_translation.tscn +++ b/addons/dialogic/Editor/Settings/CoreSettingsPages/settings_translation.tscn @@ -7,14 +7,14 @@ [sub_resource type="Image" id="Image_4jaem"] data = { -"data": PackedByteArray(255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 231, 255, 94, 94, 54, 255, 94, 94, 57, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 231, 255, 94, 94, 54, 255, 94, 94, 57, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 93, 93, 233, 255, 93, 93, 232, 255, 93, 93, 41, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 93, 93, 233, 255, 93, 93, 232, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 44, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 44, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 235, 255, 94, 94, 234, 255, 95, 95, 43, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 235, 255, 94, 94, 234, 255, 95, 95, 43, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 95, 95, 59, 255, 96, 96, 61, 255, 93, 93, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 95, 95, 59, 255, 96, 96, 61, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0), +"data": PackedByteArray(255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 92, 92, 0, 255, 92, 92, 0, 255, 92, 92, 0, 255, 92, 92, 0, 255, 92, 92, 0, 255, 92, 92, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 0, 255, 92, 92, 127, 255, 92, 92, 0, 255, 92, 92, 0, 255, 92, 92, 0, 255, 92, 92, 0, 255, 92, 92, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 0, 255, 93, 93, 255, 255, 92, 92, 127, 255, 92, 92, 0, 255, 92, 92, 0, 255, 92, 92, 0, 255, 92, 92, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 92, 92, 127, 255, 92, 92, 0, 255, 92, 92, 0, 255, 92, 92, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 92, 92, 127, 255, 92, 92, 0, 255, 92, 92, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 92, 92, 0, 255, 92, 92, 0, 255, 92, 92, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 231, 255, 90, 90, 54, 255, 94, 94, 57, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 231, 255, 90, 90, 54, 255, 94, 94, 57, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 0, 255, 93, 93, 0, 255, 91, 91, 0, 255, 91, 91, 0, 255, 91, 91, 42, 255, 90, 90, 0, 255, 94, 94, 0, 255, 91, 91, 42, 255, 93, 93, 233, 255, 92, 92, 232, 255, 93, 93, 41, 255, 90, 90, 0, 255, 94, 94, 0, 255, 91, 91, 42, 255, 93, 93, 233, 255, 92, 92, 232, 255, 92, 92, 0, 255, 92, 92, 0, 255, 91, 91, 0, 255, 91, 91, 0, 255, 91, 91, 0, 255, 91, 91, 45, 255, 93, 93, 44, 255, 91, 91, 0, 255, 91, 91, 42, 255, 91, 91, 42, 255, 93, 93, 0, 255, 91, 91, 45, 255, 93, 93, 44, 255, 91, 91, 0, 255, 91, 91, 42, 255, 91, 91, 42, 255, 91, 91, 0, 255, 91, 91, 0, 255, 91, 91, 0, 255, 91, 91, 0, 255, 91, 91, 45, 255, 92, 92, 235, 255, 92, 92, 234, 255, 89, 89, 43, 255, 91, 91, 0, 255, 91, 91, 0, 255, 91, 91, 45, 255, 92, 92, 235, 255, 92, 92, 234, 255, 89, 89, 43, 255, 91, 91, 0, 255, 91, 91, 0, 255, 91, 91, 0, 255, 91, 91, 0, 255, 92, 92, 0, 255, 92, 92, 0, 255, 92, 92, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 91, 91, 59, 255, 92, 92, 61, 255, 92, 92, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 91, 91, 59, 255, 92, 92, 61, 255, 92, 92, 0, 255, 92, 92, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0, 255, 93, 93, 0), "format": "RGBA8", "height": 16, "mipmaps": false, "width": 16 } -[sub_resource type="ImageTexture" id="ImageTexture_xbph7"] +[sub_resource type="ImageTexture" id="ImageTexture_ih5gb"] image = SubResource("Image_4jaem") [node name="Translations" type="VBoxContainer"] @@ -73,7 +73,7 @@ text = "Testing locale" layout_mode = 2 tooltip_text = "Change this locale to test your game in a different language (only in-editor). Equivalent of the testing local project setting. " -texture = SubResource("ImageTexture_xbph7") +texture = null hint_text = "Change this locale to test your game in a different language (only in-editor). Equivalent of the testing local project setting. @@ -113,12 +113,13 @@ text = "Default locale" [node name="HintTooltip" parent="TranslationSettings/VBoxContainer/Grid/VBox" instance=ExtResource("2_k2lou")] layout_mode = 2 tooltip_text = "The locale of the language your timelines are written in." -texture = SubResource("ImageTexture_xbph7") +texture = null hint_text = "The locale of the language your timelines are written in." [node name="OrigLocale" parent="TranslationSettings/VBoxContainer/Grid" instance=ExtResource("3_dq4j2")] unique_name_in_owner = true layout_mode = 2 +mode = 3 [node name="TransFile" type="HBoxContainer" parent="TranslationSettings/VBoxContainer/Grid"] layout_mode = 2 @@ -131,7 +132,7 @@ text = "Translation folder" layout_mode = 2 tooltip_text = "Choose a folder to let Dialogic save CSV files in. Also used when saving \"Inside Translation Folder\"" -texture = SubResource("ImageTexture_xbph7") +texture = null hint_text = "Choose a folder to let Dialogic save CSV files in. Also used when saving \"Inside Translation Folder\"" @@ -159,7 +160,7 @@ For example, 10 timelines will be combined into 1 CSV file. For example, 10 timelines will result in 10 CSV files. The \"Per File\" option utilises \"Output location\", in contrast, the \"Per Type\" will always use the Translation folder." -texture = SubResource("ImageTexture_xbph7") +texture = null hint_text = "Decides how many CSV files will be created. • \"Per Type\": Uses one CSV file for each type of resource: Timelines, characters, and glossaries. @@ -173,8 +174,8 @@ The \"Per File\" option utilises \"Output location\", in contrast, the \"Per Typ [node name="TransMode" type="OptionButton" parent="TranslationSettings/VBoxContainer/Grid"] unique_name_in_owner = true layout_mode = 2 -item_count = 2 selected = 0 +item_count = 2 popup/item_0/text = "Per Type" popup/item_0/id = 0 popup/item_1/text = "Per File" @@ -197,7 +198,7 @@ tooltip_text = "Decides where to save the generated CSV files. This button requires the \"Per File\" Output mode. A resource type can be: Timelines, characters, and glossaries." -texture = SubResource("ImageTexture_xbph7") +texture = null hint_text = "Decides where to save the generated CSV files. • \"Inside Translation Folder\": Uses the \"Translation folder\". @@ -211,8 +212,8 @@ A resource type can be: Timelines, characters, and glossaries." unique_name_in_owner = true layout_mode = 2 disabled = true -item_count = 2 selected = 0 +item_count = 2 popup/item_0/text = "Inside Translation Folder" popup/item_0/id = 0 popup/item_1/text = "Next to File" @@ -234,7 +235,7 @@ layout_mode = 2 tooltip_text = "Adds an empty line into per-project CSVs to differentiate between sections. For example, when a new glossary item or timeline starts, an empty line will be added." -texture = SubResource("ImageTexture_xbph7") +texture = null hint_text = "Adds an empty line into per-project CSVs to differentiate between sections. For example, when a new glossary item or timeline starts, an empty line will be added." @@ -267,7 +268,7 @@ unique_name_in_owner = true layout_mode = 2 disabled = true text = "Update CSV files" -icon = SubResource("ImageTexture_xbph7") +icon = SubResource("ImageTexture_ih5gb") [node name="HintTooltip5" parent="TranslationSettings/VBoxContainer2/Actions" instance=ExtResource("2_k2lou")] layout_mode = 2 @@ -276,9 +277,32 @@ tooltip_text = "This button will scan all timelines and generate or update their A Dialogic CSV file will be prefixed with \"dialogic_\". This action will be disabled if the \"Translation folder\" is missing or has an invalid path." -texture = SubResource("ImageTexture_xbph7") +texture = null +hint_text = "This button will scan all timelines and generate or update their CSV files. + +This will erase any change made to default locale strings in the CSV files. + +A Dialogic CSV file will be prefixed with \"dialogic_\". + +This action will be disabled if the \"Translation folder\" is missing or has an invalid path." + +[node name="UseTextFromCsvFiles" type="Button" parent="TranslationSettings/VBoxContainer2/Actions"] +unique_name_in_owner = true +layout_mode = 2 +disabled = true +text = "Use text from CSV files" +icon = SubResource("ImageTexture_ih5gb") + +[node name="HintTooltip8" parent="TranslationSettings/VBoxContainer2/Actions" instance=ExtResource("2_k2lou")] +layout_mode = 2 +tooltip_text = "Godot imports CSV files as \".translation\" files. +This buttons adds them to \"Project Settings -> Localization\". +" +texture = null hint_text = "This button will scan all timelines and generate or update their CSV files. +This will replace original text with text from the CSV files for default locale. + A Dialogic CSV file will be prefixed with \"dialogic_\". This action will be disabled if the \"Translation folder\" is missing or has an invalid path." @@ -287,14 +311,14 @@ This action will be disabled if the \"Translation folder\" is missing or has an unique_name_in_owner = true layout_mode = 2 text = "Collect translations" -icon = SubResource("ImageTexture_xbph7") +icon = SubResource("ImageTexture_ih5gb") [node name="HintTooltip6" parent="TranslationSettings/VBoxContainer2/Actions" instance=ExtResource("2_k2lou")] layout_mode = 2 tooltip_text = "Godot imports CSV files as \".translation\" files. This buttons adds them to \"Project Settings -> Localization\". " -texture = SubResource("ImageTexture_xbph7") +texture = null hint_text = "Godot imports CSV files as \".translation\" files. This buttons adds them to \"Project Settings -> Localization\". " @@ -311,7 +335,7 @@ layout_mode = 2 unique_name_in_owner = true layout_mode = 2 text = "Remove translations" -icon = SubResource("ImageTexture_xbph7") +icon = SubResource("ImageTexture_ih5gb") [node name="HintTooltip7" parent="TranslationSettings/VBoxContainer2/Actions" instance=ExtResource("2_k2lou")] layout_mode = 2 @@ -321,7 +345,7 @@ It will try to delete any \".csv\" and \".translation\" files that are related t CSV and translation files prefixed with \"dialogic_\" are treated as Dialogic-related. Removes translation IDs (eg. #id:33) from timelines and characters." -texture = SubResource("ImageTexture_xbph7") +texture = null hint_text = "Be very careful with this button! It will try to delete any \".csv\" and \".translation\" files that are related to Dialogic. diff --git a/addons/dialogic/Modules/Choice/event_choice.gd b/addons/dialogic/Modules/Choice/event_choice.gd index cbe15e366..cd4e30d7e 100644 --- a/addons/dialogic/Modules/Choice/event_choice.gd +++ b/addons/dialogic/Modules/Choice/event_choice.gd @@ -130,15 +130,21 @@ func _get_translatable_properties() -> Array: return ['text', 'disabled_text'] -func _get_property_original_translation(property:String) -> String: - match property: +func _get_property_original_translation(property_name:String) -> String: + match property_name: 'text': return text 'disabled_text': return disabled_text return '' -#endregion +func _set_property_original_translation(property_name:String, value:String) -> void: + match property_name: + 'text': + text = value + 'disabled_text': + disabled_text = value +#endregion #region EDITOR REPRESENTATION ################################################################################ diff --git a/addons/dialogic/Modules/Glossary/glossary_resource.gd b/addons/dialogic/Modules/Glossary/glossary_resource.gd index 638d03697..cbf38e212 100644 --- a/addons/dialogic/Modules/Glossary/glossary_resource.gd +++ b/addons/dialogic/Modules/Glossary/glossary_resource.gd @@ -88,7 +88,7 @@ func _remove_entry_alias(entry_key: String) -> bool: return true -## Updates the glossary entry's name and related alias keys. +## Updates the glossary entry's name. ## The [param old_entry_key] is the old unique name of the entry. ## The [param new_entry_key] is the new unique name of the entry. ## diff --git a/addons/dialogic/Modules/Jump/event_label.gd b/addons/dialogic/Modules/Jump/event_label.gd index e324739b6..57a635481 100644 --- a/addons/dialogic/Modules/Jump/event_label.gd +++ b/addons/dialogic/Modules/Jump/event_label.gd @@ -89,6 +89,12 @@ func _get_property_original_translation(property_name:String) -> String: return display_name return '' +func _set_property_original_translation(property_name:String, value:String) -> void: + match property_name: + 'display_name': + display_name = value + + ################################################################################ ## EDITOR REPRESENTATION ################################################################################ diff --git a/addons/dialogic/Modules/Text/event_text.gd b/addons/dialogic/Modules/Text/event_text.gd index 8007c1a48..f1add6437 100644 --- a/addons/dialogic/Modules/Text/event_text.gd +++ b/addons/dialogic/Modules/Text/event_text.gd @@ -369,12 +369,16 @@ func _get_translatable_properties() -> Array: return ['text'] -func _get_property_original_translation(property:String) -> String: - match property: +func _get_property_original_translation(property_name:String) -> String: + match property_name: 'text': return text return '' +func _set_property_original_translation(property_name:String, value:String) -> void: + match property_name: + 'text': + text = value #endregion diff --git a/addons/dialogic/Resources/event.gd b/addons/dialogic/Resources/event.gd index 571e4721e..c6c71be29 100644 --- a/addons/dialogic/Resources/event.gd +++ b/addons/dialogic/Resources/event.gd @@ -195,6 +195,9 @@ func _get_translatable_properties() -> Array: func _get_property_original_translation(_property_name:String) -> String: return '' +## Overwrite if this events needs translation. +func _set_property_original_translation(property_name:String, value:String) -> void: + pass ## Returns true if there is any translatable properties on this event. ## Overwrite [_get_translatable_properties()] to change this.