~mterry/ubiquity/translated-timezones

« back to all changes in this revision

Viewing changes to ubiquity/frontend/kde_components/Timezone.py

  • Committer: Michael Terry
  • Date: 2009-08-13 14:24:03 UTC
  • Revision ID: michael.terry@canonical.com-20090813142403-8nr4hlp28hvoy8k0
kde: support translated timezones too

Show diffs side-by-side

added added

removed removed

Lines of Context:
9
9
 
10
10
#contains information about a geographical timezone city
11
11
class City:
12
 
    def __init__(self, cName, zName, lat, lng, raw_zone):
13
 
        self.city_name = cName
14
 
        self.zone_name = zName
15
 
        self.lat = lat
16
 
        self.long = lng
17
 
        self.pixmap = None
18
 
        # pre-split zone text
19
 
        self.raw_zone = raw_zone
20
 
        #index in the cities array
21
 
        self.index = 0
 
12
    def __init__(self, loc, pixmap):
 
13
        self.loc = loc
 
14
        self.pixmap = pixmap
22
15
    
23
16
class TimezoneMap(QWidget):
24
17
    def __init__(self, frontend):
25
18
        QWidget.__init__(self, frontend.ui.map_frame)
26
19
        self.frontend = frontend
27
 
        #dictionary of zone name -> {'cindex', 'citites'}
28
 
        self.zones = {}
29
20
        # currently active city
30
21
        self.selected_city = None
31
22
        #dictionary of full name (ie. 'Australia/Sydney') -> city
54
45
            zonePixmaps[zone] = QPixmap('%s/timezone_%s.png' % (self.imagePath, zone));
55
46
            
56
47
        #load the timezones from database
57
 
        tzdb = ubiquity.tz.Database()
58
 
        for location in tzdb.locations:
 
48
        self.tzdb = ubiquity.tz.Database()
 
49
        for location in self.tzdb.locations:
59
50
            zone_bits = location.zone.split('/')
60
51
            
61
52
            if len(zone_bits) == 1:
62
53
                continue
63
54
            
64
 
            zoneName = zone_bits[0]
65
 
            #join the possible city names for the subregion
66
 
            #and replace the _ for a space
67
 
            cityName = '/'.join(zone_bits[1:]).replace('_', ' ')
68
 
            
69
55
            # zone is the hours offset from 0
70
56
            zoneHour = (location.raw_utc_offset.seconds)/3600.0 + location.raw_utc_offset.days * 24
71
57
            
72
58
            #wrap around
73
59
            if zoneHour > 13.0:
74
60
                zoneHour -= 24.0
75
 
            
76
 
            # add the zone if we don't have t already listed
77
 
            if not self.zones.has_key(zoneName):
78
 
                self.zones[zoneName] = {'cities' : [], 'cindex': 0}    
79
 
            
80
 
            #make new city
81
 
            city = City(cityName, zoneName, location.latitude, location.longitude, location.zone)
82
 
            
 
61
 
83
62
            #set the pixamp to show for the city
84
63
            zoneS = str(zoneHour)
85
64
            
96
75
                else:
97
76
                    #no zone...default to nothing
98
77
                    zoneS = None
99
 
                
100
 
            if zoneS:
101
 
                city.pixmap = zonePixmaps[zoneS]
102
 
            
103
 
            self.cities[location.zone] = city
104
 
            
105
 
            # add the city to the zone list
106
 
            city.index = len(self.zones[zoneName]['cities'])
107
 
            self.zones[zoneName]['cities'].append(city)
 
78
            
 
79
            pixmap = zoneS and zonePixmaps[zoneS]
 
80
            
 
81
            #make new city
 
82
            self.cities[location.zone] = City(location, pixmap)
108
83
       
109
84
        ui = self.frontend.ui
110
 
        ui.timezone_zone_combo.currentIndexChanged[str].connect(self.regionChanged)
 
85
        ui.timezone_zone_combo.currentIndexChanged[int].connect(self.regionChanged)
111
86
        ui.timezone_city_combo.currentIndexChanged[int].connect(self.cityChanged)
112
 
            
113
 
        # zone needs to be added to combo box
114
 
        keys = self.zones.keys()
115
 
        keys.sort()
116
 
        for z in keys:
117
 
            self.zones[z]['cindex'] = ui.timezone_zone_combo.count()
