From: <jb...@us...> - 2010-10-11 21:18:44
|
Revision: 652 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=652&view=rev Author: jblance Date: 2010-10-11 21:18:37 +0000 (Mon, 11 Oct 2010) Log Message: ----------- Listview search improvements from Arnd Modified Paths: -------------- pytrainer/trunk/glade/pytrainer.glade pytrainer/trunk/pytrainer/gui/windowmain.py pytrainer/trunk/pytrainer/lib/ddbb.py pytrainer/trunk/pytrainer/lib/listview.py pytrainer/trunk/pytrainer/main.py Modified: pytrainer/trunk/glade/pytrainer.glade =================================================================== --- pytrainer/trunk/glade/pytrainer.glade 2010-10-11 04:07:51 UTC (rev 651) +++ pytrainer/trunk/glade/pytrainer.glade 2010-10-11 21:18:37 UTC (rev 652) @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <glade-interface> <!-- interface-requires gtk+ 2.6 --> <!-- interface-naming-policy toplevel-contextual --> @@ -1326,7 +1326,7 @@ <widget class="GtkSpinButton" id="spinbuttonY1Min"> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="invisible_char">●</property> + <property name="invisible_char">●</property> <property name="width_chars">4</property> <property name="adjustment">0 -500 1000 1 10 0</property> <signal name="value_changed" handler="on_spinbuttonY1_value_changed"/> @@ -1344,7 +1344,7 @@ <widget class="GtkSpinButton" id="spinbuttonY1Max"> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="invisible_char">●</property> + <property name="invisible_char">●</property> <property name="width_chars">4</property> <property name="adjustment">0 -500 1000 1 10 0</property> <signal name="value_changed" handler="on_spinbuttonY1_value_changed"/> @@ -1407,7 +1407,7 @@ <property name="visible">True</property> <property name="can_focus">True</property> <property name="max_length">2</property> - <property name="invisible_char">●</property> + <property name="invisible_char">●</property> <property name="adjustment">1 1 10 1 1 0</property> <signal name="value_changed" handler="on_spinbuttonY1LineWeight_value_changed"/> </widget> @@ -1449,7 +1449,7 @@ <property name="sensitive">False</property> <property name="can_focus">True</property> <property name="max_length">2</property> - <property name="invisible_char">●</property> + <property name="invisible_char">●</property> <property name="adjustment">1 0 10 1 1 0</property> </widget> <packing> @@ -1541,7 +1541,7 @@ <widget class="GtkSpinButton" id="spinbuttonY2Min"> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="invisible_char">●</property> + <property name="invisible_char">●</property> <property name="width_chars">4</property> <property name="adjustment">0 -500 1000 1 10 0</property> </widget> @@ -1558,7 +1558,7 @@ <widget class="GtkSpinButton" id="spinbuttonY2Max"> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="invisible_char">●</property> + <property name="invisible_char">●</property> <property name="width_chars">4</property> <property name="adjustment">1 -500 1000 1 10 0</property> </widget> @@ -1628,7 +1628,7 @@ <property name="visible">True</property> <property name="can_focus">True</property> <property name="max_length">2</property> - <property name="invisible_char">●</property> + <property name="invisible_char">●</property> <property name="adjustment">1 0 10 1 1 0</property> </widget> <packing> @@ -1660,7 +1660,7 @@ <property name="sensitive">False</property> <property name="can_focus">True</property> <property name="max_length">2</property> - <property name="invisible_char">●</property> + <property name="invisible_char">●</property> <property name="adjustment">1 0 10 1 1 0</property> </widget> <packing> @@ -1737,7 +1737,7 @@ <widget class="GtkSpinButton" id="spinbuttonXMin"> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="invisible_char">●</property> + <property name="invisible_char">●</property> <property name="width_chars">4</property> <property name="adjustment">0 -500 1000 1 10 0</property> </widget> @@ -1754,7 +1754,7 @@ <widget class="GtkSpinButton" id="spinbuttonXMax"> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="invisible_char">●</property> + <property name="invisible_char">●</property> <property name="width_chars">4</property> <property name="adjustment">0 -500 1000 1 10 0</property> </widget> @@ -5268,7 +5268,7 @@ <widget class="GtkEntry" id="lsa_searchvalue"> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="invisible_char">●</property> + <property name="invisible_char">●</property> </widget> <packing> <property name="expand">False</property> @@ -5300,6 +5300,24 @@ </packing> </child> <child> + <widget class="GtkComboBox" id="lsa_distance"> + <property name="visible">True</property> + <property name="items" translatable="yes">All Distances</property> + </widget> + <packing> + <property name="position">4</property> + </packing> + </child> + <child> + <widget class="GtkComboBox" id="lsa_duration"> + <property name="visible">True</property> + <property name="items" translatable="yes">All Durations</property> + </widget> + <packing> + <property name="position">5</property> + </packing> + </child> + <child> <widget class="GtkComboBox" id="lsa_past"> <property name="visible">True</property> <property name="active">0</property> @@ -5309,7 +5327,7 @@ Last 12 months</property> </widget> <packing> - <property name="position">4</property> + <property name="position">6</property> </packing> </child> <child> @@ -5318,7 +5336,7 @@ <property name="items" translatable="yes">All Sports</property> </widget> <packing> - <property name="position">5</property> + <property name="position">7</property> </packing> </child> <child> @@ -5338,7 +5356,7 @@ <packing> <property name="expand">False</property> <property name="fill">False</property> - <property name="position">6</property> + <property name="position">8</property> </packing> </child> </widget> @@ -5539,7 +5557,7 @@ <widget class="GtkEntry" id="waypoint_longitude"> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="invisible_char">●</property> + <property name="invisible_char">●</property> </widget> <packing> <property name="left_attach">3</property> @@ -5554,7 +5572,7 @@ <widget class="GtkEntry" id="waypoint_description"> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="invisible_char">●</property> + <property name="invisible_char">●</property> </widget> <packing> <property name="left_attach">1</property> @@ -5569,7 +5587,7 @@ <widget class="GtkEntry" id="waypoint_latitude"> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="invisible_char">●</property> + <property name="invisible_char">●</property> </widget> <packing> <property name="left_attach">3</property> @@ -5582,7 +5600,7 @@ <widget class="GtkEntry" id="waypoint_name"> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="invisible_char">●</property> + <property name="invisible_char">●</property> </widget> <packing> <property name="left_attach">1</property> @@ -5827,7 +5845,7 @@ <widget class="GtkEntry" id="entryAthleteDate"> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="invisible_char">●</property> + <property name="invisible_char">●</property> </widget> <packing> <property name="left_attach">1</property> @@ -5840,7 +5858,7 @@ <widget class="GtkEntry" id="entryAthleteWeight"> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="invisible_char">●</property> + <property name="invisible_char">●</property> </widget> <packing> <property name="left_attach">1</property> @@ -5869,7 +5887,7 @@ <widget class="GtkEntry" id="entryAthleteBF"> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="invisible_char">●</property> + <property name="invisible_char">●</property> </widget> <packing> <property name="left_attach">1</property> @@ -5884,7 +5902,7 @@ <widget class="GtkEntry" id="entryAthleteRestingHR"> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="invisible_char">●</property> + <property name="invisible_char">●</property> </widget> <packing> <property name="left_attach">1</property> @@ -5913,7 +5931,7 @@ <widget class="GtkEntry" id="entryAthleteMaxHR"> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="invisible_char">●</property> + <property name="invisible_char">●</property> </widget> <packing> <property name="left_attach">1</property> @@ -5992,7 +6010,24 @@ </packing> </child> <child> - <placeholder/> + <widget class="GtkButton" id="button1"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <signal name="clicked" handler="on_athletecalendar_clicked"/> + <child> + <widget class="GtkImage" id="image7"> + <property name="visible">True</property> + <property name="stock">gtk-index</property> + </widget> + </child> + </widget> + <packing> + <property name="left_attach">2</property> + <property name="right_attach">3</property> + <property name="x_options"></property> + <property name="y_options"></property> + </packing> </child> <child> <placeholder/> @@ -6016,24 +6051,7 @@ <placeholder/> </child> <child> - <widget class="GtkButton" id="button1"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">True</property> - <signal name="clicked" handler="on_athletecalendar_clicked"/> - <child> - <widget class="GtkImage" id="image7"> - <property name="visible">True</property> - <property name="stock">gtk-index</property> - </widget> - </child> - </widget> - <packing> - <property name="left_attach">2</property> - <property name="right_attach">3</property> - <property name="x_options"></property> - <property name="y_options"></property> - </packing> + <placeholder/> </child> </widget> <packing> Modified: pytrainer/trunk/pytrainer/gui/windowmain.py =================================================================== --- pytrainer/trunk/pytrainer/gui/windowmain.py 2010-10-11 04:07:51 UTC (rev 651) +++ pytrainer/trunk/pytrainer/gui/windowmain.py 2010-10-11 21:18:37 UTC (rev 652) @@ -79,7 +79,7 @@ self.y1_color = None self.y1_linewidth = 1 # setup Search ListView - self.mylistsearch = ListSearch(self, self.pytrainer_main) + self.listsearch = ListSearch(self, self.pytrainer_main) def new(self): self.testimport = self.pytrainer_main.startup_options.testimport @@ -1049,15 +1049,12 @@ _("Average"):"average", _("Calories"):"calories" } - #search_string = self.lsa_searchvalue.get_text() - #print widget - self.mylistsearch.title = self.lsa_searchvalue.get_text() - self.mylistsearch.sport = self.lsa_sport.get_active() - self.mylistsearch.past = self.lsa_past.get_active() - #print self.mylistsearch.past - #search_string2 = "title like '%"+search_string+"%'" - #ddbb_field = lisOpt[self.lsa_searchoption.get_active_text()] - self.parent.searchListView(self.mylistsearch.condition) + self.listsearch.title = self.lsa_searchvalue.get_text() + self.listsearch.sport = self.lsa_sport.get_active() + self.listsearch.past = self.lsa_past.get_active() + self.listsearch.duration = self.lsa_duration.get_active() + self.listsearch.distance = self.lsa_distance.get_active() + self.parent.searchListView(self.listsearch.condition) def create_menulist(self,column_names): i=0 Modified: pytrainer/trunk/pytrainer/lib/ddbb.py =================================================================== --- pytrainer/trunk/pytrainer/lib/ddbb.py 2010-10-11 04:07:51 UTC (rev 651) +++ pytrainer/trunk/pytrainer/lib/ddbb.py 2010-10-11 21:18:37 UTC (rev 652) @@ -24,6 +24,63 @@ import commands, os from pytrainer.lib.date import Date +#Define the tables and their columns that should be in the database +tablesList = { "records":{ "id_record":"integer primary key autoincrement", + "date":"date", + "sport":"integer", + "distance":"float", + "time":"varchar(200)", + "beats":"float", + "average":"float", + "calories":"int", + "comments":"text", + "gpslog":"varchar(200)", + "title":"varchar(200)", + "upositive":"float", + "unegative":"float", + "maxspeed":"float", + "maxpace":"float", + "pace":"float", + "maxbeats":"float", + "date_time_local":"varchar2(20)", + "date_time_utc":"varchar2(20)", + }, + "sports":{ "id_sports":"integer primary key autoincrement", + "name":"varchar(100)", + "weight":"float", + "met":"float", + "max_pace":"integer", + }, + "waypoints":{ "id_waypoint":"integer primary key autoincrement", + "lat":"float", + "lon":"float", + "ele":"float", + "comment":"varchar(240)", + "time":"date", + "name":"varchar(200)", + "sym":"varchar(200)", + }, + "laps":{ "id_lap": "integer primary key autoincrement", + "record": "integer", + "lap_number": "integer", + "elapsed_time": "varchar(20)", + "distance": "float", + "start_lat": "float", + "start_lon": "float", + "end_lat": "float", + "end_lon": "float", + "calories": "int", + }, + "athletestats": { + "id_athletestat": "integer primary key autoincrement", + "date": "date", + "weight": "float", + "bodyfat": "float", + "restinghr": "integer", + "maxhr": "integer", + }, + } + class DDBB: def __init__(self, configuration, pytrainer_main=None): self.pytrainer_main = pytrainer_main @@ -110,67 +167,12 @@ Retrieves tables and columns from database, checks current ones and adds something if missed. New in version 1.7.0 args: none returns: none""" + global tablesList logging.debug('>>') logging.info('Checking PyTrainer database') if self.ddbb_type != "sqlite": logging.error('Support for MySQL database is decommissioned, please migrate to SQLite. Exiting check') exit(-2) - #Define the tables and their columns that should be in the database - tablesList = { "records":{ "id_record":"integer primary key autoincrement", - "date":"date", - "sport":"integer", - "distance":"float", - "time":"varchar(200)", - "beats":"float", - "average":"float", - "calories":"int", - "comments":"text", - "gpslog":"varchar(200)", - "title":"varchar(200)", - "upositive":"float", - "unegative":"float", - "maxspeed":"float", - "maxpace":"float", - "pace":"float", - "maxbeats":"float", - "date_time_local":"varchar2(20)", - "date_time_utc":"varchar2(20)", - }, - "sports":{ "id_sports":"integer primary key autoincrement", - "name":"varchar(100)", - "weight":"float", - "met":"float", - "max_pace":"integer", - }, - "waypoints":{ "id_waypoint":"integer primary key autoincrement", - "lat":"float", - "lon":"float", - "ele":"float", - "comment":"varchar(240)", - "time":"date", - "name":"varchar(200)", - "sym":"varchar(200)", - }, - "laps":{ "id_lap": "integer primary key autoincrement", - "record": "integer", - "lap_number": "integer", - "elapsed_time": "varchar(20)", - "distance": "float", - "start_lat": "float", - "start_lon": "float", - "end_lat": "float", - "end_lon": "float", - "calories": "int", - }, - "athletestats": { - "id_athletestat": "integer primary key autoincrement", - "date": "date", - "weight": "float", - "bodyfat": "float", - "restinghr": "integer", - "maxhr": "integer", - }, - } try: tablesDBT = self.ddbbObject.select("sqlite_master","name", "type IN ('table','view') AND name NOT LIKE 'sqlite_%' ORDER BY name") except: @@ -213,6 +215,14 @@ else: logging.info('Database backup successfully created') logging.debug('<<') + + def checkDBDataValues(self): + ''' Check all data in DB and report values that do not match the type ''' + global tablesList + + for table in tablesList.keys(): + pass + def populate_date_time_local(self): ''' Populate date_time_local and date from date_time_utc Modified: pytrainer/trunk/pytrainer/lib/listview.py =================================================================== --- pytrainer/trunk/pytrainer/lib/listview.py 2010-10-11 04:07:51 UTC (rev 651) +++ pytrainer/trunk/pytrainer/lib/listview.py 2010-10-11 21:18:37 UTC (rev 652) @@ -1,31 +1,34 @@ import datetime -#from profile import Profile +import math +LISTPAST = [['All Time', -99999], ['Last 4 Weeks', -31], + ['Last 6 Months', -183], ['Last 12 Months', -366]] + class ListSearch(object): """ Builds SQLite condition out of search parameters""" - def __init__(self, parent = None, pytrainer_main = None): #, data_path = None): + def __init__(self, parent = None, pytrainer_main = None): self.parent = parent self.pytrainer_main = pytrainer_main self.title = '' - self.sport = None + self.sport = 0 self.past = None - - #print self.pytrainer_main.__dict__.keys() - - #self.data_path = data_path - # just dummy until get the right listSport - #self.listSport = [0,1,2,3,4,5,6,7,8,9,10] - + self.duration = None self.listSport = self.pytrainer_main.profile.getSportList() - #print self.listSport - # make this a constant? -az self.listPast = [['All Time', -99999], ['Last 4 Weeks', -31], - ['Last 6 Months', -183], ['Last 12 Months', -366]] + ['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.listDistance = self.get_listDistance() + #print self.listDistance self.setup_lsa_sport() self.setup_lsa_past() + self.setup_lsa_duration() + self.setup_lsa_distance() def get_condition(self): - ''' sqlite condition is glued together here''' + """ Assembles sqlite condition """ _search = "" _add_and = False if self.title != "": @@ -35,26 +38,57 @@ _sport = self.listSport[self.sport-1][3] _here = "sport=%s" % _sport if _add_and: - _search +=" and " + _here + _search += " and " + _here else: _search = _here _add_and = True if self.listPast[self.past][1]: _delta = datetime.timedelta(days=self.listPast[self.past][1] ) _date = datetime.datetime.today() + _delta - _here = "date>'"+ _date.isoformat() + "'" + _here = "date>'" + _date.isoformat() + "'" if _add_and: _search += " and " + _here else: _search = _here _add_and = True + if self.listDuration[self.duration][1]: + _dur_min = int(self.listDuration[self.duration][1][0]) + _dur_max = int(self.listDuration[self.duration][1][1]) + _here = "(time between %s and %s)" % (_dur_min, _dur_max) + if _add_and: + _search += " and " + _here + else: + _search = _here + _add_and = True + if self.listDistance[self.sport][self.distance][1]: + _dis_min = int(self.listDistance[self.sport][self.distance][1][0]) + _dis_max = int(self.listDistance[self.sport][self.distance][1][1]) + _here = "(distance between %s and %s)" % (_dis_min, _dis_max) + if _add_and: + _search += " and " + _here + else: + _search = _here + _add_and = True print _search return _search + + def get_listDistance(self): + """ Not Finished. Eperimentally. Goal: compute distance intervals + for each sport individually from average and standard deviation. + """ + _all = ['All Distances', [0.0, 99999.9]] + _back = [] + _back.append( [_all] ) + for sp in self.listSport: + _back.append( [_all] ) + return _back + condition = property(get_condition) - + #listDuration = property(get_listDuration) + def setup_lsa_sport(self): - liststore_lsa = self.parent.lsa_sport.get_model() #az + liststore_lsa = self.parent.lsa_sport.get_model() if self.parent.lsa_sport.get_active() is not 0: self.parent.lsa_sport.set_active(0) #Set first item active if isnt firstEntry = self.parent.lsa_sport.get_active_text() @@ -69,7 +103,7 @@ self.parent.lsa_sport.connect("changed", self.parent.on_listareasearch_clicked) def setup_lsa_past(self): - liststore_lsa = self.parent.lsa_past.get_model() #az + liststore_lsa = self.parent.lsa_past.get_model() if self.parent.lsa_past.get_active() > 0: self.parent.lsa_past.set_active(0) #Set first item active isnt firstEntry = self.parent.lsa_past.get_active_text() @@ -79,4 +113,29 @@ self.parent.lsa_past.set_active(0) #Add handler manually, so above changes do not trigger recursive loop self.parent.lsa_past.connect("changed", self.parent.on_listareasearch_clicked) + + def setup_lsa_duration(self): + liststore_lsa = self.parent.lsa_duration.get_model() + if self.parent.lsa_duration.get_active() > 0: + self.parent.lsa_duration.set_active(0) + firstEntry = self.parent.lsa_duration.get_active_text() + liststore_lsa.clear() #Delete all items + for i in self.listDuration: + liststore_lsa.append([i[0]]) + self.parent.lsa_duration.set_active(0) + #Add handler manually, so above changes do not trigger recursive loop + self.parent.lsa_duration.connect("changed", self.parent.on_listareasearch_clicked) + + def setup_lsa_distance(self): + liststore_lsa = self.parent.lsa_distance.get_model() + if self.parent.lsa_distance.get_active() > 0: + self.parent.lsa_distance.set_active(0) + firstEntry = self.parent.lsa_distance.get_active_text() + liststore_lsa.clear() #Delete all items + for i in self.listDistance[self.sport]: + liststore_lsa.append([i[0]]) + self.parent.lsa_distance.set_active(0) + #Add handler manually, so above changes do not trigger recursive loop + self.parent.lsa_distance.connect("changed", self.parent.on_listareasearch_clicked) + Modified: pytrainer/trunk/pytrainer/main.py =================================================================== --- pytrainer/trunk/pytrainer/main.py 2010-10-11 04:07:51 UTC (rev 651) +++ pytrainer/trunk/pytrainer/main.py 2010-10-11 21:18:37 UTC (rev 652) @@ -50,7 +50,7 @@ class pyTrainer: def __init__(self,filename = None, data_path = None): #Version constants - self.version ="1.7.2_svn#651" + self.version ="1.7.2_svn#652" self.DB_version = 5 #Process command line options self.startup_options = self.get_options() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |