Example #1
0
 def __init__(self, data_path = None, waypoint = None, pytrainer_main=None):
     logging.debug(">>")
     self.data_path = data_path
     self.waypoint=waypoint
     self.pytrainer_main = pytrainer_main
     self.htmlfile = "%s/googlemaps.html" % (self.pytrainer_main.profile.tmpdir)
     self.uc = UC()
     logging.debug("<<")
Example #2
0
 def setUp(self):
     self.ddbb = DDBB()
     main = Mock()
     main.ddbb = self.ddbb
     main.profile = Profile()
     main.ddbb.connect()
     main.ddbb.create_tables(add_default=True)  # We need a sport
     self.uc = UC()
     self.uc.set_us(False)
     self.service = ActivityService(pytrainer_main=main)
     records_table = DeclarativeBase.metadata.tables['records']
     self.ddbb.session.execute(
         records_table.insert({
             'distance': 46.18,
             'maxspeed': 44.6695617695,
             'maxpace': 1.2,
             'title': u'test activity',
             'unegative': 564.08076273,
             'upositive': 553.05993673,
             'average': 22.3882142185,
             'date_time_local': u'2016-07-24 12:58:23+0300',
             'calories': 1462,
             'beats': 115.0,
             'comments': u'test comment',
             'pace': 2.4,
             'date_time_utc': u'2016-07-24T09:58:23Z',
             'date': datetime.date(2016, 7, 24),
             'duration': 7426,
             'sport': 1,
             'maxbeats': 120.0
         }))
     laps_table = DeclarativeBase.metadata.tables['laps']
     self.ddbb.session.execute(
         laps_table.insert({
             'distance': 46181.9,
             'lap_number': 0,
             'calories': 1462,
             'elapsed_time': u'7426.0',
             'record': 1,
             'intensity': u'active',
             'avg_hr': 136,
             'max_hr': 173,
             'laptrigger': u'manual'
         }))
     self.activity = self.service.get_activity(1)
 def __init__(self, parent=None, pytrainer_main=None):
     logging.debug('>>')
     self.parent = parent
     self.pytrainer_main = pytrainer_main
     self.uc = UC()
     #self.NEARLY_ZERO = 0.0000000000000000000001
     self.ax1 = None
     self.ax2 = None
     logging.debug('<<')
Example #4
0
 def __init__(self,
              parent=None,
              pytrainer_main=None,
              conf_dir=None,
              options=None):
     #TODO could use some logging
     self.parent = parent
     self.pytrainer_main = pytrainer_main
     self.uc = UC()
     self.options = options
     self.conf_dir = conf_dir
     self.tmpdir = self.pytrainer_main.profile.tmpdir
     self.data_path = self.pytrainer_main.profile.data_path
     self.googlemaps = Googlemaps(data_path=self.data_path,
                                  pytrainer_main=pytrainer_main)
     self.wp = None
Example #5
0
    def __init__(self, sport_service, parent=None):
        self.parent = parent
        self.uc = UC()
        """ Initialize all query parameters to valid default values"""
        self.title = ''
        self.sport = 0
        self.past = 0
        self.duration = 0
        self.distance = 0
        self.listSport = sport_service.get_all_sports()

        self.listPast = [[_('All Time'), -99999], [_('Last 4 Weeks'), -31],
                         [_('Last 6 Months'), -183],
                         [_('Last 12 Months'), -366]]

        self.listDuration = [[_('All Durations'), [0, 999999]],
                             [_('<1 Hour'), [0, 3600]],
                             [_('1-2 Hours'), [3600, 7200]],
                             [_('>2 Hours'), [7200, 999999]]]
        """
        self.listDistanceUS = [['All Distances', [0.0,999999.9]],
                             ['<1 mi', [0.0, 1.609344]],
                             ['1-5 mi', [1.609344, 8.04672]],
                             ['5-10 mi', [8.04672, 16.09344]],
                             ['10-20 mi', [16.09344, 32.18688]],
                             ['20-50 mi', [32.18688, 80.4672]],
                             ['>50 mi', [80.4672, 999999.9]]]        
                                                            
        self.listDistance = [['All Distances', [0.0,999999.9]],
                             ['<1 km', [0.0, 1.0]],
                             ['1-5 km', [1.0, 5.0]],
                             ['5-20 km', [5.0, 20.0]],
                             ['20-50 km', [20.0, 50.0]],
                             ['50-100 km', [50.0, 100.0]],
                             ['>100 km', [100.0, 999999.9]]]
        """

        self.listDistance = UC_LISTDISTANCE[self.uc.us]
        #print self.listDistance
        self.setup_lsa_sport()
        self.setup_lsa_past()
        self.setup_lsa_duration()
        self.setup_lsa_distance()
Example #6
0
 def setUp(self):
     self.ddbb = DDBB()
     main = Mock()
     main.ddbb = self.ddbb
     main.profile = Profile()
     main.ddbb.connect()
     main.ddbb.create_tables(add_default=True) # We need a sport
     self.uc = UC()
     self.uc.set_us(False)
     self.service = ActivityService(pytrainer_main=main)
     records_table = DeclarativeBase.metadata.tables['records']
     self.ddbb.session.execute(records_table.insert({'distance': 46.18,
                                                         'maxspeed': 44.6695617695,
                                                         'maxpace': 1.2,
                                                         'title': u'test activity',
                                                         'unegative': 564.08076273,
                                                         'upositive': 553.05993673,
                                                         'average': 22.3882142185,
                                                         'date_time_local': u'2016-07-24 12:58:23+0300',
                                                         'calories': 1462,
                                                         'beats': 115.0,
                                                         'comments': u'test comment',
                                                         'pace': 2.4,
                                                         'date_time_utc': u'2016-07-24T09:58:23Z',
                                                         'date': datetime.date(2016, 7, 24),
                                                         'duration': 7426,
                                                         'sport': 1,
                                                         'maxbeats': 120.0}))
     laps_table = DeclarativeBase.metadata.tables['laps']
     self.ddbb.session.execute(laps_table.insert({'distance': 46181.9,
                                                  'lap_number': 0,
                                                  'calories': 1462,
                                                      'elapsed_time': u'7426.0',
                                                      'record': 1,
                                                      'intensity': u'active',
                                                      'avg_hr': 136,
                                                      'max_hr': 173,
                                                      'laptrigger': u'manual'}))
     self.activity = self.service.get_activity(1)
Example #7
0
 def setUp(self):
     env = Environment()
     env.data_path = os.curdir
     env.create_directories()
     self.main = mock.Mock()
     self.main.ddbb = DDBB()
     self.main.ddbb.connect()
     self.main.ddbb.create_tables()
     self.main.profile = Profile()
     self.main.uc = UC()
     self.sport_service = SportService(self.main.ddbb)
     non_linear_sport = self.sport_service.get_sport(1)
     self.main.ddbb.session.delete(non_linear_sport)
     self.main.ddbb.session.commit()
     make_transient(non_linear_sport)
     non_linear_sport.id = None
     self.main.ddbb.session.add(non_linear_sport)
     self.main.ddbb.session.commit()
     self.main.record = Record(self.sport_service, parent=self.main)
     self.parent = Main(self.sport_service, parent=self.main)
     self.main.ddbb.session.add(
         Activity(sport=non_linear_sport,
                  date=datetime.datetime(2018, 5, 6, 10, 0, 0),
                  duration=1000,
                  distance=25))
     self.main.ddbb.session.add(
         Activity(sport=non_linear_sport,
                  date=datetime.datetime(2018, 1, 6, 10, 0, 0),
                  duration=10000,
                  distance=150))
     self.main.ddbb.session.add(
         Activity(sport=self.sport_service.get_sport(2),
                  date=datetime.datetime(2018, 1, 6, 10, 0, 0),
                  duration=10000,
                  distance=100))
     self.main.ddbb.session.commit()
Example #8
0
    def __init__(self, equipment_service, data_path = None, listSport = None, parent = None, date = None, title=None, distance=None, time=None, upositive=None, unegative=None, bpm=None, calories=None, comment=None, windowTitle=None, equipment=[]):
        logging.debug(">>")
        self.parent = parent
        self.pytrainer_main = parent.pytrainer_main
        #self.us = self.pytrainer_main.profile.prf_us_system #DEPRECATED
        self.uc = UC()
        logging.debug("Using US system: "+ str(self.uc.us))
        self.data_path = data_path
        glade_path="glade/newrecord.glade"
        root = "newrecord"
        domain = None
        self.mode = "newrecord"
        self.id_record = ""
        self.store = None
        self.active_row = None
        self.activity_data = [] 
        SimpleGladeApp.__init__(self, data_path+glade_path, root, domain)
        self.conf_options = [
            "rcd_date",
            "rcd_sport",
            "rcd_distance",
            "rcd_beats",
            "rcd_comments",
            "rcd_average",
            "rcd_calories",
            "rcd_title",
            "rcd_gpxfile",
            "rcd_upositive",
            "rcd_unegative",
            "rcd_maxbeats",
            "rcd_pace",
            "rcd_maxpace",
            "rcd_maxvel",
            ]
        self.listSport = {}
        for sport in listSport:
            self.listSport[sport.id] = sport.name
        for i in self.listSport:    
            self.rcd_sport.insert_text(i,self.listSport[i])
        self.rcd_sport.set_active(0)

        if windowTitle is not None:
            self.newrecord.set_title(windowTitle)
        if date != None:
            self.setDate(date)
        if title != None:
            self.rcd_title.set_text(title)
        if distance != None:
            #self.rcd_distance.set_text(distance)
            #myset_text(rcd_distance, 'distance', distance, us=self.us, round=2)
            self.rcd_distance.set_text(self.uc.distance(distance))
        if time != None:
            self.setTime(time)
        if distance!=None and time!=None:
            self.on_calcavs_clicked(None)
        if upositive != None:
            self.rcd_upositive.set_text(self.uc.height(upositive))
        if unegative != None:
            self.rcd_unegative.set_text(self.uc.height(unegative))
        if calories != None:
            self.rcd_calories.set_text(calories)
            
        #populate labels with units        
        self.label_rcd_distance.set_text('Distance (%s)' %self.uc.unit_distance)
        self.label_rcd_maxvel.set_text('Max (%s)' %self.uc.unit_speed)
        self.label_rcd_average.set_text('Average (%s)' %self.uc.unit_speed)
        self.label_rcd_maxpace.set_text('Max (%s)' %self.uc.unit_pace)
        self.label_rcd_pace.set_text('Pace (%s)' %self.uc.unit_pace)
        self.label_rcd_upositive.set_text('Ascent (%s)' %self.uc.unit_height)
        self.label_rcd_unegative.set_text('Descent (%s)' %self.uc.unit_height)        

        self._init_equipment(equipment, equipment_service)
        logging.debug("<<")
