GodotProjects/Sprout/addons/dialogic/Editor/Settings/Settings_Translations.gd
2023-01-03 16:54:53 -07:00

195 lines
8.3 KiB
GDScript

@tool
extends Control
enum TranslationModes {PerProject, PerTimeline}
var loading := false
func _ready():
%TransEnabled.toggled.connect(store_changes)
%OrigLocale.get_suggestions_func = get_locales
%OrigLocale.resource_icon = get_theme_icon("Translation", "EditorIcons")
%OrigLocale.value_changed.connect(store_changes)
%TransFolderPicker.value_changed.connect(store_changes)
%UpdateCsvFiles.pressed.connect(update_csv_files)
%CollectTranslations.pressed.connect(collect_translations)
%TransRemove.pressed.connect(erase_translations)
func refresh():
loading = true
%TransEnabled.button_pressed = DialogicUtil.get_project_setting('dialogic/translation/enabled', false)
%OrigLocale.set_value(DialogicUtil.get_project_setting('dialogic/translation/original_locale', TranslationServer.get_tool_locale()))
%TransMode.select(DialogicUtil.get_project_setting('dialogic/translation/file_mode', 1))
%TransFolderPicker.set_value(DialogicUtil.get_project_setting('dialogic/translation/translation_folder', ''))
loading = false
func store_changes(fake_arg = "", fake_arg2 = ""):
if loading: return
ProjectSettings.set_setting('dialogic/translation/enabled', %TransEnabled.button_pressed)
ProjectSettings.set_setting('dialogic/translation/original_locale', %OrigLocale.current_value)
ProjectSettings.set_setting('dialogic/translation/transation_folder', %TransFolderPicker.current_value)
ProjectSettings.set_setting('dialogic/translation/file_mode', %TransMode.selected)
ProjectSettings.save()
func get_locales(filter:String) -> Dictionary:
var suggestions = {}
suggestions[TranslationServer.get_tool_locale()] = {'value':TranslationServer.get_tool_locale()}
for locale in TranslationServer.get_all_languages():
suggestions[locale] = {'value':locale, 'tooltip':TranslationServer.get_language_name(locale)}
return suggestions
func update_csv_files():
var orig_locale = %OrigLocale.current_value.strip_edges()
if orig_locale.is_empty():
orig_locale = ProjectSettings.get_setting('internationalization/locale/fallback')
%OrigLocale.set_value(orig_locale)
var translation_mode = %TransMode.selected
var file : FileAccess
var files : = [] # collected to trigger reimport at the end
var csv_lines := [] # collects all current lines
var old_csv_lines := {} # contains already existing csv_lines as [key] = [value, value, ...] dict
# collect old lines in per project mode
if translation_mode == TranslationModes.PerProject:
var file_path = DialogicUtil.get_project_setting('dialogic/translation/translation_folder', 'res://')+'dialogic_translations.csv'
files.append(file_path)
if FileAccess.file_exists(file_path):
file = FileAccess.open(file_path,FileAccess.READ_WRITE)
while !file.eof_reached():
var line := file.get_csv_line()
old_csv_lines[line[0]] = line.slice(1)
csv_lines.append(['keys', orig_locale])
for timeline_path in DialogicUtil.list_resources_of_type('.dtl'):
# collect old lines in per timeline mode
var file_path = timeline_path.trim_suffix('.dtl')+'_translation.csv'
if translation_mode == TranslationModes.PerTimeline:
files.append(file_path)
if FileAccess.file_exists(file_path):
file = FileAccess.open(file_path,FileAccess.READ_WRITE)
while !file.eof_reached():
var line := file.get_csv_line()
old_csv_lines[line[0]] = line.slice(1)
csv_lines.append(['keys', orig_locale])
# load and process timeline (make events to resources)
var tml : DialogicTimeline = load(timeline_path)
tml = find_parent('EditorView').process_timeline(tml)
# now collect all the current csv_lines from timeline
for event in tml.events:
if event.can_be_translated():
if event._translation_id.is_empty():
event.add_translation_id()
event.update_text_version()
for property in event._get_translatable_properties():
csv_lines.append([event.get_property_translation_key(property), event._get_property_original_translation(property)])
# in case new translation_id's were added, we save the timeline again
tml.set_meta("timeline_not_saved", true)
tml.events_processed = false
ResourceSaver.save(tml, timeline_path)
# for per_timeline mode save the file now, then reset for next timeline
if translation_mode == TranslationModes.PerTimeline:
file = FileAccess.open(file_path, FileAccess.WRITE)
for line in csv_lines:
# in case there might be translations for this line already,
# add them at the end again (orig locale text is replaced).
if line[0] in old_csv_lines:
line.append_array(old_csv_lines[line[0]].slice(2))
file.store_csv_line(line)
csv_lines.clear()
old_csv_lines.clear()
if translation_mode == TranslationModes.PerProject:
var file_path = DialogicUtil.get_project_setting('dialogic/translation/translation_folder', 'res://')+'dialogic_translations.csv'
file = FileAccess.open(file_path, FileAccess.WRITE)
for line in csv_lines:
# in case there might be translations for this line already,
# add them at the end again (orig locale text is replaced).
if line[0] in old_csv_lines:
file.store_csv_line(line+old_csv_lines[line[0]].slice(2))
else:
file.store_csv_line(line)
## ADD CREATION/UPDATE OF CHARACTER NAMES FILE HERE!
# trigger reimport
# find_parent('EditorView').plugin_reference.editor_interface.get_resource_filesystem().reimport_files(files)
find_parent('EditorView').plugin_reference.editor_interface.get_resource_filesystem().scan_sources()
func collect_translations():
var trans_files := []
var translation_mode = %TransMode.selected
if translation_mode == TranslationModes.PerTimeline:
for timeline_path in DialogicUtil.list_resources_of_type('.dtl'):
for file in DialogicUtil.listdir(timeline_path.get_base_dir()):
file = timeline_path.get_base_dir().path_join(file)
if file.ends_with('.translation'):
if not file in trans_files:
trans_files.append(file)
if translation_mode == TranslationModes.PerProject:
var trans_folder = DialogicUtil.get_project_setting('dialogic/translation/translation_folder', 'res://')
for file in DialogicUtil.listdir(trans_folder):
file = trans_folder.path_join(file)
if file.ends_with('.translation'):
if not file in trans_files:
trans_files.append(file)
ProjectSettings.set_setting('internationalization/locale/translations', PackedStringArray(trans_files))
ProjectSettings.save()
func erase_translations():
var trans_files := Array(DialogicUtil.get_project_setting('internationalization/locale/translations', []))
var translation_mode : int = %TransMode.selected
if translation_mode == TranslationModes.PerProject:
var trans_path :String = DialogicUtil.get_project_setting('dialogic/translation/translation_folder', 'res://')
DirAccess.remove_absolute(trans_path+'dialogic_translations.csv')
DirAccess.remove_absolute(trans_path+'dialogic_translations.csv.import')
for x_file in DialogicUtil.listdir(trans_path):
if x_file.ends_with('.translation'):
trans_files.erase(trans_path.get_base_dir().path_join(x_file))
DirAccess.remove_absolute(trans_path.get_base_dir().path_join(x_file))
for timeline_path in DialogicUtil.list_resources_of_type('.dtl'):
# in per project mode, remove all translation files/resources next to the timelines
if translation_mode == TranslationModes.PerTimeline:
DirAccess.remove_absolute(timeline_path.trim_suffix('.dtl')+'_translation.csv')
DirAccess.remove_absolute(timeline_path.trim_suffix('.dtl')+'_translation.csv.import')
for x_file in DialogicUtil.listdir(timeline_path.get_base_dir()):
if x_file.ends_with('.translation'):
trans_files.erase(timeline_path.get_base_dir().path_join(x_file))
DirAccess.remove_absolute(timeline_path.get_base_dir().path_join(x_file))
# clear the timeline events of their translation_id's
var tml:DialogicTimeline = load(timeline_path)
tml = await find_parent('EditorView').process_timeline(tml)
for event in tml.get_events():
if event._translation_id:
event.remove_translation_id()
event.update_text_version()
tml.set_meta("timeline_not_saved", true)
tml.events_processed = false
ResourceSaver.save(tml, timeline_path)
ProjectSettings.set_setting('dialogic/translation/id_counter', 16)
ProjectSettings.set_setting('internationalization/locale/translations', PackedStringArray(trans_files))
ProjectSettings.save()
find_parent('EditorView').plugin_reference.editor_interface.get_resource_filesystem().scan_sources()
refresh()