From 024dbb6ffacd24d6f73052822bcb8a6eb1f2a2a8 Mon Sep 17 00:00:00 2001 From: SnayperTihCreator Date: Tue, 15 Oct 2024 21:17:40 +0300 Subject: [PATCH 1/7] A utility module has been created to work with android external storage files --- android/src/toga_android/libs/utilfile.py | 42 +++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 android/src/toga_android/libs/utilfile.py diff --git a/android/src/toga_android/libs/utilfile.py b/android/src/toga_android/libs/utilfile.py new file mode 100644 index 0000000000..b5253231ad --- /dev/null +++ b/android/src/toga_android/libs/utilfile.py @@ -0,0 +1,42 @@ +import io, abc +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): #VirtualFile + def __init__(self, bufferedReader): + self._bfr = bufferedReader + + def __del__(self): + self.close() + + def close(self): + self._bfr.close() + + def readline(self, size=0): + return self._bfr.readLine() + + def read(self, size=0): + 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 From 23684aead43aedda76f91d7e5db6f7bbd450c198 Mon Sep 17 00:00:00 2001 From: SnayperTihCreator Date: Tue, 15 Oct 2024 21:18:23 +0300 Subject: [PATCH 2/7] The file opening dialog is partially implemented --- android/src/toga_android/dialogs.py | 72 ++++++++++++++++++----------- 1 file changed, 44 insertions(+), 28 deletions(-) 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__() From 9b7af3660af6cf6e57652cc13bca8b65e448c664 Mon Sep 17 00:00:00 2001 From: SnayperTihCreator Date: Tue, 15 Oct 2024 21:41:24 +0300 Subject: [PATCH 3/7] Create 2910.misc.rst --- changes/2910.misc.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 changes/2910.misc.rst diff --git a/changes/2910.misc.rst b/changes/2910.misc.rst new file mode 100644 index 0000000000..bda65f3df9 --- /dev/null +++ b/changes/2910.misc.rst @@ -0,0 +1 @@ +Partial OpenFileDialog implementation \ No newline at end of file From c4e245f678957b3eb78ae083b189a303ebf03d70 Mon Sep 17 00:00:00 2001 From: SnayperTihCreator Date: Tue, 15 Oct 2024 21:51:18 +0300 Subject: [PATCH 4/7] Update utilfile.py --- android/src/toga_android/libs/utilfile.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/android/src/toga_android/libs/utilfile.py b/android/src/toga_android/libs/utilfile.py index b5253231ad..03843b2213 100644 --- a/android/src/toga_android/libs/utilfile.py +++ b/android/src/toga_android/libs/utilfile.py @@ -1,4 +1,5 @@ -import io, abc +import io +import abc import java BufferedReader = java.jclass("java.io.BufferedReader") From e46c5df070b2a37da9bf2934cd26214af2c67602 Mon Sep 17 00:00:00 2001 From: SnayperTihCreator Date: Tue, 15 Oct 2024 21:51:42 +0300 Subject: [PATCH 5/7] Update utilfile.py --- android/src/toga_android/libs/utilfile.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/android/src/toga_android/libs/utilfile.py b/android/src/toga_android/libs/utilfile.py index 03843b2213..7815cc3dd7 100644 --- a/android/src/toga_android/libs/utilfile.py +++ b/android/src/toga_android/libs/utilfile.py @@ -1,5 +1,6 @@ -import io import abc +import io + import java BufferedReader = java.jclass("java.io.BufferedReader") @@ -18,7 +19,7 @@ def show(self): pass -class VFile(io.TextIOBase): #VirtualFile +class VFile(io.TextIOBase): # VirtualFile def __init__(self, bufferedReader): self._bfr = bufferedReader @@ -36,7 +37,8 @@ def read(self, size=0): counter = size if size else "+" while counter: resp = self._bfr.read() - if resp == -1: break + if resp == -1: + break res += chr(resp) if isinstance(counter, int): counter -= 1 From 0d66bbf3aaf2044c8ee2bb4526b1eae3689fcd4d Mon Sep 17 00:00:00 2001 From: SnayperTihCreator Date: Tue, 15 Oct 2024 22:03:26 +0300 Subject: [PATCH 6/7] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D1=8B=20=D0=BA=D0=BE=D0=BC=D0=B5=D0=BD=D1=82=D0=B0=D1=80?= =?UTF-8?q?=D0=B8=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- android/src/toga_android/libs/utilfile.py | 19 ++++++++++++++++--- changes/2910.misc.rst | 2 +- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/android/src/toga_android/libs/utilfile.py b/android/src/toga_android/libs/utilfile.py index 7815cc3dd7..d326fe0c54 100644 --- a/android/src/toga_android/libs/utilfile.py +++ b/android/src/toga_android/libs/utilfile.py @@ -9,6 +9,8 @@ class HandlerFileDialog(abc.ABC): + """Абстрактный класс вызова файлового менеджера""" + def __init__(self, parent, app_toga): self.parent = parent self.app = app_toga._impl @@ -16,10 +18,13 @@ def __init__(self, parent, app_toga): @abc.abstractmethod def show(self): + """Запуск менеджера""" pass -class VFile(io.TextIOBase): # VirtualFile +class VFile(io.TextIOBase): + """Файл для работы с внешнем хранилищем андроида""" + def __init__(self, bufferedReader): self._bfr = bufferedReader @@ -29,10 +34,18 @@ def __del__(self): def close(self): self._bfr.close() - def readline(self, size=0): + def readline(self, size: int = 0) -> str: + """Функция для чтения строки + :param size: количество строк, которые нужно считать. + Если он равен 0, то будет прочтен весь файл + :return: Строка""" return self._bfr.readLine() - def read(self, size=0): + def read(self, size: int = 0) -> str: + """Функция для чтения строки + :param size: количество символов, которые нужно считать. + Если он равен 0, то будет прочтен весь файл + :return: Строка""" res = "" counter = size if size else "+" while counter: diff --git a/changes/2910.misc.rst b/changes/2910.misc.rst index bda65f3df9..cc4d12d4b5 100644 --- a/changes/2910.misc.rst +++ b/changes/2910.misc.rst @@ -1 +1 @@ -Partial OpenFileDialog implementation \ No newline at end of file +Partial OpenFileDialog implementation From f908fef9578fe3bc6cd00f37f0dd408883848736 Mon Sep 17 00:00:00 2001 From: SnayperTihCreator Date: Tue, 15 Oct 2024 22:03:37 +0300 Subject: [PATCH 7/7] Update utilfile.py --- android/src/toga_android/libs/utilfile.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/android/src/toga_android/libs/utilfile.py b/android/src/toga_android/libs/utilfile.py index d326fe0c54..8c3f821f22 100644 --- a/android/src/toga_android/libs/utilfile.py +++ b/android/src/toga_android/libs/utilfile.py @@ -36,16 +36,16 @@ def close(self): def readline(self, size: int = 0) -> str: """Функция для чтения строки - :param size: количество строк, которые нужно считать. - Если он равен 0, то будет прочтен весь файл - :return: Строка""" + :param size: количество строк, которые нужно считать. + Если он равен 0, то будет прочтен весь файл + :return: Строка""" return self._bfr.readLine() def read(self, size: int = 0) -> str: """Функция для чтения строки - :param size: количество символов, которые нужно считать. - Если он равен 0, то будет прочтен весь файл - :return: Строка""" + :param size: количество символов, которые нужно считать. + Если он равен 0, то будет прочтен весь файл + :return: Строка""" res = "" counter = size if size else "+" while counter: