Пример #1
0
class SelectItem(BaseDialog):
    '''
    Create a list of items called 'name' from a table and return the database
    ID of the item in item_id.
    '''

    def __init__(self, master, table, column, thing=None):

        self.logger = Logger(self, level=Logger.DEBUG)
        self.logger.debug('SelectItem enter constructor')
        self.table = table
        self.column = column
        if thing is None:
            self.thing = 'Item'
        else:
            self.thing = thing

        self.item_id = -1
        super().__init__(master)
        self.wait_window(self)
        self.logger.debug('SelectItem leave constructor')

    @debugger
    def body(self, master):
        self.title("Select %s"%(self.thing))
        self.data = Database.get_instance()

        padx = 6
        pady = 2

        frame = tk.Frame(master, bd=1, relief=tk.RIDGE)
        frame.grid(row=0, column=0, padx=4, pady=7)
        tk.Label(frame, text="Select %s"%(self.thing), font=("Helvetica", 14)).grid(row=0, column=0, columnspan=2)

        ######################
        # Populate the combo boxes
        lst = self.data.populate_list(self.table, self.column)
        lst.sort()

        ######################
        # Show the boxes
        tk.Label(frame, text='Name:').grid(row=1, column=0)
        self.cbb = ttk.Combobox(frame, values=lst)
        self.cbb.grid(row=1, column=1, padx=padx, pady=pady)
        try:
            self.cbb.current(0)
        except tk.TclError:
            mb.showerror("TCL ERROR", "No records are available to select for this table.")

    @debugger
    def validate(self):
        # Since the name was selected from the list, there is no need to
        # validate.
        return True

    @debugger
    def apply(self):
        ''' Populate the form with the selected data. '''
        id = self.data.get_id_by_name(self.table, self.column, self.cbb.get())
        self.item_id = id
Пример #2
0
class SetupPurchaseForm(supplimental_form):
    def __init__(self, notebook):
        self.logger = Logger(self, Logger.DEBUG)
        self.logger.debug(sys._getframe().f_code.co_name)
        super().__init__(notebook, notebook.PURCHASE_FRAME, 'PurchaseRecord')

        self.add_title('Purchase Setup Form')
        self.add_indirect_label('Vendor', 'vendor_ID', 'Vendor', 'name')
        self.add_dynamic_label('Gross', 'gross', width=20)
        self.add_dynamic_label('Tax', 'tax', width=20)
        self.add_dynamic_label('Shipping', 'shipping', width=20)
        self.add_combo('Purchase Type',
                       'PurchaseType',
                       'type_ID',
                       inc_row=False,
                       width=20)
        self.add_combo('Purchase Status',
                       'PurchaseStatus',
                       'status_ID',
                       width=20)
        self.add_text('Notes', 'notes', height=10)

        self.add_button('Prev')
        self.add_button('Next')
        self.add_button('Save')
        self.add_button('Delete')
        self.add_commit_btn()
Пример #3
0
class SetupNotebook(NotebookBase):

    BUSINESS_FRAME = 0
    CUSTOMERS_FRAME = 1
    VENDORS_FRAME = 2
    ACCOUNTS_FRAME = 3
    INVENTORY_FRAME = 4
    SALES_FRAME = 5
    PURCHASE_FRAME = 6
    IMPORT_FRAME = 7

    def __init__(self, master):
        self.logger = Logger(self, level=Logger.DEBUG)
        self.logger.debug(sys._getframe().f_code.co_name)
        super().__init__(master, ['Business', 'Customers', 'Vendors', 'Accounts',
                                  'Inventory', 'Sales', 'Purchase', 'Import'])

        SetupBusinessForm(self)
        SetupCustomersForm(self)
        SetupVendorsForm(self)
        SetupAccountsForm(self)
        SetupInventoryForm(self)
        SetupSalesForm(self)
        SetupPurchaseForm(self)
        SetupImportForm(self)

        self.show_frame(self.BUSINESS_FRAME)
Пример #4
0
class SingleButtonBox(tk.Frame):
    '''
    Make the button box and register the events.
    '''
    def __init__(self, master, form, text=None, *args, **kargs):
        '''
        master = The frame to bind the widgets to.
        form = Name of the form to bind the events to.
        '''
        self.logger = Logger(self, level=Logger.INFO)
        self.logger.debug("NotesBox enter constructor")

        super().__init__(master, *args, **kargs)

        self.form = form
        self.name = text.lower()
        self.events = EventHandler.get_instance()
        tk.Button(self, text=text, command=self.btn_callback).grid(row=1,
                                                                   column=2,
                                                                   padx=5,
                                                                   pady=5)
        self.logger.debug("NotesBox leave constructor")

    @debugger
    def register_events(self, save):
        '''
        save = callback for the save button
        '''
        self.events.register_event(
            '%s_btn_callback_%s' % (self.name, self.form), save)

    @debugger
    def btn_callback(self):
        self.events.raise_event('%s_btn_callback_%s' % (self.name, self.form))
Пример #5
0
class MainHomeForm(Form):
    '''
    Create the form for the Business tab under Setup.
    '''
    def __init__(self, notebook):
        self.logger = Logger(self, Logger.DEBUG)
        self.logger.debug(sys._getframe().f_code.co_name)
        super().__init__(notebook, notebook.HOME_FRAME, 'Business')

        self.add_title('Home Form')
        self.add_entry('Name', 'name', str)
        self.add_entry('Address1', 'address1', str)
        self.add_entry('Address2', 'address2', str)

        self.add_entry('City', 'city', str, inc_row=False, span=1, width=20)
        self.add_entry('State', 'state', str, width=20, span=1)

        self.add_entry('Zip Code', 'zip', str, width=20, span=1, inc_row=False)
        self.add_entry('Country', 'country', str, width=20, span=1)

        self.add_entry('Email',
                       'email_address',
                       str,
                       width=20,
                       span=1,
                       inc_row=False)
        self.add_entry('Phone', 'phone_number', str, width=20, span=1)

        self.add_entry('Web Site', 'web_site', str)
        self.add_entry('Description', 'description', str)

        self.add_text('Terms', 'terms')
        self.add_text('Returns', 'returns')
        self.add_text('Warranty', 'warranty')
        self.add_button('Save')
Пример #6
0
class ComboBox(tk.Frame):
    '''
    Implement a Combobox. Note that this requires that the table
    that it uses to populate the list must have a column called "name".
    '''
    def __init__(self, master, table, column, *args, **kargs):
        '''
        master = the frame to bind this frame to
        name   = the text of the label
        table  = the name of the database table that is associated with this widget
        column = the name of the database column this widget associates with
        '''
        self.logger = Logger(self, level=Logger.INFO)
        self.logger.debug("ComboBox enter constructor")

        super().__init__(master, *args, **kargs)

        self.table = table
        self.column = column
        self.data = Database.get_instance()

        self.content = ttk.Combobox(self, state='readonly')
        self.content.grid(row=0, column=1, padx=5, pady=5, sticky=tk.W)

        self.row = {
            'table': self.table,
            'column': self.column,
            'self': self,
            'hasid': None
        }
        self.logger.debug("ComboBox leave constructor")

    @debugger
    def populate(self, table, column):
        self.content_list = self.data.populate_list(table, column)
        self.content.configure(values=self.content_list)

    @debugger
    def read(self):
        return self.content.current() + 1

    @debugger
    def write(self, val):
        self.content.current(int(val) - 1)

    @debugger
    def clear(self):
        try:
            self.content.current(0)
        except tk.TclError:
            pass

    @debugger
    def get_line(self):
        '''
        Return the form entry to update the form.
        '''
        return self.row
