import wx import sys import os import wx.lib.mixins.listctrl as listmix from Hercules.exercisesql import * from Hercules.globals import * class ExercisesTab(wx.Panel): """Exercises tab class""" def __init__(self, parent): # Create panel wx.Panel.__init__(self, parent) # Create main sizer self.sizer = wx.BoxSizer(wx.VERTICAL) # Create exercises list sizer self.exercises_sizer = wx.BoxSizer(wx.HORIZONTAL) # Add 'ExercisesList' list into panel self.exercises_list = ExercisesList(self) # Insert exercise list into sizer self.exercises_sizer.Add(self.exercises_list, 2, wx.EXPAND) # Create sizer for control buttons self.btn_sizer = wx.BoxSizer(wx.HORIZONTAL) # Create 'Add', 'Edit' and 'Delete' buttons. # Also set up tool tip for this buttons. self.add_btn = wx.Button(self, label=_("Add")) self.add_btn.SetToolTipString(_("Add new exercise")) self.edit_btn = wx.Button(self, label=_("Edit")) self.edit_btn.SetToolTipString(_("Edit exercise")) self.del_btn = wx.Button(self, label=_("Delete")) self.del_btn.SetToolTipString(_("Delete exercise")) # Insert buttons into sizer self.btn_sizer.Add(self.add_btn, 0, wx.RIGHT, 5) self.btn_sizer.Add(self.edit_btn, 0, wx.RIGHT, 5) self.btn_sizer.Add(self.del_btn, 0, wx.RIGHT, 5) # Bind buttons events self.Bind(wx.EVT_BUTTON, self.on_add, self.add_btn) self.Bind(wx.EVT_BUTTON, self.on_edit, self.edit_btn) self.Bind(wx.EVT_BUTTON, self.on_delete, self.del_btn) # Set up master sizer self.sizer.Add(self.exercises_sizer, 1, wx.EXPAND | wx.ALL, 5) # Insert static line between list and buttons line = wx.StaticLine(self, style=wx.LI_HORIZONTAL) self.sizer.Add(line, 0, wx.EXPAND | wx.LEFT | wx.RIGHT, 5) self.sizer.Add(self.btn_sizer, 0, wx.ALL, 5) self.SetAutoLayout(True) self.SetSizer(self.sizer) def on_add(self, event): """Add new exercise""" exercise = AddNewExerciseDlg(self) # If exercise_title is not None, add it to list and db if exercise.get_exercise_title() != None: self.exercises_list.add(exercise.get_exercise_title(), exercise.get_exercise_type()) def on_edit(self, event): """Edit selected exercise""" # Get title of selected exercise exercise_title = self.exercises_list.get_exercise_title() # Get type of selected exercise exercise_type = self.exercises_list.get_exercise_type() # Edit selected exercise if exercise_title != None: exercise = EditExerciseDlg(self, exercise_title, exercise_type) # If exercise_title is Not, replace old exercise with new one if exercise.get_exercise_title() != None: self.exercises_list.edit(exercise_title, exercise.get_exercise_title(), exercise.get_exercise_type()) def on_delete(self, event): """Deleting exercise dialog box""" # Get title of selected exercise exercise = self.exercises_list.get_exercise_title() if exercise != None: msg = _("Are you sure you want delele '%s' exercise?") % exercise dlg = wx.MessageDialog(self, msg, _("Delete exercise"), wx.YES_NO | wx.ICON_WARNING) ret_val = dlg.ShowModal() if ret_val == wx.ID_YES: # Delete selected exercise self.exercises_list.delete() elif ret_val == wx.ID_NO : pass dlg.Destroy() class ExercisesList(wx.ListCtrl, listmix.ListCtrlAutoWidthMixin, ExerciseSQL): """Exercises list class""" def __init__(self, parent): # Create list control with mixins wx.ListCtrl.__init__(self, parent, style=wx.LC_REPORT | wx.LC_SINGLE_SEL) listmix.ListCtrlAutoWidthMixin.__init__(self) # Create exercises database ExerciseSQL.__init__(self, os.path.join(hercules_dir, 'exercises.db')) # Set up colums for exercises list self.InsertColumn(0, _("Title")) self.InsertColumn(1, _("Type")) # Set column width self.SetColumnWidth(0, 250) # Load exercise from database into the list self.update_list() def add(self, exercise_title, exercise_type): """Add exercise to list and save it into db""" # Insert exercise into database self.insert_exercise(exercise_title, exercise_type) self.update_list() def edit(self, old_title, new_title, new_type): """Edit selected exercise""" # Get selected item item = self._get_selected_indices() # Update selected exercise self.update_exercise(self.exercise_list[item[0]][0], new_title, new_type) self.update_list() def delete(self): """Remove exercise from list and db""" # Get selected item item = self._get_selected_indices() # Delete selected exercise from database self.delete_exercise(self.exercise_list[item[0]][0]) self.update_list() def get_exercise_title(self): """Return title of selected exercise""" # Get selected item item = self._get_selected_indices() if item != []: exercise = self._get_column_text(item[0], 0) else: exercise = None return exercise def get_exercise_type(self): """Return type of selected exercise""" # Get selected item item = self._get_selected_indices() if item != []: exercise_type = self.exercise_list[item[0]][2] else: exercise_type = None return exercise_type def update_list(self): """Updating exercise list""" self.exercise_types = [_("Compound"), _("Isolated")] self.DeleteAllItems() # Load exercise into list self.exercise_list = self.load_exercises() if self.exercise_list != []: for item in self.exercise_list: index = self.InsertStringItem(sys.maxint, item[1]) self.SetStringItem(index, 0, item[1]) self.SetStringItem(index, 1, self.exercise_types[item[2]]) else: self.exercise_list = [] def _get_selected_indices(self, state = wx.LIST_STATE_SELECTED): """get indices of selected items""" indices = [] found = 1 lastFound = -1 while found: index = self.GetNextItem(lastFound, wx.LIST_NEXT_ALL, state) if index == -1: break else: lastFound = index indices.append(index) return indices def _get_column_text(self, index, col): item = self.GetItem(index, col) return item.GetText() class ExerciseDlg(wx.Dialog): """Exercise dialog class""" def __init__(self, parent, title): # Create dialog box wx.Dialog.__init__(self, parent, title=title) # Sizer that holds all widgets in dialog box self.sizer = wx.BoxSizer(wx.VERTICAL) # Create sizer with title input box self.title_sizer = wx.BoxSizer(wx.HORIZONTAL) # Create label label = wx.StaticText(self, label=_("Title: ")) # Create title input box self.title_box = wx.TextCtrl(self, size=(250, -1)) # Insert label and title input box into sizer self.title_sizer.Add(label, 0, wx.ALIGN_CENTRE) self.title_sizer.Add(self.title_box, 1, wx.ALIGN_CENTRE) # Create sizer with type selection self.type_sizer = wx.BoxSizer(wx.HORIZONTAL) # Create type list self.type_list = (_("Compound"), _("Isolated")) # Create type selection box self.type_box = wx.RadioBox(self, label=_("Type: "), choices=self.type_list, style=wx.RA_SPECIFY_COLS) # Insert type box into sizer self.type_sizer.Add(self.type_box, 1, wx.ALIGN_CENTRE) # Create 'Ok' and 'Cancel' buttons self.btn_sizer = wx.StdDialogButtonSizer() # The 'OK' and 'Cancel' buttons btn = wx.Button(self, wx.ID_OK) self.btn_sizer.AddButton(btn) btn = wx.Button(self, wx.ID_CANCEL) self.btn_sizer.AddButton(btn) self.btn_sizer.Realize() # Set up the master sizer self.sizer.Add(self.title_sizer, 0, wx.GROW | wx.ALL, 5) self.sizer.Add(self.type_sizer, 0, wx.GROW | wx.ALL, 5) # Insert static line between controls line = wx.StaticLine(self, style=wx.LI_HORIZONTAL) self.sizer.Add(line, 0, wx.EXPAND | wx.LEFT | wx.RIGHT, 5) self.sizer.Add(self.btn_sizer, 0, wx.ALIGN_RIGHT | wx.ALL, 5) self.SetSizer(self.sizer) self.sizer.Fit(self) class AddNewExerciseDlg(ExerciseDlg): """Add new exercise class""" def __init__(self, parent): # Create exercise dialog box ExerciseDlg.__init__(self, parent, title=_("Add new exercise")) # set variables self.exercise_title = None self.exercise_type = None # cycle while True: # Show dialog box ret_val = self.ShowModal() if ret_val == wx.ID_OK: self.exercise_title = self.title_box.GetValue() self.exercise_type = self.type_box.GetSelection() # if exercise title is empty or first char is a space if self.exercise_title == '' or self.exercise_title[0] == ' ': # set variable to 'None' self.exercise_title = None self.exercise_type = None # show error message box dlg = wx.MessageDialog(self, _("Please, enter exercise title!"), _("Error"), wx.OK | wx.ICON_ERROR) dlg.ShowModal() dlg.Destroy() else: # if everything seems 'Ok' break the cycle break elif ret_val == wx.ID_CANCEL: # set variables to 'None' self.exercise_title = None self.exercise_type = None # break the cycle break self.Destroy() def get_exercise_title(self): return self.exercise_title def get_exercise_type(self): return self.exercise_type class EditExerciseDlg(ExerciseDlg): """Add new exercise class""" def __init__(self, parent, exercise_title, exercise_type): # Create exercise dialog box ExerciseDlg.__init__(self, parent, title=_("Edit exercise")) # Set up selected exercise self.title_box.SetValue(exercise_title) self.type_box.SetSelection(exercise_type) # cycle while True: # Show dialog box ret_val = self.ShowModal() if ret_val == wx.ID_OK: self.exercise_title = self.title_box.GetValue() self.exercise_type = self.type_box.GetSelection() # if exercise title is empty or first char is a space if self.exercise_title == '' or self.exercise_title[0] == ' ': self.exercise_title = None self.exercise_type = None # show error message box dlg = wx.MessageDialog(self, _("Please, enter exercise title!"), _("Error"), wx.OK | wx.ICON_ERROR) dlg.ShowModal() dlg.Destroy() else: # if everything seems 'Ok' break the cycle break elif ret_val == wx.ID_CANCEL: self.exercise_title = None self.exercise_type = None break self.Destroy() def get_exercise_title(self): return self.exercise_title def get_exercise_type(self): return self.exercise_type