def __init__(self, *args, **kwargs): ilogger.debug("Init: launching configuration window.") Tk.__init__(self, *args, **kwargs) frm = Frame(self) # container.columnconfigure(1, minsize=150) frm.grid(padx=20, pady=20) # bind shared data between windows self.key = StringVar() self.status = StringVar() self.status.set("Please provide decryption key") self.cur_manager = BusyManager(self) infoFrm = Frame(frm) infoFrm.grid(row=0, column=0, sticky="snew", padx=10, pady=10) img = Image.open("./icons/PadLock-icon.png") logo = ImageTk.PhotoImage(img) logoImg = Label(infoFrm, image=logo) logoImg.image = logo logoImg.grid(row=0, column=0, sticky="snew", padx=10, pady=10) actionFrm = LabelFrame(frm, text="Babel password") actionFrm.grid(row=0, column=1, sticky="snew", padx=10, pady=10) # actionFrm.columnconfigure(1, minsize=250) actionFrm.rowconfigure(1, minsize=10) actionFrm.rowconfigure(3, minsize=10) keyEnt = Entry(actionFrm, textvariable=self.key, show="*") keyEnt.grid(row=0, column=0, columnspan=2, sticky="snew", padx=5, pady=3) self.statusLbl = Label(actionFrm, textvariable=self.status, anchor=CENTER) self.statusLbl.grid(row=2, column=0, columnspan=2, sticky="snew", padx=10, pady=10) configBtn = Button(actionFrm, text="unlock", command=self.launch_config) configBtn.grid(row=4, column=0, sticky="snew", padx=10, pady=10) cancelBtn = Button(actionFrm, text="cancel", command=self.destroy) cancelBtn.grid(row=4, column=1, sticky="snw", padx=10, pady=10)
def __init__(self, parent, controller, **app_data): self.parent = parent Frame.__init__(self, parent) self.controller = controller self.app_data = app_data self.activeW = app_data['activeW'] self.activeW.trace('w', self.observer) self.system = app_data['system'] self.system.trace('w', self.system_observer) self.max_height = int((self.winfo_screenheight() - 200)) self.cur_manager = BusyManager(self) # icons self.runImg = app_data['img']['runM'] self.helpImg = app_data['img']['help'] # variables self.date_from = StringVar() self.date_to = StringVar() self.library = StringVar() self.report = IntVar() # layout self.rowconfigure(3, minsize=15) # register date validation self.vldt = (self.register(self.onValidateDate), '%i', '%d', '%P') # widgets genRepBtn = Button(self, image=self.runImg, command=self.generate_report) genRepBtn.grid(row=0, column=0, sticky='sw', padx=20, pady=5) self.createToolTip(genRepBtn, 'generate report') helpBtn = Button(self, image=self.helpImg, command=self.help) helpBtn.grid(row=1, column=0, sticky='sw', padx=20, pady=5) self.createToolTip(helpBtn, 'help') # criteria frame critFrm = LabelFrame(self, text='report wizard') critFrm.grid(row=0, column=1, rowspan=20, sticky='snew', padx=25, pady=10) critFrm.columnconfigure(0, minsize=20) critFrm.columnconfigure(5, minsize=20) critFrm.rowconfigure(14, minsize=10) Label(critFrm, text='criteria:', font=RBFONT).grid(row=1, column=1, columnspan=4, sticky='snw', padx=2, pady=10) Label(critFrm, text='date from:').grid(row=2, column=1, sticky='sne', padx=2, pady=5) dateFromEnt = Entry(critFrm, textvariable=self.date_from, font=RFONT, width=17, validate='key', validatecommand=self.vldt) self.createToolTip(dateFromEnt, 'YYYY-MM-DD') dateFromEnt.grid(row=2, column=2, sticky='snw', padx=2, pady=5) Label(critFrm, text='to:').grid(row=2, column=3, sticky='snew', padx=2, pady=5) dateToEnt = Entry(critFrm, textvariable=self.date_to, font=RFONT, width=17, validate='key', validatecommand=self.vldt) dateToEnt.grid(row=2, column=4, sticky='snw', padx=2, pady=5) self.createToolTip(dateToEnt, 'YYYY-MM-DD') Label(critFrm, text='library:').grid(row=3, column=1, sticky='sne', padx=2, pady=5) self.libCbx = Combobox(critFrm, textvariable=self.library, font=RFONT, width=15, state='readonly') self.libCbx.grid(row=3, column=2, sticky='snew', padx=2, pady=5) # users Label(critFrm, text='users:').grid(row=4, column=1, sticky='ne', padx=2, pady=5) scrollbar = Scrollbar(critFrm, orient=VERTICAL) scrollbar.grid(row=4, column=3, sticky='snw', pady=5) self.userLst = Listbox(critFrm, font=RFONT, selectmode=EXTENDED, width=15, yscrollcommand=scrollbar.set) self.userLst.grid(row=4, column=2, sticky='snew', pady=5) scrollbar.config(command=self.userLst.yview) Separator(critFrm, orient=HORIZONTAL).grid(row=5, column=1, columnspan=4, sticky='snew', padx=2, pady=15) # report types Label(critFrm, text='report type:', font=RBFONT).grid(row=6, column=1, columnspan=4, sticky='snw', padx=2, pady=10) fyBtn = Radiobutton(critFrm, text='current FY summary', variable=self.report, value=1) fyBtn.grid(row=7, column=1, columnspa=2, sticky='snw', padx=2, pady=5) audnBtn = Radiobutton(critFrm, text='detailed breakdown', variable=self.report, value=2) audnBtn.grid(row=8, column=1, columnspan=2, sticky='snw', padx=2, pady=5) branchBtn = Radiobutton(critFrm, text='individual branches report', variable=self.report, value=3) branchBtn.grid(row=9, column=1, columnspan=2, sticky='snw', padx=2, pady=5)
class CopyCartWidget: """ Widget for copying entire cart """ def __init__(self, parent, source_cart_id, source_cart_name, **app_data): self.parent = parent self.source_cart_id = source_cart_id self.source_cart_name = source_cart_name self.app_data = app_data self.profile_idx = self.app_data['profile_idx'] top = self.top = Toplevel(master=self.parent) top.title('Copy cart') self.cur_manager = BusyManager(self.top) # variables self.system = StringVar() self.profile = StringVar() self.profiles = sorted(self.profile_idx.values()) self.new_cart_name = StringVar() self.status = StringVar() # icons saveImg = self.app_data['img']['save'] closeImg = self.app_data['img']['delete'] # register cart name validator self.vlcn = (top.register(self.onValidateCartName), '%P') frm = Frame(top) frm.grid(row=0, column=0, sticky='snew', padx=20, pady=20) Label(frm, text=f'Copying "{self.source_cart_name}"').grid(row=0, column=0, columnspan=4, padx=10, pady=10, sticky='snew') Label(frm, text='system:').grid(row=1, column=0, sticky='snw', padx=10, pady=5) systemCbx = Combobox(frm, font=RFONT, values=['NYPL', 'BPL'], state='readonly', textvariable=self.system) systemCbx.grid(row=2, column=0, sticky='snew', padx=10, pady=5) Label(frm, text='profile:').grid(row=1, column=1, sticky='snw', padx=10, pady=5) profileCbx = Combobox(frm, font=RFONT, values=self.profiles, state='readonly', textvariable=self.profile) profileCbx.grid(row=2, column=1, sticky='snew', padx=10, pady=5) Label(frm, text='new cart name:').grid(row=3, column=0, columnspan=2, sticky='snw', padx=10, pady=5) cart_nameEnt = Entry(frm, font=RFONT, textvariable=self.new_cart_name, validate="key", validatecommand=self.vlcn) cart_nameEnt.grid(row=4, column=0, columnspan=2, sticky='snew', padx=10, pady=10) statusLbl = Label(frm, textvariable=self.status) statusLbl.grid(row=5, column=0, columnspan=2, sticky='snew', padx=10, pady=5) okBtn = Button(frm, image=saveImg, command=self.create_copy) okBtn.grid(row=6, column=0, sticky='sne', padx=25, pady=10) cancelBtn = Button(frm, image=closeImg, command=top.destroy) cancelBtn.grid(row=6, column=1, sticky='snw', padx=25, pady=10) def create_copy(self): try: self.cur_manager.busy() create_cart_copy(self.source_cart_id, self.system.get(), self.profile.get(), self.profile_idx, self.new_cart_name.get(), self.status) self.cur_manager.notbusy() except BabelError as e: self.cur_manager.notbusy() messagebox.showerror('Copying Error', e) def onValidateCartName(self, P): valid = True if len(P) > 75: valid = False if ('(' in P or ')' in P): valid = False return valid
def __init__(self, parent, source_cart_id, source_cart_name, **app_data): self.parent = parent self.source_cart_id = source_cart_id self.source_cart_name = source_cart_name self.app_data = app_data self.profile_idx = self.app_data['profile_idx'] top = self.top = Toplevel(master=self.parent) top.title('Copy cart') self.cur_manager = BusyManager(self.top) # variables self.system = StringVar() self.profile = StringVar() self.profiles = sorted(self.profile_idx.values()) self.new_cart_name = StringVar() self.status = StringVar() # icons saveImg = self.app_data['img']['save'] closeImg = self.app_data['img']['delete'] # register cart name validator self.vlcn = (top.register(self.onValidateCartName), '%P') frm = Frame(top) frm.grid(row=0, column=0, sticky='snew', padx=20, pady=20) Label(frm, text=f'Copying "{self.source_cart_name}"').grid(row=0, column=0, columnspan=4, padx=10, pady=10, sticky='snew') Label(frm, text='system:').grid(row=1, column=0, sticky='snw', padx=10, pady=5) systemCbx = Combobox(frm, font=RFONT, values=['NYPL', 'BPL'], state='readonly', textvariable=self.system) systemCbx.grid(row=2, column=0, sticky='snew', padx=10, pady=5) Label(frm, text='profile:').grid(row=1, column=1, sticky='snw', padx=10, pady=5) profileCbx = Combobox(frm, font=RFONT, values=self.profiles, state='readonly', textvariable=self.profile) profileCbx.grid(row=2, column=1, sticky='snew', padx=10, pady=5) Label(frm, text='new cart name:').grid(row=3, column=0, columnspan=2, sticky='snw', padx=10, pady=5) cart_nameEnt = Entry(frm, font=RFONT, textvariable=self.new_cart_name, validate="key", validatecommand=self.vlcn) cart_nameEnt.grid(row=4, column=0, columnspan=2, sticky='snew', padx=10, pady=10) statusLbl = Label(frm, textvariable=self.status) statusLbl.grid(row=5, column=0, columnspan=2, sticky='snew', padx=10, pady=5) okBtn = Button(frm, image=saveImg, command=self.create_copy) okBtn.grid(row=6, column=0, sticky='sne', padx=25, pady=10) cancelBtn = Button(frm, image=closeImg, command=top.destroy) cancelBtn.grid(row=6, column=1, sticky='snw', padx=25, pady=10)
class CartsView(Frame): """ Gui for managing carts """ def __init__(self, parent, controller, **app_data): self.parent = parent Frame.__init__(self, parent) self.controller = controller self.app_data = app_data self.activeW = app_data['activeW'] self.activeW.trace('w', self.observer) self.system = app_data['system'] self.system.trace('w', self.observer) self.profile = app_data['profile'] self.profile.trace('w', self.observer) self.profile_idx = app_data['profile_idx'] self.active_id = app_data['active_id'] self.cur_manager = BusyManager(self) # local variables self.status_filter = StringVar() self.selected_cart_id = IntVar() self.selected_cart_name = StringVar() self.selected_cart_owner = StringVar() # images # addImg = self.app_data['img']['add'] editImg = self.app_data['img']['edit'] self.deleteImg = self.app_data['img']['delete'] self.saveImg = self.app_data['img']['save'] helpImg = self.app_data['img']['help'] viewImg = self.app_data['img']['view'] self.viewImgS = self.app_data['img']['viewS'] copyImg = self.app_data['img']['copy'] marcImg = self.app_data['img']['marc'] sheetImg = self.app_data['img']['sheet'] linkImg = self.app_data['img']['link'] self.linkImgS = self.app_data['img']['linkS'] list_height = int((self.winfo_screenheight() - 100) / 25) Label(self, text='selected: ').grid(row=0, column=0, sticky='snw', padx=10, pady=5) self.selcartLbl = Label(self, textvariable=self.selected_cart_name, font=RFONT) self.selcartLbl.grid(row=0, column=0, sticky='sne', pady=5) # carts treeview columns = ('#', 'cart', 'date', 'status', 'owner', 'link') self.cartTrv = Treeview(self, columns=columns, displaycolumns=columns, show='headings', height=list_height) # sorting columns functionality for col in columns: self.cartTrv.heading( col, text=col, command=lambda _col=col: self.treeview_sort_column( self.cartTrv, _col, False)) self.cartTrv.column('#', width=5, anchor='center') self.cartTrv.column('cart', width=350) self.cartTrv.column('date', width=130, anchor='center') self.cartTrv.column('status', width=100, anchor='center') self.cartTrv.column('owner', width=120, anchor='center') self.cartTrv.column('link', width=6, anchor='center') self.cartTrv.grid(row=1, column=0, rowspan=20, sticky='snew') # cart treeview scrollbar scrollbar = Scrollbar(self, orient="vertical", command=self.cartTrv.yview) scrollbar.grid(row=1, column=1, rowspan=20, sticky='ns') self.cartTrv.configure(yscrollcommand=scrollbar.set) self.cartTrv.bind('<ButtonRelease-1>', self.selectItem) # action buttons frame self.actionFrm = Frame(self) self.actionFrm.grid(row=1, column=2, sticky='snew', padx=5, pady=10) self.viewBtn = Button(self.actionFrm, image=viewImg, command=self.view_data) # self.viewBtn.image = self.viewImg self.viewBtn.grid(row=1, column=0, sticky='sw', padx=10, pady=5) self.createToolTip(self.viewBtn, 'view cart') self.editBtn = Button(self.actionFrm, image=editImg, command=self.edit_data) # self.editBtn.image = editImg self.editBtn.grid(row=2, column=0, sticky='sw', padx=10, pady=5) self.createToolTip(self.editBtn, 'edit cart') self.marcBtn = Button(self.actionFrm, image=marcImg, command=self.create_marc_file) # self.marcBtn.image = marcImg self.marcBtn.grid(row=3, column=0, sticky='sw', padx=10, pady=5) self.createToolTip(self.marcBtn, 'create MARC file') self.sheetBtn = Button(self.actionFrm, image=sheetImg, command=self.create_order_sheet) # self.sheetBtn.image = sheetImg self.sheetBtn.grid(row=4, column=0, sticky='sw', padx=10, pady=5) self.createToolTip(self.sheetBtn, 'create order sheet') self.copyBtn = Button(self.actionFrm, image=copyImg, command=self.copy_data) # self.copyBtn.image = copyImg self.copyBtn.grid(row=5, column=0, sticky='sw', padx=10, pady=5) self.createToolTip(self.copyBtn, 'copy cart') self.linkBtn = Button(self.actionFrm, image=linkImg, command=self.link_ids) # self.linkBtn.image = linkImg self.linkBtn.grid(row=6, column=0, sticky='sw', padx=10, pady=5) self.createToolTip(self.linkBtn, 'link IDs') self.deleteBtn = Button(self.actionFrm, image=self.deleteImg, command=self.delete_data) # self.deleteBtn.image = self.deleteImg self.deleteBtn.grid(row=7, column=0, sticky='sw', padx=10, pady=5) self.createToolTip(self.deleteBtn, 'delete cart') self.helpBtn = Button(self.actionFrm, image=helpImg, command=self.help) # self.helpBtn.image = helpImg self.helpBtn.grid(row=8, column=0, sticky='sw', padx=10, pady=5) self.createToolTip(self.helpBtn, 'help') # cart data frame self.cartdataFrm = Frame(self) self.cartdataFrm.grid(row=1, column=3, rowspan=20, sticky='snew', padx=10, pady=5) self.cartdataTxt = Text(self.cartdataFrm, width=65, state=('disabled'), wrap=WORD, background='SystemButtonFace', borderwidth=0) self.cartdataTxt.grid(row=0, column=0, sticky='nsw') def view_data(self): self.cur_manager.busy() # reset cartdataTxt self.cartdataTxt['state'] = 'normal' self.cartdataTxt.delete(1.0, END) # display basic info summary = self.generate_cart_summary(self.selected_cart_id.get()) if summary: self.cartdataTxt.insert(END, summary) self.cartdataTxt['state'] = 'disable' self.cur_manager.notbusy() else: self.cur_manager.notbusy() def generate_cart_summary(self, cart_id): cart_rec = get_record(Cart, did=cart_id) if cart_rec: owner = self.profile_idx[cart_rec.user_id] try: library = get_record(Library, did=cart_rec.library_id).name except AttributeError: library = None stat_rec = get_record(Status, did=cart_rec.status_id) wlo_range, oid_range = get_cart_id_ranges(cart_id) lines = [] lines.append(f'cart: {cart_rec.name}') lines.append(f'status: {stat_rec.name}') lines.append(f'owner: {owner}') lines.append( f'created: {cart_rec.created} | updated: {cart_rec.updated}') lines.append(f'library: {library}') lines.append(f'blanketPO: {cart_rec.blanketPO}') lines.append(f'wlo range: {wlo_range[0]} - {wlo_range[1]}') lines.append(f'order # range: {oid_range[0]} - {oid_range[1]}') # cart_details data details = summarize_cart(cart_id) lines.append(f'languages: {details["langs"]}') lines.append(f'vendors: {details["vendors"]}') lines.append(f'material types: {details["mattypes"]}') lines.append(f'audiences: {details["audns"]}') lines.append(f'funds:') for fund, values in details["funds"].items(): lines.append( f'\t{fund}: ${values["total_cost"]:.2f}, ' f'copies: {values["copies"]}, titles: {values["titles"]}') return '\n'.join(lines) def edit_data(self): if self.selected_cart_id.get(): # figure out profile cart belongs to first self.profile.set(self.selected_cart_owner.get()) self.active_id.set(self.selected_cart_id.get()) self.controller.show_frame('CartView') def copy_data(self): if self.selected_cart_id.get(): ccw = CopyCartWidget(self, self.selected_cart_id.get(), self.selected_cart_name.get(), **self.app_data) self.wait_window(ccw.top) self.observer() def delete_data(self): if self.selected_cart_id.get(): msg = 'Are you sure you want to delete\n' \ f'"{self.selected_cart_name.get()} ' \ f'({self.selected_cart_owner.get()})" cart?' if messagebox.askokcancel('Deletion', msg): self.cur_manager.busy() delete_data_by_did(Cart, self.selected_cart_id.get()) curItem = self.cartTrv.focus() self.cartTrv.delete(curItem) self.selected_cart_id.set(0) self.selected_cart_name.set('') self.cur_manager.notbusy() def link_ids(self): source_fh = self.ask_for_source() if source_fh: try: self.cur_manager.busy() add_sierra_ids_to_orders(source_fh, self.system.get()) self.cur_manager.notbusy() messagebox.showinfo( 'Linking IDs', 'Sierra bib and order numbers linked successfully.') self.observer() except FileNotFoundError as e: self.cur_manager.notbusy() messagebox.showerror('File error', f'File not found. {e}') except BabelError as e: self.cur_manager.notbusy() messagebox.showerror('Sierra IDs Error', f'Unable to link Sierra IDs. {e}') def help(self): open_url('https://github.com/BookOps-CAT/babel/wiki/Carts') def ask_for_destination(self, parent, title, cart_name): # retrieve initial directory if 'MARC' in title: initialdir_key = 'marc_out' extention = 'mrc' file_types = ('marc file', '*.mrc') elif 'sheet' in title: initialdir_key = 'sheet_out' extention = 'xlsx' file_types = ('sheet file', '*xlsx') user_data = shelve.open(USER_DATA) if initialdir_key in user_data: initialdir = user_data[initialdir_key] else: initialdir = MY_DOCS dst_fh = filedialog.asksaveasfilename( parent=parent, title=title, filetypes=(file_types, ), initialfile=f'{cart_name}.{extention}', initialdir=initialdir) if dst_fh: user_data[initialdir_key] = path.dirname(dst_fh) user_data.close() self.dst_fh.set(dst_fh) else: user_data.close() def ask_for_source(self): user_data = shelve.open(USER_DATA) if 'ids_dir' in user_data: initialdir = user_data['ids_dir'] else: initialdir = MY_DOCS source_fh = filedialog.askopenfilename(parent=self, title='Sierra IDs file', initialdir=initialdir) if source_fh: user_data['ids_dir'] = path.dirname(source_fh) user_data.close() return source_fh def create_to_marc_widget(self, cart_rec): top = Toplevel() top.title('Saving to MARC file') self.dst_fh = StringVar() self.saving_status = StringVar() frm = Frame(top) frm.grid(row=0, column=0, sticky='snew', padx=20, pady=20) Label(frm, text=f'"{cart_rec.name}" cart').grid(row=0, column=0, columnspan=4, sticky='snew') nameEnt = Entry(frm, justify='right', textvariable=self.dst_fh, state='readonly', width=60) nameEnt.grid(row=1, column=0, columnspan=3, sticky='snew', pady=10) dstBtn = Button(frm, image=self.viewImgS, command=lambda: self.ask_for_destination( top, 'Save to MARC file', cart_rec.name)) dstBtn.grid(row=1, column=4, sticky='snw', padx=5, pady=10) progbar = Progressbar( frm, mode='determinate', orient=HORIZONTAL, ) progbar.grid(row=2, column=0, columnspan=4, sticky='snew', pady=5) statusLbl = Label(frm, textvariable=self.saving_status) statusLbl.grid(row=3, column=0, columnspan=2, sticky='snew', pady=5) btnFrm = Frame(frm) btnFrm.grid(row=4, column=0, columnspan=4, sticky='snew') btnFrm.columnconfigure(0, minsize=100) okBtn = Button( btnFrm, image=self.saveImg, command=lambda: self.launch_save2marc(top, cart_rec, progbar)) okBtn.grid(row=4, column=1, sticky='snew', padx=25, pady=10) cancelBtn = Button(btnFrm, image=self.deleteImg, command=top.destroy) cancelBtn.grid(row=4, column=2, sticky='snew', padx=25, pady=10) def launch_save2marc(self, top, cart_rec, progbar): if self.dst_fh.get(): try: self.cur_manager.busy() export_orders_to_marc_file(self.dst_fh.get(), self.saving_status, cart_rec, progbar) self.cur_manager.notbusy() except BabelError as e: self.cur_manager.notbusy() messagebox.showerror( 'Saving Error', 'Unable to create MARC file.\n' 'Run cart validation to find and correct any problems.\n' f'Error: {e}', parent=top) def create_marc_file(self): cart_rec = get_record(Cart, did=self.selected_cart_id.get()) if cart_rec: status = get_record(Status, did=cart_rec.status_id) if status.name == 'finalized': self.create_to_marc_widget(cart_rec) else: msg = f'Cart "{cart_rec.name}" is not finalized.\n' \ 'Please change cart status to proceed.' messagebox.showwarning('Output to MARC file', msg) def create_to_sheet_widget(self, cart_rec, system, cart_data): top = Toplevel() top.title('Saving to spreadsheet') self.dst_fh = StringVar() self.saving_status = StringVar() frm = Frame(top) frm.grid(row=0, column=0, sticky='snew', padx=20, pady=20) Label(frm, text=f'"{cart_rec.name}" cart').grid(row=0, column=0, columnspan=4, sticky='snew') nameEnt = Entry(frm, justify='right', textvariable=self.dst_fh, state='readonly', width=60) nameEnt.grid(row=1, column=0, columnspan=3, sticky='snew', pady=10) dstBtn = Button(frm, image=self.viewImgS, command=lambda: self.ask_for_destination( top, 'Save to spreadsheet', cart_rec.name)) dstBtn.grid(row=1, column=4, sticky='snw', padx=5, pady=10) statusLbl = Label(frm, textvariable=self.saving_status) statusLbl.grid(row=2, column=0, columnspan=2, sticky='snew', pady=5) btnFrm = Frame(frm) btnFrm.grid(row=4, column=0, columnspan=4, sticky='snew') btnFrm.columnconfigure(0, minsize=100) okBtn = Button( btnFrm, image=self.saveImg, command=lambda: save2spreadsheet(self.dst_fh.get(), self. saving_status, system, cart_data) if self.dst_fh.get() else None) okBtn.grid(row=4, column=1, sticky='snew', padx=25, pady=10) cancelBtn = Button(btnFrm, image=self.deleteImg, command=top.destroy) cancelBtn.grid(row=4, column=2, sticky='snew', padx=25, pady=10) def create_order_sheet(self): if self.selected_cart_id.get(): cart_rec = get_record(Cart, did=self.selected_cart_id.get()) status = get_record(Status, did=cart_rec.status_id) if cart_rec.system_id == 1: systemLbl = 'Brooklyn Public Library' else: systemLbl = 'New York Public Library' if status.name == 'finalized': cart_data = [] try: cart_data = get_cart_data_for_order_sheet( self.selected_cart_id.get()) except BabelError as e: messagebox.showerror( 'Retrieval Error', 'Unable to retrieve records from database.\n' f'Error: {e}') if cart_data: try: self.create_to_sheet_widget(cart_rec, systemLbl, cart_data) except BabelError as e: messagebox.showerror('Saving error', e) else: msg = f'Cart "{cart_rec.name}" is not finalized.\n' \ 'Please change cart status to proceed.' messagebox.showwarning('Output to spreadsheet', msg) def reset_cart_summary(self): self.cartdataTxt['state'] = 'normal' self.cartdataTxt.delete('1.0', END) self.cartdataTxt['state'] = 'disable' def selectItem(self, a): curItem = self.cartTrv.focus() try: self.selected_cart_id.set(self.cartTrv.item(curItem)['values'][0]) self.selected_cart_name.set( self.cartTrv.item(curItem)['values'][1]) self.selected_cart_owner.set( self.cartTrv.item(curItem)['values'][4]) self.reset_cart_summary() except IndexError: pass def treeview_sort_column(self, tv, col, reverse): tree_list = [(tv.set(k, col), k) for k in tv.get_children('')] tree_list.sort(reverse=reverse) # rearrange items in sorted positions for index, (val, k) in enumerate(tree_list): tv.move(k, '', index) # reverse sort next time tv.heading( col, command=lambda: self.treeview_sort_column(tv, col, not reverse)) def observer(self, *args): if self.activeW.get() == 'CartsView': # delete current values self.cartTrv.delete(*self.cartTrv.get_children()) # populate carts tree try: carts = get_carts_data(self.system.get(), self.profile.get(), self.status_filter.get()) except BabelError as e: carts = {} messagebox.showerror('Retrieval error', e) for cart in carts: # determine if linked and insert appropriate letter if cart[-1]: cart[-1] = 'L' else: cart[-1] = '' self.cartTrv.insert('', END, values=cart) def createToolTip(self, widget, text): toolTip = ToolTip(widget) def enter(event): toolTip.showtip(text) def leave(event): toolTip.hidetip() widget.bind('<Enter>', enter) widget.bind('<Leave>', leave)
def __init__(self, parent, controller, **app_data): self.parent = parent Frame.__init__(self, parent) self.controller = controller self.app_data = app_data self.activeW = app_data['activeW'] self.activeW.trace('w', self.observer) self.system = app_data['system'] self.system.trace('w', self.observer) self.profile = app_data['profile'] self.profile.trace('w', self.observer) self.profile_idx = app_data['profile_idx'] self.active_id = app_data['active_id'] self.cur_manager = BusyManager(self) # local variables self.status_filter = StringVar() self.selected_cart_id = IntVar() self.selected_cart_name = StringVar() self.selected_cart_owner = StringVar() # images # addImg = self.app_data['img']['add'] editImg = self.app_data['img']['edit'] self.deleteImg = self.app_data['img']['delete'] self.saveImg = self.app_data['img']['save'] helpImg = self.app_data['img']['help'] viewImg = self.app_data['img']['view'] self.viewImgS = self.app_data['img']['viewS'] copyImg = self.app_data['img']['copy'] marcImg = self.app_data['img']['marc'] sheetImg = self.app_data['img']['sheet'] linkImg = self.app_data['img']['link'] self.linkImgS = self.app_data['img']['linkS'] list_height = int((self.winfo_screenheight() - 100) / 25) Label(self, text='selected: ').grid(row=0, column=0, sticky='snw', padx=10, pady=5) self.selcartLbl = Label(self, textvariable=self.selected_cart_name, font=RFONT) self.selcartLbl.grid(row=0, column=0, sticky='sne', pady=5) # carts treeview columns = ('#', 'cart', 'date', 'status', 'owner', 'link') self.cartTrv = Treeview(self, columns=columns, displaycolumns=columns, show='headings', height=list_height) # sorting columns functionality for col in columns: self.cartTrv.heading( col, text=col, command=lambda _col=col: self.treeview_sort_column( self.cartTrv, _col, False)) self.cartTrv.column('#', width=5, anchor='center') self.cartTrv.column('cart', width=350) self.cartTrv.column('date', width=130, anchor='center') self.cartTrv.column('status', width=100, anchor='center') self.cartTrv.column('owner', width=120, anchor='center') self.cartTrv.column('link', width=6, anchor='center') self.cartTrv.grid(row=1, column=0, rowspan=20, sticky='snew') # cart treeview scrollbar scrollbar = Scrollbar(self, orient="vertical", command=self.cartTrv.yview) scrollbar.grid(row=1, column=1, rowspan=20, sticky='ns') self.cartTrv.configure(yscrollcommand=scrollbar.set) self.cartTrv.bind('<ButtonRelease-1>', self.selectItem) # action buttons frame self.actionFrm = Frame(self) self.actionFrm.grid(row=1, column=2, sticky='snew', padx=5, pady=10) self.viewBtn = Button(self.actionFrm, image=viewImg, command=self.view_data) # self.viewBtn.image = self.viewImg self.viewBtn.grid(row=1, column=0, sticky='sw', padx=10, pady=5) self.createToolTip(self.viewBtn, 'view cart') self.editBtn = Button(self.actionFrm, image=editImg, command=self.edit_data) # self.editBtn.image = editImg self.editBtn.grid(row=2, column=0, sticky='sw', padx=10, pady=5) self.createToolTip(self.editBtn, 'edit cart') self.marcBtn = Button(self.actionFrm, image=marcImg, command=self.create_marc_file) # self.marcBtn.image = marcImg self.marcBtn.grid(row=3, column=0, sticky='sw', padx=10, pady=5) self.createToolTip(self.marcBtn, 'create MARC file') self.sheetBtn = Button(self.actionFrm, image=sheetImg, command=self.create_order_sheet) # self.sheetBtn.image = sheetImg self.sheetBtn.grid(row=4, column=0, sticky='sw', padx=10, pady=5) self.createToolTip(self.sheetBtn, 'create order sheet') self.copyBtn = Button(self.actionFrm, image=copyImg, command=self.copy_data) # self.copyBtn.image = copyImg self.copyBtn.grid(row=5, column=0, sticky='sw', padx=10, pady=5) self.createToolTip(self.copyBtn, 'copy cart') self.linkBtn = Button(self.actionFrm, image=linkImg, command=self.link_ids) # self.linkBtn.image = linkImg self.linkBtn.grid(row=6, column=0, sticky='sw', padx=10, pady=5) self.createToolTip(self.linkBtn, 'link IDs') self.deleteBtn = Button(self.actionFrm, image=self.deleteImg, command=self.delete_data) # self.deleteBtn.image = self.deleteImg self.deleteBtn.grid(row=7, column=0, sticky='sw', padx=10, pady=5) self.createToolTip(self.deleteBtn, 'delete cart') self.helpBtn = Button(self.actionFrm, image=helpImg, command=self.help) # self.helpBtn.image = helpImg self.helpBtn.grid(row=8, column=0, sticky='sw', padx=10, pady=5) self.createToolTip(self.helpBtn, 'help') # cart data frame self.cartdataFrm = Frame(self) self.cartdataFrm.grid(row=1, column=3, rowspan=20, sticky='snew', padx=10, pady=5) self.cartdataTxt = Text(self.cartdataFrm, width=65, state=('disabled'), wrap=WORD, background='SystemButtonFace', borderwidth=0) self.cartdataTxt.grid(row=0, column=0, sticky='nsw')
def __init__(self, parent, **app_data): self.parent = parent self.app_data = app_data mlogger.debug('SearchView active.') self.top = Toplevel(master=self.parent) self.top.title('Search carts') self.cur_manager = BusyManager(self.top) # icons self.searchImg = self.app_data['img']['viewS'] # variables self.identifier = StringVar() self.identifier_type = StringVar() self.title = StringVar() self.title_type = StringVar() self.title_type.set('keyword') self.system = StringVar() self.library = StringVar() self.profile = StringVar() self.audn = StringVar() self.lang = StringVar() self.mattype = StringVar() self.vendor = StringVar() self.fund = StringVar() self.created_start = StringVar() self.created_end = StringVar() self.con1 = StringVar() self.con2 = StringVar() self.con3 = StringVar() self.con4 = StringVar() self.con5 = StringVar() self.con6 = StringVar() self.con7 = StringVar() self.con8 = StringVar() self.con9 = StringVar() id_values = [ 'bib #', 'blanketPO', 'ISBN', 'order #', 'other #', 'UPC', 'wlo #' ] search_types = ['keyword', 'phrase'] conjunctions = ['AND', 'OR', 'NOT', ''] self.get_comboboxes_values() date_format_msg = 'format: YYYY-MM-DD' # register validators self.vldt = (self.top.register(self.onValidateDate), '%i', '%d', '%P') # basic search frame bfrm = LabelFrame(self.top, text='Basic search') bfrm.grid(row=0, column=0, sticky='snew', padx=25, pady=25) idEnt = Entry(bfrm, font=RFONT, textvariable=self.identifier) idEnt.grid(row=0, column=0, sticky='new', padx=5, pady=15) idtypeCbx = Combobox(bfrm, font=RFONT, state='readonly', width=10, values=id_values, textvariable=self.identifier_type) idtypeCbx.grid(row=0, column=1, sticky='new', padx=5, pady=15) bsearchBtn = Button(bfrm, image=self.searchImg, command=self.basic_search) bsearchBtn.grid(row=0, column=2, sticky='new', padx=5, pady=10) self.createToolTip(bsearchBtn, 'run search') # advanced search frame afrm = LabelFrame(self.top, text='Advanced search') afrm.grid(row=1, column=0, sticky='snew', padx=25, pady=25) Label(afrm, text='title:').grid(row=0, column=1, sticky='new', padx=5, pady=15) titleEnt = Entry(afrm, font=RFONT, textvariable=self.title) titleEnt.grid(row=0, column=2, columnspan=2, sticky='new', padx=5, pady=15) titletypeCbx = Combobox(afrm, font=RFONT, state='readonly', width=10, values=search_types) titletypeCbx.grid(row=0, column=4, sticky='new', padx=5, pady=15) asearchBtn = Button(afrm, image=self.searchImg, command=self.advanced_search) asearchBtn.grid(row=0, column=5, sticky='snew', padx=5, pady=10) self.createToolTip(asearchBtn, 'run search') con1Cbx = Combobox(afrm, font=RFONT, state='readonly', width=4, textvariable=self.con1, values=conjunctions) con1Cbx.grid(row=1, column=0, sticky='new', padx=5, pady=2) Label(afrm, text='system:').grid(row=1, column=1, sticky='new', padx=5, pady=2) systemCbx = Combobox(afrm, font=RFONT, state='readonly', width=10, values=self.system_names) systemCbx.grid(row=1, column=2, sticky='new', padx=5, pady=2) con2Cbx = Combobox(afrm, font=RFONT, width=4, state='readonly', textvariable=self.con2, values=conjunctions) con2Cbx.grid(row=2, column=0, sticky='new', padx=5, pady=2) Label(afrm, text='library:').grid(row=2, column=1, sticky='new', padx=5, pady=2) libraryCbx = Combobox(afrm, font=RFONT, width=10, textvariable=self.library, values=self.library_names, state='readonly') libraryCbx.grid(row=2, column=2, sticky='new', padx=5, pady=2) con3Cbx = Combobox(afrm, font=RFONT, width=4, state='readonly', textvariable=self.con3, values=conjunctions) con3Cbx.grid(row=3, column=0, sticky='new', padx=5, pady=2) Label(afrm, text='language:').grid(row=3, column=1, sticky='new', padx=5, pady=2) langCbx = Combobox(afrm, font=RFONT, width=10, textvariable=self.lang, values=self.lang_names, state='readonly') langCbx.grid(row=3, column=2, sticky='new', padx=5, pady=2) con4Cbx = Combobox(afrm, font=RFONT, width=4, state='readonly', textvariable=self.con4, values=conjunctions) con4Cbx.grid(row=4, column=0, sticky='new', padx=5, pady=2) Label(afrm, text='vendor:').grid(row=4, column=1, sticky='new', padx=5, pady=2) vendorCbx = Combobox(afrm, font=RFONT, width=10, state='readonly', textvariable=self.vendor, values=self.vendor_names) vendorCbx.grid(row=4, column=2, sticky='new', padx=5, pady=2) con5Cbx = Combobox(afrm, font=RFONT, width=4, state='readonly', textvariable=self.con5, values=conjunctions) con5Cbx.grid(row=5, column=0, sticky='new', padx=5, pady=2) Label(afrm, text='audience:').grid(row=5, column=1, sticky='new', padx=5, pady=2) audnCbx = Combobox(afrm, font=RFONT, width=10, state='readonly', textvariable=self.audn, values=self.audn_names) audnCbx.grid(row=5, column=2, sticky='new', padx=5, pady=2) con6Cbx = Combobox(afrm, font=RFONT, width=4, state='readonly', textvariable=self.con6, values=conjunctions) con6Cbx.grid(row=6, column=0, sticky='new', padx=5, pady=2) Label(afrm, text='mat. type:').grid(row=6, column=1, sticky='new', padx=5, pady=2) mattypeCbx = Combobox(afrm, font=RFONT, width=10, state='readonly', textvariable=self.mattype, values=self.mattype_names) mattypeCbx.grid(row=6, column=2, sticky='new', padx=5, pady=2) con7Cbx = Combobox(afrm, font=RFONT, width=4, state='readonly', textvariable=self.con7, values=conjunctions) con7Cbx.grid(row=7, column=0, sticky='new', padx=5, pady=2) Label(afrm, text='fund:').grid(row=7, column=1, sticky='new', padx=5, pady=2) fundCbx = Combobox(afrm, font=RFONT, width=10, state='readonly', textvariable=self.fund, values=self.fund_codes) fundCbx.grid(row=7, column=2, sticky='new', padx=5, pady=2) con8Cbx = Combobox(afrm, font=RFONT, width=4, state='readonly', textvariable=self.con8, values=conjunctions) con8Cbx.grid(row=8, column=0, sticky='new', padx=5, pady=2) Label(afrm, text='profile:').grid(row=8, column=1, sticky='new', padx=5, pady=2) profileCbx = Combobox(afrm, font=RFONT, width=10, state='readonly', textvariable=self.profile, values=self.profile_names) profileCbx.grid(row=8, column=2, sticky='new', padx=5, pady=2) con9Cbx = Combobox(afrm, font=RFONT, width=4, state='readonly', textvariable=self.con9, values=(conjunctions[0], conjunctions[3])) con9Cbx.grid(row=9, column=0, sticky='new', padx=5, pady=2) Label(afrm, text='date:').grid(row=9, column=1, sticky='new', padx=5, pady=2) datestartEnt = Entry(afrm, font=RFONT, width=10, textvariable=self.created_start, validate="key", validatecommand=self.vldt) datestartEnt.grid(row=9, column=2, sticky='new', padx=5, pady=2) self.createToolTip(datestartEnt, date_format_msg) dateendEnt = Entry(afrm, font=RFONT, width=14, textvariable=self.created_end, validate="key", validatecommand=self.vldt) dateendEnt.grid(row=9, column=3, sticky='new', padx=5, pady=2) self.createToolTip(dateendEnt, date_format_msg)
class SearchView: """ Widget for editing Resource records """ def __init__(self, parent, **app_data): self.parent = parent self.app_data = app_data mlogger.debug('SearchView active.') self.top = Toplevel(master=self.parent) self.top.title('Search carts') self.cur_manager = BusyManager(self.top) # icons self.searchImg = self.app_data['img']['viewS'] # variables self.identifier = StringVar() self.identifier_type = StringVar() self.title = StringVar() self.title_type = StringVar() self.title_type.set('keyword') self.system = StringVar() self.library = StringVar() self.profile = StringVar() self.audn = StringVar() self.lang = StringVar() self.mattype = StringVar() self.vendor = StringVar() self.fund = StringVar() self.created_start = StringVar() self.created_end = StringVar() self.con1 = StringVar() self.con2 = StringVar() self.con3 = StringVar() self.con4 = StringVar() self.con5 = StringVar() self.con6 = StringVar() self.con7 = StringVar() self.con8 = StringVar() self.con9 = StringVar() id_values = [ 'bib #', 'blanketPO', 'ISBN', 'order #', 'other #', 'UPC', 'wlo #' ] search_types = ['keyword', 'phrase'] conjunctions = ['AND', 'OR', 'NOT', ''] self.get_comboboxes_values() date_format_msg = 'format: YYYY-MM-DD' # register validators self.vldt = (self.top.register(self.onValidateDate), '%i', '%d', '%P') # basic search frame bfrm = LabelFrame(self.top, text='Basic search') bfrm.grid(row=0, column=0, sticky='snew', padx=25, pady=25) idEnt = Entry(bfrm, font=RFONT, textvariable=self.identifier) idEnt.grid(row=0, column=0, sticky='new', padx=5, pady=15) idtypeCbx = Combobox(bfrm, font=RFONT, state='readonly', width=10, values=id_values, textvariable=self.identifier_type) idtypeCbx.grid(row=0, column=1, sticky='new', padx=5, pady=15) bsearchBtn = Button(bfrm, image=self.searchImg, command=self.basic_search) bsearchBtn.grid(row=0, column=2, sticky='new', padx=5, pady=10) self.createToolTip(bsearchBtn, 'run search') # advanced search frame afrm = LabelFrame(self.top, text='Advanced search') afrm.grid(row=1, column=0, sticky='snew', padx=25, pady=25) Label(afrm, text='title:').grid(row=0, column=1, sticky='new', padx=5, pady=15) titleEnt = Entry(afrm, font=RFONT, textvariable=self.title) titleEnt.grid(row=0, column=2, columnspan=2, sticky='new', padx=5, pady=15) titletypeCbx = Combobox(afrm, font=RFONT, state='readonly', width=10, values=search_types) titletypeCbx.grid(row=0, column=4, sticky='new', padx=5, pady=15) asearchBtn = Button(afrm, image=self.searchImg, command=self.advanced_search) asearchBtn.grid(row=0, column=5, sticky='snew', padx=5, pady=10) self.createToolTip(asearchBtn, 'run search') con1Cbx = Combobox(afrm, font=RFONT, state='readonly', width=4, textvariable=self.con1, values=conjunctions) con1Cbx.grid(row=1, column=0, sticky='new', padx=5, pady=2) Label(afrm, text='system:').grid(row=1, column=1, sticky='new', padx=5, pady=2) systemCbx = Combobox(afrm, font=RFONT, state='readonly', width=10, values=self.system_names) systemCbx.grid(row=1, column=2, sticky='new', padx=5, pady=2) con2Cbx = Combobox(afrm, font=RFONT, width=4, state='readonly', textvariable=self.con2, values=conjunctions) con2Cbx.grid(row=2, column=0, sticky='new', padx=5, pady=2) Label(afrm, text='library:').grid(row=2, column=1, sticky='new', padx=5, pady=2) libraryCbx = Combobox(afrm, font=RFONT, width=10, textvariable=self.library, values=self.library_names, state='readonly') libraryCbx.grid(row=2, column=2, sticky='new', padx=5, pady=2) con3Cbx = Combobox(afrm, font=RFONT, width=4, state='readonly', textvariable=self.con3, values=conjunctions) con3Cbx.grid(row=3, column=0, sticky='new', padx=5, pady=2) Label(afrm, text='language:').grid(row=3, column=1, sticky='new', padx=5, pady=2) langCbx = Combobox(afrm, font=RFONT, width=10, textvariable=self.lang, values=self.lang_names, state='readonly') langCbx.grid(row=3, column=2, sticky='new', padx=5, pady=2) con4Cbx = Combobox(afrm, font=RFONT, width=4, state='readonly', textvariable=self.con4, values=conjunctions) con4Cbx.grid(row=4, column=0, sticky='new', padx=5, pady=2) Label(afrm, text='vendor:').grid(row=4, column=1, sticky='new', padx=5, pady=2) vendorCbx = Combobox(afrm, font=RFONT, width=10, state='readonly', textvariable=self.vendor, values=self.vendor_names) vendorCbx.grid(row=4, column=2, sticky='new', padx=5, pady=2) con5Cbx = Combobox(afrm, font=RFONT, width=4, state='readonly', textvariable=self.con5, values=conjunctions) con5Cbx.grid(row=5, column=0, sticky='new', padx=5, pady=2) Label(afrm, text='audience:').grid(row=5, column=1, sticky='new', padx=5, pady=2) audnCbx = Combobox(afrm, font=RFONT, width=10, state='readonly', textvariable=self.audn, values=self.audn_names) audnCbx.grid(row=5, column=2, sticky='new', padx=5, pady=2) con6Cbx = Combobox(afrm, font=RFONT, width=4, state='readonly', textvariable=self.con6, values=conjunctions) con6Cbx.grid(row=6, column=0, sticky='new', padx=5, pady=2) Label(afrm, text='mat. type:').grid(row=6, column=1, sticky='new', padx=5, pady=2) mattypeCbx = Combobox(afrm, font=RFONT, width=10, state='readonly', textvariable=self.mattype, values=self.mattype_names) mattypeCbx.grid(row=6, column=2, sticky='new', padx=5, pady=2) con7Cbx = Combobox(afrm, font=RFONT, width=4, state='readonly', textvariable=self.con7, values=conjunctions) con7Cbx.grid(row=7, column=0, sticky='new', padx=5, pady=2) Label(afrm, text='fund:').grid(row=7, column=1, sticky='new', padx=5, pady=2) fundCbx = Combobox(afrm, font=RFONT, width=10, state='readonly', textvariable=self.fund, values=self.fund_codes) fundCbx.grid(row=7, column=2, sticky='new', padx=5, pady=2) con8Cbx = Combobox(afrm, font=RFONT, width=4, state='readonly', textvariable=self.con8, values=conjunctions) con8Cbx.grid(row=8, column=0, sticky='new', padx=5, pady=2) Label(afrm, text='profile:').grid(row=8, column=1, sticky='new', padx=5, pady=2) profileCbx = Combobox(afrm, font=RFONT, width=10, state='readonly', textvariable=self.profile, values=self.profile_names) profileCbx.grid(row=8, column=2, sticky='new', padx=5, pady=2) con9Cbx = Combobox(afrm, font=RFONT, width=4, state='readonly', textvariable=self.con9, values=(conjunctions[0], conjunctions[3])) con9Cbx.grid(row=9, column=0, sticky='new', padx=5, pady=2) Label(afrm, text='date:').grid(row=9, column=1, sticky='new', padx=5, pady=2) datestartEnt = Entry(afrm, font=RFONT, width=10, textvariable=self.created_start, validate="key", validatecommand=self.vldt) datestartEnt.grid(row=9, column=2, sticky='new', padx=5, pady=2) self.createToolTip(datestartEnt, date_format_msg) dateendEnt = Entry(afrm, font=RFONT, width=14, textvariable=self.created_end, validate="key", validatecommand=self.vldt) dateendEnt.grid(row=9, column=3, sticky='new', padx=5, pady=2) self.createToolTip(dateendEnt, date_format_msg) def basic_search(self): if self.identifier.get() and self.identifier_type.get(): self.cur_manager.busy() try: data = get_data_by_identifier(self.identifier.get(), self.identifier_type.get()) self.cur_manager.notbusy() self.results_widget(data) except BabelError as e: self.cur_manager.notbusy() messagebox.showerror('Search error', e, parent=self.top) else: messagebox.showwarning('Missing input', "Please enter identifier and it's type.", parent=self.top) def advanced_search(self): if self.title.get() or \ (self.created_start.get() and self.created_end.get() and self.con9.get()): messagebox.showwarning( 'Under contruction', 'Advanced search will be released in the next iteration\n' 'of Babel app.', parent=self.top) # conditions = dict( # title=(self.title.get(), self.title_type.get()), # system=(self.con1.get(), self.system.get()), # library=(self.con2.get(), self.library.get()), # lang=(self.con3.get(), self.lang.get()), # vendor=(self.con4.get(), self.vendor.get()), # audn=(self.con5.get(), self.audn.get()), # mattype=(self.con6.get(), self.mattype.get()), # fund=(self.con7.get(), self.fund.get()), # profile=(self.con8.get(), self.profile.get()), # date=( # self.con9.get(), # self.created_start.get(), self.created_end.get())) # try: # data = complex_search(conditions) # except BabelError as e: # messagebox.showerror( # 'Search error', # 'Unable to retrieve records.\n' # f'Error: {e}', # parent=self.top) # else: # messagebox.showwarning( # 'Search warning', # 'Your search must be narrowed down.\n' # 'Please select additional filters.', # parent=self.top) def results_widget(self, data): self.restop = Toplevel(master=self.top) self.top.title('Search carts restults') frm = Frame(self.restop) frm.grid(row=0, column=0, sticky='snew', padx=20, pady=20) scrollbar = Scrollbar(frm, orient=VERTICAL) scrollbar.grid(row=0, column=0, rowspan=5, sticky='snw') resultsTxt = Text(frm, wrap='word', height=30, width=120, background='SystemButtonFace', borderwidth=0, yscrollcommand=scrollbar.set) resultsTxt.grid(row=0, column=1, rowspan=5, sticky="snew", padx=10) scrollbar['command'] = resultsTxt.yview self.populate_results(resultsTxt, data) def populate_results(self, widget, data): widget['state'] = 'normal' widget.insert('1.0', f'found {len(data)} hit(s).\n\n') widget.tag_add('res_info', '1.0', '1.end') ln = 3 headers = [] lib_info = [] for d in data: widget.insert(f'{ln}.0', f"{d['title']} / {d['author']}\n") headers.append(ln) ln += 1 widget.insert( f'{ln}.0', f"ISBN:{d['isbn']} | UPC:{d['upc']} | other #:{d['other_no']}\n" ) ln += 1 widget.insert(f'{ln}.0', f"system:{d['system']} | library: {d['library']}\n") lib_info.append(ln) ln += 1 widget.insert( f'{ln}.0', f"wlo:{d['wlo']} | order #:{d['oid']} | bib #:{d['bid']}\n") ln += 1 widget.insert( f'{ln}.0', f"owner:{d['owner']} | cart:{d['cart']} | status:{d['status']} | created:{d['created']}\n" ) ln += 1 widget.insert(f'{ln}.0', f"vendor:{d['vendor']} | language:{d['lang']}\n") ln += 1 widget.insert( f'{ln}.0', f"audience:{d['audn_name']} | mat.type:{d['mattype']} | PO:{d['po']}\n" ) ln += 1 widget.insert(f'{ln}.0', f"locations: {d['locs']}\n\n") ln += 2 for h in headers: widget.tag_add('header', f'{h}.0', f'{h}.end') for li in lib_info: widget.tag_add('lib_info', f'{li}.7', f'{li}.10') widget.tag_add('lib_info', f'{li}.22', f'{li}.end') widget.tag_config('res_info', font=RBFONT, foreground='tomato2') widget.tag_config('header', font=RFONT, foreground='tomato2') widget.tag_config('lib_info', font=RFONT) widget['state'] = 'disable' def get_comboboxes_values(self): mlogger.info('SearchView getting comoboxes values') self.system_names = get_names(System) self.library_names = get_names(Library) self.lang_names = get_names(Lang) self.vendor_names = get_names(Vendor) self.audn_names = get_names(Audn) self.mattype_names = get_names(MatType) self.fund_codes = get_codes(Fund) self.profile_names = get_names(User) def onValidateDate(self, i, d, P): valid = True if d == '1': if i == '0': if P != '2': valid = False if i in ('1235689'): if not P[int(i)].isdigit(): valid = False if i in ('47'): if P[int(i)] != '-': valid = False if i == '5': if int(P[5]) > 1: valid = False if i == '8': if int(P[8]) > 3: valid = False return valid def createToolTip(self, widget, text): toolTip = ToolTip(widget) def enter(event): toolTip.showtip(text) def leave(event): toolTip.hidetip() widget.bind('<Enter>', enter) widget.bind('<Leave>', leave)
def __init__(self, parent, cart_id=None, resource_id=None, **app_data): self.parent = parent self.app_data = app_data self.cart_id = cart_id self.rec_id = resource_id self.rec = None top = self.top = Toplevel(master=self.parent) top.title('Editing resource') self.cur_manager = BusyManager(self.top) # icons saveImg = self.app_data['img']['save'] closeImg = self.app_data['img']['delete'] # variables self.title = StringVar() self.add_title = StringVar() self.author = StringVar() self.series = StringVar() self.publisher = StringVar() self.pub_date = StringVar() self.pub_place = StringVar() self.isbn = StringVar() self.upc = StringVar() self.other_no = StringVar() self.price_list = StringVar() self.price_disc = StringVar() self.misc = StringVar() # register entries validation self.vlam = (self.top.register(self.onValidatePrice), '%i', '%d', '%P') self.vlis = (self.top.register(self.onValidateIsbn), '%i', '%d', '%P') self.vldt = (self.top.register(self.onValidateDate), '%i', '%d', '%P') self.vlup = (self.top.register(self.onValidateUpc), '%i', '%d', '%P') # layout frm = Frame(top) frm.grid(row=0, column=0, sticky='snew', padx=10, pady=10) frm.columnconfigure(3, minsize=100) Label(frm, text='title:').grid(row=0, column=0, sticky='snw') titleEnt = Entry(frm, font=RFONT, textvariable=self.title) titleEnt.grid(row=0, column=1, columnspan=3, sticky='snew', padx=5, pady=5) Label(frm, text='extra title:').grid(row=1, column=0, sticky='snw') addtitleEnt = Entry(frm, font=RFONT, textvariable=self.add_title) addtitleEnt.grid(row=1, column=1, columnspan=3, sticky='snew', padx=5, pady=5) Label(frm, text='author:').grid(row=2, column=0, sticky='snw') authorEnt = Entry(frm, font=RFONT, textvariable=self.author) authorEnt.grid(row=2, column=1, columnspan=3, sticky='snew', padx=5, pady=5) Label(frm, text='series').grid(row=3, column=0, sticky='snw') seriesEnt = Entry(frm, font=RFONT, textvariable=self.series) seriesEnt.grid(row=3, column=1, columnspan=3, sticky='snew', padx=5, pady=5) Label(frm, text='publisher:').grid(row=4, column=0, sticky='snw') publisherEnt = Entry(frm, font=RFONT, textvariable=self.publisher) publisherEnt.grid(row=4, column=1, columnspan=3, sticky='snew', padx=5, pady=5) Label(frm, text='date:').grid(row=5, column=0, sticky='snw') pubdateEnt = Entry(frm, font=RFONT, textvariable=self.pub_date, validate="key", validatecommand=self.vldt) pubdateEnt.grid(row=5, column=1, sticky='snew', padx=5, pady=5) Label(frm, text='place:').grid(row=5, column=2, sticky='sne') pubplaceEnt = Entry(frm, font=RFONT, textvariable=self.pub_place) pubplaceEnt.grid(row=5, column=3, sticky='snew', padx=5, pady=5) Label(frm, text='ISBN').grid(row=6, column=0, sticky='snw') isbnEnt = Entry(frm, font=RFONT, textvariable=self.isbn, validate="key", validatecommand=self.vlis) isbnEnt.grid(row=6, column=1, sticky='snew', padx=5, pady=5) Label(frm, text='UPC:').grid(row=6, column=2, sticky='sne') upcEnt = Entry(frm, font=RFONT, textvariable=self.upc, validate="key", validatecommand=self.vlup) upcEnt.grid(row=6, column=3, sticky='snew', padx=5, pady=5) Label(frm, text='Other #:').grid(row=7, column=0, sticky='snw') othernoEnt = Entry(frm, font=RFONT, textvariable=self.other_no) othernoEnt.grid(row=7, column=1, sticky='snew', padx=5, pady=5) Label(frm, text='misc.:').grid(row=7, column=2, sticky='sne') miscEnt = Entry(frm, font=RFONT, textvariable=self.misc) miscEnt.grid(row=7, column=3, sticky='snew', padx=5, pady=5) Label(frm, text='list price ($):').grid(row=8, column=0, sticky='snw') pricelistEnt = Entry(frm, font=RFONT, textvariable=self.price_list, validate="key", validatecommand=self.vlam) pricelistEnt.grid(row=8, column=1, sticky='snew', padx=5, pady=5) Label(frm, text='discount price ($):').grid(row=8, column=2, sticky='sne') pricediscEnt = Entry(frm, font=RFONT, textvariable=self.price_disc, validate="key", validatecommand=self.vlam) pricediscEnt.grid(row=8, column=3, sticky='snew', padx=5, pady=5) Label(frm, text='summary:').grid(row=9, column=0, sticky='snw') self.summaryTxt = Text(frm, font=RFONT, wrap='word', width=50, height=5) self.summaryTxt.grid(row=9, column=1, rowspan=3, columnspan=3, sticky='snew', padx=5, pady=5) saveBtn = Button(frm, image=saveImg, command=self.save_resource) saveBtn.grid(row=12, column=1, sticky='sne', padx=5, pady=10) cancelBtn = Button(frm, image=closeImg, command=self.top.destroy) cancelBtn.grid(row=12, column=2, sticky='snw', padx=5, pady=10) if self.rec_id is not None: # populate for edit self.get_data()
def __init__(self, parent, controller, **app_data): self.parent = parent Frame.__init__(self, parent) self.controller = controller self.app_data = app_data self.activeW = app_data['activeW'] self.activeW.trace('w', self.observer) self.profile = app_data['profile'] self.system = app_data['system'] self.system.trace('w', self.observer) list_height = int((self.winfo_screenheight() - 100) / 25) # local variables self.record = None self.all_branches = IntVar() self.all_branches.trace('w', self.branch_selection_observer) self.all_branchesLbl = StringVar() self.all_branchesLbl.set('select all') self.fund_code = StringVar() self.fund_desc = StringVar() # busy icon manager self.cur_manager = BusyManager(self) # icons addImg = self.app_data['img']['add'] editImg = self.app_data['img']['edit'] deleteImg = self.app_data['img']['delete'] saveImg = self.app_data['img']['save'] helpImg = self.app_data['img']['help'] addSImg = self.app_data['img']['addS'] removeSImg = self.app_data['img']['removeS'] # register validation self.vlfu = (self.register(self.onValidateFund), '%d', '%i', '%P') # tables list Label(self, text='Funds:').grid(row=0, column=0, sticky='nw') scrollbarA = Scrollbar(self, orient=VERTICAL) scrollbarA.grid(row=1, column=1, rowspan=40, sticky='nsw') self.fundLst = Listbox(self, font=RFONT, height=list_height, selectmode=SINGLE, yscrollcommand=scrollbarA.set) self.fundLst.bind('<Double-Button-1>', self.show_fund) self.fundLst.grid(row=1, column=0, rowspan=40, sticky='snew') scrollbarA['command'] = self.fundLst.yview # action buttons self.addBtn = Button(self, image=addImg, command=self.add_data) self.addBtn.grid(row=1, column=5, sticky='sw', padx=10, pady=10) self.editBtn = Button(self, image=editImg, command=self.edit_data) self.editBtn.grid(row=2, column=5, sticky='sw', padx=10, pady=5) self.deleteBtn = Button(self, image=deleteImg, command=self.delete_data) self.deleteBtn.grid(row=3, column=5, sticky='sw', padx=10, pady=5) self.saveBtn = Button(self, image=saveImg, command=self.insert_or_update_data) self.saveBtn.grid(row=4, column=5, sticky='sw', padx=10, pady=5) self.helpBtn = Button(self, image=helpImg, command=self.help) self.helpBtn.grid(row=5, column=5, sticky='sw', padx=10, pady=5) # details/edit frame self.detFrm = LabelFrame(self, text='Fund code and constraints') self.detFrm.grid(row=0, column=6, rowspan=40, columnspan=5, sticky='snew') # fund data self.editFrm = Frame(self.detFrm) self.editFrm.grid(row=1, column=0, rowspan=5, columnspan=2, sticky='snew', padx=2) Label(self.editFrm, text='Fund code').grid(row=0, column=0, sticky='snw', pady=5) self.fundcodeEnt = Entry(self.editFrm, font=RFONT, textvariable=self.fund_code, validate="key", validatecommand=self.vlfu) self.fundcodeEnt.grid(row=1, column=0, columnspan=3, sticky='snew', pady=5) Label(self.editFrm, text='Description').grid(row=2, column=0, sticky='snw', pady=5) self.funddescEnt = Entry(self.editFrm, font=RFONT, textvariable=self.fund_desc) self.funddescEnt.grid(row=3, column=0, rowspan=2, columnspan=3, sticky='snew', pady=5) Label(self.detFrm, text='out').grid(row=0, column=4, columnspan=2, padx=2, sticky='snw') Label(self.detFrm, text='in').grid(row=0, column=7, columnspan=2, padx=2, sticky='snw') Label(self.detFrm, text='out').grid(row=0, column=11, columnspan=2, padx=2, sticky='snw') Label(self.detFrm, text='in').grid(row=0, column=14, columnspan=2, padx=2, sticky='snw') # branches self.branchFrm = LabelFrame(self.detFrm, text='Branches') self.branchFrm.grid(row=1, column=4, rowspan=10, columnspan=5, sticky='snew', padx=5) Checkbutton(self.branchFrm, textvariable=self.all_branchesLbl, variable=self.all_branches).grid(row=0, column=0, sticky='snw') scrollbarB = Scrollbar(self.branchFrm, orient=VERTICAL) scrollbarB.grid(row=1, column=1, rowspan=20, sticky='nsw', pady=2) self.branchOutLst = Listbox(self.branchFrm, font=RFONT, height=list_height, width=14, selectmode=EXTENDED, yscrollcommand=scrollbarB.set) self.branchOutLst.grid(row=1, column=0, rowspan=20, sticky='snew', padx=2, pady=2) scrollbarB['command'] = self.branchOutLst.yview self.branchInBtn = Button( self.branchFrm, image=addSImg, command=lambda: self.add_condition( 'branchLst', self.branchOutLst, self.branchInLst, self.branchOutLst.curselection())) self.branchInBtn.grid(row=1, column=2, sticky='sw', padx=2, pady=2) self.branchOutBtn = Button( self.branchFrm, image=removeSImg, command=lambda: self.remove_condition( 'branchLst', self.branchOutLst, self.branchInLst, self.branchInLst.curselection())) self.branchOutBtn.grid(row=2, column=2, sticky='sw', padx=2, pady=2) scrollbarC = Scrollbar(self.branchFrm, orient=VERTICAL) scrollbarC.grid(row=1, column=4, rowspan=20, sticky='nsw', pady=2) self.branchInLst = Listbox(self.branchFrm, font=RFONT, width=14, height=list_height, selectmode=EXTENDED, yscrollcommand=scrollbarC.set) self.branchInLst.grid(row=1, column=3, rowspan=20, sticky='snew', padx=2, pady=2) scrollbarC['command'] = self.branchInLst.yview # library self.libraryFrm = LabelFrame(self.detFrm, text='Library') self.libraryFrm.grid(row=1, column=11, rowspan=2, columnspan=5, sticky='snew', padx=5) self.libOutLst = Listbox(self.libraryFrm, font=RFONT, width=15, height=3, selectmode=EXTENDED) self.libOutLst.grid(row=0, column=0, rowspan=3, sticky='snew', padx=2, pady=2) self.libInBtn = Button(self.libraryFrm, image=addSImg, command=lambda: self.add_condition( 'libLst', self.libOutLst, self.libInLst, self.libOutLst.curselection())) # self.libInBtn.image = addSImg self.libInBtn.grid(row=0, column=1, sticky='sw', padx=5, pady=2) self.libOutBtn = Button(self.libraryFrm, image=removeSImg, command=lambda: self.remove_condition( 'LibLst', self.libOutLst, self.libInLst, self.libInLst.curselection())) # self.libOutBtn.image = removeSImg self.libOutBtn.grid(row=1, column=1, sticky='sw', padx=5, pady=2) self.libInLst = Listbox(self.libraryFrm, font=RFONT, height=3, width=15, selectmode=EXTENDED) self.libInLst.grid(row=0, column=2, rowspan=2, sticky='snew', padx=2, pady=2) # audience self.audienceFrm = LabelFrame(self.detFrm, text='Audience') self.audienceFrm.grid(row=3, column=11, rowspan=2, columnspan=5, sticky='snew', padx=5, pady=5) self.audnOutLst = Listbox(self.audienceFrm, font=RFONT, width=15, height=4, selectmode=EXTENDED) self.audnOutLst.grid(row=0, column=0, rowspan=2, sticky='snew', padx=2, pady=2) self.audnInBtn = Button(self.audienceFrm, image=addSImg, command=lambda: self.add_condition( 'audnLst', self.audnOutLst, self.audnInLst, self.audnOutLst.curselection())) # self.audnInBtn.image = addSImg self.audnInBtn.grid(row=0, column=1, sticky='sw', padx=5, pady=2) self.audnOutBtn = Button(self.audienceFrm, image=removeSImg, command=lambda: self.remove_condition( 'audnLst', self.audnOutLst, self. audnInLst, self.audnInLst.curselection())) # self.audnOutBtn.image = removeSImg self.audnOutBtn.grid(row=1, column=1, sticky='sw', padx=5, pady=2) self.audnInLst = Listbox(self.audienceFrm, font=RFONT, width=15, height=4, selectmode=EXTENDED) self.audnInLst.grid(row=0, column=2, rowspan=2, sticky='snew', padx=2, pady=2) # material type self.mattypeFrm = LabelFrame(self.detFrm, text='Material type') self.mattypeFrm.grid(row=5, column=11, rowspan=7, columnspan=5, sticky='snew', padx=5, pady=5) self.mattypeOutLst = Listbox(self.mattypeFrm, font=RFONT, width=15, height=7, selectmode=EXTENDED) self.mattypeOutLst.grid(row=0, column=0, rowspan=7, sticky='snew', padx=2, pady=2) self.mattypeInBtn = Button( self.mattypeFrm, image=addSImg, command=lambda: self.add_condition( 'mattypeLst', self.mattypeOutLst, self.mattypeInLst, self.mattypeOutLst.curselection())) # self.mattypeInBtn.image = addSImg self.mattypeInBtn.grid(row=0, column=1, sticky='sw', padx=5, pady=2) self.mattypeOutBtn = Button( self.mattypeFrm, image=removeSImg, command=lambda: self.remove_condition( 'mattypesLst', self.mattypeOutLst, self.mattypeInLst, self.mattypeInLst.curselection())) # self.mattypeOutBtn.image = removeSImg self.mattypeOutBtn.grid(row=1, column=1, sticky='sw', padx=5, pady=2) self.mattypeInLst = Listbox(self.mattypeFrm, font=RFONT, width=15, height=7, selectmode=EXTENDED) self.mattypeInLst.grid(row=0, column=2, rowspan=7, sticky='snew', padx=2, pady=2)
class FundView(Frame): """ Shared among settings widgets frame """ def __init__(self, parent, controller, **app_data): self.parent = parent Frame.__init__(self, parent) self.controller = controller self.app_data = app_data self.activeW = app_data['activeW'] self.activeW.trace('w', self.observer) self.profile = app_data['profile'] self.system = app_data['system'] self.system.trace('w', self.observer) list_height = int((self.winfo_screenheight() - 100) / 25) # local variables self.record = None self.all_branches = IntVar() self.all_branches.trace('w', self.branch_selection_observer) self.all_branchesLbl = StringVar() self.all_branchesLbl.set('select all') self.fund_code = StringVar() self.fund_desc = StringVar() # busy icon manager self.cur_manager = BusyManager(self) # icons addImg = self.app_data['img']['add'] editImg = self.app_data['img']['edit'] deleteImg = self.app_data['img']['delete'] saveImg = self.app_data['img']['save'] helpImg = self.app_data['img']['help'] addSImg = self.app_data['img']['addS'] removeSImg = self.app_data['img']['removeS'] # register validation self.vlfu = (self.register(self.onValidateFund), '%d', '%i', '%P') # tables list Label(self, text='Funds:').grid(row=0, column=0, sticky='nw') scrollbarA = Scrollbar(self, orient=VERTICAL) scrollbarA.grid(row=1, column=1, rowspan=40, sticky='nsw') self.fundLst = Listbox(self, font=RFONT, height=list_height, selectmode=SINGLE, yscrollcommand=scrollbarA.set) self.fundLst.bind('<Double-Button-1>', self.show_fund) self.fundLst.grid(row=1, column=0, rowspan=40, sticky='snew') scrollbarA['command'] = self.fundLst.yview # action buttons self.addBtn = Button(self, image=addImg, command=self.add_data) self.addBtn.grid(row=1, column=5, sticky='sw', padx=10, pady=10) self.editBtn = Button(self, image=editImg, command=self.edit_data) self.editBtn.grid(row=2, column=5, sticky='sw', padx=10, pady=5) self.deleteBtn = Button(self, image=deleteImg, command=self.delete_data) self.deleteBtn.grid(row=3, column=5, sticky='sw', padx=10, pady=5) self.saveBtn = Button(self, image=saveImg, command=self.insert_or_update_data) self.saveBtn.grid(row=4, column=5, sticky='sw', padx=10, pady=5) self.helpBtn = Button(self, image=helpImg, command=self.help) self.helpBtn.grid(row=5, column=5, sticky='sw', padx=10, pady=5) # details/edit frame self.detFrm = LabelFrame(self, text='Fund code and constraints') self.detFrm.grid(row=0, column=6, rowspan=40, columnspan=5, sticky='snew') # fund data self.editFrm = Frame(self.detFrm) self.editFrm.grid(row=1, column=0, rowspan=5, columnspan=2, sticky='snew', padx=2) Label(self.editFrm, text='Fund code').grid(row=0, column=0, sticky='snw', pady=5) self.fundcodeEnt = Entry(self.editFrm, font=RFONT, textvariable=self.fund_code, validate="key", validatecommand=self.vlfu) self.fundcodeEnt.grid(row=1, column=0, columnspan=3, sticky='snew', pady=5) Label(self.editFrm, text='Description').grid(row=2, column=0, sticky='snw', pady=5) self.funddescEnt = Entry(self.editFrm, font=RFONT, textvariable=self.fund_desc) self.funddescEnt.grid(row=3, column=0, rowspan=2, columnspan=3, sticky='snew', pady=5) Label(self.detFrm, text='out').grid(row=0, column=4, columnspan=2, padx=2, sticky='snw') Label(self.detFrm, text='in').grid(row=0, column=7, columnspan=2, padx=2, sticky='snw') Label(self.detFrm, text='out').grid(row=0, column=11, columnspan=2, padx=2, sticky='snw') Label(self.detFrm, text='in').grid(row=0, column=14, columnspan=2, padx=2, sticky='snw') # branches self.branchFrm = LabelFrame(self.detFrm, text='Branches') self.branchFrm.grid(row=1, column=4, rowspan=10, columnspan=5, sticky='snew', padx=5) Checkbutton(self.branchFrm, textvariable=self.all_branchesLbl, variable=self.all_branches).grid(row=0, column=0, sticky='snw') scrollbarB = Scrollbar(self.branchFrm, orient=VERTICAL) scrollbarB.grid(row=1, column=1, rowspan=20, sticky='nsw', pady=2) self.branchOutLst = Listbox(self.branchFrm, font=RFONT, height=list_height, width=14, selectmode=EXTENDED, yscrollcommand=scrollbarB.set) self.branchOutLst.grid(row=1, column=0, rowspan=20, sticky='snew', padx=2, pady=2) scrollbarB['command'] = self.branchOutLst.yview self.branchInBtn = Button( self.branchFrm, image=addSImg, command=lambda: self.add_condition( 'branchLst', self.branchOutLst, self.branchInLst, self.branchOutLst.curselection())) self.branchInBtn.grid(row=1, column=2, sticky='sw', padx=2, pady=2) self.branchOutBtn = Button( self.branchFrm, image=removeSImg, command=lambda: self.remove_condition( 'branchLst', self.branchOutLst, self.branchInLst, self.branchInLst.curselection())) self.branchOutBtn.grid(row=2, column=2, sticky='sw', padx=2, pady=2) scrollbarC = Scrollbar(self.branchFrm, orient=VERTICAL) scrollbarC.grid(row=1, column=4, rowspan=20, sticky='nsw', pady=2) self.branchInLst = Listbox(self.branchFrm, font=RFONT, width=14, height=list_height, selectmode=EXTENDED, yscrollcommand=scrollbarC.set) self.branchInLst.grid(row=1, column=3, rowspan=20, sticky='snew', padx=2, pady=2) scrollbarC['command'] = self.branchInLst.yview # library self.libraryFrm = LabelFrame(self.detFrm, text='Library') self.libraryFrm.grid(row=1, column=11, rowspan=2, columnspan=5, sticky='snew', padx=5) self.libOutLst = Listbox(self.libraryFrm, font=RFONT, width=15, height=3, selectmode=EXTENDED) self.libOutLst.grid(row=0, column=0, rowspan=3, sticky='snew', padx=2, pady=2) self.libInBtn = Button(self.libraryFrm, image=addSImg, command=lambda: self.add_condition( 'libLst', self.libOutLst, self.libInLst, self.libOutLst.curselection())) # self.libInBtn.image = addSImg self.libInBtn.grid(row=0, column=1, sticky='sw', padx=5, pady=2) self.libOutBtn = Button(self.libraryFrm, image=removeSImg, command=lambda: self.remove_condition( 'LibLst', self.libOutLst, self.libInLst, self.libInLst.curselection())) # self.libOutBtn.image = removeSImg self.libOutBtn.grid(row=1, column=1, sticky='sw', padx=5, pady=2) self.libInLst = Listbox(self.libraryFrm, font=RFONT, height=3, width=15, selectmode=EXTENDED) self.libInLst.grid(row=0, column=2, rowspan=2, sticky='snew', padx=2, pady=2) # audience self.audienceFrm = LabelFrame(self.detFrm, text='Audience') self.audienceFrm.grid(row=3, column=11, rowspan=2, columnspan=5, sticky='snew', padx=5, pady=5) self.audnOutLst = Listbox(self.audienceFrm, font=RFONT, width=15, height=4, selectmode=EXTENDED) self.audnOutLst.grid(row=0, column=0, rowspan=2, sticky='snew', padx=2, pady=2) self.audnInBtn = Button(self.audienceFrm, image=addSImg, command=lambda: self.add_condition( 'audnLst', self.audnOutLst, self.audnInLst, self.audnOutLst.curselection())) # self.audnInBtn.image = addSImg self.audnInBtn.grid(row=0, column=1, sticky='sw', padx=5, pady=2) self.audnOutBtn = Button(self.audienceFrm, image=removeSImg, command=lambda: self.remove_condition( 'audnLst', self.audnOutLst, self. audnInLst, self.audnInLst.curselection())) # self.audnOutBtn.image = removeSImg self.audnOutBtn.grid(row=1, column=1, sticky='sw', padx=5, pady=2) self.audnInLst = Listbox(self.audienceFrm, font=RFONT, width=15, height=4, selectmode=EXTENDED) self.audnInLst.grid(row=0, column=2, rowspan=2, sticky='snew', padx=2, pady=2) # material type self.mattypeFrm = LabelFrame(self.detFrm, text='Material type') self.mattypeFrm.grid(row=5, column=11, rowspan=7, columnspan=5, sticky='snew', padx=5, pady=5) self.mattypeOutLst = Listbox(self.mattypeFrm, font=RFONT, width=15, height=7, selectmode=EXTENDED) self.mattypeOutLst.grid(row=0, column=0, rowspan=7, sticky='snew', padx=2, pady=2) self.mattypeInBtn = Button( self.mattypeFrm, image=addSImg, command=lambda: self.add_condition( 'mattypeLst', self.mattypeOutLst, self.mattypeInLst, self.mattypeOutLst.curselection())) # self.mattypeInBtn.image = addSImg self.mattypeInBtn.grid(row=0, column=1, sticky='sw', padx=5, pady=2) self.mattypeOutBtn = Button( self.mattypeFrm, image=removeSImg, command=lambda: self.remove_condition( 'mattypesLst', self.mattypeOutLst, self.mattypeInLst, self.mattypeInLst.curselection())) # self.mattypeOutBtn.image = removeSImg self.mattypeOutBtn.grid(row=1, column=1, sticky='sw', padx=5, pady=2) self.mattypeInLst = Listbox(self.mattypeFrm, font=RFONT, width=15, height=7, selectmode=EXTENDED) self.mattypeInLst.grid(row=0, column=2, rowspan=7, sticky='snew', padx=2, pady=2) def show_fund(self, *args): mlogger.debug('Displaying fund details.') self.cur_manager.busy() enable_widgets(self.detFrm.winfo_children()) self.record = get_record(Fund, code=self.fundLst.get(ACTIVE)) self.display_branches() self.display_library() self.display_audiences() self.display_mattypes() fund_data = get_fund_data(self.record) mlogger.debug('Fund data: {}'.format(fund_data)) # display code & description self.fund_code.set(fund_data['code']) self.fund_desc.set(fund_data['describ']) # convert values to listbox indices and add conditions # branchLst branch_idx = self.get_listbox_indices('branches', self.branchOutLst, fund_data['branches']) mlogger.debug('branchOutLst index matches: {}'.format(branch_idx)) self.add_condition('branchLst', self.branchOutLst, self.branchInLst, branch_idx) # audnLst audn_idx = self.get_listbox_indices('audns', self.audnOutLst, fund_data['audns']) mlogger.debug('audnOutLst index matches: {}'.format(audn_idx)) self.add_condition('audnLst', self.audnOutLst, self.audnInLst, audn_idx) # libLst library_idx = self.get_listbox_indices('libraries', self.libOutLst, fund_data['libraries']) mlogger.debug('libOutLst index matches: {}'.format(library_idx)) self.add_condition('libLst', self.libOutLst, self.libInLst, library_idx) if self.system.get() == 1: disable_widgets(self.libraryFrm.winfo_children()) # mattypeOutLst mattype_idx = self.get_listbox_indices('mattypes', self.mattypeOutLst, fund_data['matTypes']) mlogger.debug('mattypeOutLst index matches: {}'.format(mattype_idx)) self.add_condition('mattypeLst', self.mattypeOutLst, self.mattypeInLst, mattype_idx) # lock the interface disable_widgets(self.detFrm.winfo_children()) self.cur_manager.notbusy() def add_data(self): if self.system.get(): self.record = None self.fund_code.set('') self.fund_desc.set('') enable_widgets(self.detFrm.winfo_children()) self.display_branches() self.display_library() self.display_audiences() self.display_mattypes() else: msg = 'Please select system first.' messagebox.showwarning('Input Error', msg) if self.system.get() == 1: disable_widgets(self.libraryFrm.winfo_children()) def edit_data(self): if self.record: enable_widgets(self.detFrm.winfo_children()) if self.system.get() == 1: disable_widgets(self.libraryFrm.winfo_children()) def delete_data(self): if self.record: msg = f'Are you sure you want to delete "{self.record.code}" fund?' if messagebox.askokcancel('Deletion', msg): delete_data(self.record) self.observer() def insert_or_update_data(self): missing = [] if not self.system.get(): missing.append('system') if not self.fund_code.get(): missing.append('fund code') if not self.branchInLst.get(0, END): missing.append('valid branches') if self.system.get() == 2 and not self.libInLst.get(0, END): missing.append('valid library') if not self.audnInLst.get(0, END): missing.append('valid audiences') if not self.mattypeInLst.get(0, END): missing.append('valid material types') if not missing: self.cur_manager.busy() try: if self.system.get() == 1: libraries = ['branches'] else: libraries = self.libInLst.get(0, END) kwargs = dict(system_id=self.system.get(), code=self.fund_code.get().strip(), describ=self.fund_desc.get().strip(), branches=self.branchInLst.get(0, END), libraries=libraries, audns=self.audnInLst.get(0, END), matTypes=self.mattypeInLst.get(0, END)) if not self.record: try: self.record = insert_fund(**kwargs) except BabelError as e: messagebox.showerror('Save Error', e) else: kwargs['did'] = self.record.did try: update_fund(**kwargs) except BabelError as e: messagebox.showerror('Update Error', e) self.display_funds() disable_widgets(self.detFrm.winfo_children()) except BabelError as e: self.cur_manager.notbusy() messagebox.showerror(e) finally: self.cur_manager.notbusy() else: msg = 'Missing requried elements:\n-{}'.format('\n-'.join(missing)) messagebox.showwarning('Input Error', msg) def help(self): open_url('https://github.com/BookOps-CAT/babel/wiki/Funds') def get_listbox_indices(self, widgetName, widgetLst, data): """ Given list of values, retrieves their index in listbox (widgetLst) args: widgetLst: tkinter listbox obj, listbox to be queried data: list of strings, values to be queried returns: indices: list of widgetLst indices for given values """ mlogger.debug( 'Retrieving indices for values {} in a listbox.'.format(data)) values = widgetLst.get(0, END) try: values = sorted([values.index(d) for d in data]) return values except ValueError: missing = (set(data) - set(values)) mlogger.error( f'ValueError on {widgetName}: values={missing} not found in widgets values' ) def add_condition(self, category, widgetOut, widgetIn, selected): mlogger.debug('Adding condition(s) to {} initiated.'.format(category)) values = [widgetOut.get(x) for x in selected] mlogger.debug('Selected condition values: {}'.format(values)) # remove them from out widget for x in reversed(selected): mlogger.debug('Deleting selected {}'.format(x)) widgetOut.delete(x) # sort and add them to in widget in_values = list(widgetIn.get(0, END)) mlogger.debug('Existing values: {}'.format(in_values)) widgetIn.delete(0, END) in_values.extend(values) mlogger.debug('Existing values after appending: {}'.format(in_values)) for value in sorted(in_values): widgetIn.insert(END, value) def remove_condition(self, category, widgetOut, widgetIn, selected): mlogger.debug( 'Removing condition(s) from {} initiated'.format(category)) values = [widgetIn.get(x) for x in selected] mlogger.debug('Selected condition values: {}'.format(values)) # remove from in widget for x in reversed(selected): widgetIn.delete(x) # sort and add them to out widget out_values = list(widgetOut.get(0, END)) mlogger.debug('Existing values: {}'.format(out_values)) widgetOut.delete(0, END) out_values.extend(values) mlogger.debug('Existing values after appending: {}'.format(out_values)) for value in sorted(out_values): widgetOut.insert(END, value) def display_funds(self): mlogger.debug('Displaying Funds') self.fundLst.delete(0, END) funds = get_codes(Fund, system_id=self.system.get()) for fund in sorted(funds): self.fundLst.insert(END, fund) def display_branches(self): mlogger.debug('Displaying branches.') self.branchOutLst.delete(0, END) self.branchInLst.delete(0, END) branches = get_codes(Branch, system_id=self.system.get()) for branch in branches: self.branchOutLst.insert(END, branch) def display_library(self): mlogger.debug('Displaying library.') enable_widgets(self.libraryFrm.winfo_children()) self.libOutLst.delete(0, END) self.libInLst.delete(0, END) libraries = get_names(Library) for library in libraries: self.libOutLst.insert(END, library) def display_audiences(self): mlogger.debug('Displaying audiences.') self.audnOutLst.delete(0, END) self.audnInLst.delete(0, END) audns = get_names(Audn) for audn in sorted(audns): self.audnOutLst.insert(END, audn) def display_mattypes(self): mlogger.debug('Displaying mattypes.') self.mattypeOutLst.delete(0, END) self.mattypeInLst.delete(0, END) mattypes = get_names(MatType) for mattype in sorted(mattypes): self.mattypeOutLst.insert(END, mattype) def branch_selection_observer(self, *args): mlogger.debug('FundView: branch_selection_observer activated.') if self.system.get(): if self.all_branches.get() == 1: # change label self.all_branchesLbl.set('deselect all') # remove any existing selection self.branchInLst.delete(0, END) # re-retrive branches in case some were # already selected self.display_branches() branches = self.branchOutLst.get(0, END) self.branchOutLst.delete(0, END) for branch in branches: self.branchInLst.insert(END, branch) elif self.all_branches.get() == 0: self.all_branchesLbl.set('select all') self.branchInLst.delete(0, END) self.branchOutLst.delete(0, END) self.display_branches() def observer(self, *args): if self.activeW.get() == 'FundView': mlogger.debug('FundView: observer activated.') self.record = None self.fund_code.set('') self.fund_desc.set('') enable_widgets(self.detFrm.winfo_children()) self.all_branches.set(0) # pull data from data store only self.display_funds() self.display_audiences() self.display_mattypes() if self.system.get(): # self.display_branches() self.display_library() disable_widgets(self.detFrm.winfo_children()) def onValidateFund(self, d, i, P): valid = True if d == '1': ch = P[int(i)] if not ch.isalpha() and not ch.isdigit(): valid = False if len(P) > 15: valid = False return valid