Пример #7
0
class SetupImportForm(supplimental_form):
    def __init__(self, notebook):
        self.logger = Logger(self, Logger.DEBUG)
        self.logger.debug(sys._getframe().f_code.co_name)
        super().__init__(notebook, notebook.IMPORT_FRAME, 'RawImport')

        self.add_title('Import Setup Form')
        self.add_dir_browser()
        self.add_import_btn()
Пример #8
0
class LabelBox(tk.Frame):
    '''
    Implement a consistent interface to the entry widget
    '''
    def __init__(self, master, table, column, *args, **kargs):
        '''
        master = the frame to bind this frame to
        name   = the text of the label
        table  = the name of the database table that is associated with this widget
        column = the name of the column this widget associates with
        '''
        self.logger = Logger(self, level=Logger.INFO)
        self.logger.debug("LabelBox enter constructor")

        super().__init__(master, *args, **kargs)

        self.table = table
        self.column = column
        self.content = tk.StringVar(master)
        self.entry = tk.Label(self, textvariable=self.content)
        self.entry.grid(row=0, column=1, padx=5, pady=5, sticky=tk.W)

        self.row = {
            'table': self.table,
            'column': self.column,
            'self': self,
            'hasid': None
        }
        self.logger.debug("LabelBox leave constructor")

    @debugger
    def set_id(self, table, column, id=0):
        '''
        When the column has a ID, rather than a value, use this to get the record
        that the ID references.
        '''
        self.row['hasid'] = {'table': table, 'column': column, 'id': id}
        return id

    @debugger
    def read(self):
        return self.content.get()

    @debugger
    def write(self, val):
        self.content.set(val)

    @debugger
    def clear(self):
        self.content.set('')

    @debugger
    def get_line(self):
        '''
        Return the form entry to update the form.
        '''
        return self.row
Пример #9
0
class MainSetupForm(Form):
    '''
    Create the form for the Business tab under Setup.
    '''
    def __init__(self, notebook):
        self.logger = Logger(self, Logger.DEBUG)
        self.logger.debug(sys._getframe().f_code.co_name)
        super().__init__(notebook, notebook.SETUP_FRAME, 'Business')

        self.add_notebook(SetupNotebook)
Пример #10
0
class MainReportsForm(Form):
    '''
    Create the form for the Business tab under Setup.
    '''
    def __init__(self, notebook):
        self.logger = Logger(self, Logger.DEBUG)
        self.logger.debug(sys._getframe().f_code.co_name)
        super().__init__(notebook, notebook.REPORTS_FRAME, 'Business')

        self.add_title('Reports Form')
Пример #11
0
class SetupCustomersForm(Form):
    def __init__(self, notebook):
        self.logger = Logger(self, Logger.DEBUG)
        self.logger.debug(sys._getframe().f_code.co_name)
        super().__init__(notebook, notebook.CUSTOMERS_FRAME, 'Customer')

        self.add_title('Customers Setup Form')
        self.add_dynamic_label('Date', 'date_created', width=20)
        self.add_entry('Name', 'name', str)
        self.add_entry('Address1', 'address1', str)
        self.add_entry('Address2', 'address2', str)

        self.add_entry('City', 'city', str, inc_row=False, span=1, width=20)
        self.add_entry('State', 'state', str, width=20, span=1)

        self.add_entry('Zip Code', 'zip', str, width=20, span=1, inc_row=False)
        self.add_combo('Country', 'Country', 'country_ID', width=20)

        self.add_entry('Email',
                       'email_address',
                       str,
                       width=20,
                       span=1,
                       inc_row=False)
        self.add_combo('Email Status',
                       'EmailStatus',
                       'email_status_ID',
                       width=20)

        self.add_entry('Phone',
                       'phone_number',
                       str,
                       width=20,
                       span=1,
                       inc_row=False)
        self.add_combo('Phone Status',
                       'PhoneStatus',
                       'phone_status_ID',
                       width=20)

        self.add_entry('Web Site', 'web_site', str, width=20, inc_row=False)
        self.add_combo('Class', 'ContactClass', 'class_ID', width=20)

        self.add_entry('Description', 'description', str)

        self.add_text('Notes', 'notes', height=10)

        self.add_button('Prev')
        self.add_button('Next')
        self.add_button('Select')
        self.add_button('New')
        self.add_button('Save')
        self.add_button('Delete')
Пример #12
0
    def __init__(self, configuration):
        CREATED_TEMPDIR_MESSAGE = "Created temporary directory at {tempdir}"

        self.configuration = configuration
        # A temporary directory used for this updater over runtime.
        self.tempdir = tempfile.mkdtemp()
        Logger.debug(CREATED_TEMPDIR_MESSAGE.format(tempdir=self.tempdir))

        # must switch context before instantiating updater
        # because updater depends on some module (tuf.conf) variables
        self.switch_context()
        self.updater = tuf.client.updater.Updater(
            self.configuration.hostname, self.configuration.repository_mirrors)
Пример #13
0
  def __init__(self, configuration):
    CREATED_TEMPDIR_MESSAGE = "Created temporary directory at {tempdir}"

    self.configuration = configuration
    # A temporary directory used for this updater over runtime.
    self.tempdir = tempfile.mkdtemp()
    Logger.debug(CREATED_TEMPDIR_MESSAGE.format(tempdir=self.tempdir))

    # must switch context before instantiating updater
    # because updater depends on some module (tuf.conf) variables
    self.switch_context()
    self.updater = tuf.client.updater.Updater(self.configuration.hostname,
                                              self.configuration.repository_mirrors)
Пример #14
0
class MainFrame(tk.Frame):
    '''
    Entry point of application.
    '''

    def __init__(self):
        self.logger = Logger(self, Logger.DEBUG)
        self.logger.debug(sys._getframe().f_code.co_name)

        self.master = tk.Tk()
        self.master.geometry('1000x800')
        #self.master.resizable(0, 0)
        self.master.wm_title("Accounting")

        MainNotebook(self.master)
        #self.main_notebook = MainNotebook(self.master)
        #self.setup_nb = self.main_notebook.set_form(self.main_notebook.SETUP_FRAME, SetupNotebook)


        #self.main_notebook.show_frame(self.main_notebook.HOME_FRAME)
        #self.setup_nb.show_frame(self.setup_nb.SALES_FRAME)

    @debugger
    def main(self):
        try:
            self.logger.debug("start main loop")
            self.master.mainloop()
            self.logger.debug('close database')
            #self.data.close()
            self.logger.debug("end main loop")

        except Exception:
            traceback.print_exception(*sys.exc_info())
Пример #15
0
class helpDialog:
    def __init__(self, parent):
        self.logger = Logger(self, level=Logger.DEBUG)
        self.logger.debug("enter constructer")

        self.top = tkinter.Toplevel(parent)
        self.tx = tkinter.Text(self.top, height=25, width=80)
        self.sb = tkinter.Scrollbar(self.top)
        self.sb.pack(side=tkinter.RIGHT, fill=tkinter.Y)
        self.tx.pack(side=tkinter.LEFT)
        self.sb.config(command=self.tx.yview)
        self.tx.config(yscrollcommand=self.sb.set)
        self.tx.insert(tkinter.END, help_text)
        self.tx.config(state='disabled')

        self.logger.debug("leave constructer")
