Exemple #1
0
 def print_csv(self, pytimer):
     res = print_times(pytimer, True)  # True is to print csv
     # Display message that was successful
     md = MsgDialog(pytimer.timewin, 'information', ['ok'], 'Success!',
                    "Results saved to CSV.")
     md.run()
     md.destroy()
Exemple #2
0
 def print_csv(self, pytimer):
     res = print_times(pytimer, True)  # True is to print csv
     # Display message that was successful
     md = MsgDialog(pytimer.timewin, 'information', ['ok'], 'Success!',
                    "Results saved to CSV.")
     md.run()
     md.destroy()
Exemple #3
0
 def print_html(self, btn_unused, pytimer):
     res = print_times(pytimer, False)
     # Display message that was successful
     md = MsgDialog(pytimer.timewin, 'information', ['ok'], 'Success!',
                    "Results saved to HTML.")
     md.run()
     md.destroy()
Exemple #4
0
 def print_html(self, btn_unused, pytimer):
     res = print_times(pytimer, False)
     # Display message that was successful
     md = MsgDialog(pytimer.timewin, 'information', ['ok'], 'Success!',
                    "Results saved to HTML.")
     md.run()
     md.destroy()
Exemple #5
0
 def store_new_project(self, jnk_unused, edit):
     '''Stores a new project to file and goes to root window'''
     logger = logging.getLogger('fstimer')
     logger.debug(self.path)
     if not edit:
         os.system('mkdir '+ self.path)
     regdata = {}
     regdata['projecttype'] = self.projecttype
     regdata['numlaps'] = self.numlaps
     regdata['variablelaps'] = self.variablelaps
     regdata['fields'] = self.fields
     regdata['fieldsdic'] = self.fieldsdic
     regdata['printfields'] = self.printfields
     regdata['divisions'] = self.divisions
     regdata['rankings'] = self.rankings
     logger.debug(regdata)
     os.makedirs(self.path, exist_ok=True)
     with open(join(self.path, basename(self.path)+'.reg'), 'w', encoding='utf-8') as fout:
         json.dump(regdata, fout)
     if edit:
         md = MsgDialog(self.rankingswin, 'information', ['ok'], 'Edited!', 'Project '+basename(self.path)+' successfully edited!')
     else:
         md = MsgDialog(self.rankingswin, 'information', ['ok'], 'Created!', 'Project '+basename(self.path)+' successfully created!')
     md.run()
     md.destroy()
     self.rankingswin.hide()
     if not edit:
         self.introwin.hide()
         self.rootwin = fstimer.gui.root.RootWin(self.path,
                                                 self.show_about,
                                                 self.import_prereg,
                                                 self.handle_preregistration,
                                                 self.compreg_window,
                                                 self.gen_pretimewin,
                                                 self.define_divisions)
Exemple #6
0
 def set_printfields(self, btnlist, btn_time, btn_pace, entry_pace, printfields_m):
     '''Update self.printfields'''
     # First check it is valid.
     if btn_pace.get_active():
         try:
             d = float(entry_pace.get_text())
         except ValueError:
             md = MsgDialog(self.printfieldswin, 'error', ['ok'], 'Error!', 'Distance must be a number.')
             md.run()
             md.destroy()
             return False
     # It will be valid. Let's continue.
     self.printfields = {}  # re-set
     # Start with the registration fields
     for field, btn in zip(self.fields, btnlist):
         if btn.get_active():
             self.printfields[field] = '{' + field + '}'
     # Then timing button and pace button
     if btn_time.get_active():
         self.printfields['Time'] = '{Time}'
     if btn_pace.get_active():
         self.printfields['Pace'] = '{Time}/' + entry_pace.get_text()
     # Finally custom fields
     for field in printfields_m:
         if field not in self.fields and field not in ['Time', 'Pace']:
             self.printfields[field] = str(printfields_m[field])
     if len(self.printfields) == 0:
         md = MsgDialog(self.printfieldswin, 'error', ['ok'], 'Error!', 'Must include at least one field.')
         md.run()
         md.destroy()
         return False
     return True
