def click(self): image = Image(source='E:\circle-cropped.png', size_hint=(1, 1), allow_stretch=True, size=(200, 200)) layout = GridLayout(cols=1) popupLabel = Label( text= "Mayank Raj\nEmail:\[email protected]\nphone n.\n6204396601", font_size=10) p = GridLayout(cols=2) k = GridLayout(cols=1) k.add_widget(popupLabel) p.add_widget(image) p.add_widget(k) closeButton = MDRoundFlatButton(text="done", size_hint=(.15, 0.1)) layout.add_widget(p) layout.add_widget(closeButton) popup = Popup(title='DEVELOPER', content=layout, size_hint=(0.7, 0.5), size=(700, 500), background='E:\monkuyoert.jpg') popup.open() closeButton.bind(on_press=popup.dismiss)
def __init__(self, **kwargs): super().__init__(orientation='vertical', **kwargs) self.history = [] # directory navigation history # If False - do not add a directory to the history - # The user moves down the tree. self.history_flag = True toolbar_label = self.ids.toolbar.children[1].children[0] toolbar_label.font_style = "Subtitle1" self.app = App.get_running_app() from kivymd.uix.button import MDFillRoundFlatButton as Button, MDRoundFlatButton if self.save_mode: action_button = MDRoundFlatButton( text="Save", size_hint=(1,None) ) action_button.bind(on_release=self.select_directory_on_press_button) self.add_widget(action_button) from kivymd.uix.textfield import MDTextFieldRect,MDTextField self.saveFileName = MDTextField(text=str(self.save_mode),mode='fill', multiline=False,font_size='22sp',size_hint=(1,None)) self.add_widget(self.saveFileName)
def summary(self): mycursor = main.sqliteConnection.cursor() mycursor.execute("SELECT sum(execution_time) " "FROM work_plan " "WHERE done_date = date('now')") rows = mycursor.fetchone() time = rows[0] mycursor.execute("SELECT a.task_name, max(b.execution_time) " "FROM task_type a " "JOIN work_plan b " "ON a.id_type=b.id_type " "WHERE done_date = date('now') ") row = mycursor.fetchone() max_task = row[0] max_time = row[1] mycursor.execute("SELECT a.task_name, min(b.execution_time) " "FROM task_type a " "JOIN work_plan b " "ON a.id_type=b.id_type " "WHERE done_date = date('now') ") row = mycursor.fetchone() min_task = row[0] min_time = row[1] self.ids.analysis.add_widget( MDRoundFlatButton(text="TOTAL TIME UTILIZED: " + str(time), text_color=get_color_from_hex('#e5e5e5'), pos_hint={ "x": 0, "y": 0.30 }, size_hint=(1, 0.1), font_size=13)) self.ids.analysis.add_widget( MDRoundFlatButton(text="MOST TIME SPENT ON: " + str(max_task) + " - " + str(max_time), text_color=get_color_from_hex('#e5e5e5'), pos_hint={ "x": 0, "y": 0.15 }, size_hint=(1, 0.1), font_size=13)) self.ids.analysis.add_widget( MDRoundFlatButton(text="LEAST TIME SPENT ON: " + str(min_task) + " - " + str(min_time), text_color=get_color_from_hex('#e5e5e5'), pos_hint={ "x": 0, "y": 0 }, size_hint=(1, 0.1), font_size=13))
def appendPost(self): newpost = self.ids.postbox.text usersDB.insertPost(userlogged, newpost) self.parent.get_screen("kv_menu").ids.list_on_menu.clear_widgets() global postwallwidgets postwallwidgets = [] results = usersDB.getposts() for post in reversed(results): occupation = usersDB.getAccountData(results[post], 'profession') firstname = usersDB.getAccountData(results[post], 'fname') lastname = usersDB.getAccountData(results[post], 'lname') primary_text = firstname + " " + lastname + " (" + occupation + ")" secondary_text = post textprofile = MDRoundFlatButton(text=primary_text, size_hint=(None, 0.2)) text = MDLabel(text=secondary_text, size_hint_y=0.3) underline = MDLabel(text="_" * 54, halign="center", size_hint_y=0.3) self.parent.get_screen("kv_menu").ids.list_on_menu.add_widget( textprofile) self.parent.get_screen("kv_menu").ids.list_on_menu.add_widget(text) self.parent.get_screen("kv_menu").ids.list_on_menu.add_widget( underline) print("DEBUG: Successfully loaded posts to menu.")
def deletenow(self, postdialogue): if not self.dialog: self.dialog = MDDialog( text="Discard Post?\n" + postdialogue, size_hint=(None, None), size=(200, 300), buttons=[ MDRoundFlatButton( text="CANCEL", on_release=lambda x: self.dialog.dismiss()), MDRoundFlatButton( text="DISCARD", on_release=lambda x: self.deletedscreen(postdialogue)), ], ) self.dialog.open()
def submitForm(self): if not self.dialog: self.dialog = MDDialog( text="Submit Booking\n{0}\n{1}\n{2}".format( self.ids.doctorlabel.text, self.date, self.ids.bookreason.text), size_hint=(None, None), size=(200, 300), buttons=[ MDRoundFlatButton(text="BACK", on_release=lambda x: self.dismiss()), MDRoundFlatButton( text="CONFIRM", on_release=lambda x: self.patientBookingDB(self.date)), ], ) self.dialog.open()
def __init__(self, **kwargs): Screen.__init__(self, **kwargs) layout = FloatLayout() self.add_widget(layout) #add label recipeName = MDLabel(font_style="Subtitle2", text=self.name, halign="center", pos_hint={"center_y": .95}) layout.add_widget(recipeName) #load ingredient list with open("grocery_store.json") as f: recipe_book = json.load(f) ingredients_chosen = {} for name, ing in recipe_book.items(): for key in ing: if (name == self.name): ingredients_chosen[key] = ing[key] #add ingredients list listLayout = GridLayout(cols=2, padding=40, row_force_default=True, row_default_height=45) for key in ingredients_chosen: listLayout.add_widget(MDLabel(text=key)) checkbox = MDCheckbox(on_active=self.checkbox_clicked) listLayout.add_widget(checkbox) #add checkboxes layout.add_widget(listLayout) #add back button button = MDRoundFlatButton(text='<', padding="10dp", pos_hint={ "center_x": .2, "center_y": .95 }, font_style="Subtitle1", text_color=(0, 0, 0), line_color=(1, 1, 1), line_width=1) layout.add_widget(button) button.bind(on_release=self.switch_screen)
def sh_delete_item(self): yes_button = MDFillRoundFlatButton(text="Zmazať", on_release=self.close_del_dialog, on_press=self.delete_item) no_button = MDRoundFlatButton(text="Zrušiť", on_release=self.close_del_dialog) self.del_dialog = MDDialog(title="Naozaj zmazať test?", size_hint=[0.8, 0.5], auto_dismiss=False, buttons=[no_button, yes_button]) self.del_dialog.open()
def __init__(self, **kw): super().__init__(**kw) self.connection = False self.without_connection = MDLabel(text="Sin Conexión", font_style="H3", halign="center") self.stream = KivyStream(fps=60) self.web_cam = Camera(resolution=(1080, 720), play=False) self.camera_button = MDRoundFlatButton( text="Activar Cámara", size_hint=(.5, 1), on_release=self.camera_button_action) self.connect_button = MDRoundFlatButton( text="Conectar", size_hint=(.5, 1), on_release=self.streaming_connection) self.ids.stream_box.add_widget(self.without_connection) self.ids.buttons_box.add_widget(self.connect_button) self.ids.buttons_box.add_widget(self.camera_button)
def add_prod_callback(self, prod): for i in self.available_products: if i.name == prod.text: self.products_selected.append(i) self.product_list_layout.clear_widgets() for i in self.products_selected: self.product_list_layout.add_widget(MDRoundFlatButton(text=i.name)) self.update_costing() self.layout.do_layout() self.add_prod_menu.dismiss()
def open_artists(self, *args): import start_page self.artists_screen = artists_screen = Screen(name='artists_page') artists_page = start_page.ArtistsPage(callback=self.submit_artists, ) artists_page.add_widget( MDRoundFlatButton( text='CANCEL', pos_hint={ 'center_x': 0.2, 'center_y': 0.1 }, on_press=self.cancel_artists, )) artists_screen.add_widget(artists_page) self.app.screen_manager.add_widget(artists_screen) self.app.screen_manager.current = 'artists_page'
def add_btn_to_layout(dropdown_src, layout): btn_to_add = MDRoundFlatButton( pos_hint={'top': 1}) # pos_hint={'center_x':0, 'center_y':0.5}) current = dropdown_src.current_item first_item = dropdown_src.items[0] if current != first_item: btn_to_add.text = dropdown_src.current_item btn_to_add.bind( on_release=lambda x: remove_btn_from_layout(layout, btn_to_add)) btn_to_add.color = "Primary" layout.add_widget(btn_to_add)
def on_release(self, *args): app = App.get_running_app() app.root.ids.scrollview.clear_widgets() myDB = dbOperation.db_operation() if myDB.db_connect(): result = myDB.db_select() for item in result: if 0 < result.index(item) < 11: textArr=str(item)[2:-3].split(' ') app.root.ids.scrollview.add_widget( MDRoundFlatButton( text=textArr[0], size_hint_y=None, width=200, height=40, ) )
def deletePost(self): results = usersDB.getposts() users_results = [] for post in reversed(results): if usersDB.getPostAuthor(post) == userlogged: users_results.append(post) for user_post in reversed(users_results): secondary_text = user_post textprofile = MDRoundFlatButton( text="REMOVE", size_hint=(None, 0.2), on_release=lambda x: self.deletenow(user_post)) text = MDLabel(text=secondary_text, size_hint_y=0.3) underline = MDLabel(text="_" * 54, halign="center", size_hint_y=0.3) self.ids.delete_list.add_widget(textprofile) self.ids.delete_list.add_widget(text) self.ids.delete_list.add_widget(underline) print("DEBUG: Successfully Loaded DELETE posts to menu.")
def updatePostWall(self): self.parent.get_screen("kv_menu").ids.list_on_menu.clear_widgets() results = usersDB.getposts() for post in reversed(results): occupation = usersDB.getAccountData(results[post], 'profession') firstname = usersDB.getAccountData(results[post], 'fname') lastname = usersDB.getAccountData(results[post], 'lname') primary_text = firstname + " " + lastname + " (" + occupation + ")" textprofile = MDRoundFlatButton(text=primary_text, size_hint=(None, 0.2)) text = MDLabel(text=post, size_hint_y=0.3) underline = MDLabel(text="_" * 54, halign="center", size_hint_y=0.3) self.parent.get_screen("kv_menu").ids.list_on_menu.add_widget( textprofile) self.parent.get_screen("kv_menu").ids.list_on_menu.add_widget(text) self.parent.get_screen("kv_menu").ids.list_on_menu.add_widget( underline) print("DEBUG: Successfully loaded posts to menu.")
def __init__(self, **kwargs): super(CardArray, self).__init__(**kwargs) self.popup_container = MDBoxLayout(orientation='vertical', spacing=2, padding=2) container = MDBoxLayout(orientation='vertical', spacing=2, padding=2) popup_close_button = MDRoundFlatButton(text='Exit Panel', size_hint_x=.5, on_press=self.close_popup, pos_hint={ "center_x": .5, "center_y": .5 }, md_bg_color=(1, 0, 0, 1), text_color=(1, 0, 1, 1), font_size='18sp') container.add_widget(self.popup_container) container.add_widget(popup_close_button) container.add_widget(MDLabel(text='')) self.popup = Popup(size_hint=(.4, .3), content=container)
def show_data(self, obj): inp_one = self.input_one.text inp_two = self.input_two.text inp_three = self.input_three.text doc_email = self.doctor_email.text sender_email = "*****@*****.**" passw = "hack12345" subj = "Health Check Patient Report" mesg = "Your patient on Health Check has out of bounds results. Please contact them as soon as possible." msg = MIMEMultipart() msg['From'] = sender_email msg['To'] = doc_email msg['Subject'] = subj msg.attach(MIMEText(mesg, 'plain')) if inp_one == "" or inp_two == "" or inp_three == "": text = "Please enter valid data." elif doc_email == "": text = "Please enter a valid email." else: if inp_one.isalpha() or inp_two.isalpha() or inp_three.isalpha(): text = "Please enter valid data." else: if float(inp_one) > 10.0 or float(inp_two) > 10.0 or float(inp_three) > 10.0: text = "Your test results are out of bounds. We have notified your doctor at {}".format(doc_email) server = smtplib.SMTP('smtp.gmail.com', 587) server.starttls() server.login(sender_email, passw) txt = msg.as_string() server.sendmail(sender_email, doc_email, txt) server.quit() else: text = "Your test results are within bounds. No action is needed." self.dialog = MDDialog(text=text, size_hint=(0.8, 1), buttons=[MDRoundFlatButton(text="Close", on_release=self.close)]) self.dialog.open()
def deletedscreen(self, post): self.ids.delete_label.text = "({0}) has been deleted".format(post) self.dialog.dismiss() usersDB.deletePost(userlogged, post) self.ids.delete_list.clear_widgets() results = usersDB.getposts() for post in reversed(results): secondary_text = post if userlogged == results[post]: textprofile = MDRoundFlatButton( text="REMOVE YOUR POST", size_hint=(None, 0.2), on_release=lambda x: self.deletenow(post)) text = MDLabel(text=secondary_text, size_hint_y=0.3) underline = MDLabel(text="_" * 54, halign="center", size_hint_y=0.3) self.ids.delete_list.add_widget(textprofile) self.ids.delete_list.add_widget(text) self.ids.delete_list.add_widget(underline) print("DEBUG: Successfully deleted, refreshing list")
def task(self): mycursor = main.sqliteConnection.cursor() mycursor.execute("SELECT count(id_type) " "FROM task_type ") row = mycursor.fetchone() count_of_types = str(row[0]) mycursor.execute("SELECT count(id_task) " "FROM work_plan " "WHERE done_date IS NOT NULL ") row = mycursor.fetchone() done_tasks = int(row[0]) mycursor.execute("SELECT count(id_task) " "FROM work_plan ") rows = mycursor.fetchone() to_do_tasks = int(rows[0]) mycursor.execute("SELECT sum(execution_time) " "FROM work_plan ") rows = mycursor.fetchone() execution_time = str(rows[0]) if to_do_tasks == 0: workplan = 0 else: workplan = int(done_tasks / to_do_tasks * 100) self.ids.buttons.add_widget( MDRoundFlatButton( text= count_of_types+"\n\nT A S K \nT Y P E S", text_color = get_color_from_hex('#e5e5e5'), pos_hint={"x": .05, "y": .6}, size_hint=(0.4, 0.35), font_size = 15 ) ) self.ids.buttons.add_widget( MDRoundFlatButton( text=str(done_tasks) + "\n\nD O N E\nT A S K S", text_color=get_color_from_hex('#e5e5e5'), md_bg_color=get_color_from_hex('#333333'), pos_hint={"x": .55, "y": .6}, size_hint=(0.4, 0.35), font_size=15 ) ) self.ids.buttons.add_widget( MDRoundFlatButton( text=str(workplan)+"%\n\nD O N E\nW O R K\nP L A N", text_color=get_color_from_hex('#e5e5e5'), md_bg_color=get_color_from_hex('#333333'), pos_hint={"x": .05, "y": .2}, size_hint=(0.4, 0.35), font_size=15 ) ) self.ids.buttons.add_widget( MDRoundFlatButton( text=execution_time + "\nminutes \n\nW O R K\nT I M E", text_color=get_color_from_hex('#e5e5e5'), md_bg_color=get_color_from_hex('#333333'), pos_hint={"x": .55, "y": .2}, size_hint=(0.4, 0.35), font_size=15 ) )
def summary(self, number_of_days, main_list): dt = datetime.today() days = dt.date() - timedelta(days=number_of_days) mycursor = sqliteConnection.cursor() mycursor.execute( f"SELECT count(id_task) " f"FROM work_plan " f"WHERE done_date > ? AND done_date <= date('now') ", (days, )) row = mycursor.fetchone() done_tasks = row[0] mycursor.execute( f"SELECT count(id_task) " f"FROM work_plan " f"WHERE scheduled_date > ? AND scheduled_date <= date('now') ", (days, )) row = mycursor.fetchone() all_scheduled_tasks = row[0] mycursor.execute( "SELECT SUM(execution_time) " "FROM work_plan " "WHERE done_date <= DATE('now') AND done_date > ? ", (days, )) rows = mycursor.fetchone() time = rows[0] if time == None: time = "0" else: time = time if all_scheduled_tasks == 0: precent = '0' else: precent = int(done_tasks / all_scheduled_tasks * 100) main_list.add_widget( MDRoundFlatButton(text=str(done_tasks) + "\n\nD O N E\nT A S K S", text_color=get_color_from_hex('#e5e5e5'), pos_hint={ "x": .05, "y": .0 }, size_hint=(0.27, 0.35), font_size=15)) main_list.add_widget( MDRoundFlatButton(text=str(precent) + "%\n\nD O N E\nT A S K S", text_color=get_color_from_hex('#e5e5e5'), md_bg_color=get_color_from_hex('#333333'), pos_hint={ "x": .365, "y": 0 }, size_hint=(0.27, 0.35), font_size=15)) main_list.add_widget( MDRoundFlatButton(text=str(time) + "\nminutes\n\nW O R K\nT I M E", text_color=get_color_from_hex('#e5e5e5'), pos_hint={ "x": .68, "y": 0 }, size_hint=(0.27, 0.35), font_size=15))
def day_progress(self): mycursor = main.sqliteConnection.cursor() mycursor.execute( "SELECT count(id_task) " "FROM work_plan " "WHERE scheduled_date = date('now') AND done_date IS NULL ") rows = mycursor.fetchone() count_of_types = str(rows[0]) self.ids.today_stats.add_widget( MDRoundFlatButton(text=count_of_types + "\n\nT O - D O\nT A S K S", text_color=get_color_from_hex('#e5e5e5'), pos_hint={ "x": .05, "y": .0 }, size_hint=(0.27, 0.35), font_size=15)) mycursor.execute( "SELECT count(id_task) " "FROM work_plan " "WHERE done_date IS NOT NULL AND scheduled_date = date('now') ") rows = mycursor.fetchone() done_tasks_today = int(rows[0]) mycursor.execute("SELECT count(id_task) " "FROM work_plan " "WHERE scheduled_date = date('now') ") rows = mycursor.fetchone() all_task_today = int(rows[0]) if all_task_today == 0: precent = 0 else: precent = int(done_tasks_today / all_task_today * 100) self.ids.today_stats.add_widget( MDRoundFlatButton(text=str(precent) + "%\n\nD O N E\nT A S K S", text_color=get_color_from_hex('#e5e5e5'), md_bg_color=get_color_from_hex('#333333'), pos_hint={ "x": .365, "y": 0 }, size_hint=(0.27, 0.35), font_size=15)) mycursor.execute( "SELECT count(id_task) " "FROM work_plan " "WHERE done_date IS NOT NULL AND scheduled_date = date('now') ") rows = mycursor.fetchone() done_tasks = int(rows[0]) self.ids.today_stats.add_widget( MDRoundFlatButton(text=str(done_tasks) + "\n\nD O N E\nT A S K S", text_color=get_color_from_hex('#e5e5e5'), md_bg_color=get_color_from_hex('#333333'), pos_hint={ "x": .68, "y": 0 }, size_hint=(0.27, 0.35), font_size=15))
def __init__(self, order, *args, **kwargs): super().__init__(*args, **kwargs) self.title = f"Order {str(order.order_number)}" self.order = order app = MDApp.get_running_app() scroll = ScrollView() layout = BoxLayout() layout.orientation = "vertical" b_layout = GridLayout() b_layout.cols = 3 b_layout.padding = 10 layout.add_widget(Label(text=f"Customer: {order.customer}")) layout.add_widget(Label(text=f"Email: {order.email}")) layout.add_widget(Label(text=f"Products: ")) for i in order.product: label = MDRoundFlatButton(text=i) label.pos_hint = {"center_x": .5, "center_y": .5} label.text_color = app.theme_cls.accent_color b_layout.add_widget(label) layout.add_widget(b_layout) layout.add_widget( Label(text=f"Material Cost: £{round(order.products_cost, 2)}")) layout.add_widget(Label(text=f"Customer Cost: {order.customer_price}")) layout.add_widget(Label(text=f"Markup %: {order.markup}")) layout.add_widget(Label(text=f"Order Date: {order.order_date}")) layout.add_widget( Label(text=f"Quoted Lead Time: {str(order.leadtime)}")) layout.add_widget(Label(text=f"Origin: {order.origin}")) """ PAYMENT """ payment_layout = BoxLayout() payment_layout.add_widget(Label(text=f"Payment: ")) self.payment_btn = MDRectangleFlatButton(text=self.order.payment) self.payment_menu = MDDropdownMenu(items=self.build_paymentEntrys(app), width_mult=4, caller=self.payment_btn, callback=self.payment_callback) self.payment_btn.on_release = self.payment_menu.open payment_layout.add_widget(self.payment_btn) layout.add_widget(payment_layout) """ STATUS """ status_layout = BoxLayout() status_layout.add_widget(Label(text=f"Status: ")) self.status_btn = MDRectangleFlatButton(text=self.order.status) self.status_menu = MDDropdownMenu(items=self.build_statusEntrys(app), width_mult=4, caller=self.status_btn, callback=self.status_callback) self.status_btn.on_release = self.status_menu.open status_layout.add_widget(self.status_btn) layout.add_widget(status_layout) """ DELIVERY """ delivery_layout = BoxLayout() delivery_layout.add_widget(Label(text="Delivery Method: ")) self.delivery_btn = MDRectangleFlatButton(text=self.order.delivery) self.delivery_menu = MDDropdownMenu( items=self.build_deliveryEntrys(app), width_mult=4, caller=self.delivery_btn, callback=self.delivery_callback) self.delivery_btn.on_release = self.delivery_menu.open delivery_layout.add_widget(self.delivery_btn) layout.add_widget(delivery_layout) buttonlayout = BoxLayout() buttonlayout.orientation = "horizontal" buttonlayout.add_widget( MDRectangleFlatButton(text="Return", on_release=self.dismiss)) buttonlayout.add_widget( MDRectangleFlatButton(text="Cancel Order", on_release=self.cancelOrder)) layout.add_widget(buttonlayout) scroll.add_widget(layout) self.content = scroll
def gotoTableView(self, stream, parent='', search=''): "Data records can be attatched to a post." self.currentPageNewRecordHandler = None self.streamEditPanel.clear_widgets() s = daemonconfig.userDatabases[stream] parentDoc = daemonconfig.userDatabases[stream].getDocumentByID( parent, allowOrphans=True) if not parentDoc: logging.error("nonexistent parent document") return themeColor = getColor(parentDoc) self.streamEditPanel.add_widget(self.makeBackButton()) postWidget = self.makePostWidget(stream, parentDoc, indexAssumption=False) self.streamEditPanel.add_widget(postWidget) t = (MDToolbar(title="Data Table View")) if themeColor: t.md_bg_color = themeColor t.specific_text_color = getFGForColor(themeColor) self.streamEditPanel.add_widget(t) topbar = BoxLayout(orientation="horizontal", spacing=10, adaptive_height=True) searchBar = BoxLayout(orientation="horizontal", spacing=10, adaptive_height=True) searchQuery = MDTextField(size_hint=(0.68, None), multiline=False, text=search) searchButton = MDRoundFlatButton(text="Search") searchBar.add_widget(searchQuery) searchBar.add_widget(searchButton) def doSearch(*a): self.currentPageNewRecordHandler = None self.gotoTableView(stream, parent, searchQuery.text.strip()) searchButton.bind(on_release=doSearch) def goHere(): self.currentPageNewRecordHandler = None self.gotoTableView(stream, parent, search) self.backStack.append(goHere) self.backStack = self.backStack[-50:] newEntryBar = BoxLayout(orientation="horizontal", spacing=10, adaptive_height=True) newRowName = MDTextField(size_hint=(0.68, None), multiline=False, text=search) def write(*a): for i in newRowName.text: if i in "[]{}:,./\\": return if newRowName.text.strip(): id = uuid.uuid5( uuid.UUID(parent), newRowName.text.strip().lower().replace(' ', "")) #That name already exists, jump to it if daemonconfig.userDatabases[stream].getDocumentByID( id, allowOrphans=True): self.currentPageNewRecordHandler = None self.gotoStreamRow(stream, id) return else: id = str(uuid.uuid4()) x = daemonconfig.userDatabases[stream].getDocumentsByType( "row.template", parent=parent, limit=1, allowOrphans=True) newDoc = { 'parent': parent, 'id': id, 'name': newRowName.text.strip() or id, 'type': 'row', 'leafNode': True } #Use the previously created or modified row as the template for i in x: for j in i: if j.startswith('row.'): newDoc[j] = '' self.currentPageNewRecordHandler = None self.gotoStreamRow(stream, id, newDoc) btn1 = Button(text='New Entry') btn1.bind(on_press=write) newEntryBar.add_widget(newRowName) newEntryBar.add_widget(btn1) if s.writePassword: topbar.add_widget(newEntryBar) self.streamEditPanel.add_widget(topbar) if not search: p = s.getDocumentsByType("row", limit=1000, parent=parent, allowOrphans=True) else: p = s.searchDocuments(search, "row", limit=1000, parent=parent) t = MDToolbar(title="Data Rows") if themeColor: t.md_bg_color = themeColor t.specific_text_color = getFGForColor(themeColor) self.streamEditPanel.add_widget(t) self.streamEditPanel.add_widget(searchBar) for i in p: self.streamEditPanel.add_widget(self.makeRowWidget(stream, i)) self.screenManager.current = "EditStream" def onNewRecord(db, r, sig): if db is daemonconfig.userDatabases[stream]: if r.get('parent', '') == parentDoc.get( 'parent', '') and r['type'] == "post": if not self.unsavedDataCallback: self.gotoStreamPost(stream, postID, noBack=True) elif parentDoc['id'] in r.get("parent", ''): postWidget.body.text = renderPostTemplate( daemonconfig.userDatabases[stream], parentDoc['id'], parentDoc.get("body", ''))[0] self.currentPageNewRecordHandler = onNewRecord
def gotoStreamRow(self, stream, postID, document=None, noBack=False, template=None): "Editor/viewer for ONE specific row" self.streamEditPanel.clear_widgets() self.streamEditPanel.add_widget( MDToolbar(title="Table Row in " + stream)) self.streamEditPanel.add_widget(self.makeBackButton()) if not noBack: def goHere(): self.gotoStreamRow(stream, postID) self.backStack.append(goHere) self.backStack = self.backStack[-50:] document = document or daemonconfig.userDatabases[ stream].getDocumentByID(postID, allowOrphans=True) if 'type' in document and not document['type'] == 'row': raise RuntimeError("Document is not a row") document['type'] = 'row' title = Label(text=document.get("name", ''), font_size='22sp') #Our default template if none exists #Give it a name because eventually we may want to have multiple templates. #Give it an ID so it can override any existing children of that template. #Use only the direct ID of the parent record in cade we want to move it eventually. oldTemplate = { 'type': "row.template", 'leafNode': True, 'parent': document['parent'], 'name': 'default', 'id': uuid.uuid5(uuid.UUID(document['parent'].split("/")[-1]), ".rowtemplate.default") } for i in daemonconfig.userDatabases[stream].getDocumentsByType( "row.template", parent=document['parent'], limit=1, allowOrphans=True): oldTemplate = i template = template or oldTemplate def post(*a): with daemonconfig.userDatabases[stream]: #Make sure system knows this is not an old document try: del document['time'] except: pass daemonconfig.userDatabases[stream].setDocument(document) #If the template has changed, that is how we know we need to save template changes at the same time as data changes if not template.get('time', 0) == oldTemplate.get('time', 1): daemonconfig.userDatabases[stream].setDocument(template) daemonconfig.userDatabases[stream].commit() self.unsavedDataCallback = None self.goBack() btn1 = Button(text='Save Changes') btn1.bind(on_release=post) self.streamEditPanel.add_widget(title) buttons = BoxLayout(orientation="horizontal", spacing=10, adaptive_height=True) if daemonconfig.userDatabases[stream].writePassword: self.streamEditPanel.add_widget(buttons) buttons.add_widget(btn1) def delete(*a): def reallyDelete(v): if v == postID: with daemonconfig.userDatabases[stream]: daemonconfig.userDatabases[stream].setDocument({ 'type': 'null', 'id': postID }) daemonconfig.userDatabases[stream].commit() self.gotoStreamPosts(stream) self.askQuestion("Delete table row permanently on all nodes?", postID, reallyDelete) btn1 = Button(text='Delete') btn1.bind(on_release=delete) if daemonconfig.userDatabases[stream].writePassword: buttons.add_widget(btn1) names = {} self.streamEditPanel.add_widget(MDToolbar(title="Data Columns:")) for i in template: if i.startswith('row.'): names[i] = '' for i in document: if i.startswith('row.'): if i in template: names[i] = '' else: #In the document but not the template, it is an old/obsolete column, show that to user. names[i] = '(removed)' for i in names: self.streamEditPanel.add_widget(Button(text=i[4:])) d = document.get(i, '') try: d = float(d) except: pass x = MDTextField(text=str(d) + names[i], mode='fill', multiline=False, font_size='22sp') def oc(*a, i=i, x=x): d = x.text.strip() if isinstance(d, str): d = d.strip() try: d = float(d or 0) except: pass document[i] = d x.bind(text=oc) self.streamEditPanel.add_widget(x) if isinstance(d, float) or not d.strip(): l = BoxLayout(orientation="horizontal", spacing=10, adaptive_height=True) b = MDRoundFlatButton(text="--") def f(*a, i=i, x=x): d = document.get(i, '') if isinstance(d, str): d = d.strip() try: d = float(d or 0) except: return document[i] = d - 1 x.text = str(d - 1) b.bind(on_release=f) b2 = MDRoundFlatButton(text="++") def f(*a, i=i, x=x): d = document.get(i, '') if isinstance(d, str): d = d.strip() try: d = float(d or 0) except: return document[i] = d + 1 x.text = str(document[i]) b2.bind(on_release=f) l.add_widget(b) l.add_widget(b2) self.streamEditPanel.add_widget(l) b = MDRoundFlatButton(text="Add Column") def f(*a): def f2(r): if r: template['row.' + r] = '' #Remove time field which marks it as a new record that will get a new timestamp rather than #being ignored when we go to save it, for being old. template.pop('time', None) #Redraw the whole page, it is lightweight, no DB operation needed. self.gotoStreamRow(stream, postID, document=document, noBack=True, template=template) self.askQuestion("Name of new column?", cb=f2) b.bind(on_release=f) self.streamEditPanel.add_widget(b) b = MDRoundFlatButton(text="Del Column") def f(*a): def f2(r): if r: try: del template['row.' + r] template.pop('time', None) except: pass #Redraw the whole page, it is lightweight, no DB operation needed. self.gotoStreamRow(stream, postID, document=document, noBack=True, template=template) self.askQuestion("Column to delete?", cb=f2) b.bind(on_release=f) self.streamEditPanel.add_widget(b) self.screenManager.current = "EditStream"