diff --git a/dev/filebrowser.py b/dev/filebrowser.py index 823777a..9bb1df4 100644 --- a/dev/filebrowser.py +++ b/dev/filebrowser.py @@ -108,15 +108,16 @@ def get_drives(): return drives - class I18NFileChooserListView(FileChooserListView): font_name = StringProperty("") + class I18NFileChooserListLayout(FileChooserListLayout): _ENTRY_TEMPLATE = "I18NFileListEntry" -Builder.load_string(""" +Builder.load_string( + """ #:kivy 1.0 [I18NFileListEntry@FloatLayout+TreeViewNode]: locked: False @@ -156,7 +157,6 @@ Builder.load_string(""" ) - Builder.load_string( """ #:kivy 1.2.0 diff --git a/i18n.py b/i18n.py index b83bd62..0d75a13 100644 --- a/i18n.py +++ b/i18n.py @@ -1,6 +1,7 @@ import os import polib import sys +import re from collections import defaultdict localedir = "katrain/i18n/locales" @@ -34,7 +35,10 @@ for lang in locales: errors = True elif DEFAULT_LANG in strings_to_langs[msgid]: print("Message id", msgid, "missing in ", lang, "-> Adding it from", DEFAULT_LANG) - entry = polib.POEntry(msgid=msgid, msgstr=strings_to_langs[msgid][DEFAULT_LANG], comment="TODO") + copied_msg = strings_to_langs[msgid][DEFAULT_LANG] + if lang == "haha": + copied_msg = re.sub(r"[a-zA-Z]{1,2}", "ㅋ", copied_msg) + entry = polib.POEntry(msgid=msgid, msgstr=copied_msg, comment="TODO") po[lang].append(entry) errors = True else: diff --git a/katrain/__main__.py b/katrain/__main__.py index 8c2c27d..ade0f90 100644 --- a/katrain/__main__.py +++ b/katrain/__main__.py @@ -33,6 +33,7 @@ from katrain.core.game import Game, IllegalMoveException, KaTrainSGF from katrain.core.sgf_parser import Move, ParseError from katrain.gui.kivyutils import * from katrain.gui.widgets.graph import ScoreGraph +from katrain.gui.widgets.filebrowser import I18NFileChooserListView from katrain.gui.badukpan import AnalysisControls, BadukPanControls, BadukPanWidget from katrain.gui.controlspanel import ControlsPanel from katrain.gui.popups import ConfigPopup, LoadSGFPopup, NewGamePopup, AIPopup @@ -246,10 +247,9 @@ class KaTrainGui(Screen, KaTrainBase): def _do_analyze_sgf_popup(self): if not self.fileselect_popup: - self.fileselect_popup = Popup(title="Double Click SGF file to analyze", size_hint=(0.8, 0.8)).__self__ popup_contents = LoadSGFPopup() - self.fileselect_popup.add_widget(popup_contents) - popup_contents.filesel.path = os.path.abspath(os.path.expanduser(self.config("sgf/sgf_load"))) + popup_contents.filesel.path = os.path.abspath(os.path.expanduser(self.config("general/sgf_load", "."))) + self.fileselect_popup = I18NPopup(title_key="load sgf title", size=[1200, 800], content=popup_contents).__self__ def readfile(files, _mouse): self.fileselect_popup.dismiss() @@ -323,7 +323,8 @@ class KaTrainGui(Screen, KaTrainBase): def _on_keyboard_down(self, _keyboard, keycode, _text, modifiers): if self.controls.note.focus: return # when making notes, don't allow keyboard shortcuts - first_child = App.get_running_app().root_window.children[0] + app = App.get_running_app() + first_child = app.root_window.children[0] if isinstance(first_child, Popup): if keycode[1] not in ["f5", "f6", "f7", "f8"]: return @@ -352,6 +353,8 @@ class KaTrainGui(Screen, KaTrainBase): self("new-game-popup") elif keycode[1] == "l" and "ctrl" in modifiers: self("analyze-sgf-popup") + elif keycode[1] == "f12" and "ctrl" in modifiers: + app.language = "haha" elif keycode[1] == "s" and "ctrl" in modifiers: self("output-sgf") elif keycode[1] == "c" and "ctrl" in modifiers: diff --git a/katrain/core/utils.py b/katrain/core/utils.py index 181063c..c74c4ad 100644 --- a/katrain/core/utils.py +++ b/katrain/core/utils.py @@ -46,7 +46,7 @@ def find_package_resource(path): class Lang(Observable): observers = [] callbacks = [] - FONTS = {"ko": "fonts/NotoSansKR-Regular.otf"} + FONTS = {"ko": "fonts/NotoSansKR-Regular.otf", "haha": "fonts/NotoSansKR-Regular.otf"} def __init__(self, lang): super(Lang, self).__init__() @@ -88,7 +88,7 @@ class Lang(Observable): for widget, func, args in self.observers: try: func(args[0], None, None) - print('setting',widget,widget.font_name,'->',self.font_name) + print("setting", widget, widget.font_name, "->", self.font_name) widget.font_name = self.font_name for sub_widget in [getattr(widget, "_hint_lbl", None), getattr(widget, "_msg_lbl", None)]: # MDText if sub_widget: diff --git a/katrain/gui.kv b/katrain/gui.kv index 977eb34..1f4480e 100644 --- a/katrain/gui.kv +++ b/katrain/gui.kv @@ -822,7 +822,7 @@ size_hint_y: 0.5 id: analysis_button on_press: root.open_analysis_menu() - text: 'Analysis' + text: i18n._("btn:Analyze") pos_hint: {'center_y':0.5} diff --git a/katrain/gui/widgets/filebrowser.py b/katrain/gui/widgets/filebrowser.py new file mode 100644 index 0000000..e31f523 --- /dev/null +++ b/katrain/gui/widgets/filebrowser.py @@ -0,0 +1,465 @@ +# Adapted from https://github.com/kivy-garden/filebrowser + +""" +FileBrowser +=========== +The :class:`FileBrowser` widget is an advanced file browser. You use it +similarly to FileChooser usage. +It provides a shortcut bar with links to special and system directories. +When touching next to a shortcut in the links bar, it'll expand and show +all the directories within that directory. It also facilitates specifying +custom paths to be added to the shortcuts list. +It provides a icon and list view to choose files from. And it also accepts +filter and filename inputs. +To create a FileBrowser which prints the currently selected file as well as +the current text in the filename field when 'Select' is pressed, with +a shortcut to the Documents directory added to the favorites bar:: + import os + from kivy.app import App + class TestApp(App): + def build(self): + user_path = os.path.join(get_home_directory(), 'Documents') + browser = FileBrowser(select_string='Select', + favorites=[(user_path, 'Documents')]) + browser.bind(on_success=self._fbrowser_success, + on_submit=self._fbrowser_submit) + return browser + def _fbrowser_success(self, instance): + print(instance.selection) + def _fbrowser_submit(self, instance): + print(instance.selection) + TestApp().run() +:Events: + `on_success`: + Fired when the `Select` buttons `on_release` event is called. + `on_submit`: + Fired when a file has been selected with a double-tap. +.. image:: _static/filebrowser.png + :align: right +""" +from kivy.uix.boxlayout import BoxLayout +from kivy.uix.treeview import TreeViewLabel, TreeView +from kivy.uix.filechooser import FileChooserListView, FileChooserListLayout +from kivy.properties import ObjectProperty, StringProperty, OptionProperty, ListProperty, BooleanProperty +from kivy.lang import Builder +from kivy.utils import platform +from kivy.clock import Clock +import string +from os.path import sep, dirname, expanduser, isdir, join +from os import walk +from functools import partial + +from katrain.gui.style import DEFAULT_FONT + +if platform == "win": + from ctypes import windll, create_unicode_buffer + + +def last_modified_first(files, filesystem): + return sorted(f for f in files if filesystem.is_dir(f)) + sorted([f for f in files if not filesystem.is_dir(f)], key=lambda f: -os.path.getmtime(f)) + + +def get_home_directory(): + if platform == "win": + user_path = expanduser("~") + + if not isdir(join(user_path, "Desktop")): + user_path = dirname(user_path) + + else: + user_path = expanduser("~") + + return user_path + + +def get_drives(): + drives = [] + if platform == "win": + bitmask = windll.kernel32.GetLogicalDrives() + GetVolumeInformationW = windll.kernel32.GetVolumeInformationW + for letter in string.ascii_uppercase: + if bitmask & 1: + name = create_unicode_buffer(64) + # get name of the drive + drive = letter + u":" + res = GetVolumeInformationW(drive + sep, name, 64, None, None, None, None, 0) + if isdir(drive): + drives.append((drive, name.value)) + bitmask >>= 1 + elif platform == "linux": + drives.append((sep, sep)) + drives.append((expanduser(u"~"), "~/")) + places = (sep + u"mnt", sep + u"media") + for place in places: + if isdir(place): + for directory in next(walk(place))[1]: + drives.append((place + sep + directory, directory)) + elif platform == "macosx" or platform == "ios": + drives.append((expanduser(u"~"), "~/")) + vol = sep + u"Volume" + if isdir(vol): + for drive in next(walk(vol))[1]: + drives.append((vol + sep + drive, drive)) + return drives + + +class I18NFileChooserListView(FileChooserListView): + font_name = StringProperty(DEFAULT_FONT) + show_hidden = BooleanProperty(True) # avoid errors + + +class I18NFileChooserListLayout(FileChooserListLayout): + _ENTRY_TEMPLATE = "I18NFileListEntry" + + +Builder.load_string( + """ +#:kivy 1.0 +[I18NFileListEntry@FloatLayout+TreeViewNode]: + locked: False + entries: [] + path: ctx.path + is_selected: self.path in ctx.controller().selection + orientation: 'horizontal' + size_hint_y: None + height: '24dp' + # Don't allow expansion of the ../ node + is_leaf: not ctx.isdir or ctx.name.endswith('..' + ctx.sep) or self.locked + on_touch_down: self.collide_point(*args[1].pos) and ctx.controller().entry_touched(self, args[1]) + on_touch_up: self.collide_point(*args[1].pos) and ctx.controller().entry_released(self, args[1]) + BoxLayout: + pos: root.pos + size_hint_x: None + width: root.width - dp(10) + Label: + id: filename + text_size: self.width, None + halign: 'left' + shorten: True + text: ctx.name + font_name: ctx.controller().font_name + Label: + text_size: self.width, None + size_hint_x: None + halign: 'right' + text: '{}'.format(ctx.get_nice_size()) + +: + layout: layout + I18NFileChooserListLayout: + id: layout + controller: root + """ +) + + +Builder.load_string( + """ +#:kivy 1.2.0 +#:import metrics kivy.metrics +#:import abspath os.path.abspath +#:import i18n katrain.core.utils.i18n + +