Exemple #7
0
 def rm_clicked(self, jnk_unused):
     '''Handling click on the 'remove' button of the registration window
        Throws up an 'are you sure' dialog box, and delete if yes'''
     selection = self.treeview.get_selection()
     treeiter = selection.get_selected()[1]
     # if nothing is selected, do nothing.
     if treeiter:
         rmreg_dialog = MsgDialog(self, 'warning', ['yes', 'no'], 'Really delete?', 'Are you sure you want to delete this entry?\nThis cannot be undone.')
         rmreg_dialog.set_default_response(Gtk.ResponseType.NO)
         response = rmreg_dialog.run()
         rmreg_dialog.destroy()
         if response == Gtk.ResponseType.YES:
             # Grab the current information.
             current_info = {}
             for (colid, field) in enumerate(self.fields):
                 current_info[field] = self.modelfiltersorted.get_value(treeiter, colid)
             # Find where this is in self.prereg
             preregiter = self.prereg.index(current_info)
             # converts the treeiter from sorted to filter to model, and remove
             self.regmodel.remove(self.modelfilter.convert_iter_to_child_iter(self.modelfiltersorted.convert_iter_to_child_iter(treeiter)))
             try:
                 self.ids.remove(current_info['ID'])
             except:
                 pass
             self.prereg.pop(preregiter)
             # The latest stuff has no longer been saved.
             self.regstatus.set_markup('')
Exemple #8
0
 def code_edit(self, widget, path, text):
     '''handles a change of the ranking code'''
     # Validate the code
     try:
         # First make sure all of the variables are Time or a registration field
         vars_ = re.findall("\{[^}]+\}", text)
         for var in vars_:
             name = var[1:-1]
             if not (name in self.fields or name == 'Time'):
                 raise KeyError('Cannot find variable {}'.format(name))
         # Now check that the operations work, by plugging in a float for Time, and a string
         # for everything else.
         text_test = str(text)
         for var in vars_:
             if var == '{Time}':
                 text_test = text_test.replace(var, "3.14159")
             elif self.fieldsdic[var[1:-1]]['type'] == 'entrybox_int':
                 text_test = text_test.replace(var, "20")
             else:
                 # Use a string of a number so that int() works
                 # In the future we will have typed fields.
                 text_test = text_test.replace(var, "'1000000001'")
         eval(text_test)
     except Exception as e:
         md = MsgDialog(
             self, 'error', ['ok'], 'Error!',
             'Invalid code:\n\n{}\n\nSee documentation.'.format(e))
         md.run()
         md.destroy()
         return
     treeiter = self.custommodel.get_iter(path)
     name = self.custommodel.get_value(treeiter, 0)
     self.custommodel[path][1] = text
     self.printfields[name] = text
     return
