class Umowa(Window): '''frame = entry frame''' def dod_butt(self): self.top = tk.Toplevel() self.top.title('Dodatkowi odbiorcy') self.top.grab_set() # Dodatkowe adresy adresy_frame = tk.Frame(self.top) adresy_frame.pack() self.adres1 = tk.Entry(adresy_frame, width=entry_width, borderwidth=brwid, font=font9) self.adres1.pack(pady=5) self.adres1.insert(tk.END, mailsender.dod_odbiorcy[0]) self.adres2 = tk.Entry(adresy_frame, width=entry_width, borderwidth=brwid, font=font9) self.adres2.pack(pady=5) self.adres2.insert(tk.END, mailsender.dod_odbiorcy[1]) self.adres3 = tk.Entry(adresy_frame, width=entry_width, borderwidth=brwid, font=font9) self.adres3.pack(pady=5) self.adres3.insert(tk.END, mailsender.dod_odbiorcy[2]) ok_butt = tk.Button(self.top, text='Zapisz', font=font10, width=15, command=lambda: self.wez_adresy()) ok_butt.pack() self.center(self.top, False) def wez_adresy(self): '''Pobiera adresy z entry''' mailsender.dod_odbiorcy = [ self.adres1.get().strip(), self.adres2.get().strip(), self.adres3.get().strip() ] self.top.destroy() def zmienvar(self): if self.spr_nierozw_var == 0: self.spr_nierozw_var == 1 else: self.spr_nierozw_var == 0 def zal_butt(self): '''Dodawanie załącznika.''' # Musi być osobna zmienna, problem z cancel przy wybieraniu zalacznika zalacznik = askopenfilename() if zalacznik != '' and zalacznik != (): mailsender.zalacznik = zalacznik self.zal_label.configure(text=mailsender.zalacznik.split(r'/')[-1], fg='green') def ukryj(self, entry, var): '''Funkcja blokowania entry adresów.''' if self.rej_var.get() != 1 and\ self.kor_var.get() != 1 and\ self.dost_var.get() != 1: self.adr_1_entry.config(state='disabled') if self.rej_var.get() != 2 and\ self.kor_var.get() != 2 and\ self.dost_var.get() != 2: self.adr_2_entry.config(state='disabled') if self.rej_var.get() != 3 and\ self.kor_var.get() != 3 and\ self.dost_var.get() != 3: self.adr_3_entry.config(state='disabled') if entry is not None and var is not None: if var.get(): entry.config(state='normal') else: entry.config(state='disabled') def widgets(self): '''Widgety.''' self.hidden = False page_frame = tk.Frame(self.root) left_frame = tk.Frame(page_frame) right_frame = tk.Frame(page_frame) # menu_frame = tk.Frame(page_frame) menu_frame = tk.Frame(page_frame) # W Menu frame rozne_frame = tk.Frame(menu_frame) # MENU FRAME (po prawej stronie) img = ImageTk.PhotoImage(img_resizer(goldwin, 0.45)) img_Label = tk.Label(menu_frame, image=img) img_Label.image = img img_Label.pack() zalog_label = tk.Label(menu_frame, text='Zalogowano jako:') zalog_label.pack() kons_label = tk.Label(menu_frame, text=konsultant.kto, font=font10, fg='green') kons_label.pack() menu_button = tk.Button(menu_frame, text='MENU', font=font10, width=12, padx=10, command=lambda: self.menu_butt()) menu_button.pack(pady=(10, 0)) dod_adresy_button = tk.Button(menu_frame, text='Dodaj odbiorce', font=font10, width=12, padx=10, command=lambda: self.dod_butt()) dod_adresy_button.pack() # Sprawy nierozwiązane self.spr_nierozw_var = tk.IntVar(value=0) self.spr_nierozw_cb = tk.Checkbutton(rozne_frame, text='Sprawy\nnierozwiązane', variable=self.spr_nierozw_var, font=font10, command=lambda: self.zmienvar()) self.spr_nierozw_cb.pack() # MID FRAME # img = tk.PhotoImage(file=goldwin) # img_Label = tk.Label(right_frame, image=img) # img_Label.image = img # img_Label.place(relx=.5, rely=.5, anchor='c') # LEFT FRAME # Imie i nazwisko imie = tk.Label(left_frame, text='Imię i nazwisko:', font=font10b) imie.grid(row=0, column=0) self.imie_entry = tk.Entry(left_frame, width=entry_width, borderwidth=brwid, font=font9) self.imie_entry.grid(row=0, column=1) self.imie_entry.bind_class('Entry', '<Button-3><ButtonRelease-3>', self.show_menu) # Numer telefonu tel = tk.Label(left_frame, text='Numer telefonu:', font=font10b) tel.grid(row=10, column=0) self.tel_entry = tk.Entry(left_frame, width=entry_width, borderwidth=brwid, font=font9) self.tel_entry.grid(row=10, column=1) # Data sprzedaży sprz = tk.Label(left_frame, text='Data sprzedaży:', font=font10b) sprz.grid(row=20, column=0) self.sprz_entry = tk.Entry(left_frame, width=entry_width, borderwidth=brwid, font=font9) self.sprz_entry.insert(0, stworz_date('dzis')) self.sprz_entry.grid(row=20, column=1) # Date dostarczenia dost = tk.Label(left_frame, text='Data dostarczenia:', font=font10b) dost.grid(row=30, column=0) self.dost_entry = tk.Entry(left_frame, width=entry_width, borderwidth=brwid, font=font9) self.dost_entry.grid(row=30, column=1) # Cena cena = tk.Label(left_frame, text='Cena/długość:', font=font10b) cena.grid(row=40, column=0) self.cena_entry = tk.Entry(left_frame, width=entry_width, borderwidth=brwid, font=font9) self.cena_entry.grid(row=40, column=1) # Adres mailowy mail = tk.Label(left_frame, text='Adres mailowy', font=font10b) mail.grid(row=50, column=0) self.mail_entry = tk.Entry(left_frame, width=entry_width, borderwidth=brwid, font=font9) self.mail_entry.grid(row=50, column=1) # Spacer spacer = tk.Label(left_frame) spacer.grid(row=60, column=0) # Adresy # Frame dla radiobuttonow adresy_frame = tk.Frame(left_frame) adresy_frame.grid(row=62, column=0, rowspan=5, columnspan=2) # rkd labele r_label = tk.Label(adresy_frame, text='rej', font=font10b) r_label.grid(row=0, column=1, pady=10) k_label = tk.Label(adresy_frame, text='kor', font=font10b) k_label.grid(row=0, column=2) d_label = tk.Label(adresy_frame, text='dost', font=font10b) d_label.grid(row=0, column=3) # vary self.rej_var = tk.IntVar(value=0) self.kor_var = tk.IntVar(value=0) self.dost_var = tk.IntVar(value=0) # RADIO BUTTONY # REJESTROWY # Ceidg REJESTROWY ceidg_rej_rb = tk.Radiobutton(adresy_frame, variable=self.rej_var, value=0, command=lambda: self.ukryj(None, None)) ceidg_rej_rb.grid(row=1, column=1) # Adr1 REJESTROWY adr1_rej_rb = tk.Radiobutton( adresy_frame, variable=self.rej_var, value=1, command=lambda: self.ukryj(self.adr_1_entry, self.rej_var)) adr1_rej_rb.grid(row=2, column=1) # Adr2 REJESTROWY adr2_rej_rb = tk.Radiobutton( adresy_frame, variable=self.rej_var, value=2, command=lambda: self.ukryj(self.adr_2_entry, self.rej_var)) adr2_rej_rb.grid(row=3, column=1) # Adr3 REJESTROWY adr3_rej_rb = tk.Radiobutton( adresy_frame, variable=self.rej_var, value=3, command=lambda: self.ukryj(self.adr_3_entry, self.rej_var)) adr3_rej_rb.grid(row=4, column=1) # KORESPONDENCJI # Ceidg KORESPONDENCJI ceidg_kor_rb = tk.Radiobutton(adresy_frame, variable=self.kor_var, value=0, command=lambda: self.ukryj(None, None)) ceidg_kor_rb.grid(row=1, column=2) # Adr1 KORESPONDENCJI adr1_kor_rb = tk.Radiobutton( adresy_frame, variable=self.kor_var, value=1, command=lambda: self.ukryj(self.adr_1_entry, self.kor_var)) adr1_kor_rb.grid(row=2, column=2) # Adr2 KORESPONDENCJI adr2_kor_rb = tk.Radiobutton( adresy_frame, variable=self.kor_var, value=2, command=lambda: self.ukryj(self.adr_2_entry, self.kor_var)) adr2_kor_rb.grid(row=3, column=2) # Adr3 KORESPONDENCJI adr3_kor_rb = tk.Radiobutton( adresy_frame, variable=self.kor_var, value=3, command=lambda: self.ukryj(self.adr_3_entry, self.kor_var)) adr3_kor_rb.grid(row=4, column=2) # DOSTARCZENIA # Ceidg DOSTARCZENIA ceidg_dost_rb = tk.Radiobutton(adresy_frame, variable=self.dost_var, value=0, command=lambda: self.ukryj(None, None)) ceidg_dost_rb.grid(row=1, column=3) # Adr1 DOSTARCZENIA adr1_dost_rb = tk.Radiobutton( adresy_frame, variable=self.dost_var, value=1, command=lambda: self.ukryj(self.adr_1_entry, self.dost_var)) adr1_dost_rb.grid(row=2, column=3) # Adr2 DOSTARCZENIA adr2_dost_rb = tk.Radiobutton( adresy_frame, variable=self.dost_var, value=2, command=lambda: self.ukryj(self.adr_2_entry, self.dost_var)) adr2_dost_rb.grid(row=3, column=3) # Adr3 DOSTARCZENIA adr3_dost_rb = tk.Radiobutton( adresy_frame, variable=self.dost_var, value=3, command=lambda: self.ukryj(self.adr_3_entry, self.dost_var)) adr3_dost_rb.grid(row=4, column=3) # Zaznacz wszystko CEIDG ceidg_rej_rb.select() ceidg_kor_rb.select() ceidg_dost_rb.select() # Adresy entry # CEIDG ceidg_label = tk.Label(adresy_frame, text='Adres taki sam jak rejestrowy w CEIDG', font=font10b) ceidg_label.grid(row=1, column=0, padx=(0, 20), pady=7) # Adres 1 self.adr_1_entry = tk.Entry(adresy_frame, width=entry_width, state='disabled', disabledbackground='#C0C0C0', borderwidth=brwid, font=font9) self.adr_1_entry.grid(row=2, column=0, pady=7) # Adres 2 self.adr_2_entry = tk.Entry(adresy_frame, width=entry_width, state='disabled', disabledbackground='#C0C0C0', borderwidth=brwid, font=font9) self.adr_2_entry.grid(row=3, column=0, pady=7) # Adres 3 self.adr_3_entry = tk.Entry(adresy_frame, width=entry_width, state='disabled', disabledbackground='#C0C0C0', borderwidth=brwid, font=font9) self.adr_3_entry.grid(row=4, column=0, pady=7) # Spacer spacer = tk.Label(left_frame) spacer.grid(row=100, column=0) # Branża branza = tk.Label(left_frame, text='Branża:', font=font10b) branza.grid(row=0, column=2, padx=(20, 10)) self.branza_entry = tk.Entry(left_frame, width=entry_width, borderwidth=brwid, font=font9) self.branza_entry.grid(row=0, column=3) # Pytania do prawnika pytania = tk.Label(left_frame, text='Pytania:', font=font10b) pytania.grid(row=10, column=2, padx=(20, 10)) self.pytania_entry = tk.Entry(left_frame, width=entry_width, borderwidth=brwid, font=font9) self.pytania_entry.grid(row=10, column=3) # Dodatkowe informacje dodatkowe = tk.Label(left_frame, text='Dodatkowe\ninformacje:', font=font10b) dodatkowe.grid(row=20, column=2, padx=(20, 10), rowspan=30) self.dodatkowe_entry = ScrolledText(left_frame, width=entry_width - 2, height=5, borderwidth=brwid, font=font9) self.dodatkowe_entry.grid(row=20, column=3, rowspan=30) self.dodatkowe_entry.bind_class('Text', '<Button-3><ButtonRelease-3>', self.show_menu) # Spacer spacer = tk.Label(left_frame) spacer.grid(row=140, column=0) # Załącznik zalacznik = tk.Button(left_frame, text='Załącznik', font=font10, width=12, padx=10, command=lambda: self.zal_butt()) zalacznik.grid(row=150, column=0) self.zal_label = tk.Label(left_frame, text='', font=font10b) self.zal_label.grid(row=151, column=0) # Wyślij wyslij = tk.Button(left_frame, text='Wyślij', font=font10, width=12, padx=10, command=lambda: self.wyslij_butt()) wyslij.grid(row=150, column=1) rozne_frame.pack(side=tk.BOTTOM, pady=(0, 10)) left_frame.pack(fill=tk.BOTH, expand=True, side=tk.LEFT, padx=(0, 20)) right_frame.pack(fill=tk.BOTH, expand=True, side=tk.LEFT) menu_frame.pack(fill=tk.BOTH, expand=True, padx=(0, 20)) page_frame.pack(fill=tk.BOTH, expand=True, pady=10, padx=10)
class GroceryProgram: def __init__(self, master, email_config: EmailAccessBase = None, wunderpy_config: WunderpyAccessBase = None, inital_grocery_content: str = ''): self.inital_menu_content = inital_grocery_content self.wunderpy_config = wunderpy_config self.email_config = email_config self.master = master self.master.wm_title('Grocery shopping') self.master.geometry('1000x500') self.current_menu = None # Grid definition: tk.Grid.rowconfigure(self.master, 0, weight=1) tk.Grid.columnconfigure(self.master, 0, weight=1) frame = tk.Frame(self.master) frame.grid(row=0, column=0, sticky=tk.N + tk.S + tk.E + tk.W) grid = tk.Frame(frame) grid.grid(sticky=tk.N + tk.S + tk.E + tk.W, column=0, row=0) tk.Grid.rowconfigure(frame, 0, weight=1) tk.Grid.columnconfigure(frame, 0, weight=1) ## Grocery list self.grocery_list = ScrolledText(frame, undo=True) self.grocery_list.grid(rowspan=2, columnspan=1, row=0, column=0, sticky=tk.N + tk.S + tk.E + tk.W, padx=10, pady=10) # Set callback on all key presses: bindtags = list(self.grocery_list.bindtags()) bindtags.insert(2, "custom") # index 1 is where most default bindings live self.grocery_list.bindtags(tuple(bindtags)) self.grocery_list.bind_class("custom", "<Key>", self.callback_any_key_grocery_list) self.grocery_list.bind('<Control-Return>', self.callback_controll_return_grocery_list) self.grocery_list.bind('<Control-BackSpace>', self.callback_get_recipe_from_parsed) # self.grocery_list.bind('<Key>', self.callback_parse_grocery_list) # set initial grocery_list: self.grocery_list.insert(tk.INSERT, inital_grocery_content) ## Menu list self.menu_box = ScrolledText(frame, undo=True) self.menu_box.grid(rowspan=2, columnspan=3, row=0, column=1, sticky=tk.N + tk.S + tk.E + tk.W, padx=10, pady=10) ## View menu self.view_menu_button = tk.Button(frame, text='View menu', command=self.callback_view_menu) self.view_menu_button.grid(rowspan=1, columnspan=1, row=2, column=0, sticky=tk.N + tk.S + tk.E + tk.W, padx=10, pady=10) ## View grocery list self.view_grocery_list = tk.Button(frame, text='View grocery list', command=self.callback_view_grocery_list) self.view_grocery_list.grid(rowspan=1, columnspan=1, row=3, column=0, sticky=tk.N + tk.S + tk.E + tk.W, padx=10, pady=10) ## View categories self.categories_button = tk.Button(frame, text='View categories', command=self.calback_show_categories_list) self.categories_button.grid(rowspan=1, columnspan=1, row=2, column=1, sticky=tk.N + tk.S + tk.E + tk.W, padx=10, pady=10) ## Commands self.command_text = tk.Label(frame, text='Ctrl+Enter: Reroll recipe suggestion.\nCtrl+Backspace: Lock suggestion.') self.command_text.grid(rowspan=1, columnspan=1, row=3, column=1, sticky=tk.N + tk.S + tk.E + tk.W, padx=10, pady=10) ## Email recipients self.email_target_entry = tk.Entry(frame) self.email_target_entry.grid(rowspan=1, columnspan=1, row=2, column=2, sticky=tk.N + tk.S + tk.E + tk.W, padx=10, pady=10) if self.email_config: self.email_target_entry.insert(tk.INSERT, ', '.join(self.email_config.recipients)) ## Send email_sender button self.email_button = tk.Button(frame, text='Send menu to email_sender', command=self.callback_send_menu_to_email) self.email_button.grid(rowspan=1, columnspan=1, row=2, column=3, sticky=tk.N + tk.S + tk.E + tk.W, padx=10, pady=10) if not self.email_config: self.email_button['state'] = tk.DISABLED ## Wunderlist target entry self.wunderlist_target_entry = tk.Entry(frame) self.wunderlist_target_entry.grid(rowspan=1, columnspan=1, row=3, column=2, sticky=tk.N + tk.S + tk.E + tk.W, padx=10, pady=10) if self.wunderpy_config: self.wunderlist_target_entry.insert(tk.INSERT, self.wunderpy_config.default_list) ## Send to wunderlist button: self.send_to_wunderlist_button = tk.Button(frame, text='Send groceries to Wunderlist', command=self.callback_send_to_wunderlist_button) self.send_to_wunderlist_button.grid(rowspan=1, columnspan=1, row=3, column=3, sticky=tk.N + tk.S + tk.E + tk.W, padx=10, pady=10) if not self.wunderpy_config: self.send_to_wunderlist_button['state'] = tk.DISABLED rows = range(3) columns = [] for row in rows: tk.Grid.rowconfigure(frame, row, weight=1) for column in columns: tk.Grid.columnconfigure(frame, column, weight=1) self.parse_grocery_list() def callback_get_recipe_from_parsed(self, event): cursor_position = self.grocery_list.index(tk.INSERT) row = int(cursor_position.split('.')[0]) corresponding_line = self.menu_box.get(1.0, tk.END).split('\n')[row - 1] all_lines = self.grocery_list.get(1.0, tk.END).split('\n') # Swap line: all_lines[row - 1] = corresponding_line self.grocery_list.delete(1.0, tk.END) self.grocery_list.insert(tk.INSERT, '\n'.join(all_lines)) self.grocery_list.mark_set(tk.INSERT, cursor_position) print("I've hit control+backspace at row {0} and column {1}".format( *self.grocery_list.index(tk.INSERT).split('.'))) return 'break' def callback_send_menu_to_email(self): print('send menu by email_sender button') sender = 'GroceryProgram' recipients = self.email_target_entry.get().split(', ') text = html.escape(self.current_menu.generate_menu_str(), quote=True) template = '<html><pre><font face="Courier New, Courier, monospace">%s</font></pre></html>' % text template = template.replace('\n', '<br />') send_email(self.email_config, 'Week menu', recipients, template) print('email_sender ok') def callback_send_to_wunderlist_button(self): print('send to wunderlist button') target_list = self.wunderlist_target_entry.get() # Create a list of {item, description} for all groceries processed_groceries = [] for grocery in self.current_menu.groceries.components(): item = '' if grocery['amount']: item += grocery['amount'] + ' ' item += grocery['name'] descriptions = [] for source_dict in grocery['components']: source = '' source_name = '' if source_dict['amount']: source_name += source_dict['amount'] + ' ' source_name += source_dict['name'] source += source_name if source_dict['comments']: comments = '(' + ', '.join(source_dict['comments']) + ')' source += comments + ' ' if source_dict['recipe']: recipe = ' til %s' % source_dict['recipe'] if not source_dict['recipe'] == config.language.no_recipe_name: if source_dict['recipe_multiplier'] == 1: recipe += ' for %d pers' % source_dict['recipe_made_for'] else: recipe += ' x%f' % source_dict['recipe_multiplier'] source += recipe descriptions += [source] processed_groceries += [{'item': item, 'description': ', '.join(descriptions)}] response = add_groceries_to_wunderlist(self.wunderpy_config, target_list_name=target_list, groceries=processed_groceries) print(response) def callback_controll_return_grocery_list(self, event): self.parse_grocery_list(smart=False) return 'break' def callback_any_key_grocery_list(self, event): self.parse_grocery_list() def callback_button_parse_grocery_list(self): self.parse_grocery_list(smart=False) def parse_grocery_list(self, smart=True): print('callback works') text = self.grocery_list.get(1.0, tk.END) self.menu_box.delete(1.0, tk.END) if text.strip() == 'tags': string = '\n'.join([tag for tag in COOKBOOK.available_tags.keys()]) self.menu_box.insert(tk.INSERT, string) if text.strip() == 'recipes': string = '\n'.join(COOKBOOK.available_recipes) self.menu_box.insert(tk.INSERT, string) else: # Intelligent update: Only update the lines that have changed. if not self.current_menu or not smart: self.current_menu = COOKBOOK.parse_menu(self.grocery_list.get(1.0, tk.END)) else: new_menu = COOKBOOK.parse_menu(self.grocery_list.get(1.0, tk.END)) for index, line in enumerate(new_menu.input_lines): if line in self.current_menu.input_lines: current_index = self.current_menu.input_lines.index(line) new_menu.input_lines[index] = self.current_menu.input_lines[current_index] new_menu.processed_lines[index] = self.current_menu.processed_lines[current_index] new_menu.input_plan = '\n'.join(new_menu.input_lines) new_menu.processed_plan = new_menu.create_output_lines(new_menu.processed_lines) self.current_menu = new_menu self.current_menu.process_input() self.menu_box.insert(tk.INSERT, self.current_menu.processed_plan) def callback_view_menu(self): """Callback for the send menu as email_sender button.""" print('callback_send_menu_email') if isinstance(self.current_menu, Menu): self.menu_box.delete(1.0, tk.END) self.menu_box.insert(tk.INSERT, '\n'+self.current_menu.generate_menu_str()) else: print('No menu to view') def callback_view_grocery_list(self): """Callback for the send menu as email_sender button.""" print('callback_view_grocery_list') if isinstance(self.current_menu, Menu): self.menu_box.delete(1.0, tk.END) string = '\n'.join(self.current_menu.groceries.ingredients_formatted(pretty=True, sort='alphabetical')) self.menu_box.insert(tk.INSERT, string) else: print('No menu to view') def calback_show_categories_list(self): self.menu_box.delete(1.0, tk.END) string = '\n'.join(sorted(COOKBOOK.tags)) self.menu_box.insert(tk.INSERT, string)