class MatchOff_Frame ( wx.Frame ): def __init__( self, main_window ): wx.Frame.__init__ ( self, main_window, id = wx.ID_ANY, title = u"Match Off Application", pos = wx.DefaultPosition, size = wx.Size( 509,498 ), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL ) self.SetSizeHintsSz( wx.DefaultSize, wx.DefaultSize ) self.SetFont( wx.Font( 11, 70, 90, 90, False, wx.EmptyString ) ) self.init_ui() self.make_menu() self.connect_events() self.Bind(EVT_MATCHOFF, self.on_update) self.colnames = list(uppercase) def init_ui(self): frame_sizer = wx.BoxSizer( wx.VERTICAL ) self.main_panel = wx.Panel( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL ) mp_sizer = wx.BoxSizer( wx.VERTICAL ) input_fg_sizer = wx.FlexGridSizer( 0, 2, 0, 0 ) input_fg_sizer.AddGrowableCol( 1 ) input_fg_sizer.SetFlexibleDirection( wx.BOTH ) input_fg_sizer.SetNonFlexibleGrowMode( wx.FLEX_GROWMODE_SPECIFIED ) self.fchooser_text = wx.StaticText( self.main_panel, wx.ID_ANY, u"Select File:", wx.DefaultPosition, wx.DefaultSize, 0 ) self.fchooser_text.Wrap( -1 ) self.fchooser_text.SetFont( wx.Font( 10, 70, 90, 90, False, wx.EmptyString ) ) input_fg_sizer.Add( self.fchooser_text, 0, wx.ALL|wx.ALIGN_RIGHT, 5 ) self.file_chooser = wx.FilePickerCtrl( self.main_panel, wx.ID_ANY, wx.EmptyString, u"Select a file", u"*.*", wx.DefaultPosition, wx.DefaultSize, wx.FLP_DEFAULT_STYLE ) self.file_chooser.SetFont( wx.Font( 10, 70, 90, 90, False, wx.EmptyString ) ) self.file_chooser.SetToolTipString( u"Click to select a file" ) input_fg_sizer.Add( self.file_chooser, 0, wx.ALL|wx.EXPAND, 5 ) self.ccy_label = wx.StaticText( self.main_panel, wx.ID_ANY, u"Currency Column:", wx.DefaultPosition, wx.DefaultSize, 0 ) self.ccy_label.Wrap( -1 ) self.ccy_label.SetFont( wx.Font( 10, 70, 90, 90, False, wx.EmptyString ) ) input_fg_sizer.Add( self.ccy_label, 0, wx.ALL|wx.ALIGN_RIGHT, 5 ) self.ccy_ctrl = wx.TextCtrl( self.main_panel, wx.ID_ANY, u"G", wx.DefaultPosition, wx.DefaultSize, 0 ) self.ccy_ctrl.SetFont( wx.Font( 10, 70, 90, 90, False, wx.EmptyString ) ) self.ccy_ctrl.SetToolTipString( u"Enter Column containing currency" ) input_fg_sizer.Add( self.ccy_ctrl, 0, wx.ALL|wx.EXPAND, 5 ) self.bal_label = wx.StaticText( self.main_panel, wx.ID_ANY, u"Balance Column:", wx.DefaultPosition, wx.DefaultSize, 0 ) self.bal_label.Wrap( -1 ) self.bal_label.SetFont( wx.Font( 10, 70, 90, 90, False, wx.EmptyString ) ) input_fg_sizer.Add( self.bal_label, 0, wx.ALL|wx.ALIGN_RIGHT, 5 ) self.bal_ctrl = wx.TextCtrl( self.main_panel, wx.ID_ANY, u"H", wx.DefaultPosition, wx.DefaultSize, 0 ) self.bal_ctrl.SetToolTipString( u"Enter column containing balances" ) input_fg_sizer.Add( self.bal_ctrl, 0, wx.ALL|wx.EXPAND, 5 ) mp_sizer.Add( input_fg_sizer, 0, wx.EXPAND|wx.ALL, 5 ) btn_sizer = wx.BoxSizer( wx.HORIZONTAL ) self.validate_btn = wx.Button( self.main_panel, wx.ID_ANY, u"Validate Input", wx.DefaultPosition, wx.DefaultSize, 0 ) self.validate_btn.SetFont( wx.Font( 10, 70, 90, 90, False, wx.EmptyString ) ) self.validate_btn.SetToolTipString( u"Click to confirm your inputs are correct" ) btn_sizer.Add( self.validate_btn, 0, wx.ALL, 5 ) self.match_btn = wx.Button( self.main_panel, wx.ID_ANY, u"Match Off", wx.DefaultPosition, wx.DefaultSize, 0 ) self.match_btn.SetFont( wx.Font( 10, 70, 90, 90, False, wx.EmptyString ) ) self.match_btn.Enable( False ) self.match_btn.Hide() self.match_btn.SetToolTipString( u"Click to start match off" ) btn_sizer.Add( self.match_btn, 0, wx.ALL, 5 ) self.stop_btn = wx.Button( self.main_panel, wx.ID_ANY, u"Stop Matching", wx.DefaultPosition, wx.DefaultSize, 0 ) self.stop_btn.Enable( False ) self.stop_btn.Hide() btn_sizer.Add( self.stop_btn, 0, wx.ALL, 5 ) mp_sizer.Add( btn_sizer, 0, wx.ALIGN_RIGHT, 5 ) self.output_ctrl = wx.TextCtrl( self.main_panel, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.Size( 100,100 ), wx.TE_MULTILINE|wx.TE_READONLY|wx.TE_WORDWRAP ) self.output_ctrl.SetFont( wx.Font( 12, 70, 90, 90, False, wx.EmptyString ) ) mp_sizer.Add( self.output_ctrl, 1, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL|wx.EXPAND, 5 ) self.main_panel.SetSizer( mp_sizer ) self.main_panel.Layout() mp_sizer.Fit( self.main_panel ) frame_sizer.Add( self.main_panel, 1, wx.EXPAND |wx.ALL, 5 ) self.SetSizer( frame_sizer ) self.Layout() def make_menu(self): self.menu_bar = wx.MenuBar( 0 ) self.file_menu = wx.Menu() self.open_mitem = wx.MenuItem( self.file_menu, wx.ID_ANY, u"&Open", wx.EmptyString, wx.ITEM_NORMAL ) self.file_menu.AppendItem( self.open_mitem ) self.file_menu.AppendSeparator() self.about_mitem = wx.MenuItem( self.file_menu, wx.ID_ANY, u"&About", wx.EmptyString, wx.ITEM_NORMAL ) self.file_menu.AppendItem( self.about_mitem ) self.file_menu.AppendSeparator() self.exit_mitem = wx.MenuItem( self.file_menu, wx.ID_ANY, u"&Exit", wx.EmptyString, wx.ITEM_NORMAL ) self.file_menu.AppendItem( self.exit_mitem ) self.menu_bar.Append( self.file_menu, u"&File" ) self.tutorial_menu = wx.Menu() self.tutorial_mitem = wx.MenuItem( self.tutorial_menu, wx.ID_ANY, u"&tutorial", wx.EmptyString, wx.ITEM_NORMAL ) self.tutorial_menu.AppendItem( self.tutorial_mitem ) self.menu_bar.Append( self.tutorial_menu, u"&Tutorial" ) self.SetMenuBar( self.menu_bar ) self.statusbar = self.CreateStatusBar( 1, wx.ST_SIZEGRIP, wx.ID_ANY ) self.Centre( wx.BOTH ) def connect_events(self): self.validate_btn.Bind( wx.EVT_BUTTON, self.on_validate ) self.match_btn.Bind( wx.EVT_BUTTON, self.on_matchoff ) self.Bind( wx.EVT_MENU, self.on_open, id = self.open_mitem.GetId() ) self.Bind( wx.EVT_MENU, self.on_about, id = self.about_mitem.GetId() ) self.Bind( wx.EVT_MENU, self.on_exit, id = self.exit_mitem.GetId() ) self.Bind( wx.EVT_MENU, self.on_tutorial, id = self.tutorial_mitem.GetId() ) self.file_chooser.Bind( wx.EVT_FILEPICKER_CHANGED, self.on_file_chooser ) self.stop_btn.Bind( wx.EVT_BUTTON, self.on_stop ) def on_file_chooser( self, event ): f = self.file_chooser.GetTextCtrlValue() fname, dirname = os.path.basename(f), os.path.dirname(f) self.make_matcher(fname, dirname) def on_validate( self, event ): if not self.confirm_matcher(): return if not self.check_col_val(): self.display_error_dlg("Either currency or balance column entered is invalid.") return else : bal_col_num = self.colnames.index( self.col_text ) ccy_col_num = self.colnames.index( self.ccy_text ) if not (bal_col_num and ccy_col_num and bal_col_num < self.m.ncols and ccy_col_num < self.m.ncols ): self.display_error_dlg( "Either currency or balance column entered is invalid." ) return if self.make_matcher_input_cols( ccy_col_num, bal_col_num ): self.validate_btn.Disable() def on_matchoff(self, evt): if not self.confirm_matcher(): return matcher_thread = MatcherThread(self) matcher_thread.start() self.file_chooser.SetPath("") self.match_btn.Disable() self.match_btn.Hide() self.stop_btn.Enable() self.stop_btn.Show() self.Layout() def on_update(self,evt): self.output_ctrl.AppendText( evt.get_value() ) def on_open( self, event ): self.dirname = '' dlg = wx.FileDialog(self, "Choose a file", self.dirname, "", "*.*", wx.OPEN) if dlg.ShowModal() == wx.ID_OK: fname = dlg.GetFilename() self.dirname = dlg.GetDirectory() self.make_matcher(fname, self.dirname) dlg.Destroy() def on_stop( self, event ): event.Skip() def make_matcher(self, fname, dirname): if self.verify_file_ext(fname): self.filename = os.path.join(dirname, fname) else: self.display_error_dlg("Invalid file selected.\nPlease select a valid excel 97-2003 file!") return if self.verify_filename(): self.m = Matcher(self.filename) self.m.dosetup() def on_about( self, event ): self.display_error_dlg(msg="An application to match off credits and debits", caption="Information") def on_exit( self, event ): self.Destroy() def on_tutorial( self, event ): event.Skip() def verify_file_ext(self, name): extension = os.path.splitext(name)[1] return extension.lower() == ".xls" def display_error_dlg(self, msg, caption="Error!!"): dlg = wx.MessageDialog(self, message=msg, caption=caption, style=wx.OK) dlg.ShowModal() dlg.Destroy() def verify_filename(self): if self.filename and self.verify_file_ext(self.filename): return True else: self.display_error_dlg("No file selected!") return False def validate_inputs(self): if not self.confirm_matcher(): return if not self.check_col_val(): self.display_error_dlg("Either currency or balance column entered is invalid.") return else : bal_col_num = self.colnames.index( self.col_text ) ccy_col_num = self.colnames.index( self.ccy_text ) if not (bal_col_num and ccy_col_num and bal_col_num < self.m.ncols and ccy_col_num < self.m.ncols ): self.display_error_dlg( "Either currency or balance column entered is invalid." ) return if not self.make_matcher_input_cols( ccy_col_num, bal_col_num ): return def confirm_matcher(self): self.m = getattr(self, "m", None) if not (self.m and self.m.filename): self.display_error_dlg('No Valid File Chosen. Please click "File" in the menubar and select "Open".') return False return True def check_col_val(self): col,ccy = self.bal_ctrl.GetValue(), self.ccy_ctrl.GetValue() if col and ccy: self.col_text = col.strip().upper() self.ccy_text = ccy.strip().upper() if self.col_text and self.ccy_text and self.col_text.isalpha() and self.ccy_text.isalpha()\ and self.col_text.upper() in self.colnames and self.ccy_text.upper() in self.colnames: return True else: return False def make_matcher_input_cols(self, ccy_col_num, bal_col_num): ccy = self.m.get_cell_val(4,ccy_col_num) if not ccy in self.m.FX: self.display_error_dlg("Selected Currency column is invalid.\nPlease input a valid currency column.") return False self.m.make_start_cols(ccy_col_num, bal_col_num) self.display_error_dlg("All inputs valid. Click 'Match Off' button to start") self.match_btn.Enable() self.match_btn.Show(True) self.validate_btn.Hide() self.Layout() return True