Example #9
0
class WindowRecord(SimpleGladeApp):
    def __init__(self, equipment_service, data_path = None, listSport = None, parent = None, date = None, title=None, distance=None, time=None, upositive=None, unegative=None, bpm=None, calories=None, comment=None, windowTitle=None, equipment=[]):
        logging.debug(">>")
        self.parent = parent
        self.pytrainer_main = parent.pytrainer_main
        #self.us = self.pytrainer_main.profile.prf_us_system #DEPRECATED
        self.uc = UC()
        logging.debug("Using US system: "+ str(self.uc.us))
        self.data_path = data_path
        glade_path="glade/newrecord.glade"
        root = "newrecord"
        domain = None
        self.mode = "newrecord"
        self.id_record = ""
        self.store = None
        self.active_row = None
        self.activity_data = [] 
        SimpleGladeApp.__init__(self, data_path+glade_path, root, domain)
        self.conf_options = [
            "rcd_date",
            "rcd_sport",
            "rcd_distance",
            "rcd_beats",
            "rcd_comments",
            "rcd_average",
            "rcd_calories",
            "rcd_title",
            "rcd_gpxfile",
            "rcd_upositive",
            "rcd_unegative",
            "rcd_maxbeats",
            "rcd_pace",
            "rcd_maxpace",
            "rcd_maxvel",
            ]
        self.listSport = {}
        for sport in listSport:
            self.listSport[sport.id] = sport.name
        for i in self.listSport:    
            self.rcd_sport.insert_text(i,self.listSport[i])
        self.rcd_sport.set_active(0)

        if windowTitle is not None:
            self.newrecord.set_title(windowTitle)
        if date != None:
            self.setDate(date)
        if title != None:
            self.rcd_title.set_text(title)
        if distance != None:
            #self.rcd_distance.set_text(distance)
            #myset_text(rcd_distance, 'distance', distance, us=self.us, round=2)
            self.rcd_distance.set_text(self.uc.distance(distance))
        if time != None:
            self.setTime(time)
        if distance!=None and time!=None:
            self.on_calcavs_clicked(None)
        if upositive != None:
            self.rcd_upositive.set_text(self.uc.height(upositive))
        if unegative != None:
            self.rcd_unegative.set_text(self.uc.height(unegative))
        if calories != None:
            self.rcd_calories.set_text(calories)
            
        #populate labels with units        
        self.label_rcd_distance.set_text('Distance (%s)' %self.uc.unit_distance)
        self.label_rcd_maxvel.set_text('Max (%s)' %self.uc.unit_speed)
        self.label_rcd_average.set_text('Average (%s)' %self.uc.unit_speed)
        self.label_rcd_maxpace.set_text('Max (%s)' %self.uc.unit_pace)
        self.label_rcd_pace.set_text('Pace (%s)' %self.uc.unit_pace)
        self.label_rcd_upositive.set_text('Ascent (%s)' %self.uc.unit_height)
        self.label_rcd_unegative.set_text('Descent (%s)' %self.uc.unit_height)        

        self._init_equipment(equipment, equipment_service)
        logging.debug("<<")
        
    def _init_equipment(self, selected_equipment, equipment_service):
        equipment = {}
        active_equipment = equipment_service.get_active_equipment()
        for item in active_equipment:
            equipment[item] = False
        if len(active_equipment) == 0:
            self.noActiveEquipmentMessageContainer.set_visible(True)
        for item in selected_equipment:
            equipment[item] = True
        list_store = gtk.ListStore(int, str, bool)
        for item in equipment:
            list_store.append((item.id, item.description, equipment[item]))
        tree_view = self.treeviewRecordEquipment
        cell_renderer = gtk.CellRendererToggle()
        cell_renderer.connect('toggled', self._equipment_selection_toggled)
        tree_view.append_column(gtk.TreeViewColumn("Selected", cell_renderer, active=2))
        tree_view.append_column(gtk.TreeViewColumn("Equipment Item", gtk.CellRendererText(), text=1))
        tree_view.set_model(list_store)
    
    def _equipment_selection_toggled(self, widget, path):
        list_store = self.treeviewRecordEquipment.get_model()
        iter = list_store.get_iter(path)
        value = list_store.get_value(iter, 2)
        list_store.set(iter, 2, not value)
    
    def _get_selected_equipment_ids(self):
        selected_ids = []
        list_store = self.treeviewRecordEquipment.get_model()
        iter = list_store.get_iter_first()
        while iter is not None:
            id = list_store.get_value(iter, 0)
            selected = list_store.get_value(iter, 2)
            if selected:
                selected_ids.append(id)
            iter = list_store.iter_next(iter)
        return selected_ids
    
    def getActivityData(self):
        return self.activity_data
        
    def populateMultiWindow(self, activities):
        logging.debug(">>")
        self.mode = "multiple_activities"
        #activities (activity_id, start_time, distance, duration, sport, gpx_file, file_id)
        self.activity_data = []
        #Make treeview
        self.store = self.build_tree_view()
        #Add data
        for activity in activities:
            iter = self.store.append()
            self.store.set(
                    iter,
                    0, activity[0],
                    1, activity[1],
                    2, activity[2],
                    3, activity[3],
                    4, activity[4],
                    5, activity[5]
                    )
            details = {}
            details["complete"]  = False
            details["rcd_distance"] = activity[2]
            duration = activity[3]
            if duration.count(":") == 2:
                hours, mins, secs = duration.split(":")
            else:
                hours = mins = secs = 0
            #details["rcd_hour"] = float(hours)
            #details["rcd_min"] = float(mins)
            #details["rcd_second"] = float(secs)
            #details["rcd_time"] = (((float(hours) * 60) + float(mins)) * 60) + float(secs)
            details["activity_id"] = activity[0]
            details["rcd_time"] = (float(hours), float(mins), float(secs))
            details["rcd_sport"] = activity[4]
            details["rcd_gpxfile"] = activity[5]
            details["file_id"] = activity[6]
            self.activity_data.append(details)
        self.scrolledwindowEntries.show_all()
        #Hide some of the buttons
        self.button25.hide() #GPX file "Open" button
        self.button24.hide() #GPX file "Calculate Values" button
        self.button10.hide() #Distance "Calculate" button
        self.button11.hide() #Duration "Calculate" button
        #self.button12.hide() #Velocity "Calculate" button
        self.button43.hide() #Pace "Calculate" button
        #Make GPX file 'unsensitive'
        self.rcd_gpxfile.set_sensitive(0)       
        while gtk.events_pending(): # This allows the GUI to update 
            gtk.main_iteration()    # before completion of this entire action
        #Select first row and display details
        self.treeviewEntries.set_cursor(0)
        self.show_treeviewEntries_row(0)
        logging.debug("<<")
        
    def build_tree_view(self):
        store = gtk.ListStore(  gobject.TYPE_STRING,
                                gobject.TYPE_STRING,
                                gobject.TYPE_STRING,
                                gobject.TYPE_STRING, 
                                gobject.TYPE_STRING, 
                                gobject.TYPE_STRING )
        column_names=["id", _("Start Time"), _("Distance"),_("Duration"),_("Sport"), _("GPX File")]
        for column_index, column_name in enumerate(column_names):
            #Add columns
            column = gtk.TreeViewColumn(column_name, gtk.CellRendererText(), text=column_index)
            column.set_sort_column_id(column_index)
            if column_name == "id":
                column.set_visible(False)
            column.set_resizable(True)
            self.treeviewEntries.append_column(column)
        self.treeviewEntries.set_headers_clickable(True)
        self.treeviewEntries.set_model(store)
        return store
        
    def on_accept_clicked(self,widget):
        logging.debug(">>")
        if self.mode == "multiple_activities":
            logging.debug("multiple_activities")
            #Check for edited data in comments
            if self.active_row is not None:
                buffer = self.rcd_comments.get_buffer()
                start,end = buffer.get_bounds()
                comments = buffer.get_text(start,end, True).replace("\"","'")
                self.activity_data[self.active_row]["rcd_comments"] = comments
                #Advanced tab items
                self.activity_data[self.active_row]["rcd_maxpace"] = self.rcd_maxpace.get_text()
                self.activity_data[self.active_row]["rcd_pace"] = self.rcd_pace.get_text()
                self.activity_data[self.active_row]["rcd_upositive"] = self.rcd_upositive.get_text()
                self.activity_data[self.active_row]["rcd_unegative"] = self.rcd_unegative.get_text()
                self.activity_data[self.active_row]["rcd_maxbeats"] = self.rcd_maxbeats.get_text()
                self.activity_data[self.active_row]["rcd_beats"] = self.rcd_beats.get_text()
                self.activity_data[self.active_row]["rcd_calories"] = self.rcd_calories.get_text()
            row = 0 
            for activity in self.activity_data:
                index = self.activity_data.index(activity)
                if activity["complete"] is False:
                    #Did not view or modify this record - need to get all the details
                    print "Activity incomplete.. " + activity["rcd_gpxfile"]
                    self.update_activity_data(row, activity["rcd_gpxfile"], activity["rcd_sport"])
                activity["rcd_title"] = activity["rcd_title"].replace("\"","'")
                #Add activity to DB etc
                laps = activity.pop("laps", ())
                selected_equipment_ids = self._get_selected_equipment_ids()
                self.activity_data[index]["db_id"] = self.parent.insertRecord(activity, laps, equipment=selected_equipment_ids)
                row += 1
            logging.debug("Processed %d rows of activity data" % row)
        else:
            logging.debug("Single activity")
            list_options = {}
            trackSummary = {}
            list_options["rcd_date"] = self.rcd_date.get_text()
            list_options["rcd_sport"] = self.rcd_sport.get_active_text()
            list_options["rcd_distance"] = self.uc.usr2sys_str('distance', self.rcd_distance.get_text())
            list_options["rcd_beats"] = self.rcd_beats.get_text()
            list_options["rcd_average"] = self.uc.usr2sys_str('speed', self.rcd_average.get_text())
            list_options["rcd_calories"] = self.rcd_calories.get_text()
            list_options["rcd_title"] = self.rcd_title.get_text().replace("\"","'")
            list_options["rcd_gpxfile"] = self.rcd_gpxfile.get_text()
            list_options["rcd_upositive"] = self.uc.usr2sys_str('height', self.rcd_upositive.get_text())
            list_options["rcd_unegative"] = self.uc.usr2sys_str('height', self.rcd_unegative.get_text())
            list_options["rcd_maxbeats"] = self.rcd_maxbeats.get_text()
            # 2011.11.05 - dgranda
            # Pace is shown to user in mm:ss format
            # But pace in database is stored in a mixed way: 4.30 for 4:30 (4.5 in 'decimal'). This needs to be changed!!
            list_options["rcd_pace"] = self.uc.usr2sys_str('pace', self.rcd_pace.get_text().replace(":","."))
            list_options["rcd_maxpace"] = self.uc.usr2sys_str('pace', self.rcd_maxpace.get_text().replace(":","."))
            list_options["rcd_maxvel"] = self.uc.usr2sys_str('speed', self.rcd_maxvel.get_text())
            list_options["rcd_time"] = [self.rcd_hour.get_value_as_int(),self.rcd_min.get_value_as_int(),self.rcd_second.get_value_as_int()]
            buffer = self.rcd_comments.get_buffer()
            start,end = buffer.get_bounds()
            comment = buffer.get_text(start,end, True)
            list_options["rcd_comments"] = comment.replace("\"","'")
            selected_equipment_ids = self._get_selected_equipment_ids()
            # Added to change start time, only activities without GPX+ source file - dgranda 2011/06/10
            record_time = self.rcd_starttime.get_text()
            record_date = self.rcd_date.get_text()
            localtz = Date().getLocalTZ()
            date = dateutil.parser.parse(record_date+" "+record_time+" "+localtz)
            local_date = str(date)
            utc_date = date.astimezone(tzutc()).strftime("%Y-%m-%dT%H:%M:%SZ")
            list_options["date_time_utc"] = utc_date
            list_options["date_time_local"] = local_date

            if self.mode == "newrecord":
                logging.debug('Track data: '+str(list_options))
                if list_options["rcd_gpxfile"] != "":
                    logging.info('Adding new activity based on GPX file')
                    self.parent.insertRecord(list_options, None, selected_equipment_ids)
                else:
                    logging.info('Adding new activity based on provided data')
                    #Manual entry, calculate time info
                    record_time = self.rcd_starttime.get_text()
                    record_date = self.rcd_date.get_text()
                    localtz = Date().getLocalTZ()
                    date = dateutil.parser.parse(record_date+" "+record_time+" "+localtz)
                    local_date = str(date)
                    utc_date = date.astimezone(tzutc()).strftime("%Y-%m-%dT%H:%M:%SZ")
                    list_options["date_time_utc"] = utc_date
                    list_options["date_time_local"] = local_date
                    self.parent.insertRecord(list_options, equipment=selected_equipment_ids)
            elif self.mode == "editrecord":
                self.parent.updateRecord(list_options, self.id_record, equipment=selected_equipment_ids)
        logging.debug("<<")
        self.close_window()
    
    def on_cancel_clicked(self,widget):
        self.close_window()

    def close_window(self, widget=None):
        self.newrecord.hide()
        #self.newrecord = None
        self.quit()

    def on_calendar_clicked(self,widget):
        calendardialog = WindowCalendar(self.data_path,self, date=self.rcd_date.get_text())
        calendardialog.run()

    def setDate(self,date):
        self.rcd_date.set_text(date)

    def setTime(self,timeInSeconds):
        time_in_hour = int(timeInSeconds)/3600.0
        hour = int(time_in_hour)
        min = int((time_in_hour-hour)*60)
        sec = (((time_in_hour-hour)*60)-min)*60
        self.rcd_hour.set_value(hour)
        self.rcd_min.set_value(min)
        self.rcd_second.set_value(sec)

    def setValue(self,var_name,value, format="%0.2f"):
        var = getattr(self,var_name)
        try:
            valueString = format % value
            var.set_text(valueString)
        except Exception as e:
            print var_name, value, e
            pass
    
    def setValuesFromActivity(self, activity):
        logging.debug(">>")
        self.mode = "editrecord"
        if activity is None:
            logging.debug("activity is None")
            logging.debug("<<")
            return
        self.id_record = activity.id_record
        (h, m, s) = activity.time_tuple
        self.rcd_hour.set_value(h)
        self.rcd_min.set_value(m)
        self.rcd_second.set_value(s)
        self.rcd_date.set_text(str(activity.date))
        
        #self.rcd_distance.set_text("%.2f"%activity.distance)
        #myset_text(self.rcd_distance, 'distance', activity.distance, us=self.us, round=2)
        if activity.distance is not None:
            self.rcd_distance.set_text("%.2f" %self.uc.distance(activity.distance))        
        else:
            self.rcd_distance.set_text("")
        self.rcd_average.set_text("%.2f" %self.uc.speed(activity.average))
        self.rcd_calories.set_text("%s"%activity.calories)
        self.rcd_beats.set_text("%s"%activity.beats)
        self.rcd_upositive.set_text("%.2f" %self.uc.height(activity.upositive))
        self.rcd_unegative.set_text("%.2f" %self.uc.height(activity.unegative))
        self.rcd_maxvel.set_text("%.2f" %self.uc.speed(activity.maxspeed))
        self.rcd_maxpace.set_text("%s" %self.parent.pace_from_float(self.uc.pace(activity.maxpace),True)) # value coming from DB
        self.rcd_pace.set_text("%s" %self.parent.pace_from_float(self.uc.pace(activity.pace),True)) # value coming from DB
        self.rcd_maxbeats.set_text("%s"%activity.maxbeats)
        self.rcd_title.set_text(activity.title)
        
        if activity.starttime is not None:
            self.rcd_starttime.set_text("%s" % activity.starttime)
        sportPosition = self.getSportPosition(activity.sport_id)
        self.rcd_sport.set_active(sportPosition) 
        buffer = self.rcd_comments.get_buffer()
        start,end = buffer.get_bounds()
        buffer.set_text(activity.comments)
        if activity.gpx_file is not None:
            self.rcd_gpxfile.set_text(activity.gpx_file)
            self.frameGeneral.set_sensitive(0)      #Currently record values not changed if a GPX file is present
            self.frameVelocity.set_sensitive(0)     #Greying out options to indicate this to user
            self.framePace.set_sensitive(0)
            self.frameElevation.set_sensitive(0)
            self.frameBeats.set_sensitive(0)
        logging.debug("<<")
        
    def setValues(self,values):
        #(24, u'2009-12-26', 4, 23.48, u'9979', 0.0, 8.4716666232200009, 2210, u'', None, u'', 573.0, 562.0, 11.802745244400001, 5.0499999999999998, 7.04, 0.0, u'2009-12-25T19:41:48Z', u'2009-12-26 08:41:48+13:00')
        #(50, u'2006-10-13', 1, 25.0, u'5625', 0.0, 16.0, 0, u'', gpsfile, title,upositive,unegative,maxspeed|maxpace|pace|maxbeats
        print "windowrecord setValues called"
        self.mode = "editrecord"
        self.id_record = values[0]
        self.setTime(values[4])
        self.rcd_date.set_text(str(values[1]))
        self.setValue("rcd_distance",values[3])
        self.setValue("rcd_average",values[6])
        self.setValue("rcd_calories",values[7], "%0.0f")
        self.setValue("rcd_beats",values[5], "%0.0f")
        self.setValue("rcd_upositive",values[11])
        self.setValue("rcd_unegative",values[12])
        self.setValue("rcd_maxvel",values[13])
        self.setValue("rcd_maxpace",values[14])
        self.setValue("rcd_pace",values[15])
        self.setValue("rcd_maxbeats",values[16], "%0.0f")
        self.rcd_title.set_text("%s"%values[10])
        
        local_time = values[18]
        if local_time is not None:
            dateTime = dateutil.parser.parse(local_time)
            sTime = dateTime.strftime("%X")
            self.rcd_starttime.set_text("%s" % sTime)
        sportID = values[2]
        sportPosition = self.getSportPosition(sportID)
        self.rcd_sport.set_active(sportPosition) 
        buffer = self.rcd_comments.get_buffer()
        start,end = buffer.get_bounds()
        buffer.set_text(values[8])

    def getSportPosition(self, sportID):
        """
            Function to determine the position in the sport array for a given sport ID
            Needed as once sports are deleted there are gaps in the list...
        """
        count = 0
        for key, value in self.listSport.iteritems():
            if key == sportID: 
                return count
            count +=1
        return 0
        
    def getSportPositionByName(self, sport):
        """
            Function to determine the position in the sport array for a given sport 
            Needed as once sports are deleted there are gaps in the list...
        """
        count = 0
        for key, value in self.listSport.iteritems():
            if value == sport: 
                return count
            count +=1
        return None
    
    def on_calctime_clicked(self,widget):
        logging.debug(">>")
        try:
            distance = float(self.rcd_distance.get_text()) # distance is mandatory!
            # we need either pace or speed
            try:
                average = float(self.rcd_average.get_text())
                time_in_hour = distance/average
                logging.debug("Distance: %0.3f km (mi) | Speed: %0.2f -> Time: %.f hours  " %(distance,average,time_in_hour)) 
                pace = self.parent.pace_from_float(60/average)
                logging.debug("Setting pace: %s" %pace)
                self.rcd_pace.set_text(pace)
            except:
                pace_dec = self.parent.pace_to_float(self.rcd_pace.get_text())
                time_in_hour = pace_dec*distance/60.0
                logging.debug("Distance: %0.3f km (mi) | Pace_dec: %0.2f -> Time: %.f hours" %(distance,pace_dec,time_in_hour))
                speed = distance/time_in_hour
                logging.debug("Setting average speed: %0.2f" %speed)
                self.rcd_average.set_text("%0.2f" %speed)
            self.set_recordtime(time_in_hour)
        except:
            logging.debug("Traceback: %s" % traceback.format_exc())
            pass
        logging.debug("<<")

    def update_activity_data(self, row, gpx_file, sport):
        self.activity_data[row]["rcd_comments"] = ""
        gpx_summary, laps = self.parent.summaryFromGPX(gpx_file, (sport,""))
        local_time = gpx_summary['date_time_local']
        start_date = local_time.strftime("%Y-%m-%d")
        start_time = local_time.strftime("%H:%M:%S")
        self.activity_data[row]["rcd_date"] = start_date
        self.activity_data[row]["rcd_starttime"] = start_time
        self.activity_data[row]["date_time_local"] = gpx_summary['date_time_local']
        self.activity_data[row]["date_time_utc"] = gpx_summary['date_time_utc']
        self.activity_data[row]["rcd_distance"] = gpx_summary["rcd_distance"]
        self.activity_data[row]["rcd_average"] = gpx_summary["rcd_average"]
        self.activity_data[row]["rcd_calories"] = gpx_summary["rcd_calories"]
        self.activity_data[row]["rcd_beats"] = gpx_summary["rcd_beats"]
        self.activity_data[row]["rcd_upositive"] = gpx_summary["rcd_upositive"]
        self.activity_data[row]["rcd_unegative"] = gpx_summary["rcd_unegative"]
        self.activity_data[row]["rcd_maxvel"] = gpx_summary["rcd_maxvel"]
        self.activity_data[row]["rcd_maxpace"] = gpx_summary["rcd_maxpace"]
        self.activity_data[row]["rcd_pace"] = gpx_summary["rcd_pace"]
        self.activity_data[row]["rcd_maxbeats"] = gpx_summary["rcd_maxbeats"]
        self.activity_data[row]["rcd_title"] = ""
        self.activity_data[row]["laps"] = laps
        self.activity_data[row]["complete"] = True

        
    def show_treeviewEntries_row(self, row):
        '''
        Show details of treeview entry
        TODO need to maintain any changes and display those....
        '''
        self.active_row = row
        #Get details from stored data
        #set sport
        sport = self.activity_data[row]["rcd_sport"]
        sportPosition = self.getSportPositionByName(sport)
        if sportPosition is not None:
            self.rcd_sport.set_active(sportPosition)
        #Set gpx file name
        gpx_file = self.activity_data[row]["rcd_gpxfile"]
        self.setValue("rcd_gpxfile", gpx_file, "%s")
        #set duration
        time = Date().time2second(self.activity_data[row]["rcd_time"])      #TODO Fix to use timeinseconds!!
        self.setTime(time)                                                  #TODO Fix to use timeinseconds!!
        #Set distance
        self.setValue("rcd_distance",self.activity_data[row]["rcd_distance"], "%s")
        #Set comments
        buffer = self.rcd_comments.get_buffer()
        start,end = buffer.get_bounds()
        if "rcd_comments" not in self.activity_data[row]:
            self.activity_data[row]["rcd_comments"] = ""
        buffer.set_text(self.activity_data[row]["rcd_comments"])
        while gtk.events_pending(): # This allows the GUI to update 
            gtk.main_iteration()    # before completion of this entire action
        if self.activity_data[row]["complete"] is False:
            #Haven't processed GPX file yet
            #Blank values not yet known
            self.setValue("rcd_date", "", "%s")
            self.setValue("rcd_starttime", "", "%s")
            self.setValue("rcd_average", "", "%s")
            self.setValue("rcd_calories","", "%s")
            self.setValue("rcd_beats", "", "%s")
            self.setValue("rcd_upositive", "", "%s")
            self.setValue("rcd_unegative", "", "%s")
            self.setValue("rcd_maxvel", "", "%s")
            self.rcd_maxpace.set_text("")
            self.rcd_pace.set_text("")
            self.setValue("rcd_maxbeats", "", "%s")
            while gtk.events_pending(): # This allows the GUI to update 
                gtk.main_iteration()    # before completion of this entire action
            #Get some info from gpx file
            self.update_activity_data(row, gpx_file, sport)
        self.setValue("rcd_distance",self.activity_data[row]["rcd_distance"], "%s")  
        self.setValue("rcd_date", self.activity_data[row]["rcd_date"], "%s")
        self.setValue("rcd_starttime", self.activity_data[row]["rcd_starttime"], "%s")
        self.setValue("rcd_average",self.activity_data[row]["rcd_average"])
        self.setValue("rcd_calories",self.activity_data[row]["rcd_calories"], "%s")
        self.setValue("rcd_beats",self.activity_data[row]["rcd_beats"], "%s")
        self.setValue("rcd_upositive",self.activity_data[row]["rcd_upositive"], "%s")
        self.setValue("rcd_unegative",self.activity_data[row]["rcd_unegative"], "%s")
        self.setValue("rcd_maxvel",self.activity_data[row]["rcd_maxvel"])
        self.rcd_maxpace.set_text(self.activity_data[row]["rcd_maxpace"])
        self.rcd_pace.set_text(self.activity_data[row]["rcd_pace"])
        self.setValue("rcd_maxbeats",self.activity_data[row]["rcd_maxbeats"], "%s")
        self.rcd_title.set_text(self.activity_data[row]["rcd_title"])
        
        
    def on_rcd_title_changed(self, widget):
        if self.mode == "multiple_activities" and self.active_row is not None:
            self.activity_data[self.active_row]["rcd_title"] = self.rcd_title.get_text()
            
    def on_rcd_sport_changed(self, widget):
        if self.mode == "multiple_activities" and self.active_row is not None:
            sport = self.rcd_sport.get_active_text()
            #Update sport in data store
            self.activity_data[self.active_row]["rcd_sport"] = sport
            #Update sport in treeview
            self.store[self.active_row][4] = sport
            
    def on_rcd_distance_changed(self, widget):
        if self.mode == "multiple_activities" and self.active_row is not None:
            distance = self.rcd_distance.get_text()
            #Update distance in data store
            self.activity_data[self.active_row]["rcd_distance"] = distance
            #Update distance in treeview
            self.store[self.active_row][2] = distance
            
    def on_rcd_duration_value_changed(self, widget):
        if self.mode == "multiple_activities" and self.active_row is not None:
            hour = self.rcd_hour.get_value()
            min = self.rcd_min.get_value()
            sec = self.rcd_second.get_value()
            #print hour, min, sec
            #Update duration in data store
            self.activity_data[self.active_row]["rcd_time"] = (hour, min, sec)
            #Update duration in treeview
            self.store[self.active_row][3] = "%d:%.2d:%.2d" % (int(hour), int(min), int(sec))
            
    def on_rcd_date_changed(self, widget):
        if self.mode == "multiple_activities" and self.active_row is not None:
            #Update date in data store
            self.activity_data[self.active_row]["rcd_date"] = self.rcd_date.get_text()
            
    def on_rcd_starttime_changed(self, widget):
        if self.mode == "multiple_activities" and self.active_row is not None:
            #Update start time in data store
            self.activity_data[self.active_row]["rcd_starttime"] = self.rcd_starttime.get_text()
            
    def on_treeviewEntries_row_activated(self, treeview, event):
        '''
         Callback to display details of different activity
        '''
        #Check for edited data in previous row
        if self.active_row is not None:
            #Check for edited data in comments
            buffer = self.rcd_comments.get_buffer()
            start,end = buffer.get_bounds()
            comments = buffer.get_text(start,end, True).replace("\"","'")
            self.activity_data[self.active_row]["rcd_comments"] = comments
            #Advanced tab items
            self.activity_data[self.active_row]["rcd_maxpace"] = self.rcd_maxpace.get_text()
            self.activity_data[self.active_row]["rcd_pace"] = self.rcd_pace.get_text()
            self.activity_data[self.active_row]["rcd_upositive"] = self.rcd_upositive.get_text()
            self.activity_data[self.active_row]["rcd_unegative"] = self.rcd_unegative.get_text()
            self.activity_data[self.active_row]["rcd_maxbeats"] = self.rcd_maxbeats.get_text()
            self.activity_data[self.active_row]["rcd_beats"] = self.rcd_beats.get_text()
            self.activity_data[self.active_row]["rcd_calories"] = self.rcd_calories.get_text()
        #Get row that was selected
        x = int(event.x)
        y = int(event.y)
        time = event.time
        pthinfo = treeview.get_path_at_pos(x, y)
        if pthinfo is not None:
            path, col, cellx, celly = pthinfo
            treeview.grab_focus()
            treeview.set_cursor(path, col, 0)
            while gtk.events_pending(): # This allows the GUI to update 
                gtk.main_iteration()    # before completion of this entire action
            self.show_treeviewEntries_row(path[0])

    def on_calcavs_clicked(self,widget):
        logging.debug(">>")
        hour = self.rcd_hour.get_value_as_int()
        min = self.rcd_min.get_value_as_int()
        sec = self.rcd_second.get_value_as_int()
        time = sec + (min*60) + (hour*3600)
        if time<1:
            logging.debug("Seems no time value (%s) has been entered, nothing to calculate." %time)
            return False
        distance = float(self.rcd_distance.get_text())
        if distance<1:
            logging.debug("Seems no distance value (%s) has been entered, nothing to calculate." %distance)
            return False
        logging.debug("Time: %d seconds | Distance: %0.2f km (mi)" %(time,distance))
        # Average speed        
        average_speed = distance*3600.0/time
        logging.debug("Average speed: %0.2f" %average_speed)
        self.rcd_average.set_text("%0.2f" %average_speed)
        # Average pace 
        dec_pace = 60/average_speed
        #Transform pace to mm:ss
        pace = self.parent.pace_from_float(dec_pace)
        logging.debug("Average pace: %s" %pace)
        self.rcd_pace.set_text(pace)
        logging.debug("<<")

    def on_calccalories_clicked(self,widget):
        sport = self.rcd_sport.get_active_text()
        hour = self.rcd_hour.get_value_as_int()
        min = self.rcd_min.get_value_as_int()
        sec = self.rcd_second.get_value_as_int()
        hour += float(min)/60.0 + float(sec)/(60.0*60.0)
        weight = self.pytrainer_main.profile.getValue("pytraining","prf_weight")
        try:
            weight = float(weight)
        except:
            weight = 0.0
        try:
            met = float(self.parent.getSportMet(sport))
        except:
            met = None
        try:
            extraweight = self.parent.getSportWeight(sport)
            extraweight = float(extraweight)
        except:
            extraweight = 0.0
        if met is not None:
            calories = met*(weight+extraweight)*hour
            self.rcd_calories.set_text(str(calories))

    def on_calcdistance_clicked(self,widget):
        logging.debug(">>")
        try:
            hour = self.rcd_hour.get_value_as_int()
            min = self.rcd_min.get_value_as_int()
            sec = self.rcd_second.get_value_as_int()
            time = sec + (min*60) + (hour*3600)
            time_in_hour = time/3600.0
            # we need either pace or speed
            try:
                average = float(self.rcd_average.get_text())
                distance = average*time_in_hour
                logging.debug("Time: %d seconds | Speed: %0.2f -> Distance: %0.3f km (mi)" %(time,average,distance)) 
                pace = self.parent.pace_from_float(60/average)
                logging.debug("Setting pace: %s" %pace)
                self.rcd_pace.set_text(pace)
            except:
                pace_dec = self.parent.pace_to_float(self.rcd_pace.get_text())
                distance = time/(60.0*pace_dec)
                logging.debug("Time: %d seconds | Pace_dec: %0.2f -> Distance: %0.3f km (mi)" %(time,pace_dec,distance))
                speed = distance/time_in_hour
                logging.debug("Setting average speed: %0.2f" %speed)
                self.rcd_average.set_text("%0.2f" %speed)
            self.set_distance(distance) 
        except:
            logging.debug("Traceback: %s" % traceback.format_exc())
            pass
        logging.debug("<<")
    
    def set_distance(self,distance):
        self.rcd_distance.set_text("%0.2f" %distance)
        #myset_text(rcd_distance, 'distance', distance, us=self.us, round=2)
        
    def set_maxspeed(self,vel):
        self.rcd_maxvel.set_text("%0.2f" %vel)
            
    def set_maxhr(self,hr):
        self.rcd_maxbeats.set_text("%0.2f" %hr)
            
    def set_recordtime (self,time_in_hour):
        hour = int(time_in_hour)
        min = int((time_in_hour-hour)*60)
        sec = (((time_in_hour-hour)*60)-min)*60
        self.rcd_hour.set_value(hour)
        self.rcd_min.set_value(min)
        self.rcd_second.set_value(sec)

    def on_selectfile_clicked(self,widget):
        logging.debug(">>")
        #self.filechooser = FileChooser(self.data_path,self,"set_gpxfile","open")
        #self.filechooser.run()
        from pytrainer.gui.dialogs import fileChooserDialog
        selectedFile = fileChooserDialog(title="Choose a Google Earth file (.kml) to import", multiple=False).getFiles()
        if selectedFile is not None:
            self.rcd_gpxfile.set_text(selectedFile[0])
        logging.debug("<<")

    def set_gpxfile(self):
        logging.debug(">>")
        #namefile = self.filechooser.filename
        #self.rcd_gpxfile.set_text(namefile)
        logging.debug("<<")

    def on_calculatevalues_clicked(self,widget):
        gpxfile = self.rcd_gpxfile.get_text()
        if os.path.isfile(gpxfile):
            self.frameGeneral.set_sensitive(0)
            self.frameVelocity.set_sensitive(0) 
            self.parent.actualize_fromgpx(gpxfile)