Пример #16
0
class LineWidget(tk.Frame):
    '''
    This is a special widget used to show and edit product entries for a sale
    form. It implements a single line in the list.
    '''
    def __init__(self, master, form, line, *args, **kargs):
        '''
        master = The frame to bind the widgets to.
        form = Name of the form to bind the events to.
        line = The line number of the line, displayed as a label
        '''
        self.logger = Logger(self, level=Logger.DEBUG)
        self.logger.debug("Line Widget enter constructor")
        self.data = Database.get_instance()

        super().__init__(master, *args, **kargs)

        self.form = form
        self.events = EventHandler.get_instance()
        #self.data = Database.get_instance()

        self.values = self.data.populate_list('InventoryItem', 'name')
        self.values.insert(0, '')  # first line is blank

        tk.Label(self, text='%d' % (int(line))).grid(row=0, column=0)
        self.quan = tk.Spinbox(self, from_=1, to=99, width=2)
        self.quan.grid(row=0, column=1, padx=5, pady=5)
        self.prod = ttk.Combobox(self, values=self.values, width=40)
        self.prod.grid(row=0, column=2)

        self.logger.debug("Line Widget leave constructor")

    @debugger
    def get_str(self):
        return self.prod.get()

    @debugger
    def read(self):
        val = self.prod.get()
        if not val is None and val != '':
            return (int(self.quan.get()), val)
        else:
            return None
Пример #17
0
class SetupAccountsForm(Form):
    def __init__(self, notebook):
        self.logger = Logger(self, Logger.DEBUG)
        self.logger.debug(sys._getframe().f_code.co_name)
        super().__init__(notebook, notebook.ACCOUNTS_FRAME, 'Account')

        self.add_title('Accounts Setup Form')
        self.add_entry('Name', 'name', str, width=20)
        self.add_entry('Number', 'number', str, width=20)
        self.add_combo('Type', 'AccountTypes', 'type_ID', width=20)
        self.add_entry('Total', 'total', float, width=20)
        self.add_entry('Description', 'description', str)
        self.add_text('Notes', 'notes', height=10)

        self.add_button('Prev')
        self.add_button('Next')
        self.add_button('Select')
        self.add_button('New')
        self.add_button('Save')
        self.add_button('Delete')
Пример #18
0
class CommitBase:
    def __init__(self, form_content, id):
        self.logger = Logger(self, level=Logger.DEBUG)
        self.logger.debug("Commit Base enter constructor")
        self.data = Database.get_instance()
        self.id = id
        self.form_content = form_content

    @debugger
    def get_account(self, name):
        '''
        Returns the (id, total).
        '''
        row = self.data.get_row_list_by_col('Account', 'name', name)[0]
        total = float(row['total'])
        id = row['ID']
        return (id, total)

    @debugger
    def make_generic_entry(self, gross, to_acc, from_acc, msg):

        row = {
            'date_committed': time.strftime('%m/%d/%Y'),
            'gross': gross,
            'description': msg,
            'to_account_ID': to_acc,
            'from_account_ID': from_acc,
        }
        id = self.data.insert_row('GenericTransaction', row)

        return id

    @debugger
    def connect_sale(self, id):
        row = {'generic_trans_ID': id, 'sale_trans_ID': self.id}
        self.data.insert_row('SGenericTransaction', row)

    @debugger
    def connect_purchase(self, id):
        row = {'generic_trans_ID': id, 'purchase_trans_ID': self.id}
        self.data.insert_row('PGenericTransaction', row)
Пример #19
0
class SetupInventoryForm(Form):
    def __init__(self, notebook):
        self.logger = Logger(self, Logger.DEBUG)
        self.logger.debug(sys._getframe().f_code.co_name)
        super().__init__(notebook, notebook.INVENTORY_FRAME, 'InventoryItem')

        self.add_title('Inventory Setup Form')
        self.add_entry('Name', 'name', str, width=20)
        self.add_entry('Stock Num', 'stock_num', int, width=20)
        self.add_entry('Stock', 'num_stock', int, width=20)
        self.add_entry('Retail', 'retail', float, width=20)
        self.add_entry('Wholesale', 'wholesale', float, width=20)
        self.add_entry('Description', 'description', str)
        self.add_text('Notes', 'notes', height=10)

        self.add_button('Prev')
        self.add_button('Next')
        self.add_button('Select')
        self.add_button('New')
        self.add_button('Save')
        self.add_button('Delete')
Пример #20
0
class MainNotebook(NotebookBase):

    HOME_FRAME = 0
    SALES_FRAME = 1
    PURCHASE_FRAME = 2
    REPORTS_FRAME = 3
    SETUP_FRAME = 4

    def __init__(self, master):
        self.logger = Logger(self, level=Logger.DEBUG)
        self.logger.debug(sys._getframe().f_code.co_name)
        super().__init__(master,
                         ['Home', 'Sales', 'Purchase', 'Reports', 'Setup'])

        MainHomeForm(self)
        MainSalesForm(self)
        MainPurchaseForm(self)
        MainReportsForm(self)
        MainSetupForm(self)

        self.show_frame(self.HOME_FRAME)
Пример #21
0
class NotebookBase(Notebook):
    def __init__(self, master, names=None, height=700, width=1000):
        self.logger = Logger(self, level=Logger.DEBUG)
        self.logger.debug("enter constructor")
        super().__init__(master, height=height, width=width)

        self.names = names
        if not names is None:
            for name in self.names:
                self.add_tab(name)

        self.form_class = []

    @debugger
    def get_name(self, index):
        return self.names[index]

    @debugger
    def get_index(self, name):
        for index, item in enumerate(self.names):
            if item == name:
                return index

        return None

    @debugger
    def get_form_class(self, index):
        return self.form_class[index]

    @debugger
    def set_form(self, index, form_class, **kargs):
        idx = 0
        if type(index) == type(''):
            idx = self.get_name()
        elif type(index) == type(0):
            idx = index

        self.form_class.append(form_class(self.get_frame(idx), **kargs))
        return self.form_class[-1]
Пример #22
0
class MainFrame(tk.Frame):
    '''
    This is the main frame that "contains" the other frames.
    '''
    def __init__(self):
        self.logger = Logger(self, Logger.DEBUG)
        self.logger.debug(sys._getframe().f_code.co_name)

        self.master = tk.Tk()
        self.master.wm_title("Accounting")

        self.data = Database.get_instance()

        notebook = NoteBk(self.master, height=700, width=1050)
        notebook.add_tab('Sales', DummyClass)
        notebook.add_tab('Purchase', DummyClass)
        notebook.add_tab('Reports', DummyClass)
        notebook.add_tab('Setup', SetupNotebook)

        # activate a frame for initial display
        notebook.show_frame('Sales')

    @debugger
    def main(self):

        try:
            self.logger.debug("start main loop")
            self.master.mainloop()
            self.logger.debug('close database')
            self.data.close()
            self.logger.debug("end main loop")

            # ev = EventHandler.get_instance()
            # ev.dump_events()
        except Exception:
            traceback.print_exception(*sys.exc_info())
