33
34
print 'you need pyGTK to run emesene'
36
37
class MainWindow(gtk.Window):
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.
45
46
(gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
46
47
(gobject.TYPE_STRING,)),
49
50
def __init__(self, controller):
51
52
gtk.Window.__init__(self)
53
54
self.controller = controller
54
55
self.config = controller.config
60
61
gtk.ACCEL_LOCKED, self.on_toggle_menu)
62
63
self.set_title('emesene')
65
66
self.x = self.config.glob['mainWindowX']
66
67
self.y = self.config.glob['mainWindowY']
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)
73
74
self.connect('size-allocate', self.on_size_alloc)
75
76
theme = controller.theme
83
84
self.userList = None
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']
89
self.disconectionMessage = None
85
91
self.currentInterface = 'login'
86
92
self.buildInterface('login')
88
94
self.itemSelectedId = 0
91
97
sap = self.signals.append
92
sap(self.config.connect('change::showUserPanel',
94
sap(self.config.connect('change::showSearchEntry',
96
sap(self.config.connect('change::showStatusCombo',
98
sap(self.config.connect('change::showMenu',
100
sap(self.config.connect('change::userListAvatarSize',
98
sap(self.config.connect('change::showUserPanel',
100
sap(self.config.connect('change::showSearchEntry',
102
sap(self.config.connect('change::showStatusCombo',
104
sap(self.config.connect('change::showMenu',
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?
105
111
def on_size_alloc(self, widget, allocation):
106
112
self.width = allocation.width
107
113
self.height = allocation.height
109
115
def on_toggle_menu(self, *args):
110
116
self.config.user['showMenu'] = not self.config.user['showMenu']
112
118
def saveToQuit(self):
113
119
'''Saves configuration parametes and everything needed ir order
114
120
to safely quit'''
126
132
self.controller.config.glob['mainWindowY'] = self.y
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)
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)
139
145
'''Hides itself and any other window'''
142
148
if self.get_property('visible'):
143
149
self.x, self.y = self.get_position()
145
151
if self.userList:
146
152
self.userList.tooltips.hideTooltip()
148
154
# ------------ let the window hide itself the last ---------
149
155
gtk.Window.hide(self)
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.'''
165
171
# save old login values, we may need them in new interface
167
173
user = self.login.getUser()
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)
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)
231
self.filterEntry.connect('filter-entry-lost-focus', self.lost_focus)
224
self.controller.connect('preferences-changed',
234
self.controller.connect('preferences-changed',
225
235
self.updateConfig)
227
237
elif guiType == 'loading':
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)
262
def lost_focus(self, widget):
263
if self.filterEntry.entry.get_text() =='' and not self.config.user['showSearchEntry']:
264
self.filterEntry.hide()
266
def on_key_press(self, widget, event):
267
if self.currentInterface != 'userlist':
268
if gtk.keysyms.Escape == event.keyval:
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()
276
elif self.filterEntry.entry.get_text() !='':
277
self.filterEntry.entry.set_text('')
279
elif self.filterEntry.entry.get_text() =='':
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:
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())
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':
262
306
if not self.config.user['showUserPanel']:
263
307
self.userPanel.hide()
265
309
self.userPanel.show()
267
311
if not self.config.user['showSearchEntry']:
268
312
self.filterEntry.hide()
270
314
self.filterEntry.show()
272
316
if not self.config.user['showStatusCombo']:
273
317
self.statusCombo.hide()
275
319
self.statusCombo.show()
277
321
if not self.config.user['showMenu']:
278
322
self.menu.hide();
280
324
self.menu.show();
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)'''
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)
317
361
self.userList.expand_row(path, False)
363
def getStatusBar(self):
364
eventBox = gtk.EventBox()
365
box = gtk.HBox(False, 0)
366
eventBox.set_size_request(0, 30)
368
eventBox.modify_bg(gtk.STATE_NORMAL, self.controller.tooltipColor)
369
label = gtk.Label(self.disconectionMessage)
370
label.set_ellipsize(pango.ELLIPSIZE_END)
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)
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)
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
360
419
# flag needed to avoid the double-changing of status when
361
420
# user changes it from another place
362
self.changeStatusFlag = True
421
self.changeStatusFlag = True
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)
368
428
def selfStatusChanged(self, msnp, status):
369
429
self.changeStatusFlag = False
370
430
statusOrdered = self.controller.status_ordered[1]
372
432
if emesenelib.common.reverse_status[status] in statusOrdered:
373
433
self.set_active(statusOrdered.index(\
374
434
emesenelib.common.reverse_status[status]))
376
436
self.changeStatusFlag = True
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])
444
def on_scroll_event(self,button, event):