diff --git a/addons/zylann.translation_editor/tools/csv_loader.gd b/addons/zylann.translation_editor/tools/csv_loader.gd index 1dc1ebe..b1b8ed3 100644 --- a/addons/zylann.translation_editor/tools/csv_loader.gd +++ b/addons/zylann.translation_editor/tools/csv_loader.gd @@ -1,16 +1,16 @@ tool # TODO Can't type nullable return value -static func load_csv_translation(filepath: String): +static func load_csv_translation(filepath: String, logger): var f := File.new() var err := f.open(filepath, File.READ) if err != OK: - printerr("Could not open ", filepath, " for read, code ", err) + logger.error("Could not open {0} for read, code {1}".format([filepath, err])) return null var first_row := f.get_csv_line() if first_row[0] != "id": - printerr("Translation file is missing the `id` column") + logger.error("Translation file is missing the `id` column") return null var languages := PoolStringArray() @@ -22,10 +22,10 @@ static func load_csv_translation(filepath: String): while not f.eof_reached(): var row := f.get_csv_line() if len(row) < 1 or row[0].strip_edges() == "": - printerr("Found an empty row") + logger.error("Found an empty row") continue if len(row) < len(first_row): - print("Found row smaller than header, resizing") + logger.debug("Found row smaller than header, resizing") row.resize(len(first_row)) ids.append(row[0]) var trans = PoolStringArray() @@ -49,8 +49,8 @@ class _Sorter: return a[0] < b[0] -static func save_csv_translation(filepath: String, data: Dictionary) -> Array: - print("Saving: ", data) +static func save_csv_translation(filepath: String, data: Dictionary, logger) -> Array: + logger.debug(str("Saving: ", data)) var languages_set := {} for id in data: var s = data[id] @@ -58,7 +58,7 @@ static func save_csv_translation(filepath: String, data: Dictionary) -> Array: languages_set[language] = true if len(languages_set) == 0: - printerr("No language found, nothing to save") + logger.error("No language found, nothing to save") return [] var languages := languages_set.keys() @@ -94,7 +94,7 @@ static func save_csv_translation(filepath: String, data: Dictionary) -> Array: var f := File.new() var err := f.open(filepath, File.WRITE) if err != OK: - printerr("Could not open ", filepath, " for write, code ", err) + logger.error("Could not open {0} for write, code {1}".format([filepath, err])) return [] store_csv_line(f, first_row) @@ -102,7 +102,7 @@ static func save_csv_translation(filepath: String, data: Dictionary) -> Array: store_csv_line(f, row) f.close() - print("Saved ", filepath) + logger.debug(str("Saved ", filepath)) var saved_languages := languages return saved_languages diff --git a/addons/zylann.translation_editor/tools/extractor.gd b/addons/zylann.translation_editor/tools/extractor.gd index 988f952..ca5f3d3 100644 --- a/addons/zylann.translation_editor/tools/extractor.gd +++ b/addons/zylann.translation_editor/tools/extractor.gd @@ -1,4 +1,6 @@ +const Logger = preload("./util/logger.gd") + const STATE_SEARCHING = 0 const STATE_READING_TEXT = 1 @@ -13,6 +15,7 @@ var _thread : Thread = null var _time_before := 0.0 var _ignored_paths := {} var _paths := [] +var _logger = Logger.get_for(self) func extract_async(root: String, ignored_paths := []): @@ -39,14 +42,14 @@ func _prepare(root: String, ignored_paths: Array): func _extract(root: String): - _walk(root, funcref(self, "_index_file"), funcref(self, "_filter")) + _walk(root, funcref(self, "_index_file"), funcref(self, "_filter"), _logger) for i in len(_paths): var fpath : String = _paths[i] var f := File.new() var err := f.open(fpath, File.READ) if err != OK: - printerr("Could not open '", fpath, "', for read, error ", err) + _logger.error("Could not open {0} for read, error {1}".format([fpath, err])) continue var ext := fpath.get_extension() match ext: @@ -71,7 +74,7 @@ func _finished(): _thread.wait_to_finish() _thread = null var elapsed := float(OS.get_ticks_msec() - _time_before) / 1000.0 - print("Extraction took ", elapsed, " seconds") + _logger.debug(str("Extraction took ", elapsed, " seconds")) emit_signal("finished", _strings) @@ -112,8 +115,9 @@ func _process_tscn(f: File, fpath: String): if i != -1: var begin_quote_index := line.find('"', i + len(pattern)) if begin_quote_index == -1: - printerr("Could not find begin quote after text property, in ", - fpath, " line ", line_number) + _logger.error( + "Could not find begin quote after text property, in {0}, line {1}" \ + .format([fpath, line_number])) continue var end_quote_index := line.rfind('"') @@ -179,18 +183,18 @@ func _process_gd(f: File, fpath: String): var begin_quote_index := line.find('"', call_index) if begin_quote_index == -1: # Multiline or procedural strings not supported - printerr("Begin quote not found in ", fpath, " line ", line_number) + _logger.error("Begin quote not found in {0}, line {1}".format([fpath, line_number])) break var end_quote_index := find_unescaped_quote(line, begin_quote_index + 1) if end_quote_index == -1: # Multiline or procedural strings not supported - printerr("End quote not found in ", fpath, " line ", line_number) + _logger.error("End quote not found in {0}, line {1}".format([fpath, line_number])) break text = line.substr(begin_quote_index + 1, end_quote_index - begin_quote_index - 1) var end_bracket_index := line.find(')', end_quote_index) if end_bracket_index == -1: # Multiline or procedural strings not supported - printerr("End bracket not found in ", fpath, " line ", line_number) + _logger.error("End bracket not found in {0}, line {1}".format([fpath, line_number])) break _add_string(fpath, line_number, text) search_index = end_bracket_index @@ -217,12 +221,12 @@ func _add_string(file: String, line_number: int, text: String): _strings[text][file] = line_number -static func _walk(folder_path: String, file_action: FuncRef, filter: FuncRef): +static func _walk(folder_path: String, file_action: FuncRef, filter: FuncRef, logger): #print("Walking dir ", folder_path) var d := Directory.new() var err := d.open(folder_path) if err != OK: - printerr("Could not open directory '", folder_path, "', error ", err) + logger.error("Could not open directory {0}, error {1}".format([folder_path, err])) return d.list_dir_begin(true, true) var fname := d.get_next() @@ -230,7 +234,7 @@ static func _walk(folder_path: String, file_action: FuncRef, filter: FuncRef): var fullpath := folder_path.plus_file(fname) if filter == null or filter.call_func(fullpath) == true: if d.current_is_dir(): - _walk(fullpath, file_action, filter) + _walk(fullpath, file_action, filter, logger) else: file_action.call_func(fullpath) fname = d.get_next() diff --git a/addons/zylann.translation_editor/tools/extractor_dialog.gd b/addons/zylann.translation_editor/tools/extractor_dialog.gd index 289f525..d13c233 100644 --- a/addons/zylann.translation_editor/tools/extractor_dialog.gd +++ b/addons/zylann.translation_editor/tools/extractor_dialog.gd @@ -2,6 +2,7 @@ tool extends WindowDialog const Extractor = preload("./extractor.gd") +const Logger = preload("./util/logger.gd") signal import_selected(strings) @@ -17,6 +18,7 @@ var _extractor : Extractor = null # { string => { fpath => line number } } var _results := {} var _registered_string_filter : FuncRef = null +var _logger = Logger.get_for(self) func _ready(): @@ -46,7 +48,7 @@ func _on_ExtractButton_pressed(): var root := _root_path_edit.text.strip_edges() var d := Directory.new() if not d.dir_exists(root): - printerr("Directory `", root, "` does not exist") + _logger.error("Directory {0} does not exist".format([root])) return var excluded_dirs := _excluded_dirs_edit.text.split(";", false) @@ -82,7 +84,8 @@ func _on_Extractor_progress_reported(ratio): func _on_Extractor_finished(results: Dictionary): - print("Extractor finished") + _logger.debug("Extractor finished") + _progress_bar.value = 100 _progress_bar.hide() diff --git a/addons/zylann.translation_editor/tools/plugin.gd b/addons/zylann.translation_editor/tools/plugin.gd index c271eea..f33b246 100644 --- a/addons/zylann.translation_editor/tools/plugin.gd +++ b/addons/zylann.translation_editor/tools/plugin.gd @@ -3,12 +3,14 @@ extends EditorPlugin const TranslationEditor = preload("./translation_editor.gd") const TranslationEditorScene = preload("./translation_editor.tscn") +const Logger = preload("./util/logger.gd") var _main_control : TranslationEditor = null +var _logger = Logger.get_for(self) func _enter_tree(): - print("Translation editor plugin Enter tree") + _logger.debug("Translation editor plugin Enter tree") var editor_interface := get_editor_interface() var base_control := editor_interface.get_base_control() @@ -20,7 +22,7 @@ func _enter_tree(): func _exit_tree(): - print("Translation editor plugin Exit tree") + _logger.debug("Translation editor plugin Exit tree") # The main control is not freed when the plugin is disabled _main_control.queue_free() _main_control = null diff --git a/addons/zylann.translation_editor/tools/po_loader.gd b/addons/zylann.translation_editor/tools/po_loader.gd index 7c619a8..9d7a2db 100644 --- a/addons/zylann.translation_editor/tools/po_loader.gd +++ b/addons/zylann.translation_editor/tools/po_loader.gd @@ -5,15 +5,15 @@ const STATE_MSGID = 1 const STATE_MSGSTR = 2 # TODO Can't type nullable result -static func load_po_translation(folder_path: String, valid_locales: Array): +static func load_po_translation(folder_path: String, valid_locales: Array, logger): var all_strings := {} var config := {} # TODO Get languages from configs, not from filenames - var languages := get_languages_in_folder(folder_path, valid_locales) + var languages := get_languages_in_folder(folder_path, valid_locales, logger) if len(languages) == 0: - printerr("No .po languages were found in ", folder_path) + logger.error("No .po languages were found in {0}".format([folder_path])) return all_strings for language in languages: @@ -22,7 +22,7 @@ static func load_po_translation(folder_path: String, valid_locales: Array): var f := File.new() var err := f.open(filepath, File.READ) if err != OK: - printerr("Could not open file ", filepath, " for read, error ", err) + logger.error("Could not open file {0} for read, error {1}".format([filepath, err])) return null f.store_line("") @@ -70,7 +70,7 @@ static func load_po_translation(folder_path: String, valid_locales: Array): var s : Dictionary if msgid == "": assert(len(msgstr) != 0) - config = _parse_config(msgstr) + config = _parse_config(msgstr, logger) else: if not all_strings.has(msgid): s = { @@ -90,7 +90,7 @@ static func load_po_translation(folder_path: String, valid_locales: Array): state = STATE_NONE else: - print("Unhandled .po line: ", line) + logger.warn("Unhandled .po line: {0}".format([line])) continue # TODO Return configs? @@ -105,13 +105,13 @@ static func _parse_msg(s: String) -> String: return msg.c_unescape().replace('\\"', '"') -static func _parse_config(text: String) -> Dictionary: +static func _parse_config(text: String, logger) -> Dictionary: var config := {} var lines := text.split("\n", false) - print("Config lines: ", lines) + logger.debug(str("Config lines: ", lines)) for line in lines: var splits = line.split(":") - print("Splits: ", splits) + logger.debug(str("Splits: ", splits)) config[splits[0]] = splits[1].strip_edges() return config @@ -122,7 +122,7 @@ class _Sorter: static func save_po_translations(folder_path: String, translations: Dictionary, - languages_to_save: Array) -> Array: + languages_to_save: Array, logger) -> Array: var sorter := _Sorter.new() var saved_languages := [] @@ -132,7 +132,7 @@ static func save_po_translations(folder_path: String, translations: Dictionary, var filepath := folder_path.plus_file(str(language, ".po")) var err := f.open(filepath, File.WRITE) if err != OK: - printerr("Could not open file ", filepath, " for write, error ", err) + logger.error("Could not open file {0} for write, error {1}".format([filepath, err])) continue # TODO Take as argument @@ -217,12 +217,12 @@ static func _write_msg(f: File, msgtype: String, msg: String): f.store_line(str(" \"", lines[i], "\"")) -static func get_languages_in_folder(folder_path: String, valid_locales: Array) -> Array: +static func get_languages_in_folder(folder_path: String, valid_locales: Array, logger) -> Array: var result := [] var d := Directory.new() var err := d.open(folder_path) if err != OK: - printerr("Could not open directory ", folder_path, ", error ", err) + logger.error("Could not open directory {0}, error {1}".format([folder_path, err])) return result d.list_dir_begin() var fname := d.get_next() diff --git a/addons/zylann.translation_editor/tools/translation_editor.gd b/addons/zylann.translation_editor/tools/translation_editor.gd index 0574f18..c629d76 100644 --- a/addons/zylann.translation_editor/tools/translation_editor.gd +++ b/addons/zylann.translation_editor/tools/translation_editor.gd @@ -7,6 +7,8 @@ const Locales = preload("./locales.gd") const StringEditionDialog = preload("./string_edition_dialog.gd") const LanguageSelectionDialog = preload("./language_selection_dialog.gd") const ExtractorDialog = preload("./extractor_dialog.gd") +const Util = preload("./util/util.gd") +const Logger = preload("./util/logger.gd") const StringEditionDialogScene = preload("./string_edition_dialog.tscn") const LanguageSelectionDialogScene = preload("./language_selection_dialog.tscn") @@ -46,6 +48,7 @@ var _save_folder_dialog : FileDialog = null var _base_control : Control = null var _translation_edits := {} var _dialogs_to_free_on_exit := [] +var _logger = Logger.get_for(self) var _data := {} var _languages := [] @@ -56,7 +59,7 @@ var _modified_languages := {} func _ready(): # I don't want any of this to run in the edited scene (because `tool`)... - if Engine.editor_hint and get_parent() is Viewport: + if Util.is_in_edited_scene(self): return _file_menu.get_popup().add_item("Open...", MENU_FILE_OPEN) @@ -234,16 +237,16 @@ func load_file(filepath: String): if ext == "po": var valid_locales := Locales.get_all_locale_ids() _current_path = filepath.get_base_dir() - _data = PoLoader.load_po_translation(_current_path, valid_locales) + _data = PoLoader.load_po_translation(_current_path, valid_locales, Logger.get_for(PoLoader)) _current_format = FORMAT_GETTEXT elif ext == "csv": - _data = CsvLoader.load_csv_translation(filepath) + _data = CsvLoader.load_csv_translation(filepath, Logger.get_for(CsvLoader)) _current_path = filepath _current_format = FORMAT_CSV else: - printerr("Unknown file format, cannot load ", filepath) + _logger.error("Unknown file format, cannot load {0}".format([filepath])) return _languages.clear() @@ -365,13 +368,14 @@ func save_file(path: String, format: int): languages_to_save = _languages else: languages_to_save = _modified_languages.keys() - saved_languages = PoLoader.save_po_translations(path, _data, languages_to_save) + saved_languages = PoLoader.save_po_translations( + path, _data, languages_to_save, Logger.get_for(PoLoader)) elif format == FORMAT_CSV: - saved_languages = CsvLoader.save_csv_translation(path, _data) + saved_languages = CsvLoader.save_csv_translation(path, _data, Logger.get_for(CsvLoader)) else: - printerr("Unknown file format, cannot save ", path) + _logger.error("Unknown file format, cannot save {0}".format([path])) for language in saved_languages: _set_language_unmodified(language) @@ -429,7 +433,7 @@ func _on_RemoveButton_pressed(): func _on_RemoveStringConfirmationDialog_confirmed(): var selected_items := _string_list.get_selected_items() if len(selected_items) == 0: - printerr("No selected string??") + _logger.error("No selected string??") return var strid := _string_list.get_item_text(selected_items[0]) _string_list.remove_item(selected_items[0]) @@ -466,7 +470,7 @@ func _validate_new_string_id(str_id: String): func add_new_string(strid: String): - print("Adding new string ", strid) + _logger.debug(str("Adding new string ", strid)) assert(not _data.has(strid)) var s := { "translations": {}, @@ -499,7 +503,7 @@ func _add_language(language: String): var menu_index := _file_menu.get_popup().get_item_index(MENU_FILE_REMOVE_LANGUAGE) _file_menu.get_popup().set_item_disabled(menu_index, false) - print("Added language ", language) + _logger.debug(str("Added language ", language)) func _remove_language(language: String): @@ -515,7 +519,7 @@ func _remove_language(language: String): var menu_index = _file_menu.get_popup().get_item_index(MENU_FILE_REMOVE_LANGUAGE) _file_menu.get_popup().set_item_disabled(menu_index, true) - print("Removed language ", language) + _logger.debug(str("Removed language ", language)) func _on_RemoveLanguageConfirmationDialog_confirmed(): @@ -526,7 +530,7 @@ func _on_RemoveLanguageConfirmationDialog_confirmed(): # Used as callback for filtering func _is_string_registered(text: String) -> bool: if _data == null: - print("No data") + _logger.debug("No data") return false return _data.has(text) diff --git a/addons/zylann.translation_editor/tools/util/logger.gd b/addons/zylann.translation_editor/tools/util/logger.gd new file mode 100644 index 0000000..90d8c9c --- /dev/null +++ b/addons/zylann.translation_editor/tools/util/logger.gd @@ -0,0 +1,36 @@ + +class Base: + var _context := "" + + func _init(p_context): + _context = p_context + + func debug(msg: String): + pass + + func warn(msg: String): + push_warning("{0}: {1}".format([_context, msg])) + + func error(msg: String): + push_error("{0}: {1}".format([_context, msg])) + + +class Verbose extends Base: + func _init(p_context: String).(p_context): + pass + + func debug(msg: String): + print(_context, ": ", msg) + + +static func get_for(owner: Object) -> Base: + # Note: don't store the owner. If it's a Reference, it could create a cycle + var context : String + if owner is Script: + context = owner.resource_path.get_file() + else: + context = owner.get_script().resource_path.get_file() + if OS.is_stdout_verbose(): + return Verbose.new(context) + return Base.new(context) + diff --git a/addons/zylann.translation_editor/tools/util/util.gd b/addons/zylann.translation_editor/tools/util/util.gd new file mode 100644 index 0000000..33c8ce0 --- /dev/null +++ b/addons/zylann.translation_editor/tools/util/util.gd @@ -0,0 +1,9 @@ +tool + +static func is_in_edited_scene(node: Node) -> bool: + if not node.is_inside_tree(): + return false + var edited_scene = node.get_tree().edited_scene_root + if node == edited_scene: + return true + return edited_scene != null and edited_scene.is_a_parent_of(node)