Пример #23
0
class SetupSalesForm(supplimental_form):
    def __init__(self, notebook):
        self.logger = Logger(self, Logger.DEBUG)
        self.logger.debug(sys._getframe().f_code.co_name)
        super().__init__(notebook, notebook.SALES_FRAME, 'SaleRecord')

        self.add_title('Sales Setup Form')
        self.add_indirect_label('Customer', 'customer_ID', 'Customer', 'name')
        self.add_dynamic_label('Gross', 'gross', width=20)
        self.add_dynamic_label('Fees', 'fees', width=20)
        self.add_dynamic_label('Shipping', 'shipping', width=20)
        self.add_combo('Status', 'SaleStatus', 'status_ID', width=20)
        # TODO make the products widget and add it here
        self.add_products_widget()
        self.add_text('Notes', 'notes', height=10)

        self.add_button('Prev')
        self.add_button('Next')
        self.add_button('Save')
        self.add_button('Delete')
        self.add_commit_btn()
        # TODO override the load and save forms to support products widget

    @debugger
    def save_callback(self):
        self.logger.debug('supplimental form save callback')
        if askyesno('Save record?', 'Are you sure you want to save this?'):
            self.commit_form()
            self.controls['Products']['obj'].save_btn()
            self.data.commit()

    @debugger
    def delete_callback(self):
        self.logger.debug('supplimental form delete callback')
        if askyesno('Delete record?', 'Are you sure you want to delete this?'):
            self.data.delete_row(self.table, self.row_list[self.row_index])
            self.data.delete_where(
                'ProductList', 'sale_record_ID=%d' %
                (self.controls['Products']['obj'].sale_id))
            self.row_list = self.data.get_id_list(self.table)
            self.load_form()
            self.data.commit()
Пример #24
0
class NoteBkBtn(tk.Button):
    '''
    This Button class keeps track of the state is relation to the NoteBk
    class. It makes no sense outside of that context.
    '''

    def __init__(self, master, title, uuid, *args, **kargs):
        self.logger = Logger(self, level=Logger.INFO)
        self.logger.debug("enter constructor")

        super().__init__(master, *args, **kargs)
        self.configure(width=10)
        self.configure(command=self.btn_cmd)
        self.configure(text=title)
        self.last_state = True
        self.title = title
        self.uuid = uuid
        self.events = EventHandler.get_instance()
        self.logger.debug("leave constructor")

    @debugger
    def btn_cmd(self):
        #print('here', self.title)
        self.events.raise_event('clearButtons_%s'%(self.uuid))
        self.set_state(False)
        self.events.raise_event('show_frame_%s'%(self.title), self.title)

    @debugger
    def set_state(self, state):
        self.logger.debug('button: %s, state: %s'%(self.title, str(state)))
        if state:
            self.configure(relief=tk.RAISED)
        else:
            self.configure(relief=tk.SUNKEN)
        self.last_state = state

    @debugger
    def set_last_state(self):
        #print('here1')
        self.set_state(self.last_state)
Пример #25
0
class MainFrame(tkinter.Frame):
    '''
    This is the main frame that "contains" the other frames.
    '''
    def __init__(self, master=None):
        self.logger = Logger(self, Logger.INFO)
        self.logger.debug(sys._getframe().f_code.co_name)

        tkinter.Frame.__init__(self, master)
        self.master = master
        self.master.protocol("WM_DELETE_WINDOW", self.close_window)

        self.general_params = tkinter.LabelFrame(self.master, text="General Parameters")
        self.general_params.pack()
        self.output_params = tkinter.LabelFrame(self.master, text="Output Parameters")
        self.output_params.pack(fill="both", expand="yes")

        # set up some default values
        #self.current_file_name = os.path.join(os.getcwd(), "untitled.wis")

        self.data = DataStore.get_instance()
        self.logger.debug("data store: %s"%(str(self.data)))

        self.calc = Calculator()
        self.upper_frame = UpperFrame(self.general_params)
        self.lower_frame = LowerFrame(self.output_params)

        menu = tkinter.Menu(self.master, tearoff=0)
        self.master.config(menu=menu)
        #self.master.geometry("750x450")

        fileMenu = tkinter.Menu(menu, tearoff=0)
        fileMenu.add_command(label="Load", command=self.loadCommand)
        fileMenu.add_command(label="Save", command=self.saveCommand)
        fileMenu.add_command(label="Save As", command=self.saveasCommand)
        fileMenu.add_command(label="Export", command=self.exportCommand)
        fileMenu.add_separator()
        fileMenu.add_command(label="Quit", command=self.close_window)
        menu.add_cascade(label="File", menu=fileMenu)

        settingsMenu = tkinter.Menu(menu, tearoff=0)
        settingsMenu.add_command(label="Constants", command=self.constCommand)
        settingsMenu.add_command(label="Embouchure", command=self.emboCommand)
        settingsMenu.add_command(label="Notes", command=self.notesCommand)
        menu.add_cascade(label="Settings", menu=settingsMenu)

        editMenu = tkinter.Menu(menu, tearoff=0)
        editMenu.add_command(label="Help", command=self.helpCommand)
        editMenu.add_command(label="About", command=self.aboutCommand)
        editMenu.add_command(label="Dump", command=self.dumpInternalData)
        menu.add_cascade(label="Help", menu=editMenu)

        tkinter.Label(self.master, text="Tilbury Woodwinds Whistle Calculator",
                    font=("Helvetica", 14)).pack()

        self.upper_frame.create_frame()
        self.lower_frame.update_frame()

    @debugger
    def set_state(self):
        self.upper_frame.set_state()
        self.lower_frame.set_state()

    @debugger
    def get_state(self):
        self.upper_frame.get_state()
        self.lower_frame.get_state()

    @debugger
    def close_window(self):
        if self.data.get_change_flag():
            if messagebox.askyesno("Quit", "Do you want to save the changes before quitting?"):
                self.logger.debug('save')
                self.saveCommand()
            else:
                self.logger.debug('ignore')
        self.master.destroy()

    @debugger
    def loadCommand(self):
        f = filedialog.askopenfilename(initialfile=self.data.get_file_name(), filetypes=(("Whistle Files","*.wis"), ("all files", "*.*")))
        if f != '':
            self.logger.debug("loading file: %s"%(f))
            self.data.load(f)
            self.data.set_file_name(f)
            raise_event("UPDATE_LOWER_FRAME_EVENT")
            self.set_state()
        else:
            self.logger.debug("cancel")

    @debugger
    def saveCommand(self):
        #d = filedialog.askdirectory(initialdir=os.getcwd(), mustexist=True)
        #p = os.path.join(d, self.data.get_file_name())
        p = os.path.join(os.getcwd(), self.data.get_file_name())
        if p != '':
            self.logger.debug("saving file = " + p )
            self.data.save(p)
        else:
            self.logger.debug("cancel")

    @debugger
    def saveasCommand(self):
        f = filedialog.asksaveasfilename(initialfile=self.data.get_file_name(), filetypes=(("Whistle Files","*.wis"), ("all files", "*.*")))
        if f != '':
            self.logger.debug("file save as = " + f)
            self.data.save(f)
            self.data.set_file_name(f)
        else:
            self.logger.debug("cancel")

    @debugger
    def aboutCommand(self):
        messagebox.showinfo(
            "About", "Tilbury Woodwinds Company\nWhistle Calculator\nChuck Tilbury (c) 2019\nVersion: 1.0\nData Version: %s"%(self.data.get_version()))

    @debugger
    def dumpInternalData(self):
        self.data.print_data()
        utility.dump_events()

    @debugger
    def helpCommand(self):
        #messagebox.showinfo(
        #    "Help",
        dialogs.helpDialog(self.master)

    @debugger
    def exportCommand(self):
        name = self.data.get_file_name().replace('.wis', '.txt')
        f = filedialog.asksaveasfilename(initialfile=name, filetypes=(("Text Files","*.txt"), ("all files", "*.*")))
        if f != '':
            self.logger.debug("export file as = " + f)
            with open(f, 'w') as fh:
                fh.write("\n%s\n"%("-"*60))
                fh.write("%s\n"%(self.data.get_title()))
                fh.write("%s\n\n"%("-"*60))
                fh.write("BELL:       %s (%0.3f Hz)\n"%(
                            self.data.note_table[self.data.get_bell_note_select()]['note'],
                            self.data.note_table[self.data.get_bell_note_select()]['frequency']))
                fh.write("ID:         %0.3f\n"%(self.data.get_inside_dia()))
                fh.write("WALL:       %0.3f\n"%(self.data.get_wall_thickness()))
                fh.write("NUM HOLES:  %d\n"%(self.data.get_number_holes()))
                if self.data.get_units() == False:
                    fh.write("UNITS:      inches\n")
                else:
                    fh.write("UNITS:      millimeters\n")
                fh.write("LENGTH:     %0.4f\n"%(self.data.get_length()))
                fh.write("\n%s\n"%("-"*60))
                fh.write("          Drill     Location    Note       Frequency\n")
                for x in range(self.data.get_number_holes()):
                    fh.write("%-10s"%("Hole %d"%(x+1)))

                    if not self.data.get_units():
                        if self.data.get_disp_frac():
                            fh.write("%-10s"%(utility.reduce(self.data.get_hole_size(x))))
                        else:
                            fh.write("%-10s"%("%0.4f"%(self.data.get_hole_size(x))))
                    else:
                        fh.write("%-10s"%("%0.4f"%(self.data.get_hole_size(x))))

                    fh.write("%-12s"%("%0.4f"%(self.data.get_hole_xloc(x))))
                    fh.write("%-10s "%(self.data.get_hole_note(x)))
                    fh.write("%0.4f Hz\n"%(self.data.get_hole_freq(x)))

                fh.write("\n%s\n"%("-"*60))
                fh.write("Notes:\n\n")
                fh.write("%s"%(self.data.get_notes()))
                fh.write("\n%s\n"%("-"*60))
                fh.write("\nCut sheet generated on %s\nby Tilbury Woodwinds Whistle Calculator\n\n"%(time.ctime()))

        else:
            self.logger.debug("cancel")

    @debugger
    def emboCommand(self):
        dialogs.EmbouchureDialog(self.master)
        raise_event("UPDATE_LOWER_FRAME_EVENT")
        raise_event("UPDATE_UPPER_EVENT")

    @debugger
    def constCommand(self):
        dialogs.ConstDialog(self.master)
        raise_event("UPDATE_LOWER_FRAME_EVENT")
        raise_event("UPDATE_UPPER_EVENT")

    @debugger
    def notesCommand(self):
        dialogs.NotesDialog(self.master)