Example #10
0
    def __init__(self, equipment_service, data_path = None, listSport = None, parent = None, date = None, title=None, distance=None, time=None, upositive=None, unegative=None, bpm=None, calories=None, comment=None, windowTitle=None, equipment=[]):
        logging.debug(">>")
        self.parent = parent
        self.pytrainer_main = parent.pytrainer_main
        self.uc = UC()
        logging.debug("Using US system: %s", self.uc.us)
        self.data_path = data_path
        self.mode = "newrecord"
        self.id_record = ""
        self.store = None
        self.active_row = None
        self.activity_data = [] 
        SimpleBuilderApp.__init__(self, "newrecord.ui")
        self.conf_options = [
            "rcd_date",
            "rcd_sport",
            "rcd_distance",
            "rcd_beats",
            "rcd_comments",
            "rcd_average",
            "rcd_calories",
            "rcd_title",
            "rcd_gpxfile",
            "rcd_upositive",
            "rcd_unegative",
            "rcd_maxbeats",
            "rcd_pace",
            "rcd_maxpace",
            "rcd_maxvel",
            ]
        self.listSport = {}
        for sport in listSport:
            self.listSport[sport.id] = sport.name
        for i in self.listSport:    
            self.rcd_sport.insert_text(i,self.listSport[i])
        self.rcd_sport.set_active(0)

        if windowTitle is not None:
            self.newrecord.set_title(windowTitle)
        if date != None:
            self.setDate(date)
        if title != None:
            self.rcd_title.set_text(title)
        if distance != None:
            #self.rcd_distance.set_text(distance)
            #myset_text(rcd_distance, 'distance', distance, us=self.us, round=2)
            self.rcd_distance.set_text(self.uc.distance(distance))
        if time != None:
            self.setTime(time)
        if distance!=None and time!=None:
            self.on_calcavs_clicked(None)
        if upositive != None:
            self.rcd_upositive.set_text(self.uc.height(upositive))
        if unegative != None:
            self.rcd_unegative.set_text(self.uc.height(unegative))
        if calories != None:
            self.rcd_calories.set_text(calories)
            
        #populate labels with units        
        self.label_rcd_distance.set_text(_('Distance') + ' (%s)' %self.uc.unit_distance)
        self.label_rcd_maxvel.set_text(_('Max') + ' (%s)' %self.uc.unit_speed)
        self.label_rcd_average.set_text(_('Average') + ' (%s)' %self.uc.unit_speed)
        self.label_rcd_maxpace.set_text(_('Max') + ' (%s)' %self.uc.unit_pace)
        self.label_rcd_pace.set_text(_('Pace') + ' (%s)' %self.uc.unit_pace)
        self.label_rcd_upositive.set_text(_('Ascent') + ' (%s)' %self.uc.unit_height)
        self.label_rcd_unegative.set_text(_('Descent') + ' (%s)' %self.uc.unit_height)        

        self._init_equipment(equipment, equipment_service)
        logging.debug("<<")
