~ubuntu-branches/ubuntu/karmic/emesene/karmic

« back to all changes in this revision

Viewing changes to MainWindow.py

  • Committer: Bazaar Package Importer
  • Author(s): Laurent Bigonville
  • Date: 2009-08-24 10:58:29 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20090824105829-rlawufckorou1exz
Tags: 1.5-1ubuntu1
* Merge from debian unstable, remaining changes (LP: #417371):
  - Add check_notifications.patch to check if the current notification
    system supports actions
  - Drop python-dcop suggests, not in the archive anymore
* Drop debian/patches/currentSong_plugin_support_amarok2.patch:
  merged upstream

Show diffs side-by-side

added added

removed removed

Lines of Context:
29
29
try:
30
30
    import gtk
31
31
    import gobject
 
32
    import pango
32
33
except:
33
34
    print 'you need pyGTK to run emesene'
34
35
    sys.exit(-1)
35
36
 
36
37
class MainWindow(gtk.Window):
37
38
    '''
38
 
    This class represent the main window of emesene, 
 
39
    This class represent the main window of emesene,
39
40
    it inherit from gtk.Window
40
41
    and basically it is a container for other classes.
41
42
    '''
42
43
 
43
44
    __gsignals__ = {
44
 
        'gui-build-done' : 
 
45
        'gui-build-done' :
45
46
            (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
46
47
                (gobject.TYPE_STRING,)),
47
48
    }
49
50
    def __init__(self, controller):
50
51
        '''Constructor'''
51
52
        gtk.Window.__init__(self)
52
 
        
 
53
 
53
54
        self.controller = controller
54
55
        self.config = controller.config
55
56
        # accelerators
60
61
            gtk.ACCEL_LOCKED, self.on_toggle_menu)
61
62
 
62
63
        self.set_title('emesene')
63
 
        self.set_role('main') 
64
 
        
 
64
        self.set_role('main')
 
65
 
65
66
        self.x = self.config.glob['mainWindowX']
66
67
        self.y = self.config.glob['mainWindowY']
67
68
 
69
70
        self.width = self.config.glob['mainWindowWidth']
70
71
        self.height = self.config.glob['mainWindowHeight']
71
72
        self.set_default_size(self.width , self.height)
72
 
       
 
73
 
73
74
        self.connect('size-allocate', self.on_size_alloc)
74
75
 
75
76
        theme = controller.theme
81
82
        self.vbox = None
82
83
        self.login = None
83
84
        self.userList = None
84
 
        
 
85
        #The next generates a variable with letters and numbers to manage the searches
 
86
        self.acceptedCharacters = map(chr, range(97, 123)) + map(chr, range(65, 91)) \
 
87
            + ['0','1','2','3','4','5','6','7','8','9']
 
88
 
 
89
        self.disconectionMessage = None
 
90
 
85
91
        self.currentInterface = 'login'
86
92
        self.buildInterface('login')
87
 
        
 
93
 
88
94
        self.itemSelectedId = 0
89
 
        
 
95
 
90
96
        self.signals = []
91
97
        sap = self.signals.append
92
 
        sap(self.config.connect('change::showUserPanel', 
93
 
            self.updateConfig))
94
 
        sap(self.config.connect('change::showSearchEntry', 
95
 
            self.updateConfig))
96
 
        sap(self.config.connect('change::showStatusCombo', 
97
 
            self.updateConfig))
98
 
        sap(self.config.connect('change::showMenu', 
99
 
            self.updateConfig))