Пример #26
0
class Database(object):
    '''
    The goal of this class is to move all SQL composition out of the program
    logic and place it here.
    '''

    __instance = None

    @staticmethod
    def get_instance():
        '''
        This static method is used to get the singleton object for this class.
        '''
        if Database.__instance == None:
            Database()
        return Database.__instance

    def __init__(self):

        # gate the access to __init__()
        if Database.__instance != None:
            raise Exception(
                "Database class is a singleton. Use get_instance() instead.")
        else:
            Database.__instance = self

        # Continue with init exactly once.
        self.logger = Logger(self, Logger.DEBUG)
        self.logger.debug("enter constructor")
        self.data_version = '1.0'
        self.database_name = 'accounting.db'
        self.db_create_file = 'database.sql'
        self.db_pop_file = 'populate.sql'
        self.open()
        locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')
        self.logger.debug("leave constructor")

    @debugger
    def open(self):

        if not os.path.isfile(self.database_name):
            self.create_database()

        self.db = sql.connect(self.database_name)
        self.db.row_factory = sql.Row

    @debugger
    def close(self):
        self.db.commit()
        self.db.close()

    @debugger
    def read_statement(self, fh):
        '''
        Read a statement from the *.sql file and return it. This skips comments and concatinates lines
        until a ';' is read.

        A comment is text that starts with a '#' and continues to the end of the line.
        '''
        retv = ''
        for line in fh:
            # strip comments from the line
            idx = line.find('#')
            line = line[0:idx].strip()
            # If there is anything left, append it to the return value.
            if len(line) > 0:
                retv += " %s" % (line)
                if line[-1] == ';':
                    break

        return retv

    @debugger
    def run_file(self, db, name):
        '''
        Execute all of the statements in a *.sql file.
        '''

        with open(name) as fh:
            while True:
                line = self.read_statement(fh)
                if len(line) > 0:
                    db.execute(line)
                else:
                    break

    @debugger
    def create_database(self):
        '''
        Create the database if it does not exist already.
        '''
        # Load the DB creation file and create the database from that.
        self.logger.info("creating database")

        c = sql.connect(self.database_name)
        db = c.cursor()
        self.run_file(db, self.db_create_file)
        self.run_file(db, self.db_pop_file)
        c.commit()
        c.close()

    @debugger
    def get_columns(self, table):
        '''
        Return a dict where all column names are keys with blank data.
        '''
        # TODO: make the data the type of element that the column uses.
        retv = {}
        cols = self.execute('PRAGMA table_info(%s);' % (table))
        for item in cols:
            retv[item[1]] = ''
        return cols

    @debugger
    def get_column_list(self, table):
        '''
        Return a list with all of the column names.
        '''
        retv = []
        cols = self.execute('PRAGMA table_info(%s);' % (table))
        for item in cols:
            retv.append(item[1])
        return retv

    @debugger
    def execute(self, sql):
        '''
        Execute an arbitrary SQL statement.
        '''
        self.logger.debug("SQL=%s" % (sql))
        return self.db.execute(sql)

    @debugger
    def commit(self):
        '''
        Commit the database to disk.
        '''
        self.db.commit()

    @debugger
    def populate_list(self, table, column):
        '''
        Return a list with all of the items then the column of the table.
        '''
        curs = self.execute('select %s from %s;' % (column, table))
        retv = []
        for item in curs:
            retv.append(' '.join(item))
            #retv.append(item)
        return retv

    @debugger
    def get_row_by_id(self, table, ID):
        '''
        Return a dict of all of the columns in the row that has the specified ID.
        '''
        curs = self.execute('select * from %s where ID = %d;' %
                            (table, ID)).fetchall()
        try:
            retv = dict(curs[0])
            return retv
        except IndexError:
            return None

    @debugger
    def get_id_by_row(self, table, col, val):
        '''
        Return a dictionary of the columns in the row where a data element matches the value given.
        '''
        if type(val) is str:
            sql = 'SELECT ID FROM %s WHERE %s = \"%s\";' % (table, col, val)
        else:
            sql = 'SELECT ID FROM %s WHERE %s = %s;' % (table, col, val)
        row = self.execute(sql).fetchall()

        if len(row) == 0:
            return None
        else:
            return dict(row[0])['ID']

    @debugger
    def get_cursor(self):
        '''
        Return the current database cursor.
        '''
        return self.db.cursor()

    @debugger
    def get_id_list(self, table, where=None):
        '''
        Get a list of all of the IDs in the table
        '''
        retv = []
        if where is None:
            sql = 'SELECT ID FROM %s;' % (table)
        else:
            sql = 'SELECT ID FROM %s WHERE %s;' % (table, where)
        cur = self.execute(sql)
        for item in cur:
            retv.append(item[0])

        return retv

    @debugger
    def get_row_list(self, table, where):
        '''
        Get a generic list of rows based on more than one criteria
        '''
        retv = []
        sql = 'SELECT * FROM %s WHERE %s' % (table, where)
        cur = self.execute(sql)
        for item in cur:
            retv.append(dict(item))

        if len(retv) == 0:
            return None
        else:
            return retv

    @debugger
    def get_row_list_by_col(self, table, col, val):
        '''
        Get the list of all rows where the column has a certain value
        '''
        retv = []
        if type(val) is str:
            sql = 'SELECT * FROM %s WHERE %s = \"%s\";' % (table, col, val)
        else:
            sql = 'SELECT * FROM %s WHERE %s = %s;' % (table, col, val)

        self.logger.debug("SQL=%s" % (sql))
        cur = self.execute(sql)
        for item in cur:
            retv.append(dict(item))

        if len(retv) == 0:
            return None
        else:
            return retv

    @debugger
    def get_id_by_name(self, table, col, val):
        '''
        Return the ID where the data in the column matches the value. Only returns the
        first match.
        '''
        if type(val) is str:
            sql = 'select ID from %s where %s = \"%s\";' % (table, col, val)
        else:
            sql = 'select ID from %s where %s = %s;' % (table, col, str(val))

        curs = self.execute(sql)
        recs = curs.fetchall()

        retv = None
        for row in recs:
            retv = row[0]
            break

        return retv

    @debugger
    def get_single_value(self, table, col, row_id):
        '''
        Retrieve a single value where the table, column and row ID are known.
        '''
        sql = 'SELECT %s FROM %s WHERE ID=%d;' % (col, table, row_id)
        self.logger.debug("SQL=%s" % (sql))
        curs = self.execute(sql)
        recs = curs.fetchall()

        retv = None
        for row in recs:
            retv = row[0]
            break

        return retv

    @debugger
    def set_single_value(self, table, col, row_id, val):
        '''
        Retrieve a single value where the table, column and row ID are known.
        '''
        vals = tuple([val])
        sql = 'UPDATE %s SET %s=? WHERE ID=%d;' % (table, col, row_id)
        self.logger.debug("SQL=%s (%s)" % (sql, vals))

        return self.db.execute(sql, vals)

    @debugger
    def insert_row(self, table, rec):
        '''
        Insert a row from a dictionary. This expects a dictionary where the keys are the column names and
        the values are to be inserted in to the columns.
        '''
        keys = ','.join(rec.keys())
        qmks = ','.join(list('?' * len(rec)))
        vals = tuple(rec.values())

        sql = 'INSERT INTO %s (%s) VALUES (%s);' % (table, keys, qmks)
        self.logger.debug("SQL=%s (%s)" % (sql, vals))
        return self.db.execute(sql, vals).lastrowid

    @debugger
    def update_row(self, table, rec, where):
        '''
        Update a row from a dictionary. This expects a dictionary where the keys are the column names and
        the data is the value to place in those columns. A condition must be specified, such as ID=123.
        Otherwise the database will have incorrect data placed in it.
        '''
        keys = '=?,'.join(rec.keys())
        keys += '=?'
        vals = tuple(rec.values())

        sql = 'UPDATE %s SET %s WHERE %s;' % (table, keys, where)
        self.logger.debug("SQL=%s (%s)" % (sql, vals))
        return self.db.execute(sql, vals)

    @debugger
    def update_row_by_id(self, table, rec, id):
        '''
        Update a row using a dictionary and the id of the row. This expects a dictionary where the keys are
        the column names and the data is the value to be placed in the columns.
        '''
        keys = '=?,'.join(rec.keys())
        keys += '=?'
        vals = tuple(rec.values())

        sql = 'UPDATE %s SET %s WHERE ID = %d;' % (table, keys, id)
        self.logger.debug("SQL=%s (%s)" % (sql, vals))
        return self.db.execute(sql, vals)

    @debugger
    def delete_row(self, table, id):
        '''
        Delete the row given by the ID
        '''
        sql = 'DELETE FROM %s WHERE ID = %d;' % (table, id)
        self.logger.debug("SQL=%s" % (sql))
        return self.db.execute(sql)

    @debugger
    def delete_where(self, table, where):
        '''
        Delete rows that conform to the "where" clause.
        '''
        sql = 'DELETE FROM %s WHERE %s;' % (table, where)
        self.logger.debug("SQL=%s" % (sql))
        return self.db.execute(sql)

    @debugger
    def if_rec_exists(self, table, column, value):
        '''
        Return True if there is a row that has the column with the value
        '''
        if type(value) is int or type(value) is float:
            sql = 'SELECT %s FROM %s WHERE %s = %s;' % (column, table, column,
                                                        str(value))
        else:
            sql = 'SELECT %s FROM %s WHERE %s = \"%s\";' % (column, table,
                                                            column, value)
        cursor = self.db.execute(sql)
        if cursor.fetchone() is None:
            return False

        return True

    @debugger
    def convert_value(self, val, value_type, abs_val=True):
        '''
        Convert the value to the specified type. The value_type is an actual python type name.
        '''
        retv = None
        self.logger.debug('val type: %s, value: %s, target type: %s' %
                          (type(val), val, value_type))
        #try:
        if type(val) is value_type:
            retv = val
        elif value_type is str:
            retv = str(val)
        else:
            if value_type is float:
                if type(val) is str:
                    if val == '':
                        retv = 0.0
                    else:
                        if abs_val:
                            retv = abs(locale.atof(val))
                        else:
                            retv = locale.atof(val)
                else:
                    if abs_val:
                        retv = abs(locale.atof(val))
                    else:
                        retv = locale.atof(val)

            elif value_type is int:
                if abs_val:
                    retv = int(abs(locale.atof(val)))
                else:
                    retv = int(locale.atof(val))
        # except:
        #     self.logger.error('Cannot convert value')
        #     exit(1)

        self.logger.debug('made it here: %s' % (str(retv)))
        return retv
