class FileCheckUi(App): tv = None def build(self): l = BoxLayout(orientation='vertical') b = Button(text='Run') b.bind(on_press=self.btn_run) b.size_hint = 1, 1 sv = ScrollView() sv.size_hint = 1, 10 self.tv = TreeView(root_options=dict(text='Results')) self.tv.size_hint = 1, None self.tv.bind(minimum_height = self.tv.setter('height')) sv.add_widget(self.tv) l.add_widget(b) l.add_widget(sv) return l def list2tree(self, lbl, lst): tvn = self.tv.add_node(TreeViewLabel(text=lbl)) for t in lst: self.tv.add_node(TreeViewLabel(text=t), tvn) def report(self, added, error, missing): self.report_clear () self.list2tree ('Added', added) self.list2tree('Error', error) self.list2tree('Missing', missing) def report_clear(self): while len (self.tv.root.nodes) > 0: self.tv.remove_node (self.tv.root.nodes[0]) def btn_run(self, value): fdb = '/sdcard/Download/filedb.csv' self.dw = None self.dw = CsvTest.DirWalker () self.dw.filedb.load( fdb) self.dw.walk ( '/sdcard/Download') self.dw.filedb.save (fdb) self.report( self.dw.filedb.added, self.dw.filedb.errors, self.dw.filedb.not_visited())
class RowSelectorWidget(BoxLayout): def __init__(self, **kwargs): super(RowSelectorWidget, self).__init__(**kwargs) self.tree_view = TreeView(hide_root=True, indent_level=4) self.add_widget(self.tree_view) self.row_values = {} self.callback = self.null_callback def null_callback(self): pass def set_callback(self, callback_func): self.callback = callback_func def on_touch_down(self, touch): super(RowSelectorWidget, self).on_touch_down(touch) self.callback() def setDemoRows(self, numRows): self.clearRows() for i in range(numRows): self.addRow('Row ' + str(i)) def addRow(self, row_val): node = TreeViewLabel(text=str(row_val)) self.tree_view.add_node(node) self.row_values[node] = row_val def clearRows(self): self.row_values = {} self.remove_widget(self.tree_view) self.tree_view = TreeView(hide_root=True, indent_level=4) self.add_widget(self.tree_view) def setRows(self, row_list): self.clearRows() for r in row_list: self.addRow(r) def get_selected_row(self): sel_node = self.tree_view.selected_node if sel_node and sel_node in self.row_values.keys(): return self.row_values[sel_node] else: return None def remove_selected_row(self): sel_node = self.tree_view.selected_node if sel_node is not None: self.row_values[sel_node] = None del self.row_values[sel_node] self.tree_view.remove_node(sel_node) def get_height(self, expected_node_height=1.0): HEIGHT_FACTOR = 1.1575 height = 0 for node in self.tree_view.iterate_all_nodes(): height += dp(node.height * expected_node_height * HEIGHT_FACTOR) return height def get_num_Rows(self): return len(self.row_values)
class KivyPanelABM(GridLayout): def __init__(self, lista, nombreABM, **kwargs): # make sure we aren't overriding any important functionality super(KivyPanelABM, self).__init__(**kwargs) self.cols = 2 self.nombreABM = nombreABM self.lista = TreeView(hide_root=True, size_hint_x=0.9) self.add_widget(self.lista) self.panelbotoneraAcciones = GridLayout(cols=1, size_hint_x=0.1, size_hint_y=None, size=(0, 32)) # self.panelbotoneraAcciones.padding=[100,10,10,10] self.btnAdd = Button(background_normal="Add.png", size_hint=(None, None), size=(32, 32)) self.btnAdd.bind(on_press=self.btnEventAdd) self.btnEdit = Button(background_normal="Edit.png", size_hint=(None, None), size=(32, 32)) self.btnEdit.bind(on_press=self.btnEventEdit) self.btnDel = Button(background_normal="Delete.png", size_hint=(None, None), size=(32, 32)) self.btnDel.bind(on_press=self.btnEventDel) self.panelbotoneraAcciones.add_widget(self.btnAdd) self.panelbotoneraAcciones.add_widget(self.btnEdit) self.panelbotoneraAcciones.add_widget(self.btnDel) self.add_widget(self.panelbotoneraAcciones) for elemento in lista: self.lista.add_node(TreeViewLabel(text=elemento)) def getLista(self): list = [] print("arbol: " + str(self.lista)) for nodo in self.lista.iterate_all_nodes(node=None): list.append(nodo.text) return list[1:] def btnEventAdd(self, value): panel = GridLayout(cols=1) self.text = TextInput() panel.add_widget(self.text) # botonGuardar = Button(text="guardar")uardar) panel.add_widget(Button(text="guardar", on_press=self.guardar)) self.popup = Popup(title='Agregar ' + self.nombreABM, content=panel, size_hint=(1, 0.6)) self.popup.open() def guardar(self, value): self.lista.add_node(TreeViewLabel(text=self.text.text)) self.popup.dismiss() def __deleteItem__(self): if self.lista.selected_node: self.lista.remove_node(self.lista.selected_node) def btnEventDel(self, value): self.__deleteItem__() def btnEventEdit(self, value): panel = GridLayout(cols=1) self.text = TextInput(text=self.lista.get_selected_node().text) panel.add_widget(self.text) panel.add_widget(Button(text="guardar", on_press=self.modificar)) self.popup = Popup(title='Editar ' + self.nombreABM, content=panel, size_hint=(1, 0.6)) self.popup.open() def modificar(self, value): self.lista.get_selected_node().text = self.text.text # self.lista.add_node(TreeViewLabel(text=self.text.text)) self.popup.dismiss()
class MainScreen(Screen): file_view = ObjectProperty(None) Builder.load_file('gui/mainscreen.kv') stop = threading.Event() def setup_cloud_task(self): try: controller.setup_cloud(AES_CRYPTO) except CloudTokenError as err: open_popup_error('Cloud Token', err) self.stop.set() def on_pre_enter(self, *args): controller.setup_stash() # use thread for background task, use clock in a background task to access the ui threading.Thread(target=self.setup_cloud_task).start() file_names = controller.get_uploaded_file_names() self.file_view = TreeView(hide_root=True, indent_level=4) self.file_view.size_hint = 1, None self.file_view.bind(minimum_height=self.file_view.setter('height')) self.scroll_view.add_widget(self.file_view) for file_name in file_names: self.file_view.add_node(TreeViewLabel(text=file_name)) self.max_storage_size = controller.get_max_storage_size() self.usage_bar.max = self.max_storage_size self.update_storage_view() def dismiss_popup(self): self._popup.dismiss() def select_file(self): content = LoadDialog(load=self.upload_file, cancel=self.dismiss_popup) self._popup = Popup(title="Upload file", content=content, size_hint=(0.9, 0.9)) self._popup.open() def update_storage_view(self): self.used_storage_size = controller.get_used_storage_size() self.usage_label.text = controller.get_data_type_format(self.used_storage_size, self.max_storage_size) self.usage_bar.value = self.used_storage_size def get_free_storage_size(self): return self.max_storage_size - self.used_storage_size def split_input_file_task(self): controller.save_file_input(self.filename, self.file_input, AES_CRYPTO) self.file_view.add_node(TreeViewLabel(text=self.filename)) self.update_storage_view() try: controller.update_data(self.filename, AES_CRYPTO) except CloudTokenError as err: open_popup_error('Cloud Token', err) self.stop.set() def upload_file_task(self): with open(os.path.join(self.path, self.filename[0]), utils.READ_BINARY_MODE) as file: self.file_input = file.read() if controller.is_storage_available(len(self.file_input), self.get_free_storage_size()): self.filename = os.path.basename(self.filename[0]) self.split_input_file_task() else: open_popup('Upload Error', 'Not enough storage available.') self.stop.set() def upload_file(self, path, filename): self.path = path self.filename = filename threading.Thread(target=self.upload_file_task).start() self.dismiss_popup() def get_selected_node(self): selected_node = self.file_view.selected_node if selected_node is None: raise NoSelectedNode('No file has been selected.') return selected_node def select_location(self): try: self.selected_node_text = self.get_selected_node().text except NoSelectedNode as err: open_popup_error('Download error', err) return content = SaveDialog(save=self.save, cancel=self.dismiss_popup) content.file_name_label.text = self.selected_node_text self._popup = Popup(title="Download file", content=content, size_hint=(0.9, 0.9)) self._popup.open() def download_file_task(self): try: controller.download_selected_file(self.selected_node_text, self.path, self.filename, AES_CRYPTO) open_popup('Download file', 'Download was successful') except (DownloadFileError, FileSizeError, CloudTokenError) as err: open_popup_error('Download error', err) return self.stop.set() def save(self, path, filename): self.path = path self.filename = filename threading.Thread(target=self.download_file_task).start() self.dismiss_popup() def delete_file_task(self): controller.delete_selected_node(self.selected_node_text) self.update_storage_view() self.stop.set() def delete_selected_file(self): try: self.selected_node = self.get_selected_node() self.selected_node_text = self.selected_node.text except NoSelectedNode as err: open_popup_error('Delete error', err) return self.file_view.remove_node(self.selected_node) threading.Thread(target=self.delete_file_task).start()
class JournalOverviewScreen(Screen): def __init__(self, **kwargs): super(JournalOverviewScreen, self).__init__(**kwargs) v_layout = BoxLayout(orientation='vertical', spacing=30) self.tree_view = TreeView(root_options=dict(text='Tree One'), hide_root=True, indent_level=4) self.tree_view.size_hint = (1, None) self.tree_view.bind(minimum_height=self.tree_view.setter('height')) scroll = ScrollView(pos=(0, 0)) scroll.add_widget(self.tree_view) v_layout.add_widget(scroll) change_journal_layout = BoxLayout(orientation='horizontal', spacing=5, size_hint_y=0.1) change_journal_layout.add_widget(Label(text='Journal file:')) self.journal_file_input = TextInput( text=App.get_running_app().journal_file) change_journal_layout.add_widget(self.journal_file_input) change_journal_layout.add_widget( Button(text='Set another', on_press=self.set_another_journal)) v_layout.add_widget(change_journal_layout) back_to_progress_button = Button(text='Back', size_hint_y=0.2) back_to_progress_button.on_press = self.goto_progress v_layout.add_widget(back_to_progress_button) self.add_widget(v_layout) def on_pre_enter(self): self.populate_tree_view() def on_leave(self): for node in self.tree_view.iterate_all_nodes(): self.tree_view.remove_node(node) def populate_tree_view(self): journal = App.get_running_app().journal journal_node = self.tree_view.add_node( TreeViewLabel(text='Journal', is_open=True)) for training in journal.trainings: training_node = self.tree_view.add_node( TreeViewLabel(text=training.description['date'] + ': Training'), journal_node) label_str = 'Start time: ' + \ str( training.description['start_time'] ) #training.description['start_time'].strftime('%H:%M:%S') self.tree_view.add_node(TreeViewLabel(text=label_str), training_node) label_str = 'End time: ' + \ str( training.description['end_time'] ) self.tree_view.add_node(TreeViewLabel(text=label_str), training_node) label_str = 'Duration: ' + \ str( training.description['duration'] ) self.tree_view.add_node(TreeViewLabel(text=label_str), training_node) label_str = 'Training program: ' + \ str( training.description['training_program'] ) self.tree_view.add_node(TreeViewLabel(text=label_str), training_node) label_str = 'Training index in program: ' + \ str( training.description['training_index_in_program'] ) self.tree_view.add_node(TreeViewLabel(text=label_str), training_node) for exercise in training.exercises: title_node_text = 'Exercise: ' + exercise.description['name'] if 'Metric' in exercise.description.get('type'): title_node_text = 'Metric: ' + exercise.description['name'] exc_node = self.tree_view.add_node( TreeViewLabel(text=title_node_text), training_node) for essential_field in exercise.essential_fields: label_str = essential_field + \ ': ' + str( exercise.description[essential_field] ) self.tree_view.add_node(TreeViewLabel(text=label_str), exc_node) if exercise.description['comment']: label_str = 'Comment: ' + \ str( exercise.description['comment'] ) self.tree_view.add_node(TreeViewLabel(text=label_str), exc_node) if training.description['comment']: label_str = 'Comment: ' + \ str( training.description['comment'] ) self.tree_view.add_node(TreeViewLabel(text=label_str), training_node) def goto_progress(self): self.parent.current = 'view_progress' def set_another_journal(self, *rest): app = App.get_running_app() journal_file = self.journal_file_input.text filename, file_extension = os.path.splitext(journal_file) if file_extension != '.json': self.show_not_json_popup() return if journal_file != app.journal_file: app.journal_file = journal_file if os.path.isfile(app.journal_file): app.journal = Journal.load_journal(app.journal_file) else: app.journal = Journal() app.write_config() for node in self.tree_view.iterate_all_nodes(): self.tree_view.remove_node(node) self.populate_tree_view() def show_not_json_popup(self): popup_content = BoxLayout(orientation='vertical') popup_content.add_widget( Label(text='The journal file is expected ' + 'to have a ".json" extension.\n' + 'Please, specify ' + 'another file.', haling='center')) close_btn = Button(text='Ok', size_hint_y=0.2) popup_content.add_widget(close_btn) popup = Popup(title='Error: journal file is not JSON', content=popup_content, size_hint=(None, None), size=(400, 400)) close_btn.bind(on_press=popup.dismiss) popup.open()