100
 
        sap(self.config.connect('change::userListAvatarSize', 
 
98
        sap(self.config.connect('change::showUserPanel',
 
99
            self.updateConfig))
 
100
        sap(self.config.connect('change::showSearchEntry',
 
101
            self.updateConfig))
 
102
        sap(self.config.connect('change::showStatusCombo',
 
103
            self.updateConfig))
 
104
        sap(self.config.connect('change::showMenu',
 
105
            self.updateConfig))
 
106
        sap(self.config.connect('change::userListAvatarSize',
101
107
            self.updateSize))
102
108
        sap(self.config.connect('change::smallIcons', self.updateSize))
103
109
        # TODO: do we need disconnecting these signals?
104
 
        
 
110
 
105
111
    def on_size_alloc(self, widget, allocation):
106
112
        self.width = allocation.width
107
113
        self.height = allocation.height
108
 
    
 
114
 
109
115
    def on_toggle_menu(self, *args):
110
116
        self.config.user['showMenu'] = not self.config.user['showMenu']
111
 
        
 
117
 
112
118
    def saveToQuit(self):
113
119
        '''Saves configuration parametes and everything needed ir order
114
120
        to safely quit'''
118
124
                self.userList.saveGroupState()
119
125
            except:
120
126
                pass
121
 
        
 
127
 
122
128
        self.controller.config.glob['mainWindowWidth'] = self.width
123
129
        self.controller.config.glob['mainWindowHeight'] = self.height
124
130
 
126
132
        self.controller.config.glob['mainWindowY'] = self.y
127
133
 
128
134
    def quit(self, status = 0):
129
 
        '''close the window, and do all the things needed...'''     
 
135
        '''close the window, and do all the things needed...'''
130
136
        self.controller.quit(status)
131
 
        
 
137
 
132
138
    def show(self):
133
139
        '''Shows itself'''
134
 
        if not (self.x <= 0 or self.y <= 0):
 
140
        if not (self.x < 0 or self.y < 0):
135
141
            self.move(self.x, self.y)
136
142
        gtk.Window.show(self)
137
 
        
 
143
 
138
144
    def hide(self):
139
145
        '''Hides itself and any other window'''
140
146
 
141
147
        # saves position
142
148
        if self.get_property('visible'):
143
149
            self.x, self.y = self.get_position()
144
 
        
 
150
 
145
151
        if self.userList:
146
152
            self.userList.tooltips.hideTooltip()
147
 
        
 
153
 
148
154
        # ------------ let the window hide itself the last ---------
149
155
        gtk.Window.hide(self)
150
156
 
161
167
    def buildInterface(self , guiType = 'login'):
162
168
        '''build the interface depending on the guiType parameter, by
163
169
        default build the login window.'''
164
 
        
 
170
 
165
171
        # save old login values, we may need them in new interface
166
172
        if self.login:
167
173
            user = self.login.getUser()
170
176
        else:
171
177
            user = passwd = status = ''
172
178
 
173
 
        if self.get_child() != None:
 
179
        if self.get_child():
174
180
            self.remove(self.vbox)
175
 
        
 
181
 
176
182
        if self.userList:
177
183
            self.userList.tooltips.hideTooltip()
178
184
            self.userList.disconnect(self.itemSelectedId)
185
191
                emesenelib.common.debug('Error when removing loginImage')
186
192
 
187
193
        self.currentInterface = guiType
188
 
                    
 
194
 
189
195
        #widgets
190
196
 
191
197
        self.vbox = gtk.VBox(spacing=2)
198
204
        if guiType == 'login':
199
205
            self.vbox.pack_start(self.menu, False, False)
200
206
            self.login = Login.Login(self.controller, 'login')
 
207
            if self.disconectionMessage != None:
 
208
                self.vbox.pack_start(self.getStatusBar(), False, False, 0)
 
209
                self.disconectionMessage = None
201
210
            self.vbox.pack_start(self.login)
202
211
        elif guiType == 'userlist':
203
212
            self.login = None
206
215
                self.controller.theme, self.controller.config)
207
216
            self.itemSelectedId = self.userList.connect('item-selected',
208
217
                self.onItemSelected)
209
 
            
 
218
 
210
219
            self.userPanel = UserPanel.UserPanel(self.controller)
211
220
            self.vbox.pack_start(self.userPanel, False, False)
212
221
            self.filterEntry = FilterEntry.FilterEntry(
219
228
            vbox2.pack_start(self.statusCombo, False, False)
220
229
            vbox2.set_border_width(2)
221
230
            self.vbox.pack_start(vbox2)
222
 
            
 
231
            self.filterEntry.connect('filter-entry-lost-focus', self.lost_focus)
 
232
 
223
233
            vbox2.show_all()
224
 
            self.controller.connect('preferences-changed', 
 
234
            self.controller.connect('preferences-changed',
225
235
                self.updateConfig)
226
236
 
227
237
        elif guiType == 'loading':
239
249
            self.vbox.pack_start(self.menu, False, False)
240
250
            self.vbox.pack_start(self.login)
241
251
            self.menu.show_all()
242
 
        
 
252
 
243
253
        self.menu.show_all()
244
254
        self.add(self.vbox)
245
255
        self.vbox.show()
247
257
 
248
258
        self.connect('delete-event' , self.hideOrClose)
249
259
        self.emit('gui-build-done', guiType)
 
260
        self.connect('key-press-event', self.on_key_press)
 
261
 
 
262
    def lost_focus(self, widget):
 
263
        if self.filterEntry.entry.get_text() =='' and not self.config.user['showSearchEntry']:
 
264
            self.filterEntry.hide()
 
265
 
 
266
    def on_key_press(self, widget, event):
 
267
        if self.currentInterface != 'userlist': 
 
268
            if gtk.keysyms.Escape == event.keyval:
 
269
                self.hideOrClose()
 
270
        else:
 
271
            from gtk.gdk import CONTROL_MASK, MOD1_MASK
 
272
            if gtk.keysyms.Escape == event.keyval:
 
273
                if self.filterEntry.entry.get_text() =='' and not self.config.user['showSearchEntry'] and self.filterEntry.entry.is_focus():
 
274
                    self.filterEntry.hide()
 
275
                    return True
 
276
                elif self.filterEntry.entry.get_text() !='':
 
277
                    self.filterEntry.entry.set_text('')
 
278
                    return True
 
279
                elif self.filterEntry.entry.get_text() =='':
 
280
                    self.hideOrClose()
 
281
                    return True
 
282
            elif  not self.userPanel.tNick.is_focus() and not self.userPanel.tPersonalMessage.is_focus(): 
 
283
                if not self.filterEntry.entry.is_focus() : 
 
284
                    if gtk.gdk.keyval_name(event.keyval)  in self.acceptedCharacters: 
 
285
                        if event.state & CONTROL_MASK or event.state & MOD1_MASK:
 
286
                            return False
 
287
                        else:
 
288
                            if self.filterEntry.entry.get_text() =='' and not self.config.user['showSearchEntry']:
 
289
                                self.filterEntry.show()
 
290
                            self.filterEntry.entry.set_text(self.filterEntry.entry.get_text() + gtk.gdk.keyval_name(event.keyval))
 
291
                            self.filterEntry.entry.grab_focus()
 
292
                            self.filterEntry.entry.set_position(self.filterEntry.entry.get_text_length())
 
293
                            return True
250
294
 
251
295
    def updateConfig(self, *args):
252
296
        self.update(self.controller, False)
258
302
    def update(self, controller, refresUserList=True):
259
303
        if not controller or self.currentInterface != 'userlist':
260
304
            return
261
 
        
 
305
 
262
306
        if not self.config.user['showUserPanel']:
263
307
            self.userPanel.hide()
264
308
        else:
265
309
            self.userPanel.show()
266
 
            
 
310
 
267
311
        if not self.config.user['showSearchEntry']:
268
312
            self.filterEntry.hide()
269
313
        else:
270
314
            self.filterEntry.show()
271
 
                
 
315
 
272
316
        if not self.config.user['showStatusCombo']:
273
317
            self.statusCombo.hide()
274
318
        else:
275
319
            self.statusCombo.show()
276
 
        
 
320
 
277
321
        if not self.config.user['showMenu']:
278
322
            self.menu.hide();
279
323
        else:
280
324
            self.menu.show();
281
 
        
 
325
 
282
326
        # update UserPanel Nick and PM
283
327
        if self.config.user['showUserPanel']:
284
328
            self.userPanel.personalMessageRefresh()
297
341
        (if we are in userlist mode)'''
298
342
 
299
343
        if self.currentInterface == 'userlist':
300
 
            groups = self.controller.msn.contactManager.groups 
 
344
            groups = self.controller.msn.contactManager.groups
301
345
            groups[_('no group')] = \
302
346
                self.controller.msn.contactManager.noGroup
303
347
            self.userList.fill(groups, force)
315
359
                self.userList.collapse_row(path)
316
360
            else:
317
361
                self.userList.expand_row(path, False)
318
 
    
 
362
 
 
363
    def getStatusBar(self):
 
364
        eventBox = gtk.EventBox()
 
365
        box = gtk.HBox(False, 0)
 
366
        eventBox.set_size_request(0, 30)
 
367
        eventBox.add(box)
 
368
        eventBox.modify_bg(gtk.STATE_NORMAL, self.controller.tooltipColor)
 
369
        label = gtk.Label(self.disconectionMessage)
 
370
        label.set_ellipsize(pango.ELLIPSIZE_END)
 
371
        image = gtk.Image()
 
372
        image.set_from_stock (gtk.STOCK_DIALOG_INFO, gtk.ICON_SIZE_LARGE_TOOLBAR)
 
373
        box.pack_start(image, False, False, 5)
 
374
        box.pack_start(label, True, True, 5)
 
375
        eventBox.show_all()
 
376
        return eventBox
 
377
 
319
378
 
320
379
class StatusCombo(gtk.ComboBox):
321
380
    '''this class represent the combo where you set the status'''
338
397
        self.statusPixbufCell.set_property('xpad', 5)
339
398
        self.statusTextCell.set_property('xalign', 0.0)
340
399
        self.statusTextCell.set_property('xpad', 5)
341
 
        self.statusTextCell.set_property('width', 195)
 
400
        self.statusTextCell.set_property('width', 158)
342
401
        self.add_attribute(self.statusPixbufCell, 'pixbuf', 0)
343
402
        self.add_attribute(self.statusTextCell, 'text', 2)
344
403
        self.set_resize_mode(0)
350
409
        for i in controller.status_ordered[0]:
351
410
            if self.controller.contacts.get_status() == i:
352
411
                self.set_active(j)
353
 
                
 
412
 
354
413
            if i != 'FLN':
355
414
                self.statusListStore.append([
356
 
                    self.controller.theme.statusToPixbuf(i), i,
 
415
                    self.controller.theme.statusToPixbuf(i).scale_simple(20,20,gtk.gdk.INTERP_BILINEAR), i,
357
416
                    _(self.controller.status_ordered[2][j])]) # re-gettext-it
358
417
            j += 1
359
418
 
360
419
        # flag needed to avoid the double-changing of status when
361
420
        # user changes it from another place
362
 
        self.changeStatusFlag = True 
363
 
        
 
421
        self.changeStatusFlag = True
 
422
 
 
423
        self.connect('scroll-event', self.on_scroll_event)
364
424
        self.connect('changed', self.on_status_changed, self.changeStatusFlag)
365
 
        self.controller.msn.connect('self-status-changed', 
 
425
        self.controller.msn.connect('self-status-changed',
366
426
            self.selfStatusChanged)
367
427
 
368
428
    def selfStatusChanged(self, msnp, status):
369
429
        self.changeStatusFlag = False
370
430
        statusOrdered = self.controller.status_ordered[1]
371
 
        
 
431
 
372
432
        if emesenelib.common.reverse_status[status] in statusOrdered:
373
433
            self.set_active(statusOrdered.index(\
374
434
                emesenelib.common.reverse_status[status]))
375
 
                
 
435
 
376
436
        self.changeStatusFlag = True
377
437
 
378
438
    def on_status_changed(self , *args):
379
439
        if self.changeStatusFlag:
380
440
            asd = self.statusListStore.get(self.get_active_iter(), 1)
381
 
            print "on_status_changed", asd
 
441
            #print "on_status_changed", asd
382
442
            self.controller.contacts.set_status(asd[0])
 
443
 
 
444
    def on_scroll_event(self,button, event):
 
445
        self.popup()
 
446
        return True