pyflutter-app 0.1.8__tar.gz → 0.2.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. {pyflutter_app-0.1.8 → pyflutter_app-0.2.1}/.idea/modules.xml +1 -1
  2. pyflutter_app-0.1.8/.idea/pyflutter.iml → pyflutter_app-0.2.1/.idea/pyflutter_app.iml +2 -2
  3. {pyflutter_app-0.1.8 → pyflutter_app-0.2.1}/PKG-INFO +2 -1
  4. {pyflutter_app-0.1.8 → pyflutter_app-0.2.1}/converter/config_app.py +2 -3
  5. {pyflutter_app-0.1.8 → pyflutter_app-0.2.1}/converter/home_page/_page_edit.py +5 -9
  6. {pyflutter_app-0.1.8 → pyflutter_app-0.2.1}/converter/home_page/controller.py +217 -131
  7. {pyflutter_app-0.1.8 → pyflutter_app-0.2.1}/converter/home_page/model.py +56 -34
  8. {pyflutter_app-0.1.8 → pyflutter_app-0.2.1}/converter/home_page/view.py +59 -43
  9. {pyflutter_app-0.1.8 → pyflutter_app-0.2.1}/converter/lib_toi.py +96 -32
  10. pyflutter_app-0.2.1/converter/page_forms/__init__.py +191 -0
  11. pyflutter_app-0.2.1/converter/page_forms/common.py +155 -0
  12. pyflutter_app-0.2.1/converter/page_forms/controller_forms.py +193 -0
  13. pyflutter_app-0.2.1/converter/page_forms/model_forms.py +68 -0
  14. {pyflutter_app-0.1.8 → pyflutter_app-0.2.1}/converter/table_widget.py +7 -7
  15. pyflutter_app-0.2.1/converter/util.py +42 -0
  16. pyflutter_app-0.2.1/main.py +17 -0
  17. {pyflutter_app-0.1.8 → pyflutter_app-0.2.1}/pyflutter_ui/__init__.py +17 -13
  18. {pyflutter_app-0.1.8 → pyflutter_app-0.2.1}/pyflutter_ui/app.py +3 -19
  19. {pyflutter_app-0.1.8 → pyflutter_app-0.2.1}/pyflutter_ui/file_picker.py +1 -2
  20. {pyflutter_app-0.1.8 → pyflutter_app-0.2.1}/pyflutter_ui/navigator.py +5 -7
  21. pyflutter_app-0.2.1/pyflutter_ui/scheduler.py +154 -0
  22. {pyflutter_app-0.1.8 → pyflutter_app-0.2.1}/pyflutter_ui/theme.py +3 -4
  23. pyflutter_app-0.2.1/pyflutter_ui/ui/__init__.py +27 -0
  24. pyflutter_app-0.2.1/pyflutter_ui/ui/buttons.py +219 -0
  25. pyflutter_app-0.2.1/pyflutter_ui/ui/container.py +119 -0
  26. {pyflutter_app-0.1.8/pyflutter_ui → pyflutter_app-0.2.1/pyflutter_ui/ui}/core.py +88 -57
  27. {pyflutter_app-0.1.8/pyflutter_ui → pyflutter_app-0.2.1/pyflutter_ui/ui}/list_builder.py +158 -17
  28. pyflutter_app-0.2.1/pyflutter_ui/ui/progress.py +80 -0
  29. pyflutter_app-0.2.1/pyflutter_ui/ui/tables.py +109 -0
  30. {pyflutter_app-0.1.8/pyflutter_ui → pyflutter_app-0.2.1/pyflutter_ui/ui}/widgets.py +270 -726
  31. {pyflutter_app-0.1.8 → pyflutter_app-0.2.1}/pyproject.toml +2 -1
  32. {pyflutter_app-0.1.8 → pyflutter_app-0.2.1}/table_stream/__init__.py +3 -3
  33. pyflutter_app-0.2.1/table_stream/file_names.py +542 -0
  34. pyflutter_app-0.2.1/table_stream/notifier.py +109 -0
  35. pyflutter_app-0.2.1/table_stream/pattner/__init__.py +3 -0
  36. {pyflutter_app-0.1.8 → pyflutter_app-0.2.1}/table_stream/sheet/load.py +7 -7
  37. {pyflutter_app-0.1.8 → pyflutter_app-0.2.1}/table_stream/sheet/parse.py +14 -15
  38. {pyflutter_app-0.1.8 → pyflutter_app-0.2.1}/table_stream/sheet/save.py +2 -2
  39. {pyflutter_app-0.1.8 → pyflutter_app-0.2.1}/table_stream/state.py +47 -37
  40. {pyflutter_app-0.1.8 → pyflutter_app-0.2.1}/table_stream/sysfiles.py +7 -0
  41. pyflutter_app-0.2.1/table_stream/thread.py +125 -0
  42. {pyflutter_app-0.1.8 → pyflutter_app-0.2.1}/uv.lock +15 -1
  43. pyflutter_app-0.1.8/converter/file_documents.py +0 -234
  44. pyflutter_app-0.1.8/converter/page_forms/__init__.py +0 -192
  45. pyflutter_app-0.1.8/converter/page_forms/common.py +0 -103
  46. pyflutter_app-0.1.8/converter/page_forms/controller_forms.py +0 -194
  47. pyflutter_app-0.1.8/converter/page_forms/model_forms.py +0 -52
  48. pyflutter_app-0.1.8/main.py +0 -40
  49. pyflutter_app-0.1.8/table_stream/notifier.py +0 -173
  50. pyflutter_app-0.1.8/table_stream/pattner/__init__.py +0 -7
  51. pyflutter_app-0.1.8/table_stream/pattner/observer.py +0 -279
  52. pyflutter_app-0.1.8/table_stream/thread.py +0 -171
  53. {pyflutter_app-0.1.8 → pyflutter_app-0.2.1}/.gitignore +0 -0
  54. {pyflutter_app-0.1.8 → pyflutter_app-0.2.1}/.idea/.gitignore +0 -0
  55. {pyflutter_app-0.1.8 → pyflutter_app-0.2.1}/.idea/inspectionProfiles/Project_Default.xml +0 -0
  56. {pyflutter_app-0.1.8 → pyflutter_app-0.2.1}/.idea/inspectionProfiles/profiles_settings.xml +0 -0
  57. {pyflutter_app-0.1.8 → pyflutter_app-0.2.1}/.idea/misc.xml +0 -0
  58. {pyflutter_app-0.1.8 → pyflutter_app-0.2.1}/.idea/vcs.xml +0 -0
  59. {pyflutter_app-0.1.8 → pyflutter_app-0.2.1}/README.md +0 -0
  60. {pyflutter_app-0.1.8 → pyflutter_app-0.2.1}/converter/__init__.py +0 -0
  61. {pyflutter_app-0.1.8 → pyflutter_app-0.2.1}/converter/__main__.py +0 -0
  62. {pyflutter_app-0.1.8 → pyflutter_app-0.2.1}/converter/assets/forms_config.json +0 -0
  63. {pyflutter_app-0.1.8 → pyflutter_app-0.2.1}/converter/home_page/__init__.py +0 -0
  64. {pyflutter_app-0.1.8 → pyflutter_app-0.2.1}/converter/page_forms/config.py +0 -0
  65. {pyflutter_app-0.1.8 → pyflutter_app-0.2.1}/converter/page_forms/service.py +0 -0
  66. {pyflutter_app-0.1.8 → pyflutter_app-0.2.1}/converter/run.py +0 -0
  67. {pyflutter_app-0.1.8 → pyflutter_app-0.2.1}/converter/whatsapp/__init__.py +0 -0
  68. {pyflutter_app-0.1.8 → pyflutter_app-0.2.1}/converter/whatsapp/model.py +0 -0
  69. {pyflutter_app-0.1.8 → pyflutter_app-0.2.1}/export_app.sh +0 -0
  70. {pyflutter_app-0.1.8 → pyflutter_app-0.2.1}/local_build/linux.sh +0 -0
  71. {pyflutter_app-0.1.8 → pyflutter_app-0.2.1}/local_build/send.sh +0 -0
  72. {pyflutter_app-0.1.8 → pyflutter_app-0.2.1}/table_stream/erros.py +0 -0
  73. {pyflutter_app-0.1.8 → pyflutter_app-0.2.1}/table_stream/hash_map.py +0 -0
  74. {pyflutter_app-0.1.8 → pyflutter_app-0.2.1}/table_stream/pattner/adapter.py +0 -0
  75. {pyflutter_app-0.1.8 → pyflutter_app-0.2.1}/table_stream/sheet/__init__.py +0 -0
  76. {pyflutter_app-0.1.8 → pyflutter_app-0.2.1}/table_stream/sheet/check_mod.py +0 -0
  77. {pyflutter_app-0.1.8 → pyflutter_app-0.2.1}/table_stream/sheet/options.py +0 -0
  78. {pyflutter_app-0.1.8 → pyflutter_app-0.2.1}/table_stream/workbook.py +0 -0