Example #11
0
class WindowRecord(SimpleBuilderApp):
    def __init__(self, equipment_service, data_path = None, listSport = None, parent = None, date = None, title=None, distance=None, time=None, upositive=None, unegative=None, bpm=None, calories=None, comment=None, windowTitle=None, equipment=[]):
        logging.debug(">>")
        self.parent = parent
        self.pytrainer_main = parent.pytrainer_main
        self.uc = UC()
        logging.debug("Using US system: %s", self.uc.us)
        self.data_path = data_path
        self.mode = "newrecord"
        self.id_record = ""
        self.store = None
        self.active_row = None
        self.activity_data = [] 
        SimpleBuilderApp.__init__(self, "newrecord.ui")
        self.conf_options = [
            "rcd_date",
            "rcd_sport",
            "rcd_distance",
            "rcd_beats",
            "rcd_comments",
            "rcd_average",
            "rcd_calories",
            "rcd_title",
            "rcd_gpxfile",
            "rcd_upositive",
            "rcd_unegative",
            "rcd_maxbeats",
            "rcd_pace",
            "rcd_maxpace",
            "rcd_maxvel",
            ]
        self.listSport = {}
        for sport in listSport:
            self.listSport[sport.id] = sport.name
        for i in self.listSport:    
            self.rcd_sport.insert_text(i,self.listSport[i])
        self.rcd_sport.set_active(0)

        if windowTitle is not None:
            self.newrecord.set_title(windowTitle)
        if date != None:
            self.setDate(date)
        if title != None:
            self.rcd_title.set_text(title)
        if distance != None:
            #self.rcd_distance.set_text(distance)
            #myset_text(rcd_distance, 'distance', distance, us=self.us, round=2)
            self.rcd_distance.set_text(self.uc.distance(distance))
        if time != None:
            self.setTime(time)
        if distance!=None and time!=None:
            self.on_calcavs_clicked(None)
        if upositive != None:
            self.rcd_upositive.set_text(self.uc.height(upositive))
        if unegative != None:
            self.rcd_unegative.set_text(self.uc.height(unegative))
        if calories != None:
            self.rcd_calories.set_text(calories)
            
        #populate labels with units        
        self.label_rcd_distance.set_text(_('Distance') + ' (%s)' %self.uc.unit_distance)
        self.label_rcd_maxvel.set_text(_('Max') + ' (%s)' %self.uc.unit_speed)
        self.label_rcd_average.set_text(_('Average') + ' (%s)' %self.uc.unit_speed)
        self.label_rcd_maxpace.set_text(_('Max') + ' (%s)' %self.uc.unit_pace)
        self.label_rcd_pace.set_text(_('Pace') + ' (%s)' %self.uc.unit_pace)
        self.label_rcd_upositive.set_text(_('Ascent') + ' (%s)' %self.uc.unit_height)
        self.label_rcd_unegative.set_text(_('Descent') + ' (%s)' %self.uc.unit_height)        

        self._init_equipment(equipment, equipment_service)
        logging.debug("<<")
        
    def _init_equipment(self, selected_equipment, equipment_service):
        equipment = {}
        active_equipment = equipment_service.get_active_equipment()
        for item in active_equipment:
            equipment[item] = False
        if len(active_equipment) == 0:
            self.noActiveEquipmentMessageContainer.set_visible(True)
        for item in selected_equipment:
            equipment[item] = True
        list_store = Gtk.ListStore(int, str, bool)
        for item in equipment:
            list_store.append((item.id, item.description, equipment[item]))
        tree_view = self.treeviewRecordEquipment
        cell_renderer = Gtk.CellRendererToggle()
        cell_renderer.connect('toggled', self._equipment_selection_toggled)
        tree_view.append_column(Gtk.TreeViewColumn("Selected", cell_renderer, active=2))
        tree_view.append_column(Gtk.TreeViewColumn("Equipment Item", Gtk.CellRendererText(), text=1))
        tree_view.set_model(list_store)
    
    def _equipment_selection_toggled(self, widget, path):
        list_store = self.treeviewRecordEquipment.get_model()
        iter = list_store.get_iter(path)
        value = list_store.get_value(iter, 2)
        list_store.set(iter, 2, not value)
    
    def _get_selected_equipment_ids(self):
        selected_ids = []
        list_store = self.treeviewRecordEquipment.get_model()
        iter = list_store.get_iter_first()
        while iter is not None:
            id = list_store.get_value(iter, 0)
            selected = list_store.get_value(iter, 2)
            if selected:
                selected_ids.append(id)
            iter = list_store.iter_next(iter)
        return selected_ids
    
    def getActivityData(self):
        return self.activity_data
        
    def populateMultiWindow(self, activities):
        logging.debug(">>")
        self.mode = "multiple_activities"
        #activities (activity_id, start_time, distance, duration, sport, gpx_file, file_id)
        self.activity_data = []
        #Make treeview
        self.store = self.build_tree_view()
        #Add data
        for activity in activities:
            iter = self.store.append()
            self.store.set(
                    iter,
                    0, activity[0],
                    1, activity[1],
                    2, activity[2],
                    3, activity[3],
                    4, activity[4],
                    5, activity[5]
                    )
            details = {}
            details["complete"]  = False
            details["rcd_distance"] = activity[2]
            duration = activity[3]
            if duration.count(":") == 2:
                hours, mins, secs = duration.split(":")
            else:
                hours = mins = secs = 0
            #details["rcd_hour"] = float(hours)
            #details["rcd_min"] = float(mins)
            #details["rcd_second"] = float(secs)
            #details["rcd_time"] = (((float(hours) * 60) + float(mins)) * 60) + float(secs)
            details["activity_id"] = activity[0]
            details["rcd_time"] = (float(hours), float(mins), float(secs))
            if activity[4] is not None:
                details["rcd_sport"] = activity[4]
            else:
                # No sport was provided, preliminary set the current selection from window
                details["rcd_sport"] = gtk_str(self.rcd_sport.get_active_text())
            details["rcd_gpxfile"] = activity[5]
            details["file_id"] = activity[6]
            self.activity_data.append(details)
        self.scrolledwindowEntries.show_all()
        #Hide some of the buttons
        self.button25.hide() #GPX file "Open" button
        self.button24.hide() #GPX file "Calculate Values" button
        self.button10.hide() #Distance "Calculate" button
        self.button11.hide() #Duration "Calculate" button
        #self.button12.hide() #Velocity "Calculate" button
        self.button43.hide() #Pace "Calculate" button
        #Make GPX file 'unsensitive'
        self.rcd_gpxfile.set_sensitive(0)       
        while Gtk.events_pending(): # This allows the GUI to update
            Gtk.main_iteration()    # before completion of this entire action
        #Select first row and display details
        self.treeviewEntries.set_cursor(0)  
        self.show_treeviewEntries_row(0)
        logging.debug("<<")
        
    def build_tree_view(self):
        store = Gtk.ListStore(  GObject.TYPE_STRING,
                                GObject.TYPE_STRING,
                                GObject.TYPE_STRING,
                                GObject.TYPE_STRING,
                                GObject.TYPE_STRING,
                                GObject.TYPE_STRING )
        column_names=["id", _("Start Time"), _("Distance"),_("Duration"),_("Sport"), _("GPX File")]
        for column_index, column_name in enumerate(column_names):
            #Add columns
            column = Gtk.TreeViewColumn(column_name, Gtk.CellRendererText(), text=column_index)
            column.set_sort_column_id(column_index)
            if column_name == "id":
                column.set_visible(False)
            column.set_resizable(True)
            self.treeviewEntries.append_column(column)
        self.treeviewEntries.set_headers_clickable(True)
        self.treeviewEntries.set_model(store)
        return store
        
    def on_accept_clicked(self,widget):
        logging.debug(">>")
        if self.mode == "multiple_activities":
            logging.debug("multiple_activities")
            #Check for edited data in comments
            if self.active_row is not None:
                buffer = self.rcd_comments.get_buffer()
                start,end = buffer.get_bounds()
                comments = gtk_str(buffer.get_text(start,end, True))
                self.activity_data[self.active_row]["rcd_comments"] = comments
                #Advanced tab items
                self.activity_data[self.active_row]["rcd_maxpace"] = gtk_str(self.rcd_maxpace.get_text())
                self.activity_data[self.active_row]["rcd_pace"] = gtk_str(self.rcd_pace.get_text())
                self.activity_data[self.active_row]["rcd_upositive"] = gtk_str(self.rcd_upositive.get_text())
                self.activity_data[self.active_row]["rcd_unegative"] = gtk_str(self.rcd_unegative.get_text())
                self.activity_data[self.active_row]["rcd_maxbeats"] = gtk_str(self.rcd_maxbeats.get_text())
                self.activity_data[self.active_row]["rcd_beats"] = gtk_str(self.rcd_beats.get_text())
                self.activity_data[self.active_row]["rcd_calories"] = gtk_str(self.rcd_calories.get_text())
            row = 0 
            for activity in self.activity_data:
                index = self.activity_data.index(activity)
                if activity["complete"] is False:
                    #Did not view or modify this record - need to get all the details
                    logging.debug("Activity incomplete.. %s", activity["rcd_gpxfile"])
                    self.update_activity_data(row, activity["rcd_gpxfile"], activity["rcd_sport"])
                activity["rcd_title"] = activity["rcd_title"].replace("\"","'")
                #Add activity to DB etc
                laps = activity.pop("laps", ())
                selected_equipment_ids = self._get_selected_equipment_ids()
                self.activity_data[index]["db_id"] = self.parent.insertRecord(activity, laps, equipment=selected_equipment_ids)
                row += 1
            logging.debug("Processed %d rows of activity data", row)
        else:
            logging.debug("Single activity")
            list_options = {}
            trackSummary = {}
            list_options["rcd_date"] = gtk_str(self.rcd_date.get_text())
            list_options["rcd_sport"] = gtk_str(self.rcd_sport.get_active_text())
            list_options["rcd_distance"] = self.uc.usr2sys_str('distance',
                                                               gtk_str(self.rcd_distance.get_text()))
            list_options["rcd_beats"] = gtk_str(self.rcd_beats.get_text())
            list_options["rcd_average"] = self.uc.usr2sys_str('speed',
                                                              gtk_str(self.rcd_average.get_text()))
            list_options["rcd_calories"] = gtk_str(self.rcd_calories.get_text())
            list_options["rcd_title"] = gtk_str(self.rcd_title.get_text())
            list_options["rcd_gpxfile"] = gtk_str(self.rcd_gpxfile.get_text())
            list_options["rcd_upositive"] = self.uc.usr2sys_str('height',
                                                                gtk_str(self.rcd_upositive.get_text()))
            list_options["rcd_unegative"] = self.uc.usr2sys_str('height',
                                                                gtk_str(self.rcd_unegative.get_text()))
            list_options["rcd_maxbeats"] = gtk_str(self.rcd_maxbeats.get_text())
            # 2011.11.05 - dgranda
            # Pace is shown to user in mm:ss format
            # But pace in database is stored in a mixed way: 4.30 for 4:30 (4.5 in 'decimal'). This needs to be changed!!
            list_options["rcd_pace"] = self.uc.usr2sys_str('pace', gtk_str(self.rcd_pace.get_text()).replace(":","."))
            list_options["rcd_maxpace"] = self.uc.usr2sys_str('pace', gtk_str(self.rcd_maxpace.get_text()).replace(":","."))
            list_options["rcd_maxvel"] = self.uc.usr2sys_str('speed', gtk_str(self.rcd_maxvel.get_text()))
            list_options["rcd_time"] = [self.rcd_hour.get_value_as_int(),self.rcd_min.get_value_as_int(),self.rcd_second.get_value_as_int()]
            buffer = self.rcd_comments.get_buffer()
            start,end = buffer.get_bounds()
            comment = gtk_str(buffer.get_text(start,end, True))
            list_options["rcd_comments"] = comment
            selected_equipment_ids = self._get_selected_equipment_ids()
            # Added to change start time, only activities without GPX+ source file - dgranda 2011/06/10
            record_time = gtk_str(self.rcd_starttime.get_text())
            record_date = gtk_str(self.rcd_date.get_text())
            localtz = getLocalTZ()
            date = dateutil.parser.parse(record_date+" "+record_time+" "+localtz)
            local_date = str(date)
            utc_date = date.astimezone(tzutc()).strftime("%Y-%m-%dT%H:%M:%SZ")
            list_options["date_time_utc"] = utc_date
            list_options["date_time_local"] = local_date

            if self.mode == "newrecord":
                logging.debug('Track data: %s', list_options)
                if list_options["rcd_gpxfile"] != "":
                    logging.info('Adding new activity based on GPX file')
                    self.parent.insertRecord(list_options, None, selected_equipment_ids)
                else:
                    logging.info('Adding new activity based on provided data')
                    #Manual entry, calculate time info
                    record_time = gtk_str(self.rcd_starttime.get_text())
                    record_date = gtk_str(self.rcd_date.get_text())
                    localtz = getLocalTZ()
                    date = dateutil.parser.parse(record_date+" "+record_time+" "+localtz)
                    local_date = str(date)
                    utc_date = date.astimezone(tzutc()).strftime("%Y-%m-%dT%H:%M:%SZ")
                    list_options["date_time_utc"] = utc_date
                    list_options["date_time_local"] = local_date

                    try:
                        self.parent.insertRecord(
                                list_options,
                                equipment=selected_equipment_ids)
                    except ValueError:
                        msg = ("Unable to add an activity record without any "
                               "sports, please add a sport in preferences' "
                               "<i>Sports</i> tab.")
                        logging.error(msg)
                        warning_dialog(title=_("Error Adding Activity Record"), text=_(msg))

            elif self.mode == "editrecord":
                self.parent.updateRecord(list_options, self.id_record, equipment=selected_equipment_ids)
        logging.debug("<<")
        self.close_window()
    
    def on_cancel_clicked(self,widget):
        self.close_window()

    def close_window(self, widget=None):
        self.newrecord.hide()
        #self.newrecord = None
        self.quit()

    def on_calendar_clicked(self,widget):
        calendardialog = WindowCalendar(self.data_path,self, date=gtk_str(self.rcd_date.get_text()))
        calendardialog.run()

    def setDate(self,date):
        self.rcd_date.set_text(date)

    def setTime(self,timeInSeconds):
        time_in_hour = int(timeInSeconds)/3600.0
        hour = int(time_in_hour)
        min = int((time_in_hour-hour)*60)
        sec = (((time_in_hour-hour)*60)-min)*60
        self.rcd_hour.set_value(hour)
        self.rcd_min.set_value(min)
        self.rcd_second.set_value(sec)

    def setValue(self,var_name,value, format="%0.2f"):
        var = getattr(self,var_name)
        try:
            valueString = format % value
            var.set_text(valueString)
        except Exception as e:
            logging.debug("setValue: %s, %s, %s", var_name, value, e)
            pass
    
    def setValuesFromActivity(self, activity):
        logging.debug(">>")
        self.mode = "editrecord"
        if activity is None:
            logging.debug("activity is None")
            logging.debug("<<")
            return
        self.id_record = activity.id
        (h, m, s) = activity.time_tuple
        self.rcd_hour.set_value(h)
        self.rcd_min.set_value(m)
        self.rcd_second.set_value(s)
        self.rcd_date.set_text(str(activity.date))
        
        #self.rcd_distance.set_text("%.2f"%activity.distance)
        #myset_text(self.rcd_distance, 'distance', activity.distance, us=self.us, round=2)
        if activity.distance is not None:
            self.rcd_distance.set_text("%.2f" %self.uc.distance(activity.distance))        
        else:
            self.rcd_distance.set_text("")
        self.rcd_average.set_text("%.2f" %self.uc.speed(activity.average))
        self.rcd_calories.set_text("%s"%activity.calories)
        self.rcd_beats.set_text("%s"%activity.beats)
        self.rcd_upositive.set_text("%.2f" %self.uc.height(activity.upositive))
        self.rcd_unegative.set_text("%.2f" %self.uc.height(activity.unegative))
        self.rcd_maxvel.set_text("%.2f" %self.uc.speed(activity.maxspeed))
        self.rcd_maxpace.set_text("%s" %self.parent.pace_from_float(self.uc.pace(activity.maxpace),True)) # value coming from DB
        self.rcd_pace.set_text("%s" %self.parent.pace_from_float(self.uc.pace(activity.pace),True)) # value coming from DB
        self.rcd_maxbeats.set_text("%s"%activity.maxbeats)
        self.rcd_title.set_text(activity.title)
        
        if activity.starttime is not None:
            self.rcd_starttime.set_text("%s" % activity.starttime)
        sportPosition = self.getSportPosition(activity.sport_id)
        self.rcd_sport.set_active(sportPosition) 
        buffer = self.rcd_comments.get_buffer()
        start,end = buffer.get_bounds()
        buffer.set_text(activity.comments)
        if activity.gpx_file is not None:
            self.rcd_gpxfile.set_text(activity.gpx_file)
            self.frameGeneral.set_sensitive(0)      #Currently record values not changed if a GPX file is present
            self.frameVelocity.set_sensitive(0)     #Greying out options to indicate this to user
            self.framePace.set_sensitive(0)
            self.frameElevation.set_sensitive(0)
            self.frameBeats.set_sensitive(0)
        logging.debug("<<")
        
    def setValues(self,values):
        #(24, u'2009-12-26', 4, 23.48, u'9979', 0.0, 8.4716666232200009, 2210, u'', None, u'', 573.0, 562.0, 11.802745244400001, 5.0499999999999998, 7.04, 0.0, u'2009-12-25T19:41:48Z', u'2009-12-26 08:41:48+13:00')
        #(50, u'2006-10-13', 1, 25.0, u'5625', 0.0, 16.0, 0, u'', gpsfile, title,upositive,unegative,maxspeed|maxpace|pace|maxbeats
        logging.debug("windowrecord setValues called")
        self.mode = "editrecord"
        self.id_record = values[0]
        self.setTime(values[4])
        self.rcd_date.set_text(str(values[1]))
        self.setValue("rcd_distance",values[3])
        self.setValue("rcd_average",values[6])
        self.setValue("rcd_calories",values[7], "%0.0f")
        self.setValue("rcd_beats",values[5], "%0.0f")
        self.setValue("rcd_upositive",values[11])
        self.setValue("rcd_unegative",values[12])
        self.setValue("rcd_maxvel",values[13])
        self.setValue("rcd_maxpace",values[14])
        self.setValue("rcd_pace",values[15])
        self.setValue("rcd_maxbeats",values[16], "%0.0f")
        self.rcd_title.set_text("%s"%values[10])
        
        local_time = values[18]
        if local_time is not None:
            dateTime = dateutil.parser.parse(local_time)
            sTime = dateTime.strftime("%X")
            self.rcd_starttime.set_text("%s" % sTime)
        sportID = values[2]
        sportPosition = self.getSportPosition(sportID)
        self.rcd_sport.set_active(sportPosition) 
        buffer = self.rcd_comments.get_buffer()
        start,end = buffer.get_bounds()
        buffer.set_text(values[8])

    def getSportPosition(self, sportID):
        """
            Function to determine the position in the sport array for a given sport ID
            Needed as once sports are deleted there are gaps in the list...
        """
        count = 0
        for key, value in self.listSport.items():
            if key == sportID: 
                return count
            count +=1
        return 0
        
    def getSportPositionByName(self, sport):
        """
            Function to determine the position in the sport array for a given sport 
            Needed as once sports are deleted there are gaps in the list...
        """
        count = 0
        for key, value in self.listSport.items():
            if value == sport: 
                return count
            count +=1
        return None
    
    def on_calctime_clicked(self,widget):
        logging.debug(">>")
        try:
            distance = float(gtk_str(self.rcd_distance.get_text())) # distance is mandatory!
            # we need either pace or speed
            try:
                average = float(gtk_str(self.rcd_average.get_text()))
                time_in_hour = distance/average
                logging.debug("Distance: %0.3f km (mi) | Speed: %0.2f -> Time: %.f hours",
                              distance, average, time_in_hour)
                pace = self.parent.pace_from_float(60/average)
                logging.debug("Setting pace: %s", pace)
                self.rcd_pace.set_text(pace)
            except:
                pace_dec = self.parent.pace_to_float(gtk_str(self.rcd_pace.get_text()))
                time_in_hour = pace_dec*distance/60.0
                logging.debug("Distance: %0.3f km (mi) | Pace_dec: %0.2f -> Time: %.f hours",
                              distance, pace_dec, time_in_hour)
                speed = distance/time_in_hour
                logging.debug("Setting average speed: %0.2f", speed)
                self.rcd_average.set_text("%0.2f" %speed)
            self.set_recordtime(time_in_hour)
        except:
            logging.debug("Traceback: %s" % traceback.format_exc())
            pass
        logging.debug("<<")

    def update_activity_data(self, row, gpx_file, sport):
        logging.debug(">>")
        self.activity_data[row]["rcd_comments"] = ""
        gpx_summary, laps = self.parent.summaryFromGPX(gpx_file, (sport,""))
        local_time = gpx_summary['date_time_local']
        start_date = local_time.strftime("%Y-%m-%d")
        start_time = local_time.strftime("%H:%M:%S")
        self.activity_data[row]["rcd_date"] = start_date
        self.activity_data[row]["rcd_starttime"] = start_time
        self.activity_data[row]["date_time_local"] = gpx_summary['date_time_local']
        self.activity_data[row]["date_time_utc"] = gpx_summary['date_time_utc']
        self.activity_data[row]["rcd_time"] = gpx_summary["rcd_time"]
        self.activity_data[row]["rcd_distance"] = gpx_summary["rcd_distance"]
        self.activity_data[row]["rcd_average"] = gpx_summary["rcd_average"]
        self.activity_data[row]["rcd_calories"] = gpx_summary["rcd_calories"]
        self.activity_data[row]["rcd_beats"] = gpx_summary["rcd_beats"]
        self.activity_data[row]["rcd_upositive"] = gpx_summary["rcd_upositive"]
        self.activity_data[row]["rcd_unegative"] = gpx_summary["rcd_unegative"]
        self.activity_data[row]["rcd_maxvel"] = gpx_summary["rcd_maxvel"]
        self.activity_data[row]["rcd_maxpace"] = gpx_summary["rcd_maxpace"]
        self.activity_data[row]["rcd_pace"] = gpx_summary["rcd_pace"]
        self.activity_data[row]["rcd_maxbeats"] = gpx_summary["rcd_maxbeats"]
        self.activity_data[row]["rcd_title"] = ""
        self.activity_data[row]["laps"] = laps
        self.activity_data[row]["complete"] = True
        logging.debug("<<")

        
    def show_treeviewEntries_row(self, row):
        '''
        Show details of treeview entry
        TODO need to maintain any changes and display those....
        '''
        logging.debug(">>")
        self.active_row = row
        #Get details from stored data
        #set sport
        sport = self.activity_data[row]["rcd_sport"]
        sportPosition = self.getSportPositionByName(sport)
        if sportPosition is not None:
            self.rcd_sport.set_active(sportPosition)
        #Set gpx file name
        gpx_file = self.activity_data[row]["rcd_gpxfile"]
        self.setValue("rcd_gpxfile", gpx_file, "%s")
        #set duration
        time = time2second(self.activity_data[row]["rcd_time"])      #TODO Fix to use timeinseconds!!
        self.setTime(time)                                                  #TODO Fix to use timeinseconds!!
        #Set distance
        self.setValue("rcd_distance",self.activity_data[row]["rcd_distance"], "%s")
        #Set comments
        buffer = self.rcd_comments.get_buffer()
        start,end = buffer.get_bounds()
        if "rcd_comments" not in self.activity_data[row]:
            self.activity_data[row]["rcd_comments"] = ""
        buffer.set_text(self.activity_data[row]["rcd_comments"])
        while Gtk.events_pending(): # This allows the GUI to update
            Gtk.main_iteration()    # before completion of this entire action
        if self.activity_data[row]["complete"] is False:
            #Haven't processed GPX file yet
            #Blank values not yet known
            self.setValue("rcd_date", "", "%s")
            self.setValue("rcd_starttime", "", "%s")
            self.setValue("rcd_average", "", "%s")
            self.setValue("rcd_calories","", "%s")
            self.setValue("rcd_beats", "", "%s")
            self.setValue("rcd_upositive", "", "%s")
            self.setValue("rcd_unegative", "", "%s")
            self.setValue("rcd_maxvel", "", "%s")
            self.rcd_maxpace.set_text("")
            self.rcd_pace.set_text("")
            self.setValue("rcd_maxbeats", "", "%s")
            while Gtk.events_pending(): # This allows the GUI to update
                Gtk.main_iteration()    # before completion of this entire action
            #Get some info from gpx file
            self.update_activity_data(row, gpx_file, sport)
        self.setValue("rcd_distance",self.activity_data[row]["rcd_distance"], "%s") 
        time = time2second(self.activity_data[row]["rcd_time"])
        self.setTime(time)  
        self.setValue("rcd_date", self.activity_data[row]["rcd_date"], "%s")
        self.setValue("rcd_starttime", self.activity_data[row]["rcd_starttime"], "%s")
        self.setValue("rcd_average",self.activity_data[row]["rcd_average"])
        self.setValue("rcd_calories",self.activity_data[row]["rcd_calories"], "%s")
        self.setValue("rcd_beats",self.activity_data[row]["rcd_beats"], "%s")
        self.setValue("rcd_upositive",self.activity_data[row]["rcd_upositive"], "%s")
        self.setValue("rcd_unegative",self.activity_data[row]["rcd_unegative"], "%s")
        self.setValue("rcd_maxvel",self.activity_data[row]["rcd_maxvel"])
        self.rcd_maxpace.set_text(self.activity_data[row]["rcd_maxpace"])
        self.rcd_pace.set_text(self.activity_data[row]["rcd_pace"])
        self.setValue("rcd_maxbeats",self.activity_data[row]["rcd_maxbeats"], "%s")
        self.rcd_title.set_text(self.activity_data[row]["rcd_title"])
        logging.debug("<<")
        
        
    def on_rcd_title_changed(self, widget):
        if self.mode == "multiple_activities" and self.active_row is not None:
            self.activity_data[self.active_row]["rcd_title"] = gtk_str(self.rcd_title.get_text())
            
    def on_rcd_sport_changed(self, widget):
        if self.mode == "multiple_activities" and self.active_row is not None:
            sport = gtk_str(self.rcd_sport.get_active_text())
            #Update sport in data store
            self.activity_data[self.active_row]["rcd_sport"] = sport
            #Update sport in treeview
            self.store[self.active_row][4] = sport
            
    def on_rcd_distance_changed(self, widget):
        if self.mode == "multiple_activities" and self.active_row is not None:
            distance = gtk_str(self.rcd_distance.get_text())
            #Update distance in data store
            self.activity_data[self.active_row]["rcd_distance"] = distance
            #Update distance in treeview
            self.store[self.active_row][2] = distance
            
    def on_rcd_duration_value_changed(self, widget):
        if self.mode == "multiple_activities" and self.active_row is not None:
            hour = self.rcd_hour.get_value()
            min = self.rcd_min.get_value()
            sec = self.rcd_second.get_value()
            #print hour, min, sec
            #Update duration in data store
            self.activity_data[self.active_row]["rcd_time"] = (hour, min, sec)
            #Update duration in treeview
            self.store[self.active_row][3] = "%d:%.2d:%.2d" % (int(hour), int(min), int(sec))
            
    def on_rcd_date_changed(self, widget):
        if self.mode == "multiple_activities" and self.active_row is not None:
            #Update date in data store
            self.activity_data[self.active_row]["rcd_date"] = gtk_str(self.rcd_date.get_text())
            
    def on_rcd_starttime_changed(self, widget):
        if self.mode == "multiple_activities" and self.active_row is not None:
            #Update start time in data store
            self.activity_data[self.active_row]["rcd_starttime"] = gtk_str(self.rcd_starttime.get_text())
            
    def on_treeviewEntries_row_activated(self, treeview, event):
        '''
         Callback to display details of different activity
        '''
        #Check for edited data in previous row
        if self.active_row is not None:
            #Check for edited data in comments
            buffer = self.rcd_comments.get_buffer()
            start,end = buffer.get_bounds()
            comments = gtk_str(buffer.get_text(start,end, True))
            self.activity_data[self.active_row]["rcd_comments"] = comments
            #Advanced tab items
            self.activity_data[self.active_row]["rcd_maxpace"] = gtk_str(self.rcd_maxpace.get_text())
            self.activity_data[self.active_row]["rcd_pace"] = gtk_str(self.rcd_pace.get_text())
            self.activity_data[self.active_row]["rcd_upositive"] = gtk_str(self.rcd_upositive.get_text())
            self.activity_data[self.active_row]["rcd_unegative"] = gtk_str(self.rcd_unegative.get_text())
            self.activity_data[self.active_row]["rcd_maxbeats"] = gtk_str(self.rcd_maxbeats.get_text())
            self.activity_data[self.active_row]["rcd_beats"] = gtk_str(self.rcd_beats.get_text())
            self.activity_data[self.active_row]["rcd_calories"] = gtk_str(self.rcd_calories.get_text())
        #Get row that was selected
        x = int(event.x)
        y = int(event.y)
        time = event.time
        pthinfo = treeview.get_path_at_pos(x, y)
        if pthinfo is not None:
            path, col, cellx, celly = pthinfo
            treeview.grab_focus()
            treeview.set_cursor(path, col, 0)
            while Gtk.events_pending(): # This allows the GUI to update
                Gtk.main_iteration()    # before completion of this entire action
            self.show_treeviewEntries_row(path[0])

    def on_calcavs_clicked(self,widget):
        logging.debug(">>")
        hour = self.rcd_hour.get_value_as_int()
        min = self.rcd_min.get_value_as_int()
        sec = self.rcd_second.get_value_as_int()
        time = sec + (min*60) + (hour*3600)
        if time<1:
            logging.debug("Seems no time value (%s) has been entered, nothing to calculate.", time)
            return False
        distance = float(gtk_str(self.rcd_distance.get_text()))
        if distance<1:
            logging.debug("Seems no distance value (%s) has been entered, nothing to calculate.", distance)
            return False
        logging.debug("Time: %d seconds | Distance: %0.2f km (mi)", time, distance)
        # Average speed        
        average_speed = distance*3600.0/time
        logging.debug("Average speed: %0.2f", average_speed)
        self.rcd_average.set_text("%0.2f" %average_speed)
        # Average pace 
        dec_pace = 60/average_speed
        #Transform pace to mm:ss
        pace = self.parent.pace_from_float(dec_pace)
        logging.debug("Average pace: %s", pace)
        self.rcd_pace.set_text(pace)
        logging.debug("<<")

    def on_calccalories_clicked(self,widget):
        sport = gtk_str(self.rcd_sport.get_active_text())
        hour = self.rcd_hour.get_value_as_int()
        min = self.rcd_min.get_value_as_int()
        sec = self.rcd_second.get_value_as_int()
        hour += float(min)/60.0 + float(sec)/(60.0*60.0)
        weight = self.pytrainer_main.profile.getValue("pytraining","prf_weight")
        try:
            weight = float(weight)
        except:
            weight = 0.0
        try:
            met = float(self.parent.getSportMet(sport))
        except:
            met = None
        try:
            extraweight = self.parent.getSportWeight(sport)
            extraweight = float(extraweight)
        except:
            extraweight = 0.0
        if met is not None:
            calories = met*(weight+extraweight)*hour
            self.rcd_calories.set_text(str(calories))

    def on_calcdistance_clicked(self,widget):
        logging.debug(">>")
        try:
            hour = self.rcd_hour.get_value_as_int()
            min = self.rcd_min.get_value_as_int()
            sec = self.rcd_second.get_value_as_int()
            time = sec + (min*60) + (hour*3600)
            time_in_hour = time/3600.0
            # we need either pace or speed
            try:
                average = float(gtk_str(self.rcd_average.get_text()))
                distance = average*time_in_hour
                logging.debug("Time: %d seconds | Speed: %0.2f -> Distance: %0.3f km (mi)",
                              time, average, distance)
                pace = self.parent.pace_from_float(60/average)
                logging.debug("Setting pace: %s", pace)
                self.rcd_pace.set_text(pace)
            except:
                pace_dec = self.parent.pace_to_float(gtk_str(self.rcd_pace.get_text()))
                distance = time/(60.0*pace_dec)
                logging.debug("Time: %d seconds | Pace_dec: %0.2f -> Distance: %0.3f km (mi)",
                              time, pace_dec, distance)
                speed = distance/time_in_hour
                logging.debug("Setting average speed: %0.2f", speed)
                self.rcd_average.set_text("%0.2f" %speed)
            self.set_distance(distance) 
        except:
            logging.debug("Traceback: %s" % traceback.format_exc())
            pass
        logging.debug("<<")
    
    def set_distance(self,distance):
        self.rcd_distance.set_text("%0.2f" %distance)
        #myset_text(rcd_distance, 'distance', distance, us=self.us, round=2)
        
    def set_maxspeed(self,vel):
        self.rcd_maxvel.set_text("%0.2f" %vel)
            
    def set_maxhr(self,hr):
        self.rcd_maxbeats.set_text("%0.2f" %hr)
            
    def set_recordtime (self,time_in_hour):
        hour = int(time_in_hour)
        min = int((time_in_hour-hour)*60)
        sec = (((time_in_hour-hour)*60)-min)*60
        self.rcd_hour.set_value(hour)
        self.rcd_min.set_value(min)
        self.rcd_second.set_value(sec)

    def on_selectfile_clicked(self,widget):
        logging.debug(">>")
        from pytrainer.gui.dialogs import fileChooserDialog
        selectedFile = fileChooserDialog(title="Choose a Google Earth file (.kml) to import", multiple=False).getFiles()
        if selectedFile is not None:
            self.rcd_gpxfile.set_text(selectedFile[0])
        logging.debug("<<")

    def set_gpxfile(self):
        logging.debug(">>")
        logging.debug("<<")

    def on_calculatevalues_clicked(self,widget):
        gpxfile = gtk_str(self.rcd_gpxfile.get_text())
        if os.path.isfile(gpxfile):
            self.frameGeneral.set_sensitive(0)
            self.frameVelocity.set_sensitive(0) 
            self.parent.actualize_fromgpx(gpxfile)
