class TopErrorWindow(Toplevel): def __init__(self, title, message, detail): Toplevel.__init__(self) self.details_expanded = False self.title(title) self.geometry('380x95') self.minsize(380, 95) self.maxsize(425, 250) self.rowconfigure(0, weight=0) self.rowconfigure(1, weight=1) self.columnconfigure(0, weight=1) button_frame = Frame(self) button_frame.grid(row=0, column=0, sticky='nsew') button_frame.columnconfigure(0, weight=1) button_frame.columnconfigure(1, weight=1) text_frame = Frame(self) text_frame.grid(row=1, column=0, padx=(7, 7), pady=(7, 7), sticky='nsew') text_frame.rowconfigure(0, weight=1) text_frame.columnconfigure(0, weight=1) ttk.Label(button_frame, text=message).grid(row=0, column=0, columnspan=2, pady=(7, 7)) ttk.Button(button_frame, text='OK', command=self.destroy).grid(row=1, column=0, sticky='e') ttk.Button(button_frame, text='Details', command=self.toggle_details).grid(row=1, column=1, sticky='w') self.textbox = Text(text_frame, height=6) self.textbox.insert('1.0', detail) self.textbox.config(state='disabled') self.scrollb = Scrollbar(text_frame, command=self.textbox.yview) self.textbox.config(yscrollcommand=self.scrollb.set) def toggle_details(self): if self.details_expanded: self.textbox.grid_forget() self.scrollb.grid_forget() self.geometry('380x95') self.details_expanded = False else: self.textbox.grid(row=0, column=0, sticky='nsew') self.scrollb.grid(row=0, column=1, sticky='nsew') self.geometry('380x160') self.details_expanded = True
class adminPage(Frame): def __init__(self, parent, main, **kw): Frame.__init__(self, parent, **kw) self.main = main self.label_head = Label(text='Admin Page', font=MED_FONT) self.adm_stock_l = Label(text='Stock Name: ') self.adm_stock = StringVar() self.adm_stock_c = Combobox(textvariable=self.adm_stock) self.adm_ncost_l = Label(text='New Cost of Stock: ') self.adm_namount_l = Label(text='New number of stocks added: ') self.adm_namount = Entry() self.adm_ncost = Entry() self.adm_update_b = Button(text='UPDATE', command=self.update) self.back_b = Button(text='Log Out', command=self.back) self.view_f_text = Text(height=20, width=30) self.view_scroll = Scrollbar(orient=VERTICAL, command=self.view_f_text.yview) self.view_f_text.config(yscrollcommand=self.view_scroll.set) self.new_stock = False def back(self): self.main.show_frame(LOGIN_PAGE, ADMIN_PAGE) self.main.login = False self.main.admin = False def showItems(self, main): self.label_head.grid(column=0, row=0, columnspan=3) self.adm_stock_l.grid(column=0, row=1) self.adm_stock_c.grid(column=1, row=1) self.adm_stock_c.config(values=main.shares_dict.keys()) self.adm_ncost_l.grid(column=0, row=2) self.adm_ncost.grid(column=1, row=2) self.adm_namount_l.grid(column=0, row=3) self.adm_namount.grid(column=1, row=3) self.adm_update_b.grid(column=0, row=4) self.back_b.grid(column=1, row=4) self.view_stock() self.view_f_text.grid(column=0, row=5, sticky='nsew', columnspan=2) self.view_scroll.grid(column=2, row=5, sticky='ns') def hideItems(self, main): self.label_head.grid_forget() self.adm_stock_l.grid_forget() self.adm_stock_c.grid_forget() self.adm_ncost_l.grid_forget() self.adm_ncost.grid_forget() self.adm_namount_l.grid_forget() self.adm_namount.grid_forget() self.adm_update_b.grid_forget() self.back_b.grid_forget() self.view_f_text.grid_forget() self.view_scroll.grid_forget() def update(self): stock_name = self.adm_stock.get() ncost = int(self.adm_ncost.get()) namount = self.adm_namount.get() if ncost < 0: showinfo(message='Enter valid cost, Please check data') self.adm_ncost.delete(0, END) elif namount == '': namount = '0' elif int(namount) < 0: showinfo(message='Enter valid amount, Please check data') self.adm_namount.delete(0, END) elif stock_name not in self.main.shares_dict: if not self.new_stock: showinfo( message= 'Are you sure you want to add this new stock \n Check the details once again' ) self.new_stock = True else: self.main.shares_dict[stock_name] = {} self.main.shares_dict[stock_name]['cost'] = str(ncost) self.main.shares_dict[stock_name]['tot_amount'] = namount self.main.shares_dict[stock_name]['name'] = stock_name self.main.shares_dict[stock_name]['tot_sold'] = '0' self.new_stock = False buff = { 'tot_owned': '0', 'name': stock_name, 'money_spent': '0' } for name in self.main.users_dict: self.main.users_dict[name].append(buff) self.adm_namount.delete(0, END) self.adm_ncost.delete(0, END) self.view_stock() self.adm_stock.set('') else: self.main.shares_dict[stock_name]['cost'] = str(ncost) tot_amount = int(self.main.shares_dict[stock_name]['tot_amount']) self.main.shares_dict[stock_name]['tot_amount'] = str(tot_amount + int(namount)) self.adm_namount.delete(0, END) self.adm_ncost.delete(0, END) self.view_stock() def view_stock(self): self.view_f_text.config(state='normal') self.view_f_text.delete('1.0', 'end') key = self.main.shares_dict.keys() for name in key: li = self.main.shares_dict[name] txt_b1 = ' ' * 10 + 'Name: ' self.view_f_text.insert('end', txt_b1) self.view_f_text.insert('end', name + '\n') txt_b2 = ' ' * 10 + 'Cost Price: ' self.view_f_text.insert('end', txt_b2) self.view_f_text.insert('end', li['cost'] + '\n') available_num = int(li['tot_amount']) - int(li['tot_sold']) txt_b3 = ' ' * 10 + 'Available amount: ' self.view_f_text.insert('end', txt_b3) self.view_f_text.insert('end', str(available_num) + '\n') txt_b4 = ' ' * 10 + '*' * 20 self.view_f_text.insert('end', '\n' + txt_b4 + '\n\n') self.view_f_text.config(state='disabled')
class viewStock(Frame): '''The Frame that is kind of a logged in view and contains buttons to move to sell, buy or log out. At the same time it it also shows what stocks one has along with their profit and more''' def __init__(self, parent, main, **kw): Frame.__init__(self, parent, **kw) self.view_f_text = Text(width=30) self.main = main self.view_scroll = Scrollbar(orient = VERTICAL, command=self.view_f_text.yview) self.view_f_text.config(yscrollcommand = self.view_scroll.set) self.label_head = Label(text='Stocks available', font = MED_FONT) self.back_b = Button(text='Login and Buy', command = self.back ) self.buy_b = Button(text='BUY', command = self.buy) self.sell_b = Button(text='SELL', command = self.sell) def buy(self): '''the call back if we click on buy and takes us to the buy window''' self.main.frames[RETAIL_PAGE].page = 'b' self.main.show_frame(RETAIL_PAGE, VIEW_STOCK) def sell(self): '''the call back if we click on sell and it takes us to the sell window''' self.main.frames[RETAIL_PAGE].page = 's' self.main.show_frame(RETAIL_PAGE, VIEW_STOCK) def back(self): '''this is kind of the ''' self.main.show_frame(LOGIN_PAGE, VIEW_STOCK) self.main.login = False self.main.admin = False def showItems(self, main): if main.login: self.back_b.config(text='Log Out') self.label_head.config(text='Logged in as %s'%self.main.present_user) self.buy_b.grid(column=0, row=2, columnspan=2) self.sell_b.grid(column=0, row=3, columnspan=2) else: self.back_b.config(text='Login and Buy') self.label_head.configure(text='View Stock') self.label_head.grid(column=0, row=0, columnspan=2) self.view_f_text.grid(column=0, row=1, sticky='nsew') self.view_scroll.grid(column=2, row=1) self.back_b.grid(column=0, row=4, columnspan=2) self.view_stock() def hideItems(self, main): self.label_head.grid_forget() self.view_f_text.grid_forget() self.view_scroll.grid_forget() self.back_b.grid_forget() if main.login: self.buy_b.grid_forget() self.sell_b.grid_forget() def view_stock(self): self.view_f_text.config(state='normal') self.view_f_text.delete('1.0', 'end') if self.main.login and not self.main.admin: l2 = self.main.accounts[self.main.present_user] txt_1 = 'Balance: ' + l2['balance'] + '\n' + 'Profit: ' + l2['profit'] + '\n'*2 + '*'*20 + '\n' self.view_f_text.insert('end',txt_1) key = self.main.shares_dict.keys() if not self.main.login: for name in key: li = self.main.shares_dict[name] txt_b1 = 'Name: ' self.view_f_text.insert('end',txt_b1) self.view_f_text.insert('end',name+'\n') txt_b2 = 'Cost Price: ' self.view_f_text.insert('end',txt_b2) self.view_f_text.insert('end',li['cost']+'\n') available_num = int(li['tot_amount']) - int(li['tot_sold']) txt_b3 = 'Available amount: ' self.view_f_text.insert('end',txt_b3) self.view_f_text.insert('end',str(available_num)+'\n') txt_b4 = '*'*20 self.view_f_text.insert('end','\n'+txt_b4+'\n\n') self.view_scroll.grid(column=1, row=0, rowspan=2, sticky='nswe') if self.main.login: for name in key: li = self.main.shares_dict[name] txt_b1 = 'Name: ' self.view_f_text.insert('end',txt_b1) self.view_f_text.insert('end',name+'\n') txt_b2 = 'Cost Price: ' self.view_f_text.insert('end',txt_b2) self.view_f_text.insert('end',li['cost']+'\n') available_num = int(li['tot_amount']) - int(li['tot_sold']) txt_b3 = 'Available amount: ' self.view_f_text.insert('end',txt_b3) self.view_f_text.insert('end',str(available_num)+'\n') lis = self.main.p_user_dict for i in lis: if i['name'] == name: lis = i break txt1 = 'Stocks owned: '+lis['tot_owned']+'\n' if not lis['tot_owned'] == '0' else '' self.view_f_text.insert('end', txt1) txt2 = 'Money spent: '+ lis['money_spent']+'\n' if not lis['tot_owned'] == '0' else '' self.view_f_text.insert('end', txt2) txt_b4 = '*'*20 self.view_f_text.insert('end','\n'+txt_b4+'\n\n') self.view_f_text.config(state='disabled') else: self.view_f_text.config(state='disabled')
class Interface(Frame): def __init__(self, master=None, *_): Frame.__init__(self, master) self.master = master # settings variables self.word_wrap = BooleanVar() self.word_wrap.set(True) self.__show_status_bar = BooleanVar() self.__show_status_bar.set(True) self.fnt = font.Font(family="Courier New", size=10) self.find_open = False self.replace_open = False self.goto_open = False self.prior_search = '' self.prior_goto = '' # init methods self.__init_main_window() self.__build_status_bar() self.__build_menu_bar() self.__bind_shortcuts() self.toggle_word_wrap() self.context_menu = Menu(self.master, tearoff=0) self.last_hash = get_signature(self.text_area.get(1.0, END)) def __init_main_window(self): self.text_area = Text(self.master, undo=True) self.text_area.config(font=self.fnt, wrap=WORD) # To add scrollbar self.scroll_bar_x = Scrollbar(self.master, orient=HORIZONTAL) self.scroll_bar_y = Scrollbar(self.master, orient=VERTICAL) __file = None try: self.master.wm_iconbitmap('notepad.ico') except TclError: log.error("unable to set icon to notepad.ico") pass # Set the window text self.master.title('Untitled - Notepad') # To make the text area auto resizable self.master.grid_rowconfigure(0, weight=1) self.master.grid_columnconfigure(0, weight=1) self.text_area.grid(column=0, row=0, sticky='nsew') self.scroll_bar_y.grid(column=1, row=0, sticky='nsew') self.scroll_bar_x.grid(column=0, row=1, stic='nsew') # Scrollbar will adjust automatically according to the content self.scroll_bar_x.config(command=self.text_area.xview) self.scroll_bar_y.config(command=self.text_area.yview) self.text_area.config(xscrollcommand=self.scroll_bar_x.set, yscrollcommand=self.scroll_bar_y.set) self.text_area.focus() def __build_menu_bar(self): # main and submenus self.menu_bar = Menu(self.master) self.file_menu = Menu(self.menu_bar, tearoff=0) self.edit_menu = Menu(self.menu_bar, tearoff=0) self.format_menu = Menu(self.menu_bar, tearoff=0) self.thisViewMenu = Menu(self.menu_bar, tearoff=0) self.help_menu = Menu(self.menu_bar, tearoff=0) # File Menu self.menu_bar.add_cascade(label='File', underline=0, menu=self.file_menu) self.file_menu.add_command(label='New', underline=0, accelerator='Ctrl+N', command=new_file) self.file_menu.add_command(label='Open...', underline=0, accelerator='Ctrl+O', command=open_file) self.file_menu.add_command(label='Save', underline=0, accelerator='Ctrl+S', command=save_file) self.file_menu.add_command(label='Save As...', underline=5, command=save_file_as) self.file_menu.add_separator() self.file_menu.add_command(label='Page Setup...', underline=5, accelerator='Ctrl+S', command=save_file) self.file_menu.add_command(label='Print', underline=0, accelerator='Ctrl+P', command=save_file) self.file_menu.add_separator() self.file_menu.add_command(label='Exit', underline=1, command=self.quit_application) # Edit Menu self.menu_bar.add_cascade(label='Edit', underline=0, menu=self.edit_menu) self.edit_menu.add_command(label='Undo', underline=0, accelerator='Ctrl+Z', command=self.undo) self.edit_menu.add_separator() self.edit_menu.add_command(label='Cut', underline=2, accelerator='Ctrl+X', command=self.cut) self.edit_menu.add_command(label='Copy', underline=0, accelerator='Ctrl+C', command=self.copy) self.edit_menu.add_command(label='Paste', underline=0, accelerator='Ctrl+V', command=self.paste) self.edit_menu.add_command(label='Delete', underline=2, accelerator='Del', command=self.delete) self.edit_menu.add_command(label='Search with Bing... ', underline=0, accelerator='Ctrl+B', command=self.search_selected_text) self.edit_menu.add_separator() self.edit_menu.add_command(label='Find...', underline=0, accelerator='Ctrl+F', command=self.show_find) self.edit_menu.add_command(label='Find Next', underline=5, accelerator='F3', command=self.find_next) self.edit_menu.add_command(label='Replace...', underline=0, accelerator='Ctrl+H', command=self.show_find_replace) self.edit_menu.add_command(label='Go To...', underline=0, accelerator='Ctrl+G', command=self.show_goto) self.edit_menu.add_separator() self.edit_menu.add_command(label='Select All', underline=7, accelerator='Ctrl+A', command=lambda: self.select_all()) self.edit_menu.add_command(label='Time/Date', underline=5, accelerator='F5', command=self.time_date) # Format Menu self.menu_bar.add_cascade(label='Format', underline=0, menu=self.format_menu) self.format_menu.add_checkbutton(label='Word Wrap', underline=0, variable=self.word_wrap, command=self.toggle_word_wrap) self.format_menu.add_command(label='Font...', underline=0, command=self.set_font) # View Menu self.menu_bar.add_cascade(label='View', underline=1, menu=self.thisViewMenu) self.thisViewMenu.add_checkbutton(label='Status Bar', underline=0, variable=self.__show_status_bar, command=self.toggle_status_bar) # Help Menu self.menu_bar.add_cascade(label='Help', underline=0, menu=self.help_menu) self.help_menu.add_command(label='View Help', underline=5, command=self.get_help) self.help_menu.add_separator() self.help_menu.add_command(label='About Notepad', underline=0, command=show_about) self.master.config(menu=self.menu_bar) def show_context_menu(self, event): try: self.context_menu = Menu(self.master, tearoff=0) self.context_menu.add_command(label='Undo', underline=2, accelerator='Ctrl+Z', command=self.undo) self.context_menu.add_separator() self.context_menu.add_command(label='Cut', underline=2, accelerator='Ctrl+X', command=self.cut) self.context_menu.add_command(label='Copy', underline=0, accelerator='Ctrl+C', command=self.copy) self.context_menu.add_command(label='Paste', underline=0, accelerator='Ctrl+V', command=self.paste) self.context_menu.add_command(label='Delete', underline=2, accelerator='Del', command=self.delete) self.context_menu.add_separator() self.context_menu.add_command(label='Select All', underline=2, accelerator='Ctrl+A', command=self.select_all) self.context_menu.add_separator() self.context_menu.add_command(label='Search with Bing... ', underline=0, accelerator='Ctrl+B', command=self.search_selected_text) self.context_menu.tk_popup(event.x_root, event.y_root) finally: self.context_menu.grab_release() def set_font(self): fnt = fontpicker.ask_font(family=self.fnt.actual(option='family'), size=self.fnt.actual(option='size'), weight=self.fnt.actual(option='weight'), slant=self.fnt.actual(option='slant')) if fnt: self.fnt = font.Font(family=fnt['family'], size=int(fnt['size']), weight=fnt['weight'], slant=fnt['slant']) self.text_area.config(font=self.fnt) def __build_status_bar(self): self.status_bar = Label(self.master, text="Ln 1, Col 1\t", bd=1, relief=SUNKEN, anchor='e') self.toggle_status_bar() def toggle_status_bar(self): if self.__show_status_bar.get(): self.status_bar.grid(sticky='sew') else: self.status_bar.grid_forget() def toggle_word_wrap(self): if self.word_wrap.get(): self.text_area.config(wrap=WORD) self.scroll_bar_x.grid_forget() log.info("word wrap on, scroll bar off") else: self.text_area.config(wrap=NONE) self.scroll_bar_x.grid(column=0, row=1, sticky='nsew') log.info("word wrap off, scroll bar on") def __bind_shortcuts(self): self.master.bind_class('Text', '<Control-a>', self.select_all) self.master.bind_class('Text', '<Control-A>', self.select_all) self.master.bind_class('Text', '<Control-s>', save_file) self.master.bind_class('Text', '<Control-S>', save_file) self.master.bind_class('Text', '<Control-n>', new_file) self.master.bind_class('Text', '<Control-N>', new_file) self.master.bind_class('Text', '<Control-b>', self.search_selected_text) self.master.bind_class('Text', '<Control-B>', self.search_selected_text) self.master.bind_class('Text', '<Control-f>', self.show_find) self.master.bind_class('Text', '<Control-F>', self.show_find) self.master.bind_class('Text', '<Control-h>', self.show_find_replace) self.master.bind_class('Text', '<Control-H>', self.show_find_replace) self.master.bind_class('Text', '<Control-g>', self.show_goto) self.master.bind_class('Text', '<Control-G>', self.show_goto) self.master.bind_class('Text', '<F5>', self.time_date) self.master.bind_class('Text', '<F3>', self.find_next) self.text_area.bind_class(self.text_area, '<Any-KeyPress>', self.on_key) self.text_area.bind_class(self.text_area, '<Button-1>', self.on_click) self.text_area.bind_class(self.text_area, '<Button-3>', self.show_context_menu) def quit_application(self): if notepad.has_changed(): save_box = messagebox.askquestion( 'Confirm save', 'Do you want to save before closing this file?', icon='warning') if save_box == 'yes': save_file() self.master.destroy() exit() def undo(self, *_): self.text_area.event_generate('<<Undo>>') def on_key(self, *_): self.update_status_bar(INSERT) def on_click(self, *_): self.update_status_bar(CURRENT) try: self.context_menu.destroy() except AttributeError: log.warning( 'error occurred while trying to exit context menu, probably not instansiated' ) def update_status_bar(self, obj): row, col = self.text_area.index(obj).split('.') self.status_bar.config(text=str('Ln ' + row + ', Col ' + col + ' \t')) def cut(self, *_): self.text_area.event_generate('<<Cut>>') def copy(self, *_): self.text_area.event_generate('<<Copy>>') def paste(self, *_): self.text_area.event_generate('<<Paste>>') def select_all(self, *_): self.text_area.tag_add('sel', '1.0', 'end') def delete(self, *_): self.text_area.event_generate('<Delete>') def search_selected_text(self, *_): try: s = self.text_area.selection_get() if s is not None: search_with_bing(s) else: log.debug('selection was empty, not searching with bing') except TclError: print('TclError - Probably because nothing was selected ') def time_date(self, *_): now = datetime.now() s = now.strftime("%I:%M %p %m/%d/%Y") self.text_area.insert(INSERT, s) def show_find(self, *_): if not self.find_open: self.find_open = True FindWindow(master=self) def show_find_replace(self, *_): if not self.replace_open: self.replace_open = True FindReplaceWindow(master=self) def show_goto(self, *_): if not self.goto_open: self.goto_open = True GotoWindow(master=self) @staticmethod def get_help(): search_with_bing("get+help+with+notepad+in+windows+10") def run(self): # Run main application self.master.mainloop() def set_title(self, string): self.master.title(string + ' - Notepad') def clear_text(self): self.text_area.delete(1.0, END) def get_text(self): return self.text_area.get(1.0, END) def write_text(self, text, start_index=1.0): self.text_area.insert(start_index, text) def find_next(self, _): search_string = self.prior_search location = self.text_area.search(search_string, self.text_area.index(INSERT), nocase=True) log.info('searching next -- forwards') if location != '': log.info('found ' + search_string + ' at position ' + location) row, col = get_index(location) end_col = str(col + len(search_string)) end_location = str(str(row) + '.' + end_col) self.text_area.mark_set("insert", end_location) self.text_area.see("insert") self.text_area.tag_remove('sel', "1.0", END) self.text_area.tag_raise("sel") self.text_area.tag_add('sel', location, end_location) self.text_area.focus() else: log.warning(search_string + 'string not found') def has_changed(self): if get_signature(self.text_area.get(1.0, END)) == self.last_hash: log.info('file has changed') return False else: log.info('file has not changed') return True