@@ -2,7 +2,7 @@
2
2
  <project version="4">
3
3
  <component name="ProjectModuleManager">
4
4
  <modules>
5
- <module fileurl="file://$PROJECT_DIR$/.idea/pyflutter.iml" filepath="$PROJECT_DIR$/.idea/pyflutter.iml" />
5
+ <module fileurl="file://$PROJECT_DIR$/.idea/pyflutter_app.iml" filepath="$PROJECT_DIR$/.idea/pyflutter_app.iml" />
6
6
  </modules>
7
7
  </component>
8
8
  </project>
@@ -1,10 +1,10 @@
1
1
  <?xml version="1.0" encoding="UTF-8"?>
2
- <module type="PYTHON_MODULE" version="4">
2
+ <module external.system.id="pyproject.toml" type="PYTHON_MODULE" version="4">
3
3
  <component name="NewModuleRootManager">
4
4
  <content url="file://$MODULE_DIR$">
5
5
  <excludeFolder url="file://$MODULE_DIR$/.venv" />
6
6
  </content>
7
- <orderEntry type="jdk" jdkName="uv (pyflutter)" jdkType="Python SDK" />
7
+ <orderEntry type="jdk" jdkName="~/GIT/pyflutter/.venv" jdkType="Python SDK" />
8
8
  <orderEntry type="sourceFolder" forTests="false" />