Exemple #9
0
 def resume_times(self, jnk_unused, isMerge):
     '''Handles click on Resume button'''
     chooser = Gtk.FileChooserDialog(title='Choose timing results to resume', parent=self, action=Gtk.FileChooserAction.OPEN, buttons=('Cancel', Gtk.ResponseType.CANCEL, 'OK', Gtk.ResponseType.OK))
     chooser.set_current_folder(self.path)
     ffilter = Gtk.FileFilter()
     ffilter.set_name('Timing results')
     ffilter.add_pattern('*_times.json')
     chooser.add_filter(ffilter)
     response = chooser.run()
     if response == Gtk.ResponseType.OK:
         filename = chooser.get_filename()
         try:
             with open(filename, 'r', encoding='utf-8') as fin:
                 saveresults = json.load(fin)
             newrawtimes = saveresults['rawtimes']
             if isMerge:
                 if self.rawtimes['ids'] and not self.rawtimes['times']:
                     if newrawtimes['times'] and not newrawtimes['ids']:
                         #Merge! We have IDs, merge in times.
                         self.rawtimes['times'] = list(newrawtimes['times'])
                     else:
                         raise MergeError('Must be pure IDs merged into pure times, or vice versa')
                 elif self.rawtimes['times'] and not self.rawtimes['ids']:
                     if newrawtimes['ids'] and not newrawtimes['times']:
                         #Merge! We have times, merge in IDS.
                         self.rawtimes['ids'] = list(newrawtimes['ids'])
                     else:
                         raise MergeError('Must be pure IDs merged into pure times, or vice versa')
                 else:
                     raise MergeError('Must be pure IDs merged into pure times, or vice versa')
             else:
                 self.rawtimes['ids'] = newrawtimes['ids']
                 self.rawtimes['times'] = newrawtimes['times']
                 #self.timestr = saveresults['timestr'] #We will _not_ overwrite when resuming.
                 self.t0 = saveresults['t0']
                 GLib.timeout_add(100, self.update_clock) #start the stopwatch
             # Recompute how many racers have checked in
             self.racers_in = [0] * self.numlaps
             for ID in self.rawtimes['ids']:
                 self.update_racers(ID)
             self.offset = len(self.rawtimes['times']) - len(self.rawtimes['ids'])
             # Update racers' label
             self.update_racers_label()
             self.timemodel.clear()
             if self.offset >= 0:
                 adj_ids = ['' for i_unused in range(self.offset)]
                 adj_ids.extend(self.rawtimes['ids'])
                 adj_times = list(self.rawtimes['times'])
             elif self.offset < 0:
                 adj_times = ['' for i_unused in range(-self.offset)]
                 adj_times.extend(self.rawtimes['times'])
                 adj_ids = list(self.rawtimes['ids'])
             for entry in zip(adj_ids, adj_times):
                 self.timemodel.append(list(entry))
         except (IOError, ValueError, TypeError, MergeError) as e:
             error_dialog = MsgDialog(self, 'error', ['ok'], 'Oops...', 'ERROR: Failed to %s : %s.' % ('merge' if isMerge else 'resume', e))
             response = error_dialog.run()
             error_dialog.destroy()
     chooser.destroy()
Exemple #10
0
 def restart_t0(self, jnk_unused):
     '''Handles click on restart clock button'''
     restart_t0_dialog = MsgDialog(self, 'warning', ['yes', 'no'], 'Are you sure?', 
                                   'Are you sure you want to restart the race clock?\nThis cannot be undone.')
     restart_t0_dialog.set_default_response(Gtk.ResponseType.NO)
     response = restart_t0_dialog.run()
     restart_t0_dialog.destroy()
     if response == Gtk.ResponseType.YES:
         self.t0 = time.time()
Exemple #11
0
 def print_excel(self, pytimer):
     #res = print_times(pytimer, True)
     res = print_times(
         pytimer, OutputFormat.EXCEL)  # True is to print csv OutputFormat
     # Display message that was successful
     md = MsgDialog(pytimer.timewin, 'information', ['ok'], 'Success!',
                    "Results saved to EXCEL.")
     md.run()
     md.destroy()
Exemple #12
0
 def done_timing(self, source):
     '''Handles click on the Done button
        Gives a dialog before closing.'''
     oktime_dialog2 = MsgDialog(self, 'question', ['yes', 'no', 'cancel'], 'Save?', 'Do you want to save before finishing?\nUnsaved data will be lost.')
     response2 = oktime_dialog2.run()
     oktime_dialog2.destroy()
     if response2 == Gtk.ResponseType.CANCEL:
         return
     elif response2 == Gtk.ResponseType.YES:
         self.save_times(None)
     self.hide()
Exemple #13
0
 def restart_t0(self, jnk_unused):
     '''Handles click on restart clock button'''
     restart_t0_dialog = MsgDialog(
         self, 'warning', ['yes', 'no'], 'Are you sure?',
         'Are you sure you want to restart the race clock?\nThis cannot be undone.'
     )
     restart_t0_dialog.set_default_response(Gtk.ResponseType.NO)
     response = restart_t0_dialog.run()
     restart_t0_dialog.destroy()
     if response == Gtk.ResponseType.YES:
         self.t0 = time.time()