118
 
            ui.timezone_zone_combo.addItem(z)
119
87
       
 
88
    def refresh_timezones(self):
 
89
        lang = self.frontend.locale.split('_', 1)[0]
 
90
        shortlist = self.frontend.dbfilter.build_shortlist_region_pairs(lang)
 
91
        longlist = self.frontend.dbfilter.build_region_pairs()
 
92
 
 
93
        self.frontend.ui.timezone_zone_combo.clear()
 
94
        for pair in shortlist:
 
95
            self.frontend.ui.timezone_zone_combo.addItem(pair[0], pair[1])
 
96
        self.frontend.ui.timezone_zone_combo.insertSeparator(self.frontend.ui.timezone_zone_combo.count())
 
97
        for pair in longlist:
 
98
            self.frontend.ui.timezone_zone_combo.addItem(pair[0], pair[2])
 
99
 
 
100
    def populateCities(self, regionIndex):
 
101
        self.frontend.ui.timezone_city_combo.clear()
 
102
 
 
103
        code = str(self.frontend.ui.timezone_zone_combo.itemData(regionIndex).toPyObject())
 
104
        countries = self.frontend.dbfilter.get_countries_for_region(code)
 
105
        if not countries: # must have been a country code itself
 
106
            countries = [code]
 
107
 
 
108
        shortlist, longlist = self.frontend.dbfilter.build_timezone_pairs(countries)
 
109
 
 
110
        for pair in shortlist:
 
111
            self.frontend.ui.timezone_city_combo.addItem(pair[0], pair[1])
 
112
        if shortlist:
 
113
            self.frontend.ui.timezone_city_combo.insertSeparator(self.frontend.ui.timezone_city_combo.count())
 
114
        for pair in longlist:
 
115
            self.frontend.ui.timezone_city_combo.addItem(pair[0], pair[1])
 
116
 
 
117
        return len(countries) == 1 and self.frontend.dbfilter.get_default_for_region(countries[0])
 
118
 
120
119
    # called when the region(zone) combo changes
121
 
    def regionChanged(self, region):
122
 
        self.frontend.ui.timezone_city_combo.clear()
123
 
        #blank entry first to prevent a city from being selected
124
 
        self.frontend.ui.timezone_city_combo.addItem("")
125
 
        
126
 
        #add all the cities
127
 
        for c in self.zones[str(region)]['cities']:
128
 
            self.frontend.ui.timezone_city_combo.addItem(c.city_name, QVariant(c))
129
 
            
 
120
    def regionChanged(self, regionIndex):
 
121
        if self.frontend.dbfilter is None:
 
122
            return
 
123
 
 
124
        self.frontend.ui.timezone_city_combo.currentIndexChanged[int].disconnect(self.cityChanged)
 
125
        default = self.populateCities(regionIndex)
 
126
        self.frontend.ui.timezone_city_combo.currentIndexChanged[int].connect(self.cityChanged)
 
127
 
 
128
        if default:
 
129
            self.set_timezone(default)
 
130
        else:
 
131
            self.frontend.ui.timezone_city_combo.setCurrentIndex(0)
 
132
 
130
133
    # called when the city combo changes
131
134
    def cityChanged(self, cityindex):
132
 
        if cityindex < 1:
133
 
            return
134
 
            
135
 
        city = self.frontend.ui.timezone_city_combo.itemData(cityindex).toPyObject()
136
 
        self.selected_city = city
137
 
        self.repaint()
 
135
        zone = str(self.frontend.ui.timezone_city_combo.itemData(cityindex).toPyObject())
 
136
        loc = self.tzdb.get_loc(zone)
 
137
        city = loc and self.cities[loc.zone]
 
138
        import traceback
 
139
        print '* selecting...', city and city.loc.zone
 
140
        traceback.print_stack(limit=5)
 
141
        print '* selected city is', city and city.loc.zone
 
142
        if city:
 
143
            self.selected_city = city
 
144
            self.repaint()
138
145
        
139
146
    #taken from gtk side
140
147
    def longitudeToX(self, longitude):
175
182
        
176
183
        if self.selected_city != None:
177
184
            c = self.selected_city
178
 
            cpos = self.getPosition(c.lat, c.long)
 
185
            cpos = self.getPosition(c.loc.latitude, c.loc.longitude)
179
186
            