9
9
  </component>
10
10
  <component name="PyDocumentationSettings">
@@ -1,9 +1,10 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: pyflutter_app
3
- Version: 0.1.8
3
+ Version: 0.2.1
4
4
  Summary: Bibliotecas Python para conversão de documentos, interface e processamento de tabelas.
5
5
  Requires-Python: >=3.14
6
6
  Requires-Dist: openpyxl>=3.1.5
7
+ Requires-Dist: pandas-stubs~=3.0.3
7
8
  Requires-Dist: pandas>=3.0.0
8
9
  Description-Content-Type: text/markdown
9
10
 
@@ -1,11 +1,10 @@
1
1
  from __future__ import annotations
2
- from typing import Any, Callable
3
2
  from dataclasses import dataclass
4
3
 
5
- from table_stream.sysfiles import File, Directory, UserFileSystem, JsonConvert, JsonData
4
+ from table_stream.sysfiles import File, Directory, UserFileSystem, JsonConvert
6
5
  from table_stream import HashMapDict
7
6
  from pyflutter_ui.theme import ThemeMode
8
- from pyflutter_ui.core import ValueNotifier, ChangeNotifier
7
+ from pyflutter_ui.ui.core import ValueNotifier
9
8
 
10
9
 
11
10
  @dataclass
@@ -1,21 +1,17 @@
1
1
  # converter/excel/page_edit.py
2
2
  from __future__ import annotations
3
3
 