Exemple #14
0
 def save_times(self, jnk_unused):
     '''Handles click on the Save button
        jsonn dump to the already specified filename'''
     saveresults = {}
     saveresults['rawtimes'] = self.rawtimes
     saveresults['timestr'] = self.timestr
     saveresults['t0'] = self.t0
     with open(os.path.join(self.path, os.path.basename(self.path)+'_'+self.timestr+'_times.json'), 'w', encoding='utf-8') as fout:
         json.dump(saveresults, fout)
     md = MsgDialog(self, 'information', ['ok'], 'Saved!', 'Times saved!')
     md.run()
     md.destroy()
Exemple #15
0
 def done_timing(self, source):
     '''Handles click on the Done button
        Gives a dialog before closing.'''
     oktime_dialog2 = MsgDialog(
         self, 'question', ['yes', 'no', 'cancel'], 'Save?',
         'Do you want to save before finishing?\nUnsaved data will be lost.'
     )
     response2 = oktime_dialog2.run()
     oktime_dialog2.destroy()
     if response2 == Gtk.ResponseType.CANCEL:
         return
     elif response2 == Gtk.ResponseType.YES:
         self.save_times(None)
     self.hide()
Exemple #16
0
 def preregister_ok_cb(self, jnk_unused, regid_btn, handle_registration_cb):
     '''If OK is pushed on the pre-register window.'''
     #First check if the file already exists
     regid = regid_btn.get_value_as_int()
     filename = os.path.join(self.path, os.path.basename(self.path)+'_registration_'+str(regid)+'.json')
     if os.path.exists(filename):
         #Raise a warning window
         md = MsgDialog(self, 'warning', ['ok', 'cancel'], 'Proceed?', "A file with this registration number already exists.\nIf you continue it will be overwritten!")
         resp = md.run()
         md.destroy()
         #Check the result.
         if resp == Gtk.ResponseType.CANCEL:
             #Do nothing.
             return
     #Else, continue on.
     handle_registration_cb(regid)
Exemple #17
0
 def close_clicked(self, jnk_unused):
     '''Handles click on the 'close' button on the registration window.
        Throws up a 'do you want to save' dialog, and close the window'''
     okreg_dialog = MsgDialog(self, 'question', ['yes', 'no'], 'Save?', 'Do you want to save before finishing?\nUnsaved data will be lost.')
     okreg_dialog.set_default_response(Gtk.ResponseType.YES)
     response = okreg_dialog.run()
     okreg_dialog.destroy()
     if response == Gtk.ResponseType.YES:
         # this will save
         save_res = self.save_clicked(None)
         if not save_res:
             return
     self.hide()
     # Clear the file setting from pre-reg, in case pre-reg is
     # re-run without selecting a file
     del self.prereg[:]
Exemple #18
0
 def timing_rm_time(self, jnk_unused):
     '''Handles click on Drop time comment
        Throws up an 'are you sure' dialog box, and drop if yes.'''
     treeselection = self.timeview.get_selection()
     pathlist = treeselection.get_selected_rows()[1]
     if len(pathlist) == 0:
         # we don't load any windows or do anything
         pass
     elif len(pathlist) > 1:
         # this is a one-at-a-time operation
         pass
     elif len(pathlist) == 1:
         # Figure out what row this is in the timeview
         row = pathlist[0][0]
         # Now figure out what index in self.rawtimes['times'] it is.
         timeidx = row - max(0, -self.offset)
         if timeidx >= 0:
             # Otherwise, there is no time here so there is nothing to do.
             # Ask if we are sure.
             rmtime_dialog = MsgDialog(
                 self, 'warning', ['yes', 'no'], 'Are you sure?',
                 'Are you sure you want to drop this time and shift all later times down earlier in the list?\nThis cannot be undone.'
             )
             rmtime_dialog.set_default_response(Gtk.ResponseType.NO)
             response = rmtime_dialog.run()
             rmtime_dialog.destroy()
             if response == Gtk.ResponseType.YES:
                 # Make the shift in self.rawtimes and self.offset
                 self.rawtimes['times'].pop(timeidx)
                 self.offset -= 1
                 # And now shift everything on the display.
                 rowcounter = int(row)
                 for i in range(timeidx - 1, -1, -1):
                     # Write rawtimes[i] into row rowcounter
                     treeiter = self.timemodel.get_iter((rowcounter, ))
                     self.timemodel.set_value(
                         treeiter, 1, str(self.rawtimes['times'][i]))
                     rowcounter -= 1
                 # Now we tackle the last value - there are two possibilities.
                 if self.offset < 0:
                     # There is a buffer of IDs, and this one should be cleared.
                     treeiter = self.timemodel.get_iter((rowcounter, ))
                     self.timemodel.set_value(treeiter, 1, '')
                 else:
                     # there is a blank row at the top which should be removed.
                     treeiter = self.timemodel.get_iter((rowcounter, ))
                     self.timemodel.remove(treeiter)