Example #12
0
 def __init__(self, data_path=None, parent=None):
     self.parent = parent
     self.pytrainer_main = parent
     self.data_path = data_path
     self.uc = UC()
Example #13
0
class ActivityTest(unittest.TestCase):

    def setUp(self):
        self.ddbb = DDBB()
        main = Mock()
        main.ddbb = self.ddbb
        main.profile = Profile()
        main.ddbb.connect()
        main.ddbb.create_tables(add_default=True) # We need a sport
        self.uc = UC()
        self.uc.set_us(False)
        self.service = ActivityService(pytrainer_main=main)
        records_table = DeclarativeBase.metadata.tables['records']
        self.ddbb.session.execute(records_table.insert({'distance': 46.18,
                                                            'maxspeed': 44.6695617695,
                                                            'maxpace': 1.2,
                                                            'title': u'test activity',
                                                            'unegative': 564.08076273,
                                                            'upositive': 553.05993673,
                                                            'average': 22.3882142185,
                                                            'date_time_local': u'2016-07-24 12:58:23+0300',
                                                            'calories': 1462,
                                                            'beats': 115.0,
                                                            'comments': u'test comment',
                                                            'pace': 2.4,
                                                            'date_time_utc': u'2016-07-24T09:58:23Z',
                                                            'date': datetime.date(2016, 7, 24),
                                                            'duration': 7426,
                                                            'sport': 1,
                                                            'maxbeats': 120.0}))
        laps_table = DeclarativeBase.metadata.tables['laps']
        self.ddbb.session.execute(laps_table.insert({'distance': 46181.9,
                                                     'lap_number': 0,
                                                     'calories': 1462,
                                                         'elapsed_time': u'7426.0',
                                                         'record': 1,
                                                         'intensity': u'active',
                                                         'avg_hr': 136,
                                                         'max_hr': 173,
                                                         'laptrigger': u'manual'}))
        self.activity = self.service.get_activity(1)

    def tearDown(self):
        self.service.clear_pool()
        self.ddbb.disconnect()
        self.ddbb.drop_tables()
        self.uc.set_us(False)

    def test_activity_date_time(self):
        self.assertEqual(self.activity.date_time, datetime.datetime(2016, 7, 24,
                                                                        12, 58, 23,
                                                    tzinfo=tzoffset(None, 10800)))

    def test_activity_distance(self):
        self.assertEqual(self.activity.distance, 46.18)

    def test_activity_sport_name(self):
        self.assertEqual(self.activity.sport_name, 'Mountain Bike')

    def test_activity_duration(self):
        self.assertEqual(self.activity.duration, 7426)

    def test_activity_time(self):
        self.assertEqual(self.activity.time, self.activity.duration)

    def test_activity_starttime(self):
        self.assertEqual(self.activity.starttime, '12:58:23 PM')

    def test_activity_time_tuple(self):
        self.assertEqual(self.activity.time_tuple, (2, 3, 46))

    def test_activity_lap(self):
        self.maxDiff = None
        self.assertEqual(self.activity.laps[0], {'distance': 46181.9, 'end_lon': None, 'lap_number': 0, 'start_lon': None, 'id_lap': 1, 'calories': 1462, 'comments': None, 'laptrigger': u'manual', 'elapsed_time': u'7426.0', 'record': 1, 'intensity': u'active', 'avg_hr': 136, 'max_hr': 173, 'end_lat': None, 'start_lat': None, 'max_speed': None})
        lap = self.activity.Laps[0]
        self.assertEqual(lap.distance, 46181.9)
        self.assertEqual(lap.duration, 7426.0)
        self.assertEqual(lap.calories, 1462)
        self.assertEqual(lap.avg_hr, 136)
        self.assertEqual(lap.max_hr, 173)
        self.assertEqual(lap.activity, self.activity)
        self.assertEqual(lap.lap_number, 0)
        self.assertEqual(lap.intensity, u'active')
        self.assertEqual(lap.laptrigger, u'manual')

    def test_activity_get_value_f(self):
        self.assertEqual(self.activity.get_value_f('distance', "%0.2f"), '46.18')
        self.assertEqual(self.activity.get_value_f('average', "%0.2f"), '22.39')
        self.assertEqual(self.activity.get_value_f('maxspeed', "%0.2f"), '44.67')
        self.assertEqual(self.activity.get_value_f('time', '%s'), '2:03:46')
        self.assertEqual(self.activity.get_value_f('calories', "%0.0f"), '1462')
        self.assertEqual(self.activity.get_value_f('pace', "%s"), '2:24')
        self.assertEqual(self.activity.get_value_f('maxpace', "%s"), '1:12')
        self.assertEqual(self.activity.get_value_f('upositive', "%0.2f"), '553.06')
        self.assertEqual(self.activity.get_value_f('unegative', "%0.2f"), '564.08')

    def test_activity_get_value_f_us(self):
        self.uc.set_us(True)
        self.assertEqual(self.activity.get_value_f('distance', "%0.2f"), '28.69')
        self.assertEqual(self.activity.get_value_f('average', "%0.2f"), '13.91')
        self.assertEqual(self.activity.get_value_f('maxspeed', "%0.2f"), '27.76')
        self.assertEqual(self.activity.get_value_f('time', '%s'), '2:03:46')
        self.assertEqual(self.activity.get_value_f('calories', "%0.0f"), '1462')
        self.assertEqual(self.activity.get_value_f('pace', "%s"), '3:52')
        self.assertEqual(self.activity.get_value_f('maxpace', "%s"), '1:56')
        self.assertEqual(self.activity.get_value_f('upositive', "%0.2f"), '1814.50')
        self.assertEqual(self.activity.get_value_f('unegative', "%0.2f"), '1850.66')

    def test_activity_service_null(self):
        none_activity = self.service.get_activity(None)
        self.assertIsNone(none_activity.id)

    def test_activity_remove(self):
        self.service.remove_activity_from_db(self.activity)
        try:
            self.service.get_activity(1)
        except NoResultFound:
            pass
        else:
            self.fail()

    def test_activities_for_day(self):
        activity = list(self.service.get_activities_for_day(datetime.date(2016, 7, 24)))[0]
        self.assertEqual(self.activity, activity)

    def test_activities_period(self):
        activity = list(self.service.get_activities_period(DateRange.for_week_containing(datetime.date(2016, 7, 24))))[0]
        self.assertEqual(self.activity, activity)

    def test_all_activities(self):
        activity = list(self.service.get_all_activities())[0]
        self.assertEqual(self.activity, activity)