4
- import pandas as pd
5
- from pyflutter_ui import (
4
+ from converter.util import (
6
5
  BuildContext, FlutterWidget, StatelessWidget,
7
6
  Consumer, Column, Row, Expanded, Divider,
8
- ElevatedButton, Text, SizedBox, Scaffold, AppBar,
9
- MainAxisAlignment, CrossAxisAlignment,
10
- SnackBar, SnackBarType, TableView, ValueNotifier,
11
- ValueListenableBuilder, Provider, DropdownButton
7
+ Text, SizedBox, Scaffold, MainAxisAlignment, SnackBar, SnackBarType, TableView, ValueNotifier,
8
+ ValueListenableBuilder, Provider, DropdownButton, ElevatedButton, ArrayList,
12
9
  )
13
- from pyflutter_ui.widgets import ElevatedButton
14
10
 
15
- from converter.home_page.controller import ControllerHomePage, DataNotifer, CommandEditColumns
11
+ from converter.home_page.controller import ControllerHomePage, CommandEditColumns
16
12
  from converter.table_widget import TableOrProgress
17
- from table_stream import ArrayList
18
13
 
14
+ import pandas as pd
19
15
 
20
16
  class PageEditExcel(StatelessWidget):
21
17
  """
@@ -1,32 +1,60 @@
1
1
  from __future__ import annotations
2
- from typing import Any, Callable
2
+ from typing import Callable, TypeVar
3
3
 
4
4
  import pandas as pd
5
5
  from pandas import DataFrame
6
6
 
7
- from table_stream import (
7
+ from converter.util import (
8
8
  SheetLoader, SheetType, SaveData, csvEncoding, csvSeparator,
9
9
  CsvOptions, OptionsIOSheet, ParserData, FactorySaveData,
10
- FactorySheetLoader, ArrayList, HashMapDict, ControllerThread,
11
- ConsumerThread, ThreadStateContext, ContextState
10
+ FactorySheetLoader, ControllerThread, ArrayList, HashMapDict,
11
+ Directory, File, NotInicializedState, StateValue, EventState,
12
+ ThreadStateValue
12
13
  )
13
- from table_stream.sysfiles import Directory, File
14
- from table_stream.state import NotInicializedState
15
14
 
16
15
  from pyflutter_ui import ChangeNotifier, CommandNotifier, ValueNotifier, Provider
17
16
  from converter.home_page.model import ExcelModel
18
17
  from converter.config_app import AppConfigNotifier, MapConfig
19
18
 
19
+ T = TypeVar('T')
20
+
21
+
22
+ class ValueNotifierEvent[T](ValueNotifier):
23
+
24
+ def __init__(self, value: T) -> None:
25
+ super().__init__(value)
26
+ self.state_value: StateValue[T] = StateValue()
27
+
28
+ @property
29
+ def running(self) -> bool:
30
+ return self.state_value.is_running()
31
+
32
+ @property
33
+ def state(self) -> EventState:
34
+ return self.state_value.get_state()
35
+
36
+ def get_controller(self) -> ControllerHomePage:
37
+ return Provider.read(ControllerHomePage)
20
38
 
21
- class FileNotifier(ValueNotifier[HashMapDict[str, File]]):
39
+
40
+ class FileNotifier(ValueNotifierEvent[HashMapDict[str, File]]):
22
41
  """
23
42
  Controller/Notificador
24
43
 
25
44
  Notifica sobre a alteração de arquivos selecionados/adicionados pelo usuário.
26
45
  """
27
46
 
28
- def __init__(self, value: Any) -> None:
47
+ def __init__(self, value: HashMapDict[str, File]) -> None:
29
48
  super().__init__(value)
49
+ self.file: File = None
50
+
51
+ def set_selected_file(self, f: File):
52
+ if not self.value.header().contains(f.basename()):
53
+ self._value.set_value(f.basename(), f)
54
+
55
+ self.file = f
56
+ print(f'Arquivo alterado ... {f.absolute()}')
57
+ self.notify_listeners()
30
58
 
31
59
  def get_file_from_name(self, name: str) -> File:
32
60
  if not self.value.header().contains(name):
@@ -52,14 +80,21 @@ class FileNotifier(ValueNotifier[HashMapDict[str, File]]):
52
80
  self.notify_listeners()
53
81
 
54
82
 
55
- class DataNotifer(ValueNotifier[pd.DataFrame]):
83
+ class DataNotifer(ValueNotifierEvent[pd.DataFrame]):
84
+ """
85
+ Controller/Notificador
56
86
 
87
+ Notifica sobre a alteração de um DataFrame()
88
+ """
57
89
  def __init__(self, value: DataFrame) -> None:
58
90
  super().__init__(value)
59
- self.running: bool = False
60
91
  cols = ArrayList(value.columns.tolist())
61
92
  self.selectedColumnSheet: str = cols.get_first() if cols.size() > 0 else "-"
62
93
 
94
+ @property
95
+ def controller(self) -> ControllerHomePage:
96
+ return self.get_controller()
97
+
63
98
  @property
64
99
  def value(self) -> DataFrame:
65
100
  return self._value
@@ -77,22 +112,24 @@ class DataNotifer(ValueNotifier[pd.DataFrame]):
77
112
 
78
113
  def set_selected_column_sheet(self, col: str):
79
114
  self.selectedColumnSheet = col
80
- print(f'{__class__.__name__} coluna alterada: {col}')
115
+ print(f'{__class__.__name__} Coluna selecionada: {col}')
81
116
 
82
117
  def clear(self):
83
- self.running = False
84
- self.value = pd.DataFrame()
118
+ self._result = pd.DataFrame()
119
+ self.state_value.reset_state()
85
120
 
86
121
 
87
- class CommandEditColumns(ValueNotifier[ArrayList[str]]):
122
+ class CommandEditColumns(ValueNotifierEvent[ArrayList[str]]):
88
123
 
89
- def __init__(self, value: ArrayList[str], controller: ControllerHomePage) -> None:
124
+ def __init__(self, value: ArrayList[str]) -> None:
90
125
  super().__init__(value)
91
- self.running: bool = False
92
- self.controller: ControllerHomePage = controller
93
126
  self._columnsEdit: ArrayList[str] = value
94
127
  self.selectedColumn: str | None = None
95
128
 
129
+ @property
130
+ def controller(self) -> ControllerHomePage:
131
+ return self.get_controller()
132
+
96
133
  @property
97
134
  def columns(self) -> ArrayList[str]:
98
135
  return ArrayList(self.controller.data_notifier.value.columns.tolist())
@@ -129,23 +166,22 @@ class CommandEditColumns(ValueNotifier[ArrayList[str]]):
129
166
  remove_list.append(col)
130
167
 
131
168
  if remove_list.size() < 1:
132
- self.running = False
169
+ self.state_value.reset_state()
133
170
  self.notify_listeners()
134
171
  return
135
172
 
136
- self.running = True
173
+ self.state_value.start()
137
174
  self.notify_listeners()
138
175
  self.controller.model.delete_columns(self.data, cols)
139
176
 
140
- def _action_finish_delete_cols(self, c: ThreadStateContext[pd.DataFrame]):
177
+ def _action_finish_delete_cols(self, c: ThreadStateValue[pd.DataFrame]):
141
178
  if c.state.is_error():
142
- self.running = False
179
+ self.state_value = c
143
180
  self.notify_listeners()
144
181
  return
145
182
 
146
- self.data = c.value
147
- self.running = False
148
-
183
+ self.data = c.get_result()
184
+ self.state_value.reset_state()
149
185
  self.notify_listeners()
150
186
 
151
187
 
@@ -153,56 +189,50 @@ class ControllerTextOperations(ValueNotifier[str]):
153
189
 
154
190
  def __init__(self, controller: ControllerHomePage) -> None:
155
191
  super().__init__("-")
156
- self.context_state: ContextState = ContextState()
192
+ self.context_state: StateValue = StateValue()
157
193
  self.controller: ControllerHomePage = controller
158
194
 
159
195
  def set_value(self, v: str):
160
196
  self.value = v
161
197
 
162
198
 
163
- class ControllerHomePage(ValueNotifier[DataFrame]):
199
+ class ControllerHomePage(ChangeNotifier):
164
200
 
165
- def __init__(self, model: ExcelModel, *, value: pd.DataFrame = None) -> None:
166
- if value is None:
167
- value = pd.DataFrame()
168
- super().__init__(value)
201
+ def __init__(self, model: ExcelModel) -> None:
202
+ super().__init__()
169
203
  self.model: ExcelModel = model
170
- self.context_state: ThreadStateContext = ThreadStateContext()
171
-
172
- # Opções para leitura de uma planilha
204
+ self.state_value: ThreadStateValue = ThreadStateValue()
205
+ self.show_msg: Callable[[str], None] = None
206
+ self.show_error: Callable[[str], None] = None
207
+
208
+ # Opções para leitura de CSV
173
209
  self.csv_options = CsvOptions()
174
- self._file: File = None
175
- self._sheet_name: str = None
176
210
 
177
- self.sheet_names: ArrayList[str] = ArrayList()
211
+ #======================================================#
212
+ # Comando para leitura do DataFrame()
213
+ #======================================================#
214
+ self.data_notifier = DataNotifer(pd.DataFrame())
178
215
 
216
+ #======================================================#
179
217
  # Mapa de arquivos importados pelo usuário
218
+ #======================================================#
180
219
  self.files_notifier: FileNotifier = FileNotifier(HashMapDict())
220
+
221
+ # Nomes das ABAS de uma planilha.
222
+ self._sheet_name: str = None
223
+ self.sheet_names: ArrayList[str] = ArrayList()
181
224
 
182
225
  # Opções de exportação
183
226
  self._options_save: OptionsIOSheet = OptionsIOSheet(SheetType.EXCEL)
184
227
 
185
- #======================================================#
186
- # Comandos notificadores
187
- #======================================================#
188
- self.data_notifier = DataNotifer(pd.DataFrame())
189
- self.data_columns = CommandEditColumns(ArrayList(), self)
228
+ self.data_columns = CommandEditColumns(ArrayList())
190
229
  self.controller_text: ControllerTextOperations = ControllerTextOperations(self)
191
-
192
- # Consumer para notificar sobre a leitura de planilha
193
- self._consumer_load_data: ConsumerThread = self._create_consumer(self.on_finish_load_data)
194
- self._consumer_load_data.on_error = self.on_error_load_data
195
-
196
- # Consumer para a leitura das abas de uma planilha
197
- self._consumer_load_sheet_names: ConsumerThread = self._create_consumer(self.on_finish_load_sheet_names)
198
-
199
- # Consumer para exportação de mapas
200
- self._consumer_export_maps: ConsumerThread = self._create_consumer(self.on_finish_export_maps)
201
-
202
- # Menssagens
203
- self.msg_erro_operation = None
204
- self.msg_init_operation = None
205
-
230
+ self._counter_operation: int = 0
231
+
232
+ @property
233
+ def state_event(self) -> EventState:
234
+ return self.state_value.state
235
+
206
236
  @property
207
237
  def sheet_name(self) -> str:
208
238
  return self._sheet_name
@@ -210,150 +240,206 @@ class ControllerHomePage(ValueNotifier[DataFrame]):
210
240
  @sheet_name.setter
211
241
  def sheet_name(self, new: str):
212
242
  if not self.sheet_names.contains(new):
213
- print(f'[DEBUG] Aba ... {new} não está disponível para o arquivo: {self._file}')
243
+ m = f'ABA ... {new} não está disponível para o arquivo: {self.get_file_sheet()}'
244
+ self.ui_message_error(m)
214
245
  return
215
246
 
216
247
  self._sheet_name = new
217
- self.msg_init_operation = f"Aba atualizada ... {self._sheet_name}"
218
248
  self.notify_listeners()
219
249
  self.command_load_data()
220
250
 
221
251
  @property
222
252
  def options_load(self) -> OptionsIOSheet | None:
223
- if self._file is None:
253
+ if self.get_file_sheet() is None:
224
254
  return None
225
255
 
226
- opt_load = OptionsIOSheet(SheetType.EXCEL if self._file.is_excel() else SheetType.CSV)
256
+ opt_load = OptionsIOSheet(SheetType.EXCEL if self.get_file_sheet().is_excel() else SheetType.CSV)
227
257
 
228
- if self._file.is_ods():
258
+ if self.get_file_sheet().is_ods():
229
259
  opt_load.sheet_type = SheetType.ODS
230
260
  if self._sheet_name is not None:
231
261
  opt_load.sheet_name = self._sheet_name
232
-
233
262
  return opt_load
234
263
 
235
264
  @property
236
265
  def running(self) -> bool:
237
- return self.context_state.is_running()
266
+ return self.state_value.is_running()
238
267
 
239
268
  @property
240
269
  def files(self) -> ArrayList[File]:
241
270
  return self.files_notifier.value.values()
242
-
243
- def command_start_operation(self, c: ThreadStateContext) -> None:
244
- if self.context_state.is_running():
245
- print(f'{__class__.__name__} [DEBUG] .. existe outra operação em andamento.')
271
+
272
+ def ui_message(self, m: str):
273
+ if self.show_msg is None:
246
274
  return
275
+ self.show_msg(m)
276
+
277
+ def ui_message_error(self, e: str):
278
+ if self.show_error is None:
279
+ return
280
+ self.show_error(e)
281
+
282
+ def get_file_sheet(self) -> File:
283
+ """
284
+ """
285
+ return self.files_notifier.file
286
+
287
+ def set_file_sheet(self, file: File):
288
+ """
289
+ """
290
+ self.files_notifier.set_selected_file(file)
291
+ options: OptionsIOSheet = self.options_load
292
+
293
+ if options is None:
294
+ return
295
+
296
+ if self.model.is_running():
297
+ self.ui_message(
298
+ "Existe outra operação em andamento. \nO arquvo foi atualizado mas não foi possível carregar as abas"
299
+ )
300
+
301
+ return
302
+
303
+ self.command_load_sheet_names()
304
+
305
+ def reset_state(self):
306
+ self.state_value.reset_state()
307
+ self.msg_error = None
308
+ self.msg_success = None
309
+ self.msg_init_operation = None
310
+ #self.data_notifier.state_value.reset_state()
311
+
312
+ print(f'{__class__.__name__} Estado resetado com sucesso ... {self.state_event.state_name}')
313
+ self.notify_listeners()
314
+
315
+ def on_init_operation(self) -> None:
316
+
317
+ if self.running:
318
+ print('-' * 60)
319
+ print(f'{__class__.__name__} [ATENÇÃO] ... existe outra operação em andamento.')
247
320
 
248
- print(f'{__class__.__name__} => INICIANDO OPERAÇÃO -> Estado ... {self.context_state.state.name}')
249
- self.context_state = c
321
+ print('*' * 60)
322
+ self._counter_operation += 1
323
+ print(f'{__class__.__name__} [INICIANDO OPERAÇÃO {self._counter_operation}] ... {self.state_value.state.state_name}')
324
+
325
+ self.state_value.start()
250
326
  self.notify_listeners()
251
327
 
252
- def _create_consumer(self, on_finish: Callable[[ThreadStateContext]]) -> ConsumerThread:
253
- consumer = ConsumerThread(ThreadStateContext, on_finish=on_finish)
254
- consumer.on_start = self.command_start_operation
255
- return consumer
328
+ def _create_state_value(self, on_finish: Callable[[ThreadStateValue], None]) -> ThreadStateValue:
329
+ state = ThreadStateValue()
330
+ state.on_finish = on_finish
331
+ return state
256
332
 
257
333
  def command_delete_columns(self):
258
- if self.running:
259
- raise RuntimeError("Já existe outra operação de leitura em andamento...")
260
334
  self.data_columns.delete_columns(self.data_columns.value)
261
335
 
262
336
  def command_load_data(self) -> None:
263
- if self.running:
264
- raise RuntimeError("Já existe outra operação de leitura em andamento...")
265
-
337
+ """
338
+ Metódo chamado pela VIEW para ler um DataFrame()
339
+ """
340
+
266
341
  options = self.options_load
267
342
  if options is None:
268
343
  return
269
344
 
270
- self.data_notifier.running = True
345
+ self.state_value = self._create_state_value(self.on_finish_load_data)
346
+
347
+ self.data_notifier.state_value = self.state_value
271
348
  self.data_notifier.value = pd.DataFrame()
272
- self.msg_init_operation = "Carregando dados..."
273
-
274
- self.model.load_dataframe(self._file, options, consumer=self._consumer_load_data)
349
+ self.on_init_operation()
350
+
351
+ print(f'{__class__.__name__} Iniciando a leitura do DataFrame()')
352
+
353
+ self.model.load_dataframe(
354
+ self.get_file_sheet(), options, state_value=self.state_value,
355
+ )
275
356
 
276
357
  def command_load_sheet_names(self) -> None:
277
- options: OptionsIOSheet = self.options_load
358
+
359
+ options: OptionsIOSheet = self.options_load # type: ignore
278
360
  if options is None:
279
361
  return
280
362
 
281
- self.context_state.start()
282
- self.notify_listeners()
363
+ self.state_value = self._create_state_value(self.on_finish_load_sheet_names)
364
+ self.on_init_operation()
365
+
366
+ print(f'{__class__.__name__} Iniciando a leitura das abas do arquivo {self.get_file_sheet().basename()}')
283
367
 
284
368
  self.model.load_sheet_names(
285
- self._file,
286
- options,
287
- consumer=self._consumer_load_sheet_names
369
+ self.get_file_sheet(),
370
+ options,
371
+ state_value=self.state_value
288
372
  )
289
373
 
290
374
  def command_export_maps(self):
375
+
291
376
  self.controller_text.value = "Exportando mapas aguarde"
292
- self.data_notifier.running = True
293
- self.notify_listeners()
377
+ self.state_value = self._create_state_value(self.on_finish_export_maps)
294
378
 
295
379
  config: AppConfigNotifier = Provider.read(AppConfigNotifier)
296
380
  col = self.data_notifier.selectedColumnSheet
297
381
  work_dir = config.value.work_dir
298
382
 
383
+ self.on_init_operation()
384
+ self.data_notifier.state_value = self.state_value
385
+
299
386
  self.model.export_maps(
300
387
  self.data_notifier.value,
301
388
  work_dir.concat("Mapas", True).concat(col, True),
302
389
  self.data_notifier.selectedColumnSheet,
303
- consumer=self._consumer_export_maps,
390
+ state_value=self.state_value,
304
391
  receiver_progress=self.controller_text.set_value,
305
392
  )
393
+
394
+ def check_running(self) -> bool:
395
+ if self.running:
396
+ print(f'{__class__.__name__} existe outra operação em andamento!!!')
397
+ return False
398
+ return True
399
+
400
+ def on_finish_export_maps(self, context: ThreadStateValue):
401
+ self.state_value = context
306
402
 
307
- def on_finish_export_maps(self, context: ThreadStateContext):
308
- self.context_state = context
309
- self.data_notifier.running = False
310
- self.controller_text.value = "Mapas exportados com sucesso."
311
- self.notify_listeners()
312
- self.context_state.set_state(NotInicializedState())
403
+ if self.state_value.is_error():
404
+ self.notify_listeners()
405
+ return
313
406
 
314
- def on_error_load_data(self, result: ThreadStateContext):
315
- self.data_notifier.running = False
316
- self.msg_erro_operation = f'{result.get_exception()}'
317
-
318
- def on_finish_load_data(self, result: ThreadStateContext[pd.DataFrame]) -> None:
319
- self.data_notifier.running = False
320
- self.data_notifier.value = result.value
321
-
322
- if not self.data_notifier.value.empty:
323
- self.msg_init_operation = "Planilha carregada com sucesso..."
324
-
325
- self.context_state = result
407
+ self.data_notifier.state_value = ThreadStateValue()
408
+ self.controller_text.value = "Mapas exportados com sucesso."
409
+
410
+ def on_finish_load_data(self, result: ThreadStateValue[pd.DataFrame]) -> None:
411
+ self.data_notifier.state_value = ThreadStateValue()
412
+
413
+ if result.is_error():
414
+ self.state_value.fail(result.get_exception())
415
+ self.data_notifier.value = pd.DataFrame()
416
+ self.ui_message_error(f"{self.state_value.get_exception()}")
417
+ self.notify_listeners()
418
+ return
419
+
420
+ self.data_notifier.value = result.get_result()
421
+ self.reset_state()
326
422
  self.notify_listeners()
327
- self.context_state.set_state(NotInicializedState())
423
+
424
+ def on_finish_load_sheet_names(self, element: ThreadStateValue[ArrayList[str]]) -> None:
328
425
 
329
- def on_finish_load_sheet_names(self, c: ThreadStateContext[ArrayList[str]]) -> None:
330
- self.sheet_names = c.value
331
- self.context_state = c
332
- self.notify_listeners()
426
+ if element.is_error():
427
+ self.state_value.fail(element.get_exception())
428
+ self.ui_message_error(f"{self.state_value.get_exception()}")
429
+ self.notify_listeners()
430
+ return
333
431
 
334
- self.context_state.set_state(NotInicializedState())
432
+ self.sheet_names = element.get_result()
335
433
  self.sheet_name = self.sheet_names.get_first()
434
+ self.notify_listeners()
336
435
 
337
- def get_file_sheet(self) -> File:
338
- return self._file
339
-
340
- def set_file_sheet(self, file: File):
341
- if self.context_state.state.is_running():
342
- return
343
-
344
- self._file = file
345
- options: OptionsIOSheet = self.options_load
346
-
347
- if options is None:
348
- return
349
- self.command_load_sheet_names()
350
-
351
436
  def add_files(self, files: ArrayList[File]):
352
437
  self.files_notifier.add_files(files)
353
- if self._file is not None:
438
+
439
+ if self.files_notifier.value.header().size() < 0:
354
440
  return
355
441
 
356
- if self.files_notifier.value.header().size() > 0:
442
+ if self.data_notifier.value.empty:
357
443
  self.set_file_sheet(self.files_notifier.value.get_first())
358
444
 
359
445
  def init_state(self, data: HashMapDict = None):