Exemple #19
0
 def save_times(self, jnk_unused):
     '''Handles click on the Save button
        jsonn dump to the already specified filename'''
     saveresults = {}
     saveresults['rawtimes'] = self.rawtimes
     saveresults['timestr'] = self.timestr
     saveresults['t0'] = self.t0
     with open(os.path.join(
             self.path,
             os.path.basename(self.path) + '_' + self.timestr +
             '_times.json'),
               'w',
               encoding='utf-8') as fout:
         json.dump(saveresults, fout)
     md = MsgDialog(self, 'information', ['ok'], 'Saved!', 'Times saved!')
     md.run()
     md.destroy()
Exemple #20
0
 def timing_rm_time(self, jnk_unused):
     '''Handles click on Drop time comment
        Throws up an 'are you sure' dialog box, and drop if yes.'''
     treeselection = self.timeview.get_selection()
     pathlist = treeselection.get_selected_rows()[1]
     if len(pathlist) == 0:
         # we don't load any windows or do anything
         pass
     elif len(pathlist) > 1:
         # this is a one-at-a-time operation
         pass
     elif len(pathlist) == 1:
         # Figure out what row this is in the timeview
         row = pathlist[0][0]
         # Now figure out what index in self.rawtimes['times'] it is.
         timeidx = row-max(0, -self.offset)
         if timeidx >= 0:
             # Otherwise, there is no time here so there is nothing to do.
             # Ask if we are sure.
             rmtime_dialog = MsgDialog(self, 'warning', ['yes', 'no'], 'Are you sure?', 'Are you sure you want to drop this time and shift all later times down earlier in the list?\nThis cannot be undone.')
             rmtime_dialog.set_default_response(Gtk.ResponseType.NO)
             response = rmtime_dialog.run()
             rmtime_dialog.destroy()
             if response == Gtk.ResponseType.YES:
                 # Make the shift in self.rawtimes and self.offset
                 self.rawtimes['times'].pop(timeidx)
                 self.offset -= 1
                 # And now shift everything on the display.
                 rowcounter = int(row)
                 for i in range(timeidx-1, -1, -1):
                     # Write rawtimes[i] into row rowcounter
                     treeiter = self.timemodel.get_iter((rowcounter,))
                     self.timemodel.set_value(treeiter, 1, str(self.rawtimes['times'][i]))
                     rowcounter -= 1
                 # Now we tackle the last value - there are two possibilities.
                 if self.offset < 0:
                     # There is a buffer of IDs, and this one should be cleared.
                     treeiter = self.timemodel.get_iter((rowcounter,))
                     self.timemodel.set_value(treeiter, 1, '')
                 else:
                     # there is a blank row at the top which should be removed.
                     treeiter = self.timemodel.get_iter((rowcounter,))
                     self.timemodel.remove(treeiter)
Exemple #21
0
 def name_edit(self, widget, path, text):
     '''handles a change of a ranking name'''
     treeiter = self.custommodel.get_iter(path)
     old_name = self.custommodel.get_value(treeiter, 0)
     # Check if it was changed
     if text != old_name:
         if text in ['Time', 'Pace']:
             md = MsgDialog(self, 'error', ['ok'], 'Error!',
                            'Names "Time" and "Pace" are reserved.')
             md.run()
             md.destroy()
         elif text not in self.printfields and text not in self.fields:
             self.custommodel[path][0] = text
             self.printfields[text] = self.printfields[old_name]
             self.printfields.pop(old_name)
         else:
             md = MsgDialog(self, 'error', ['ok'], 'Error!',
                            'Field name "%s" is already used!' % text)
             md.run()
             md.destroy()
     return