Пример #27
0
class Database(object):

    __instance = None

    @staticmethod
    def get_instance():
        '''
        This static method is used to get the singleton object for this class.
        '''
        if Database.__instance == None:
            Database()
        return Database.__instance

    def __init__(self):

        # gate the accress to __init__()
        if Database.__instance != None:
            raise Exception(
                "Database class is a singleton. Use get_instance() instead.")
        else:
            Database.__instance = self

        # Continue with init exactly once.
        self.logger = Logger(self, Logger.DEBUG)
        self.logger.debug("enter constructor")
        self.data_version = '1.0'
        self.database_name = 'shop-timer.db'
        self.open()
        self.logger.debug("leave constructor")

    @debugger
    def open(self):
        if not os.path.isfile(self.database_name):
            self.create_database()

        self.db = sql.connect(self.database_name)

    @debugger
    def close(self):
        self.db.commit()
        self.db.close()

    @debugger
    def create_database(self):
        c = sql.connect(self.database_name)
        db = c.cursor()
        db.execute('''create table assembly (
            ID INTEGER PRIMARY KEY AUTOINCREMENT,
            name TEXT NOT NULL,
            number TEXT NOT NULL,
            description TEXT,
            notes TEXT,
            created REAL NOT NULL,
            modified REAL NOT NULL
        );''')
        db.execute('''create table part (
            ID INTEGER PRIMARY KEY AUTOINCREMENT,
            name TEXT NOT NULL,
            number TEXT NOT NULL,
            description TEXT,
            notes TEXT,
            created REAL NOT NULL,
            modified REAL NOT NULL,
            assembly_ID INT NOT NULL
        );''')
        db.execute('''create table action (
            ID INTEGER PRIMARY KEY AUTOINCREMENT,
            name TEXT NOT NULL,
            seq_number INTEGER NOT NULL,
            description TEXT,
            notes TEXT,
            created REAL NOT NULL,
            modified REAL NOT NULL,
            part_ID INT NOT NULL
        );''')
        db.execute('''create table timer (
            ID INTEGER PRIMARY KEY AUTOINCREMENT,
            name TEXT NOT NULL,
            description TEXT,
            notes TEXT,
            created REAL NOT NULL,
            modified REAL NOT NULL,
            action_ID INT NOT NULL
        );''')
        db.execute('''create table timer_instance (
            ID INTEGER PRIMARY KEY AUTOINCREMENT,
            name TEXT NOT NULL,
            start REAL NOT NULL,
            end REAL NOT NULL,
            total REAL NOT NULL,
            timer_ID INT NOT NULL
        );''')
        db.execute('''create table housekeeping (
            ID INTEGER PRIMARY KEY AUTOINCREMENT,
            last_timer_id INTEGER,
            data_version TEXT
        );''')
        db.execute("insert into housekeeping (data_version) values ('1.0');")
        c.commit()
        c.close()

    @debugger
    def _insert(self, table, fields, values):
        '''
        Do a SQL "insert" command. Create a row in the database.
        table = the table name as a string
        fields = [field names as strings]
        values = [values for the fields]
        The values can be any arbitrary type that can be converted to a string.
        '''
        sv = []
        for v in values:
            if type(v) == str:
                sv.append("\'%s\'" % (v))
            else:
                sv.append(str(v))

        sql = 'insert into %s (%s) values (%s);' % (table, ','.join(fields),
                                                    ','.join(sv))
        self.execute(sql)
        self.commit()

    @debugger
    def _select(self, table, fields=None, where=None):
        '''
        Do a SQL "select" command. Returns one or more rows as a database cursor.
        table = the table name as a string
        fields = [field names as strings]
        where = an optional expression presented as a string
        '''
        if fields is None:
            if not where is None:
                sql = "select * from %s where %s;" % (table, where)
            else:
                sql = "select * from %s;" % (table)
        elif type(fields) is str:
            if not where is None:
                sql = "select %s from %s where %s;" % (fields, table, where)
            else:
                sql = "select %s from %s;" % (fields, table)
        else:
            if not where is None:
                sql = "select %s from %s where %s;" % (','.join(fields), table,
                                                       where)
            else:
                sql = "select %s from %s;" % (','.join(fields), table)

        return self.execute(sql)

    @debugger
    def _update(self, table, field, value, where):
        '''
        Do a SQL "update" command. Modifies a row.
        table = the table name as a string
        field = a single field name as a string, or a list of field names
        value = the value to put in the field, or a list of values. may be any type
        where = a required expression presented as a string

        If the fields and values are not the same size of array, it will throw
        an IndexError exception.
        '''
        if type(field) is list:
            # convert a list of field, value variables
            arr = []
            for idx, item in enumerate(field):
                if type(value[idx]) is str:
                    arr.append('%s = \'%s\'' % (item, str(value[idx])))
                else:
                    arr.append('%s = %s' % (item, str(value[idx])))
            val = ','.join(arr)
            sql = "update %s set %s where %s;" % (table, val, where)

        else:
            if type(value) is str:
                val = "\'%s\'" % (value)
            else:
                val = str(value)
            sql = "update %s set %s = %s where %s;" % (table, field, val,
                                                       where)

        self.execute(sql)
        self.commit()

    @debugger
    def _delete(self, table, id):
        '''
        Do a SQL "delete" command. Delete a row from the database.
        table = the table name
        id = the row ID to delete
        '''
        sql = 'delete from %s where ID = %d;' % (table, id)
        self.execute(sql)
        self.commit()

    @debugger
    def get_columns(self, table):
        '''
        Return a list of all column names for the table specified.
        '''
        cols = self.execute('PRAGMA table_info(%s);' % (table))
        # for item in cols:
        #    print(item)
        return cols

    @debugger
    def convert_cursor(self, cursor, names):
        '''
        Returns a list of dicts where each row of data is in the dict with the
        name given in the order that it was read from the database.
        cursor = Sqlite3 database cursor
        names = list of names in the order they are expected
        '''
        ret_lst = []
        for row in cursor:
            val = {}
            for idx, item in enumerate(names):
                if not item is None:
                    val[item] = row[idx]
            ret_lst.append(val)

        return ret_lst

    @debugger
    def get_version(self):
        return self.data_version

    # Utilities
    @debugger
    def validate_type(self, var, t):
        '''
        Validate the type of the srguement. If it cannot be converted, then the program cannot continue.
        This is considered a developer error. The exceptions here only happen if the input validation
        from the GUI has failed.
        '''
        if type(var) != t:
            if t is float:
                try:
                    tmp = float(var)
                    return tmp
                except ValueError:
                    mbox.showerror(
                        "FATAL ERROR", "expected type %s but got type %s" %
                        (str(t), str(type(var))))
                    self.logger.fatal("expected type %s but got type %s" %
                                      (str(t), str(type(var))))
                except:
                    mbox.showerror("FATAL ERROR", "float type error.")
                    self.logger.fatal("float type error.")

            elif t is int:
                try:
                    tmp = int(var)
                    return tmp
                except ValueError:
                    mbox.showerror(
                        "FATAL ERROR", "expected type %s but got type %s" %
                        (str(t), str(type(var))))
                    self.logger.fatal("expected type %s but got type %s" %
                                      (str(t), str(type(var))))
                except:
                    mbox.showerror("FATAL ERROR", "int type error.")
                    self.logger.fatal("int type error.")

            elif t is bool:
                try:
                    tmp = bool(var)
                    return tmp
                except ValueError:
                    mbox.showerror(
                        "FATAL ERROR", "expected type %s but got type %s" %
                        (str(t), str(type(var))))
                    self.logger.fatal("expected type %s but got type %s" %
                                      (str(t), str(type(var))))
                except:
                    mbox.showerror("FATAL ERROR", "bool type error.")
                    self.logger.fatal("bool type error.")

            elif t is str:
                # anything can be converted to a str()
                return str(var)
            else:
                mbox.showerror(
                    "FATAL ERROR",
                    "attempt to validate an unexpected type %s as type %s." %
                    (str(type(var)), str(t)))
                self.logger.fatal(
                    "attempt to validate an unexpected type %s as type %s." %
                    (str(type(var)), str(t)))
        else:
            return var

    @debugger
    def execute(self, sql):
        self.logger.debug("SQL=%s" % (sql))
        return self.db.execute(sql)

    @debugger
    def commit(self):
        self.db.commit()
