def create_scrollable_treeview(nested_dicts, onclick, root_label): tv = TreeView(root_options={'text': root_label}) def populate_tree(parent, level, index, path): obj = level if index is None else level[index] if hasattr(obj, 'name'): label = TreeViewLabel(text=obj.name, onclick=onclick) label.path = copy(path) tv.add_node(label, parent) else: try: indices = obj.iterkeys() except AttributeError: indices = xrange(len(obj)) # This `if` is a hack to deal with the root of the given tree if index is None: group_node = None else: group_node = TreeViewLabel(text=index) tv.add_node(group_node, parent) for index in indices: populate_tree(group_node, obj, index, path + [index]) populate_tree(None, nested_dicts, None, []) # Make the tree scrollable inside the ScrollView tv.size_hint_y = None tv.bind(minimum_height=tv.setter('height')) scrollable = ScrollView() scrollable.add_widget(tv) return scrollable
def getMergedTreeView(self): try: tv = TreeView(hide_root=True) tv.size_hint = 1, None tv.bind(minimum_height=tv.setter('height')) for key in self.config_files: merged_dict = self.config_files[key].get_merged_config() for key in merged_dict: if isinstance(merged_dict[key], dict): newnode = tv.add_node( TreeViewLabel(text=str(key), font_size=self.label_font_size, color=self.key_label_color)) self._addNodeToMergedTreeView(tv, newnode, merged_dict[key]) else: newnode = tv.add_node( TreeViewLabel(text=str(key) + ':' + str(merged_dict[key]), font_size=self.label_font_size, color=self.key_label_color)) scv = ScrollView(pos=(0, 0), bar_width=10) scv.add_widget(tv) return scv except: e = sys.exc_info()[0] self.log.exception("Error: %s" % e) raise
class FilesTreeWidget(BoxLayout): def __init__(self, tree, remove_node_callback, **kwargs): super(FilesTreeWidget, self).__init__(**kwargs) self.tree = tree self.remove_node_callback = remove_node_callback self.tv = TreeView(load_func=self.load_func, root_options={'text': tree.root.get_name()}) self.tv.size_hint = 1, None self.tv.bind(minimum_height=self.tv.setter('height')) scroll_view = ScrollView() scroll_view.add_widget(self.tv) self.add_widget(scroll_view) def load_func(self, tv, node): if node is None or not isinstance(node, FileTreeViewLabel): dir = self.tree.root else: dir = node.get_dir() for child in dir.get_children(): label = FileTreeViewLabel(child, self.tree, self.tv, self.remove_node_callback, text=child.get_name()) label.is_leaf = child.if_is_file() yield label
def update_content(self, *args): widget = self.console.widget if not widget: return from kivy.uix.scrollview import ScrollView self.root = root = BoxLayout() self.sv = sv = ScrollView(scroll_type=["bars", "content"], bar_width='10dp') treeview = TreeView(hide_root=True, size_hint_y=None) treeview.bind(minimum_height=treeview.setter("height")) keys = list(widget.properties().keys()) keys.sort() node = None wk_widget = weakref.ref(widget) for key in keys: node = TreeViewProperty(key=key, widget_ref=wk_widget) node.bind(is_selected=self.show_property) try: widget.bind(**{ key: partial(self.update_node_content, weakref.ref(node)) }) except: pass treeview.add_node(node) root.add_widget(sv) sv.add_widget(treeview) self.console.set_content(root)
def update_content(self, *args): widget = self.console.widget if not widget: return from kivy.uix.scrollview import ScrollView self.root = root = BoxLayout() self.sv = sv = ScrollView(scroll_type=["bars", "content"]) treeview = TreeView(hide_root=True, size_hint_y=None) treeview.bind(minimum_height=treeview.setter("height")) keys = list(widget.properties().keys()) keys.sort() node = None wk_widget = weakref.ref(widget) for key in keys: text = '%s' % key node = TreeViewProperty(text=text, key=key, widget_ref=wk_widget) node.bind(is_selected=self.show_property) try: widget.bind(**{ key: partial(self.update_node_content, weakref.ref(node)) }) except: pass treeview.add_node(node) root.add_widget(sv) sv.add_widget(treeview) self.console.set_content(root)
def getTreeViewAsFiles(self): try: tv = TreeView(hide_root=True) tv.size_hint = 1, None tv.bind(minimum_height = tv.setter('height')) for key in self.config_files: newnode = tv.add_node(TreeViewLabel(text=self.config_files[key].filename, font_size=self.label_font_size, color=self.filename_label_color)) for child_filename in self.config_files[key].child_files: self._addFileNodeToFileTreeView(tv, newnode, self.config_files[key].child_files[child_filename]) for configkey in self.config_files[key].config: if isinstance(self.config_files[key].config[configkey], dict): self._addDictNodeToFileTreeView(tv, newnode, configkey, self.config_files[key].config[configkey]) else: tv.add_node(TreeViewLabel(text=str(configkey) + ':' + str(self.config_files[key].config[configkey]), font_size=self.label_font_size, color=self.key_label_color), newnode) scv = ScrollView(pos = (0, 0), bar_width = 10) scv.add_widget(tv) return scv except: e = sys.exc_info()[0] self.log.exception("Error: %s" % e ) raise
def build(cls): #if exists(cls.pickle_fn()): # result = pickle.load(open(cls.pickle_fn(), "rb" ) ) tv = TreeView(hide_root=True) tv.size_hint = 1, None tv.bind(minimum_height=tv.setter('height')) data = Data() groups = data.get_groups() ingredients = data.get_ingredients() def already_created(node, text): if hasattr(node, 'text'): return node.text == text else: return False for group in groups: if len( list( filter( lambda seq: already_created(seq, group['group']), tv.iterate_all_nodes()))) == 0: node_group = tv.add_node(TreeViewLabel(text=group['group'])) node_group = list( filter(lambda seq: already_created(seq, group['group']), tv.iterate_all_nodes())) if len(node_group) > 0: if len( list( filter( lambda seq: already_created( seq, group['subgroup']), tv.iterate_all_nodes()))) == 0: node_subgroup = tv.add_node( TreeViewLabel(text=group['subgroup']), node_group[0]) for ingredient in ingredients: node_subgroup = list( filter( lambda seq: already_created(seq, ingredient['food_subgroup' ]), tv.iterate_all_nodes())) if len(node_subgroup) > 0: tv.add_node( IngredientListPopupItem( prop_id=ingredient['id'], name=ingredient['name'], name_scientific=ingredient['name_scientific'], description=ingredient['description']), node_subgroup[0]) else: print('error adding {0}', ingredient['name']) cls.tv = tv
def _create_tree(instance: "SettingTree") -> TreeView: """ :return: """ tree: Tree = _get_data(instance) tv = TreeView(hide_root=True) tv.bind(minimum_height=tv.setter('height')) populate_tree_view(tv, None, tree) return tv
def build(self): #for i in range(30): # btn = Button(text=str(i), size=(480, 40), # size_hint=(None, None)) # layout.add_widget(btn) tv = TreeView(root_options=dict(text='Tree One'), hide_root=True, indent_level=4) tv.size_hint = 1, None tv.bind(minimum_height = tv.setter('height')) populate_tree_view(tv) root = ScrollView(pos = (0, 0)) root.add_widget(tv) return root
def AddAsset(self): """show the add asset dialog""" try: popup = Popup(title="select asset") popup.size_hint = (0.8,0.8) tv = TreeView(root_options=dict(text='Tree One'), hide_root=True, indent_level=4) tv.size_hint = 1, None tv.bind(minimum_height = tv.setter('height')) tv.load_func = self.populateTreeNode tv.bind(selected_node=self.on_assetSelected) root = ScrollView(pos = (0, 0)) root.add_widget(tv) popup.add_widget(root) popup.open() except Exception as e: showError(e)
def fill_tree(self, filtre): self.scroll.clear_widgets() tree = TreeView(hide_root=True, size_hint_y=None, size_hint_x = 0.6) tree.bind(minimum_height=tree.setter('height'), selected_node=self.show_details) self.scroll.add_widget(tree) for uv in self.uvs: if uv[0].startswith(filtre.upper()) and uv[1] != 0: node = TreeViewLabel(text=u"%s (%s €)" % (uv[0], uv[1]*0.06), font_size=30, size_hint_y=None, padding=(20,20)) tree.add_node(node) self.tree = tree
def showAssetSelector(self): """renders the root grounds in the treeview.""" try: popup = Popup(title="select asset") popup.size_hint = (0.8, 0.8) tv = TreeView(root_options=dict(text='Tree One'), hide_root=True, indent_level=4) tv.size_hint = 1, None tv.bind(minimum_height=tv.setter('height')) tv.load_func = self.populateTreeNode tv.bind(selected_node=self.on_assetChanged) root = ScrollView(pos=(0, 0)) root.add_widget(tv) popup.add_widget(root) popup.open() except Exception as e: showError(e)
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 POSFMApp(App): def build(self): layout = FloatLayout() self.tv = TreeView(root_options=dict(text='Tree One'), hide_root=True, indent_level=0, indent_start=0) self.tv.size_hint = 1, None self.tv.bind(minimum_height = self.tv.setter('height')) self.populate_tree_view(self.tv) self.camera = Button(text = 'Camera', size_hint =(1/3.,.23), background_color=[1,0,0,.6], pos_hint={'x':0,'y':0}) self.add = Button(text = 'Add', size_hint =(1/3.,.23), background_color=[1,0,0,.6], pos_hint={'x':1/3.,'y':0}) self.sort = Button(text = 'Sort', size_hint =(1/3.,.23), background_color=[1,0,0,.6], pos_hint={'x':2/3.,'y':0}) root = ScrollView(pos = (0, 0)) root.add_widget(self.tv) layout.add_widget(root) layout.add_widget(self.camera) layout.add_widget(self.add) layout.add_widget(self.sort) return layout def populate_tree_view(self, tv): for i, item in enumerate(foodlist): if item.categ not in usedcat.keys(): catbutton = TreeViewButton(text='%s' % item.categ, font_size = '50sp', size = (100, 450), background_color=[1,1,0,1]) catbutton.bind(on_press=self.cat_clicked) g = self.tv.add_node(catbutton) usedcat[item.categ] = g else: g = usedcat[item.categ] itembutton = TreeViewButton(text='%s' % item.name, font_size = '30sp', size = (100,150), background_color=[0,1,1,1]) itembutton.outline_height = 10 self.tv.add_node(itembutton, g) def cat_clicked(self, button): self.tv.toggle_node(button)
def getTreeViewAsFiles(self): try: tv = TreeView(hide_root=True) tv.size_hint = 1, None tv.bind(minimum_height=tv.setter('height')) for key in self.config_files: newnode = tv.add_node( TreeViewLabel(text=self.config_files[key].filename, font_size=self.label_font_size, color=self.filename_label_color)) for child_filename in self.config_files[key].child_files: self._addFileNodeToFileTreeView( tv, newnode, self.config_files[key].child_files[child_filename]) for configkey in self.config_files[key].config: if isinstance(self.config_files[key].config[configkey], dict): self._addDictNodeToFileTreeView( tv, newnode, configkey, self.config_files[key].config[configkey]) else: tv.add_node( TreeViewLabel( text=str(configkey) + ':' + str(self.config_files[key].config[configkey]), font_size=self.label_font_size, color=self.key_label_color), newnode) scv = ScrollView(pos=(0, 0), bar_width=10) scv.add_widget(tv) return scv except: e = sys.exc_info()[0] self.log.exception("Error: %s" % e) raise
def getMergedTreeView(self): try: tv = TreeView(hide_root=True) tv.size_hint = 1, None tv.bind(minimum_height = tv.setter('height')) for key in self.config_files: merged_dict = self.config_files[key].get_merged_config() for key in merged_dict: if isinstance(merged_dict[key], dict): newnode = tv.add_node(TreeViewLabel(text=str(key), font_size=self.label_font_size, color=self.key_label_color)) self._addNodeToMergedTreeView(tv, newnode, merged_dict[key]) else: newnode = tv.add_node(TreeViewLabel(text=str(key) + ':' + str(merged_dict[key]), font_size=self.label_font_size, color=self.key_label_color)) scv = ScrollView(pos = (0, 0), bar_width = 10) scv.add_widget(tv) return scv except: e = sys.exc_info()[0] self.log.exception("Error: %s" % e ) raise
class OrderScreen(Screen): level1tv_oprop = ObjectProperty( ) # treeview BoxLayout id reference kv orderlist_lay tv_oprop = ObjectProperty() ## treview ObjectProperty level2lv_oprop = ObjectProperty( ) # listview level2 BoxLayout id reference kv orderlist_lay level3lv_oprop = ObjectProperty( ) # listview orderlist BoxLayout id reference kv orderlist_lay totalorder_nprop = NumericProperty() # total order changeorder_oprop = ObjectProperty( ) #####button 'send order' id reference kv change 'send_orders' or 'update' product_name = StringProperty() edit_pop = ObjectProperty() # popup edit orders date = dt.date.isoformat(dt.date.today()) def __init__(self, *args, **kwargs): super(OrderScreen, self).__init__(*args, **kwargs) self.scoll = ScrollView() app = App.get_running_app() self.tv_oprop = TreeView(size_hint_y=None, hide_root=True) #create trevview self.tv_oprop.bind(minimum_height=self.tv_oprop.setter("height")) add = self.tv_oprop.add_node self.tvfood = add( TreeViewButton(text='Food', size=(120, 40), is_open=False)) #TreeViewButton food for key in app.menu['Food'].keys(): add( TreeViewButton( text=key, on_press=self.populate_level2, size=(120, 40), ), self.tvfood) self.tvdrink = add( TreeViewButton(text='Drink', size=(120, 40), on_press=self.node_click, is_open=False)) self.tvfood.bind(on_press=self.node_click) for key in app.menu['Drink'].keys(): #TreeViewButton food add( TreeViewButton( text=key, on_press=self.populate_level2, size=(120, 40), ), self.tvdrink) self.args_converter_level2 = lambda row_index, rec: { 'text': rec['text'], 'price': rec['price'], 'level1': rec['level1'], 'level2': rec['level2'], 'choices': rec['choices'], 'on_press': self.add_item } self.level2_adapter = SimpleListAdapter( data=[], args_converter=self.args_converter_level2, selection_mode='single', cls=Level2ListItemButton) self.args_converter_level3 = lambda row_index, rec: { 'product': rec['product_name'], 'price': rec['price'], 'level1': rec['level1'], 'level2': rec['level2'], 'choices': rec['choices'], 'quantity': rec['quantity'], 'mychoices': rec['mychoices'] } self.level3_adapter = ListAdapter( data=[], args_converter=self.args_converter_level3, selection_mode='single', allow_empty_selection=True, template='OrderListItem') self.scoll.add_widget(self.tv_oprop) self.level1tv_oprop.add_widget(self.scoll, index=1) self.list_view_level2 = ListView(adapter=self.level2_adapter) self.level2lv_oprop.add_widget(self.list_view_level2) self.list_view_level3 = ListView(adapter=self.level3_adapter) self.level3lv_oprop.add_widget(self.list_view_level3, index=1) def node_click(self, btn, *args): # if node open close other node Food,Drink if btn.text == 'Food': node1 = self.tvdrink node2 = self.tvfood elif btn.text == 'Drink': node1 = self.tvfood node2 = self.tvdrink if node1.is_open: self.tv_oprop.toggle_node(node1) self.tv_oprop.toggle_node(node2) def populate_level2(self, btn, *args): #listview level2 app = App.get_running_app() level1 = btn.parent_node.text l2 = [{ 'text': d['productname'], 'price': d['price'], 'level1': btn.parent_node.text, 'level2': btn.text, 'choices': d['choices'] } for d in app.menu[level1][str(btn.text)] ] #,'withwithout':d['withwithout']} self.level2_adapter.data = l2 def add_item(self, btn, *args): #listview2 insert orderlistview myitem = None if self.level3_adapter.data: for index, item in enumerate(self.level3_adapter.data): if item['product_name'] == btn.text: myitem = self.level3_adapter.data.pop(index) break if myitem: myitem['quantity'] = str(int(myitem['quantity']) + 1) self.level3_adapter.data.insert(0, myitem) self.totalorder_nprop += myitem['price'] else: self.level3_adapter.data.insert( 0, { 'product_name': btn.text, 'price': btn.price, 'level1': btn.level1, 'level2': btn.level2, 'choices': btn.choices, 'quantity': '1', 'mychoices': '' }) count = 0 for items in self.level3_adapter.data: count += items['price'] * float(items['quantity']) self.totalorder_nprop = count def add_product(self, btn, *args): #button + add product amount = 0 row_id = btn.get_id #id row from orderlistitem from kv_files quantity = btn.parent.children[ 3].text # quantity btn get ListItemLabel btn.parent.children[3].text = str(int(quantity) + 1) # ListItemLabel +1 self.level3_adapter.data[row_id]['quantity'] = btn.parent.children[ 3].text #get item quantity for add product listorder,na krataei to quantity for items in self.level3_adapter.data: # total price*quantity amount += items['price'] * float(items['quantity']) self.totalorder_nprop = amount def remove_product(self, btn, *args): #button - remove product amount = self.totalorder_nprop row_id = btn.get_id #id quantity = btn.parent.children[3].text if btn.parent.children[3].text > '1': btn.parent.children[3].text = str(int(quantity) - 1) self.level3_adapter.data[row_id]['quantity'] = btn.parent.children[ 3].text for items in self.level3_adapter.data: amount -= items['price'] * float(items['quantity']) self.totalorder_nprop -= amount def openchoice_pop(self, btn, *args): #open pop_up app = App.get_running_app() self.popup_content = EditProducts() self.product_name = btn.parent.children[ 5].text ## product name get label popup row_id = btn.get_id self.items = self.level3_adapter.data[row_id] #items row id self.popup_content.choices_adapter.data = [{ 'text': choice, 'active': self.items['choices'][choice] } for choice in self.items['choices']] self.edit_pop.content = self.popup_content self.edit_pop.title = 'Choices' self.edit_pop.auto_dismiss = False self.edit_pop.open() firstitem = None if self.level3_adapter.data: for index, item in enumerate(self.level3_adapter.data): if int(item['quantity']) > 1: firstitem = self.level3_adapter.data.pop(index) newitem = firstitem.copy() newitem['quantity'] = str(int(item['quantity']) - 1) firstitem['quantity'] = '1' self.level3_adapter.data.insert(0, item) self.level3_adapter.data.insert(0, newitem) def delete_product(self, btn, *args): #button delete product row_id = btn.get_id price = self.level3_adapter.data[row_id]['price'] #price quantity = self.level3_adapter.data[row_id]['quantity'] self.totalorder_nprop -= price * float(quantity) del self.level3_adapter.data[row_id] def btn_back_managementorders_success( self, req, result): # result oders take accordion app = App.get_running_app() if result.has_key('resp'): if platform == 'android': app.root.PythonActivity.toastError(result['resp']) else: print result['resp'] else: app.root.sm.current = 'Table' if platform == 'android': app.root.PythonActivity.toastError(result['respno']) else: print result['respno'] def btn_back_managementorders(self, btn, *args): # button < back management order app = App.get_running_app() app.root.sm.current = 'managementorders' payload = {'table': self.thesi_lbl.text.split(' ')[1]} params = urllib.urlencode(payload) app.root.url_request( app.root.server_url + 'data/backmanagement/' + app.root.apikey, params, self.btn_back_managementorders_success, app.root.error_request, app.root.failure_request) del self.level3_adapter.data[:] self.totalorder_nprop = 0 def delete_order_success(self, req, result): app = App.get_running_app() if result.has_key('resp'): orderstable = result['orderstablelist'] app.root.management_scr.items_acc.clear_widgets() app.root.management_scr.createaccordion(orderstable) del self.level3_adapter.data[:] #list orderlist self.totalorder_nprop = 0 if platform == 'android': app.root.PythonActivity.toastError(result['resp']) else: print result['resp'] def delete_order(self, *args): # delete order with orderid app = App.get_running_app() payload = { 'order_id': app.root.management_scr.order_id, 'table': self.thesi_lbl.text.split(' ')[1] } params = urllib.urlencode(payload) app.root.url_request( app.root.server_url + 'data/deleteorder/' + app.root.apikey, params, self.delete_order_success, app.root.error_request, app.root.failure_request) def order_btn_press(self, orderid, *args): #button send order,update if self.changeorder_oprop.text == 'UPDATE ORDER': #update order self.send_data(neworder=False) else: self.send_data(neworder=True) def send_data_success(self, req, result): app = App.get_running_app() if result.has_key('save'): orderstable = result['getorder'] app.root.management_scr.createaccordion(orderstable) if platform == 'android': app.root.PythonActivity.toastError(result['save']) else: print result['save'] else: if platform == 'android': app.root.PythonActivity.toastError(result['up']) else: print result['up'] app.root.management_scr.items_acc.clear_widgets() orderstable = result['getorder'] print orderstable, 'getorder' app.root.management_scr.createaccordion(orderstable) del self.level3_adapter.data[:] self.totalorder_nprop = 0 def send_data(self, neworder=True, *args): #send order,table,total app = App.get_running_app() order_data = {} order_data['customer_id'] = app.root.customer_id order_data['user_id'] = app.root.user_id order_data['acount'] = '' order_data['items'] = self.level3_adapter.data order_data['table'] = self.thesi_lbl.text.split(' ')[1] order_data['total'] = self.totalorder_nprop order_data['status'] = 'new' order_data['date'] = str(self.date) order_data['datetime'] = str(self.date) order_data['saved'] = str(datetime.datetime.now()) order_data['datetime'] = str(dt.date.isoformat(dt.date.today())) if app.root.apikey: if neworder: payload = { 'order_data': json.dumps(order_data), 'table': self.thesi_lbl.text.split(' ')[1], 'total': self.totalorder_nprop } params = urllib.urlencode(payload) app.root.url_request( app.root.server_url + 'data/insertorder/' + app.root.apikey, params, self.send_data_success, app.root.error_request, app.root.failure_request) else: payload = { '_id': app.root.management_scr.order_id, 'order_data': json.dumps(order_data), 'table': self.thesi_lbl.text.split(' ')[1], 'total': self.totalorder_nprop } params = urllib.urlencode(payload) print self.totalorder_nprop, 'self.totalorder_nprop' app.root.url_request( app.root.server_url + 'data/updateorder/' + app.root.apikey, params, self.send_data_success, app.root.error_request, app.root.failure_request)
class TreeWidget(BoxLayout): def __init__(self, **kwargs): super(TreeWidget, self).__init__(**kwargs) self.selected = None self.items = [] # self.on_touch_down=self.touch def populate_tree_view(self, tree_view, parent, node): if parent is None: tree_node = tree_view.add_node( TreeViewLabel( text=node['node_id'], on_touch_up=self.touch1, is_open=True, font_size=25, )) # ,bcolor=random.choice(self.colors) tree_node.item = node["item"] self.items.append(tree_node) else: tl = TreeViewLabel( text=node['node_id'], is_open=False, font_size=25, ) # ,bcolor=random.choice(self.colors) tl.item = node["item"] tree_node = tree_view.add_node(tl, parent) for child_node in node['children']: self.populate_tree_view(tree_view, tree_node, child_node) def define(self, tree1, callback, colors): self.callback = callback self.colors = colors self.tv = TreeView(root_options=dict(text='Playlists'), hide_root=True, on_touch_down=self.touch2, indent_level=10) self.tv.size_hint = 1, None self.tv.bind(minimum_height=self.tv.setter('height')) self.populate_tree_view(self.tv, None, tree1) root = ScrollView(pos=(0, 0)) root.add_widget(self.tv) self.add_widget(root) def touch1(self, instance, touch): return False def touch2(self, instance, touch): """ Handle a touch event on a child TreeViewLabel :param args: :param kwargs: :return: """ node = self.tv.get_node_at_pos(touch.pos) if not node: return try: self.callback(node.item["uri"], node.text) return True except: pass self.tv.toggle_node(node) node.dispatch('on_touch_down', touch) return True
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()
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()