Exemple #22
0
 def preregister_ok_cb(self, jnk_unused, regid_btn, handle_registration_cb):
     '''If OK is pushed on the pre-register window.'''
     #First check if the file already exists
     regid = regid_btn.get_value_as_int()
     filename = os.path.join(
         self.path,
         os.path.basename(self.path) + '_registration_' + str(regid) +
         '.json')
     if os.path.exists(filename):
         #Raise a warning window
         md = MsgDialog(
             self, 'warning', ['ok', 'cancel'], 'Proceed?',
             "A file with this registration number already exists.\nIf you continue it will be overwritten!"
         )
         resp = md.run()
         md.destroy()
         #Check the result.
         if resp == Gtk.ResponseType.CANCEL:
             #Do nothing.
             return
     #Else, continue on.
     handle_registration_cb(regid)
Exemple #23
0
 def editsingletimedone(self, treeiter, new_id, new_time):
     '''Handled result of the editing of a given time'''
     row = self.timemodel.get_path(treeiter)[0]
     if not re.match('^[0-9:.]*$', new_time):
         md = MsgDialog(self, 'error', ['ok'], 'Error!',
                        'Time is not valid format.')
         md.run()
         md.destroy()
         return
     if row < self.offset:
         if new_id:
             # we are putting an ID in a slot that we hadn't reached yet
             # Fill in any other missing ones up to this point with ''.
             ids = [str(new_id)]
             ids.extend(['' for i_unused in range(self.offset - row - 1)])
             ids.extend(self.rawtimes['ids'])
             self.rawtimes['ids'] = list(ids)
             self.offset = row  #the new offset
             self.rawtimes['times'][row] = str(new_time)  #the new time
             self.timemodel.set_value(treeiter, 0, str(new_id))
             self.timemodel.set_value(treeiter, 1, str(new_time))
         elif new_time:
             # we are adjusting the time only.
             self.rawtimes['times'][row] = str(new_time)  #the new time
             self.timemodel.set_value(treeiter, 1, str(new_time))
         else:
             # we are clearing this entry. pop it from time and adjust offset.
             self.rawtimes['times'].pop(row)
             self.offset -= 1
             self.timemodel.remove(treeiter)
     elif row == self.offset and new_time and not new_id:
         # then we are clearing the most recent ID.
         # We pop it and adjust self.offset and adjust the time.
         self.rawtimes['ids'].pop(0)
         self.rawtimes['times'][row] = str(new_time)
         self.offset += 1
         self.timemodel.set_value(treeiter, 0, str(new_id))
         self.timemodel.set_value(treeiter, 1, str(new_time))
     elif row < -self.offset:
         # Here we are making edits to a slot where there is an ID, but no time.
         if new_time:
             #we are putting a time in a slot that we hadn't reached yet. Fill in any other missing ones up to this point with blanks.
             times = [str(new_time)]
             times.extend(
                 ['' for i_unused in range(-self.offset - row - 1)])
             times.extend(self.rawtimes['times'])
             self.rawtimes['times'] = list(times)
             self.offset = -row  #the new offset
             self.rawtimes['ids'][row] = str(new_id)  #the new time
             self.timemodel.set_value(treeiter, 0, str(new_id))
             self.timemodel.set_value(treeiter, 1, str(new_time))
         elif new_id:
             #we are adjusting the id only.
             self.rawtimes['ids'][row] = str(new_id)  #the new time
             self.timemodel.set_value(treeiter, 0, str(new_id))
         else:
             #we are clearing this entry. pop it from id and adjust offset.
             self.rawtimes['ids'].pop(row)
             self.offset += 1
             self.timemodel.remove(treeiter)
     else:
         if not new_time and not new_id:
             # we are clearing the entry
             if self.offset > 0:
                 self.rawtimes['ids'].pop(row - self.offset)
                 self.rawtimes['times'].pop(row)
             elif self.offset <= 0:
                 self.rawtimes['ids'].pop(row)
                 self.rawtimes['times'].pop(row + self.offset)
             self.timemodel.remove(treeiter)
         else:
             # adjust the entry; no changes to the stack otherwise.
             if self.offset > 0:
                 self.rawtimes['ids'][row - self.offset] = str(new_id)
                 self.rawtimes['times'][row] = str(new_time)
             elif self.offset <= 0:
                 self.rawtimes['ids'][row] = str(new_id)
                 self.rawtimes['times'][row + self.offset] = str(new_time)
             self.timemodel.set_value(treeiter, 0, str(new_id))
             self.timemodel.set_value(treeiter, 1, str(new_time))
     #reset lapcounter, if used..
     if self.numlaps > 1:
         self.lapcounter = defaultdict(int)
         self.lapcounter.update(Counter(self.rawtimes['ids']))
     self.winedittime.hide()