180
187
            if (c.pixmap):
181
188
                painter.drawPixmap(self.rect(), c.pixmap)
188
195
            
189
196
            # paint the time instead of the name
190
197
            try:
191
 
                now = datetime.datetime.now(ubiquity.tz.SystemTzInfo(c.raw_zone))
 
198
                now = datetime.datetime.now(ubiquity.tz.SystemTzInfo(c.loc.zone))
192
199
                timestring = now.strftime('%X')
193
200
                
194
201
                start = cpos + QPoint(3,-3)
274
281
        # get closest city to the point clicked
275
282
        closest = None
276
283
        bestdist = 0
277
 
        for z in self.zones.values():
278
 
            for c in z['cities']:
279
 
                np = pos - self.getPosition(c.lat, c.long)
280
 
                dist = np.x() * np.x() + np.y() * np.y()
281
 
                if (dist < bestdist or closest == None):
282
 
                    closest = c
283
 
                    bestdist = dist
284
 
                    continue
 
284
        for c in self.tzdb.locations:
 
285
            np = pos - self.getPosition(c.latitude, c.longitude)
 
286
            dist = np.x() * np.x() + np.y() * np.y()
 
287
            if (dist < bestdist or closest is None):
 
288
                closest = c
 
289
                bestdist = dist
285
290
        
286
291
        #we need to set the combo boxes
287
292
        #this will cause the redraw we need
288
 
        if closest != None:
289
 
            cindex = self.zones[closest.zone_name]['cindex']
290
 
            self.frontend.ui.timezone_zone_combo.setCurrentIndex(cindex)
291
 
            self.frontend.ui.timezone_city_combo.setCurrentIndex(closest.index + 1)
 
293
        if closest is not None:
 
294
            self._set_timezone(closest)
292
295
 
293
296
    # sets the timezone based on the full name (i.e 'Australia/Sydney')
294
297
    def set_timezone(self, name):
295
 
        self._set_timezone(self.cities[name])
 
298
        self._set_timezone(self.tzdb.get_loc(name), name)
296
299
    
297
300
    # internal set timezone based on a city
298
 
    def _set_timezone(self, city):
299
 
        cindex = self.zones[city.zone_name]['cindex']
300
 
        self.frontend.ui.timezone_zone_combo.setCurrentIndex(cindex)
301
 
        self.frontend.ui.timezone_city_combo.setCurrentIndex(city.index + 1)
 
301
    def _set_timezone(self, loc, city=None):
 
302
        self.frontend.ui.timezone_zone_combo.currentIndexChanged[int].disconnect(self.regionChanged)
 
303
        self.frontend.ui.timezone_city_combo.currentIndexChanged[int].disconnect(self.cityChanged)
 
304
 
 
305
        city = city or loc.zone
 
306
 
 
307
        for i in range(self.frontend.ui.timezone_zone_combo.count()):
 
308
            code = str(self.frontend.ui.timezone_zone_combo.itemData(i).toPyObject())
 
309
            countries = self.frontend.dbfilter.get_countries_for_region(code)
 
310
            if not countries: # must have been a country code itself
 
311
                countries = [code]
 
312
            if loc.country in countries:
 
313
                self.frontend.ui.timezone_zone_combo.setCurrentIndex(i)
 
314
                self.populateCities(i)
 
315
                break
 
316
 
 
317
        for i in range(self.frontend.ui.timezone_city_combo.count()):
 
318
            code = str(self.frontend.ui.timezone_city_combo.itemData(i).toPyObject())
 
319
            if city == code:
 
320
                self.frontend.ui.timezone_city_combo.setCurrentIndex(i)
 
321
                self.cityChanged(i)
 
322
                break
 
323
 
 
324
        self.frontend.ui.timezone_zone_combo.currentIndexChanged[int].connect(self.regionChanged)
 
325
        self.frontend.ui.timezone_city_combo.currentIndexChanged[int].connect(self.cityChanged)
302
326
 
303
327
    # return the full timezone string
304
328
    def get_timezone(self):
305
 
        if self.selected_city == None:
306
 
            return None
307
 
        
308
 
        return self.selected_city.raw_zone
 
329
        i = self.frontend.ui.timezone_city_combo.currentIndex()
 
330
        return str(self.frontend.ui.timezone_city_combo.itemData(i).toPyObject())