Пример #28
0
    def cleanup(self):
        """Clean up after certain side effects, such as temporary directories."""

        DELETED_TEMPDIR_MESSAGE = "Deleted temporary directory at {tempdir}"
        shutil.rmtree(self.tempdir)
        Logger.debug(DELETED_TEMPDIR_MESSAGE.format(tempdir=self.tempdir))
Пример #29
0
  def cleanup(self):
    """Clean up after certain side effects, such as temporary directories."""

    DELETED_TEMPDIR_MESSAGE = "Deleted temporary directory at {tempdir}"
    shutil.rmtree(self.tempdir)
    Logger.debug(DELETED_TEMPDIR_MESSAGE.format(tempdir=self.tempdir))
Пример #30
0
class EntryBox(tk.Frame):
    '''
    Implement a consistent interface to the entry widget
    '''
    def __init__(self,
                 master,
                 table,
                 column,
                 width=None,
                 readonly=False,
                 *args,
                 **kargs):
        '''
        master = the frame to bind this frame to
        name   = the text of the label
        table  = the name of the database table that is associated with this widget
        column = the name of the column this widget associates with
        lw = label width
        cw = control width
        '''
        self.logger = Logger(self, level=Logger.INFO)
        self.logger.debug("EntryBox enter constructor")

        super().__init__(master, *args, **kargs)

        self.table = table
        self.column = column
        self.readonly = readonly
        self.content = tk.StringVar(master)
        self.entry = tk.Entry(self, textvariable=self.content, width=width)
        self.entry.grid(row=0, column=1, padx=5, pady=5, sticky=tk.W)
        if self.readonly:
            self.entry.configure(state='readonly')

        self.row = {
            'table': self.table,
            'column': self.column,
            'self': self,
            'hasid': None
        }
        self.logger.debug("EntryBox leave constructor")

    @debugger
    def read(self):
        return self.content.get()

    @debugger
    def write(self, val):
        if self.readonly:
            self.entry.configure(state='normal')
        self.content.set(val)
        if self.readonly:
            self.entry.configure(state='readonly')

    @debugger
    def clear(self):
        self.content.set('')

    @debugger
    def get_line(self):
        '''
        Return the form entry to update the form.
        '''
        return self.row