Exemple #24
0
 def resume_times(self, jnk_unused, isMerge):
     '''Handles click on Resume button'''
     chooser = Gtk.FileChooserDialog(
         title='Choose timing results to resume',
         parent=self,
         action=Gtk.FileChooserAction.OPEN,
         buttons=('Cancel', Gtk.ResponseType.CANCEL, 'OK',
                  Gtk.ResponseType.OK))
     chooser.set_current_folder(self.path)
     ffilter = Gtk.FileFilter()
     ffilter.set_name('Timing results')
     ffilter.add_pattern('*_times.json')
     chooser.add_filter(ffilter)
     response = chooser.run()
     if response == Gtk.ResponseType.OK:
         filename = chooser.get_filename()
         try:
             with open(filename, 'r', encoding='utf-8') as fin:
                 saveresults = json.load(fin)
             newrawtimes = saveresults['rawtimes']
             if isMerge:
                 if self.rawtimes['ids'] and not self.rawtimes['times']:
                     if newrawtimes['times'] and not newrawtimes['ids']:
                         #Merge! We have IDs, merge in times.
                         self.rawtimes['times'] = list(newrawtimes['times'])
                     else:
                         raise MergeError(
                             'Must be pure IDs merged into pure times, or vice versa'
                         )
                 elif self.rawtimes['times'] and not self.rawtimes['ids']:
                     if newrawtimes['ids'] and not newrawtimes['times']:
                         #Merge! We have times, merge in IDS.
                         self.rawtimes['ids'] = list(newrawtimes['ids'])
                     else:
                         raise MergeError(
                             'Must be pure IDs merged into pure times, or vice versa'
                         )
                 else:
                     raise MergeError(
                         'Must be pure IDs merged into pure times, or vice versa'
                     )
             else:
                 self.rawtimes['ids'] = newrawtimes['ids']
                 self.rawtimes['times'] = newrawtimes['times']
                 #self.timestr = saveresults['timestr'] #We will _not_ overwrite when resuming.
                 self.t0 = saveresults['t0']
                 GLib.timeout_add(100,
                                  self.update_clock)  #start the stopwatch
             # Recompute how many racers have checked in
             self.racers_in = [0] * self.numlaps
             for ID in self.rawtimes['ids']:
                 self.update_racers(ID)
             self.offset = len(self.rawtimes['times']) - len(
                 self.rawtimes['ids'])
             # Update racers' label
             self.update_racers_label()
             self.timemodel.clear()
             if self.offset >= 0:
                 adj_ids = ['' for i_unused in range(self.offset)]
                 adj_ids.extend(self.rawtimes['ids'])
                 adj_times = list(self.rawtimes['times'])
             elif self.offset < 0:
                 adj_times = ['' for i_unused in range(-self.offset)]
                 adj_times.extend(self.rawtimes['times'])
                 adj_ids = list(self.rawtimes['ids'])
             for entry in zip(adj_ids, adj_times):
                 self.timemodel.append(list(entry))
         except (IOError, ValueError, TypeError, MergeError) as e:
             error_dialog = MsgDialog(
                 self, 'error', ['ok'], 'Oops...',
                 'ERROR: Failed to %s : %s.' %
                 ('merge' if isMerge else 'resume', e))
             response = error_dialog.run()
             error_dialog.destroy()
     chooser.destroy()
