diff --git a/android/src/toga_android/dialogs.py b/android/src/toga_android/dialogs.py index 56c3366bd0..30ede9faec 100644 --- a/android/src/toga_android/dialogs.py +++ b/android/src/toga_android/dialogs.py @@ -1,10 +1,12 @@ from android import R from android.app import AlertDialog -from android.content import DialogInterface +from android.content import DialogInterface, Intent from java import dynamic_proxy import toga +from .libs import utilfile as uf + class OnClickListener(dynamic_proxy(DialogInterface.OnClickListener)): def __init__(self, fn=None, value=None): @@ -31,12 +33,12 @@ def show(self, host_window, future): class TextDialog(BaseDialog): def __init__( - self, - title, - message, - positive_text, - negative_text=None, - icon=None, + self, + title, + message, + positive_text, + negative_text=None, + icon=None, ): super().__init__() @@ -104,10 +106,10 @@ def __init__(self, title, message): class StackTraceDialog(BaseDialog): def __init__( - self, - title, - message, - **kwargs, + self, + title, + message, + **kwargs, ): super().__init__() @@ -117,11 +119,11 @@ def __init__( class SaveFileDialog(BaseDialog): def __init__( - self, - title, - filename, - initial_directory, - file_types=None, + self, + title, + filename, + initial_directory, + file_types=None, ): super().__init__() @@ -130,25 +132,39 @@ def __init__( class OpenFileDialog(BaseDialog): + class HandlerOpenDialog(uf.HandlerFileDialog): + def show(self): + intent = Intent(Intent.ACTION_OPEN_DOCUMENT) + intent.addCategory(Intent.CATEGORY_OPENABLE) + intent.setType("*/*") + self.app.start_activity(intent, on_complete=self.parent.handler) + def __init__( - self, - title, - initial_directory, - file_types, - multiple_select, + self, + title, + initial_directory, + file_types, + multiple_select, ): - super().__init__() + self.native = OpenFileDialog.HandlerOpenDialog(self, toga.App.app.current_window) + self.mActive = self.native.mActive - toga.App.app.factory.not_implemented("dialogs.OpenFileDialog()") - self.native = None + def handler(self, code, indent): + self._handler(indent.getData()) + + def _handler(self, uri): + ist = self.mActive.getContentResolver().openInputStream(uri) + isr = uf.InputStreamReader(uf.Objects.requireNonNull(ist)) + reader = uf.VFile(uf.BufferedReader(isr)) + self.future.set_result(reader) class SelectFolderDialog(BaseDialog): def __init__( - self, - title, - initial_directory, - multiple_select, + self, + title, + initial_directory, + multiple_select, ): super().__init__() diff --git a/android/src/toga_android/libs/utilfile.py b/android/src/toga_android/libs/utilfile.py new file mode 100644 index 0000000000..8c3f821f22 --- /dev/null +++ b/android/src/toga_android/libs/utilfile.py @@ -0,0 +1,58 @@ +import abc +import io + +import java + +BufferedReader = java.jclass("java.io.BufferedReader") +InputStreamReader = java.jclass("java.io.InputStreamReader") +Objects = java.jclass("java.util.Objects") + + +class HandlerFileDialog(abc.ABC): + """Абстрактный класс вызова файлового менеджера""" + + def __init__(self, parent, app_toga): + self.parent = parent + self.app = app_toga._impl + self.mActive = app_toga._impl.native + + @abc.abstractmethod + def show(self): + """Запуск менеджера""" + pass + + +class VFile(io.TextIOBase): + """Файл для работы с внешнем хранилищем андроида""" + + def __init__(self, bufferedReader): + self._bfr = bufferedReader + + def __del__(self): + self.close() + + def close(self): + self._bfr.close() + + def readline(self, size: int = 0) -> str: + """Функция для чтения строки + :param size: количество строк, которые нужно считать. + Если он равен 0, то будет прочтен весь файл + :return: Строка""" + return self._bfr.readLine() + + def read(self, size: int = 0) -> str: + """Функция для чтения строки + :param size: количество символов, которые нужно считать. + Если он равен 0, то будет прочтен весь файл + :return: Строка""" + res = "" + counter = size if size else "+" + while counter: + resp = self._bfr.read() + if resp == -1: + break + res += chr(resp) + if isinstance(counter, int): + counter -= 1 + return res diff --git a/changes/2910.misc.rst b/changes/2910.misc.rst new file mode 100644 index 0000000000..cc4d12d4b5 --- /dev/null +++ b/changes/2910.misc.rst @@ -0,0 +1 @@ +Partial OpenFileDialog implementation