Пример #31
0
class LineBox(tk.Frame):
    '''
    This is a container for the line widgets. It holds a variable number of
    line boxes and has the ability to write them all to the database when the
    write method is called.
    '''
    def __init__(self, master, form=None, *args, **kargs):
        '''
        master = The frame to bind the widgets to.
        name_id = The id of the line containing the customer to associate
        form = Name of the form to bind the events to.
        '''
        self.logger = Logger(self, level=Logger.DEBUG)
        self.logger.debug("Line Widget enter constructor")

        super().__init__(master, bd=1, relief=tk.RIDGE, *args, **kargs)

        #self.name_id = int(name_id)
        self.form = form
        self.events = EventHandler.get_instance()
        self.data = Database.get_instance()
        self.line_list = []
        self.crnt_index = 0
        self.events.register_event('next_button', self.clear)
        self.events.register_event('prev_button', self.clear)

        # add button
        tk.Button(self, text="Add", command=self.add).grid(row=0, column=0)
        # reset button
        tk.Button(self, text="Reset", command=self.clear).grid(row=0, column=1)

        # add one line widget
        self.add()
        # self.row = {'table': None, 'column':None, 'self':self, 'hasid':None}
        self.logger.debug("Line Widget leave constructor")

    @debugger
    def add(self):
        '''
        Method that actually adds the line to the widget.
        '''
        line = LineWidget(self, None, self.crnt_index + 1)
        line.grid(row=self.crnt_index + 1, column=0, columnspan=2, padx=5)
        self.line_list.append(line)
        self.crnt_index += 1

    # @debugger
    # def get_line(self):
    #     return self.row

    @debugger
    def clear(self):
        '''
        Reset the widget to having one blank line.
        '''
        for item in self.line_list:
            item.grid_forget()
        self.line_list = []
        self.crnt_index = 0
        self.add()

    @debugger
    def read(self, sale_id):
        '''
        Read method saves the contects to the database
        '''
        for item in self.line_list:
            (quan, name) = item.read()
            if name != '':
                row = {
                    'sale_record_ID': sale_id,
                    'quantity': quan,
                    'inventory_ID':
                    self.data.get_id_by_name('InventoryItem', name)
                }
                self.data.insert_row('ProductList', row)

        self.data.commit()

    @debugger
    def write(self):
        '''
        This function does nothing for this widget
        '''
        self.clear()
Пример #32
0
class ButtonBox(tk.Frame):
    '''
    Make the button box and register the events.
    '''
    def __init__(self,
                 master,
                 form,
                 disable_select=False,
                 disable_new=False,
                 *args,
                 **kargs):
        '''
        master = The frame to bind the widgets to.
        form = Name of the form to bind the events to.
        '''
        self.logger = Logger(self, level=Logger.INFO)
        self.logger.debug("NotesBox enter constructor")

        super().__init__(master, *args, **kargs)

        row = 0
        col = 0

        self.form = form
        self.events = EventHandler.get_instance()
        tk.Button(self, text='Prev', command=self.prev_btn).grid(row=row,
                                                                 column=col,
                                                                 padx=5,
                                                                 pady=5)
        col += 1
        tk.Button(self, text='Next', command=self.next_btn).grid(row=row,
                                                                 column=col,
                                                                 padx=5,
                                                                 pady=5)
        if not disable_select:
            col += 1
            tk.Button(self, text='Select',
                      command=self.select_btn).grid(row=row,
                                                    column=col,
                                                    padx=5,
                                                    pady=5)
        if not disable_new:
            col += 1
            tk.Button(self, text='New', command=self.new_btn).grid(row=row,
                                                                   column=col,
                                                                   padx=5,
                                                                   pady=5)
        col += 1
        tk.Button(self, text='Save', command=self.save_btn).grid(row=row,
                                                                 column=col,
                                                                 padx=5,
                                                                 pady=5)
        col += 1
        tk.Button(self, text='Delete',
                  command=self.delete_btn).grid(row=row,
                                                column=col,
                                                padx=5,
                                                pady=5)

    @debugger
    def register_events(self, next, prev, select, new, save, delete):
        '''
        next = callback for the next button
        prev = callback for the prev button
        select = callback for the select button
        new = callback for the new button
        save = callback for the save button
        delete = callback for the delete button
        '''
        self.events.register_event('next_btn_%s' % (self.form), next)
        self.events.register_event('prev_btn_%s' % (self.form), prev)
        self.events.register_event('select_btn_%s' % (self.form), select)
        self.events.register_event('new_btn_%s' % (self.form), new)
        self.events.register_event('save_btn_%s' % (self.form), save)
        self.events.register_event('delete_btn_%s' % (self.form), delete)

    @debugger
    def next_btn(self):
        self.events.raise_event('next_btn_%s' % (self.form))

    @debugger
    def prev_btn(self):
        self.events.raise_event('prev_btn_%s' % (self.form))

    @debugger
    def select_btn(self):
        self.events.raise_event('select_btn_%s' % (self.form))

    @debugger
    def new_btn(self):
        self.events.raise_event('new_btn_%s' % (self.form))

    @debugger
    def save_btn(self):
        self.events.raise_event('save_btn_%s' % (self.form))

    @debugger
    def delete_btn(self):
        self.events.raise_event('delete_btn_%s' % (self.form))