Exemple #25
0
 def editsingletimedone(self, treeiter, new_id, new_time):
     '''Handled result of the editing of a given time'''
     row = self.timemodel.get_path(treeiter)[0]
     if not re.match('^[0-9:.]*$', new_time):
         md = MsgDialog(self, 'error', ['ok'], 'Error!', 'Time is not valid format.')
         md.run()
         md.destroy()
         return
     if row < self.offset:
         if new_id:
             # we are putting an ID in a slot that we hadn't reached yet
             # Fill in any other missing ones up to this point with ''.
             ids = [str(new_id)]
             ids.extend(['' for i_unused in range(self.offset-row-1)])
             ids.extend(self.rawtimes['ids'])
             self.rawtimes['ids'] = list(ids)
             self.offset = row #the new offset
             self.rawtimes['times'][row] = str(new_time) #the new time
             self.timemodel.set_value(treeiter, 0, str(new_id))
             self.timemodel.set_value(treeiter, 1, str(new_time))
         elif new_time:
             # we are adjusting the time only.
             self.rawtimes['times'][row] = str(new_time) #the new time
             self.timemodel.set_value(treeiter, 1, str(new_time))
         else:
             # we are clearing this entry. pop it from time and adjust offset.
             self.rawtimes['times'].pop(row)
             self.offset -= 1
             self.timemodel.remove(treeiter)
     elif row == self.offset and new_time and not new_id:
         # then we are clearing the most recent ID.
         # We pop it and adjust self.offset and adjust the time.
         self.rawtimes['ids'].pop(0)
         self.rawtimes['times'][row] = str(new_time)
         self.offset += 1
         self.timemodel.set_value(treeiter, 0, str(new_id))
         self.timemodel.set_value(treeiter, 1, str(new_time))
     elif row < -self.offset:
         # Here we are making edits to a slot where there is an ID, but no time.
         if new_time:
             #we are putting a time in a slot that we hadn't reached yet. Fill in any other missing ones up to this point with blanks.
             times = [str(new_time)]
             times.extend(['' for i_unused in range(-self.offset-row-1)])
             times.extend(self.rawtimes['times'])
             self.rawtimes['times'] = list(times)
             self.offset = -row #the new offset
             self.rawtimes['ids'][row] = str(new_id) #the new time
             self.timemodel.set_value(treeiter, 0, str(new_id))
             self.timemodel.set_value(treeiter, 1, str(new_time))
         elif new_id:
             #we are adjusting the id only.
             self.rawtimes['ids'][row] = str(new_id) #the new time
             self.timemodel.set_value(treeiter, 0, str(new_id))
         else:
             #we are clearing this entry. pop it from id and adjust offset.
             self.rawtimes['ids'].pop(row)
             self.offset += 1
             self.timemodel.remove(treeiter)
     else:
         if not new_time and not new_id:
             # we are clearing the entry
             if self.offset > 0:
                 self.rawtimes['ids'].pop(row-self.offset)
                 self.rawtimes['times'].pop(row)
             elif self.offset <= 0:
                 self.rawtimes['ids'].pop(row)
                 self.rawtimes['times'].pop(row+self.offset)
             self.timemodel.remove(treeiter)
         else:
             # adjust the entry; no changes to the stack otherwise.
             if self.offset > 0:
                 self.rawtimes['ids'][row-self.offset] = str(new_id)
                 self.rawtimes['times'][row] = str(new_time)
             elif self.offset <= 0:
                 self.rawtimes['ids'][row] = str(new_id)
                 self.rawtimes['times'][row+self.offset] = str(new_time)
             self.timemodel.set_value(treeiter, 0, str(new_id))
             self.timemodel.set_value(treeiter, 1, str(new_time))
     #reset lapcounter, if used..
     if self.numlaps > 1:
         self.lapcounter = defaultdict(int)
         self.lapcounter.update(Counter(self.rawtimes['ids']))
     self.winedittime.hide()