~ubuntu-branches/ubuntu/oneiric/emesene/oneiric-proposed

« back to all changes in this revision

Viewing changes to emesene/gui/gtkui/Login.py

  • Committer: Bazaar Package Importer
  • Author(s): Devid Antonio Filoni
  • Date: 2011-03-03 14:49:13 UTC
  • mfrom: (1.1.9 upstream)
  • Revision ID: james.westby@ubuntu.com-20110303144913-0adl9cmw2s35lvzo
Tags: 2.0~git20110303-0ubuntu1
* New upstream git revision (LP: #728469).
* Remove debian/watch, debian/emesene.xpm, debian/install and
  debian/README.source files.
* Remove 21_svn2451_fix_avatar and 20_dont_build_own_libmimic patches.
* debian/control: modify python to python (>= 2.5) in Build-Depends field.
* debian/control: remove python-libmimic from Recommends field.
* debian/control: modify python-gtk2 (>= 2.10) to python-gtk2 (>= 2.12) in
  Depends field.
* debian/control: add python-appindicator and python-xmpp to Recommends
  field.
* debian/control: add python-papyon (>= 0.5.4) and python-webkit to Depends
  field.
* debian/control: update Description field.
* debian/control: add python-setuptools to Build-Depends field.
* debian/control: move python-dbus and python-notify to Depends field.
* Update debian/copyright file.
* Update debian/links file.
* debian/menu: update description field.
* Bump Standards-Version to 3.9.1.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- coding: utf-8 -*-
 
2
 
 
3
#    This file is part of emesene.
 
4
#
 
5
#    emesene is free software; you can redistribute it and/or modify
 
6
#    it under the terms of the GNU General Public License as published by
 
7
#    the Free Software Foundation; either version 3 of the License, or
 
8
#    (at your option) any later version.
 
9
#
 
10
#    emesene is distributed in the hope that it will be useful,
 
11
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
#    GNU General Public License for more details.
 
14
#
 
15
#    You should have received a copy of the GNU General Public License
 
16
#    along with emesene; if not, write to the Free Software
 
17
#    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
18
 
 
19
import gtk
 
20
import base64
 
21
import gobject
 
22
import sys
 
23
from shutil import rmtree
 
24
 
 
25
import e3
 
26
import gui
 
27
import utils
 
28
import extension
 
29
import StatusButton
 
30
import stock
 
31
 
 
32
import logging
 
33
log = logging.getLogger('gtkui.Login')
 
34
 
 
35
class LoginBase(gtk.Alignment):
 
36
    ''' base widget that holds the visual stuff '''
 
37
    def __init__(self, callback, args=None):
 
38
        gtk.Alignment.__init__(self, xalign=0.5, yalign=0.5, xscale=0.0,
 
39
            yscale=1.0)
 
40
 
 
41
        self.dialog = extension.get_default('dialog')
 
42
        Avatar = extension.get_default('avatar')
 
43
        NiceBar = extension.get_default('nice bar')
 
44
 
 
45
        self.liststore = gtk.ListStore(gobject.TYPE_STRING, gtk.gdk.Pixbuf)
 
46
        completion = gtk.EntryCompletion()
 
47
        completion.set_model(self.liststore)
 
48
        pixbufcell = gtk.CellRendererPixbuf()
 
49
        completion.pack_start(pixbufcell)
 
50
        completion.add_attribute(pixbufcell, 'pixbuf', 1)
 
51
        completion.set_text_column(0)
 
52
        completion.set_inline_selection(True)
 
53
 
 
54
        self.pixbuf = utils.safe_gtk_pixbuf_load(gui.theme.user)
 
55
 
 
56
        self.cmb_account = gtk.ComboBoxEntry(self.liststore, 0)
 
57
        self.cmb_account.set_tooltip_text(_('Account'))
 
58
        self.cmb_account.get_children()[0].set_completion(completion)
 
59
        self.cmb_account.get_children()[0].connect('key-press-event',
 
60
            self._on_account_key_press)
 
61
        self.cmb_account.connect('changed',
 
62
            self._on_account_changed)
 
63
        self.cmb_account.connect('key-release-event',
 
64
            self._on_account_key_release)
 
65
 
 
66
        self.btn_status = StatusButton.StatusButton()
 
67
        self.btn_status.set_tooltip_text(_('Status'))
 
68
        self.btn_status.set_status(e3.status.ONLINE)
 
69
        self.btn_status.set_size_request(34, -1)
 
70
 
 
71
        self.txt_password = gtk.Entry()
 
72
        self.txt_password.set_tooltip_text(_('Password'))
 
73
        self.txt_password.set_visibility(False)
 
74
        self.txt_password.connect('key-press-event',
 
75
            self._on_password_key_press)
 
76
        self.txt_password.connect('changed', self._on_password_changed)
 
77
        self.txt_password.set_sensitive(False)
 
78
 
 
79
        pix_account = utils.safe_gtk_pixbuf_load(gui.theme.user)
 
80
        pix_password = utils.safe_gtk_pixbuf_load(gui.theme.password)
 
81
 
 
82
        self.avatar = Avatar()
 
83
 
 
84
        self.remember_account = gtk.CheckButton(_('Remember me'))
 
85
        self.remember_password = gtk.CheckButton(_('Remember password'))
 
86
        self.auto_login = gtk.CheckButton(_('Auto-login'))
 
87
 
 
88
        self.remember_account.connect('toggled',
 
89
            self._on_remember_account_toggled)
 
90
        self.remember_password.connect('toggled',
 
91
            self._on_remember_password_toggled)
 
92
        self.auto_login.connect('toggled',
 
93
            self._on_auto_login_toggled)
 
94
 
 
95
        self.remember_account.set_sensitive(False)
 
96
        self.remember_password.set_sensitive(False)
 
97
        self.auto_login.set_sensitive(False)
 
98
 
 
99
        self.forget_me = gtk.Button()
 
100
        self.forget_me.set_tooltip_text(_('Delete user'))
 
101
        forget_img = gtk.image_new_from_stock(gtk.STOCK_CANCEL, gtk.ICON_SIZE_MENU)
 
102
        self.forget_me.set_image(forget_img)
 
103
        self.forget_me.set_relief(gtk.RELIEF_NONE)
 
104
        self.forget_me.set_border_width(0)
 
105
        self.forget_me.set_size_request(34, -1)
 
106
        self.forget_me.connect('clicked', self._on_forget_me_clicked)
 
107
        self.forget_me.set_sensitive(False)
 
108
 
 
109
        hboxremember = gtk.HBox(spacing=2)
 
110
        hboxremember.pack_start(self.remember_account, False)
 
111
 
 
112
        vbox_remember = gtk.VBox(spacing=4)
 
113
        vbox_remember.set_border_width(8)
 
114
        vbox_remember.pack_start(hboxremember)
 
115
        vbox_remember.pack_start(self.remember_password)
 
116
        vbox_remember.pack_start(self.auto_login)
 
117
        vbox_remember.pack_start(gtk.Label())
 
118
 
 
119
        self.b_connect = gtk.Button(stock=gtk.STOCK_CONNECT)
 
120
        self.b_connect.connect('clicked', self._on_connect_clicked)
 
121
        self.b_connect.set_sensitive(False)
 
122
 
 
123
        self.b_cancel = gtk.Button(stock=gtk.STOCK_CANCEL)
 
124
        self.b_cancel.connect('clicked', self._on_cancel_clicked)
 
125
 
 
126
        vbuttonbox = gtk.VButtonBox()
 
127
        vbuttonbox.set_spacing(8)
 
128
        vbuttonbox.pack_start(self.b_connect)
 
129
        vbuttonbox.pack_start(self.b_cancel)
 
130
 
 
131
        vbox_content = gtk.VBox()
 
132
 
 
133
        hbox_account = gtk.HBox(spacing=6)
 
134
        img_accountpix = gtk.Image()
 
135
        img_accountpix.set_from_pixbuf(utils.scale_nicely(pix_account))
 
136
        hbox_account.pack_start(img_accountpix, False)
 
137
        hbox_account.pack_start(self.cmb_account)
 
138
        hbox_account.pack_start(self.forget_me, False)
 
139
 
 
140
        hbox_password = gtk.HBox(spacing=6)
 
141
        img_password = gtk.Image()
 
142
        img_password.set_from_pixbuf(utils.scale_nicely(pix_password))
 
143
        hbox_password.pack_start(img_password, False)
 
144
        hbox_password.pack_start(self.txt_password)
 
145
        hbox_password.pack_start(self.btn_status, False)
 
146
 
 
147
        session_combo_store = gtk.ListStore(gtk.gdk.Pixbuf, str)
 
148
        crp = gtk.CellRendererPixbuf()
 
149
        crt = gtk.CellRendererText()
 
150
        crp.set_property("xalign", 0)
 
151
        crt.set_property("xalign", 0)
 
152
 
 
153
        self.session_combo = gtk.ComboBox()
 
154
        self.session_combo.set_tooltip_text(_('Choose your network'))
 
155
        self.session_combo.set_model(session_combo_store)
 
156
        self.session_combo.pack_start(crp)
 
157
        self.session_combo.pack_start(crt)
 
158
        self.session_combo.add_attribute(crp, "pixbuf", 0)
 
159
        self.session_combo.add_attribute(crt, "text", 1)
 
160
 
 
161
        self.b_preferences = gtk.Button()
 
162
        self.b_preferences.set_tooltip_text(_('Preferences'))
 
163
        self.img_preferences = gtk.image_new_from_stock(gtk.STOCK_PREFERENCES,
 
164
            gtk.ICON_SIZE_MENU)
 
165
        self.img_preferences.set_sensitive(False)
 
166
        self.b_preferences.set_image(self.img_preferences)
 
167
        self.b_preferences.set_relief(gtk.RELIEF_NONE)
 
168
        self.b_preferences.connect('enter-notify-event',
 
169
            self._on_preferences_enter)
 
170
        self.b_preferences.connect('leave-notify-event',
 
171
            self._on_preferences_leave)
 
172
        self.b_preferences.connect('clicked',
 
173
            self._on_preferences_selected)
 
174
        self.b_preferences.set_size_request(34, -1)
 
175
 
 
176
        img_sessionpix = gtk.image_new_from_stock(gtk.STOCK_CONNECT, gtk.ICON_SIZE_MENU)
 
177
        img_sessionpix.set_size_request(20, -1)
 
178
        img_sessionpix.set_sensitive(False)
 
179
        hbox_session = gtk.HBox(spacing=6)
 
180
        hbox_session.pack_start(img_sessionpix, False)
 
181
        hbox_session.pack_start(self.session_combo)
 
182
        hbox_session.pack_start(self.b_preferences, False)
 
183
 
 
184
        vbox_entries = gtk.VBox(spacing=12)
 
185
        vbox_entries.set_border_width(8)
 
186
        vbox_entries.pack_start(hbox_account)
 
187
        vbox_entries.pack_start(hbox_password)
 
188
        vbox_entries.pack_start(hbox_session)
 
189
 
 
190
        self.nicebar = NiceBar()
 
191
 
 
192
        th_pix = utils.safe_gtk_pixbuf_load(gui.theme.throbber, None,
 
193
                animated=True)
 
194
        self.throbber = gtk.image_new_from_animation(th_pix)
 
195
        self.label_timer = gtk.Label()
 
196
        self.label_timer.set_markup(_('<b>Connection error!\n </b>'))
 
197
 
 
198
        al_label_timer = gtk.Alignment(xalign=0.5, yalign=0.5, xscale=0.0,
 
199
            yscale=0.0)
 
200
        al_throbber = gtk.Alignment(xalign=0.5, yalign=0.5, xscale=0.2,
 
201
            yscale=0.2)
 
202
        al_vbox_entries = gtk.Alignment(xalign=0.5, yalign=0.5, xscale=0.2,
 
203
            yscale=0.0)
 
204
        al_vbox_remember = gtk.Alignment(xalign=0.5, yalign=0.5, xscale=0.0,
 
205
            yscale=0.2)
 
206
        al_button = gtk.Alignment(xalign=0.5, yalign=0.5, xscale=0.2)
 
207
        al_account = gtk.Alignment(xalign=0.5, yalign=0.5, xscale=0.0,
 
208
            yscale=0.0)
 
209
 
 
210
        al_label_timer.add(self.label_timer)
 
211
        al_throbber.add(self.throbber)
 
212
        al_vbox_entries.add(vbox_entries)
 
213
        al_vbox_remember.add(vbox_remember)
 
214
        al_button.add(vbuttonbox)
 
215
        al_account.add(self.avatar)
 
216
 
 
217
        vbox = gtk.VBox()
 
218
        vbox_top = gtk.VBox()
 
219
        vbox_far_bottom = gtk.VBox()
 
220
 
 
221
        vbox_bottom = gtk.VBox(True)
 
222
        vbox_content.pack_start(al_account, True, False)
 
223
        vbox_content.pack_start(al_vbox_entries, False)
 
224
        vbox_content.pack_start(al_vbox_remember, True, False)
 
225
        vbox_bottom.pack_start(al_label_timer, True, False)
 
226
        vbox_bottom.pack_start(al_throbber, False)
 
227
        vbox_bottom.pack_start(al_button)
 
228
        vbox_content.pack_start(vbox_bottom)
 
229
 
 
230
        vbox.pack_start(self.nicebar, False)
 
231
        vbox.pack_start(vbox_top)
 
232
        vbox.pack_start(vbox_content)
 
233
        vbox.pack_start(vbox_far_bottom)
 
234
 
 
235
        self.add(vbox)
 
236
        vbox.show_all()
 
237
 
 
238
    def _on_cancel_clicked(self, button):
 
239
        '''
 
240
        overload this
 
241
        '''
 
242
        return
 
243
 
 
244
class Login(LoginBase):
 
245
    '''
 
246
    widget that represents the login window
 
247
    '''
 
248
    def __init__(self, callback, on_preferences_changed,
 
249
                config, config_dir, config_path, proxy=None,
 
250
                use_http=None, session_id=None, cancel_clicked=False,
 
251
                no_autologin=False):
 
252
 
 
253
        LoginBase.__init__(self, callback)
 
254
 
 
255
        self.config = config
 
256
        self.config_dir = config_dir
 
257
        self.config_path = config_path
 
258
        self.callback = callback
 
259
        self.cancel_clicked=cancel_clicked
 
260
        self.on_preferences_changed = on_preferences_changed
 
261
        self.no_autologin = no_autologin
 
262
        # the id of the default extension that handles the session
 
263
        # used to select the default session on the preference dialog
 
264
        self.use_http = use_http
 
265
        self.session_id = session_id
 
266
 
 
267
        account = self.config.get_or_set('last_logged_account', '')
 
268
        self.config.get_or_set('service', 'msn')
 
269
        self.remembers = self.config.get_or_set('d_remembers', {})
 
270
        self.config.get_or_set('d_user_service', {})
 
271
        self.status = self.config.get_or_set('d_status',{})
 
272
        self.accounts = self.config.d_accounts
 
273
 
 
274
        self._reload_account_list()
 
275
        self.__combo_session_list=[]
 
276
 
 
277
        if proxy is None:
 
278
            self.proxy = e3.Proxy()
 
279
        else:
 
280
            self.proxy = proxy
 
281
 
 
282
        self.services = {}
 
283
 
 
284
        if session_id is not None:
 
285
            for ext_id, ext in extension.get_extensions('session').iteritems():
 
286
                for service_name, service_data in ext.SERVICES.iteritems():
 
287
                    self.services[service_name] = service_data
 
288
 
 
289
                if session_id == ext_id and self.config.service in ext.SERVICES:
 
290
                    self.server_host = ext.SERVICES[self.config.service]['host']
 
291
                    self.server_port = ext.SERVICES[self.config.service]['port']
 
292
                    break
 
293
            else:
 
294
                self.config.service = 'msn'
 
295
                self.server_host = 'messenger.hotmail.com'
 
296
                self.server_port = '1863'
 
297
        else:
 
298
            self.config.service = 'msn'
 
299
            self.server_host = 'messenger.hotmail.com'
 
300
            self.server_port = '1863'
 
301
 
 
302
        avatar_path = self.config_dir.join(self.server_host, account, 'avatars', 'last')
 
303
        self.avatar.set_from_file(avatar_path)
 
304
 
 
305
        self.nicebar.hide()
 
306
        self.throbber.hide()
 
307
        self.label_timer.hide()
 
308
        self.b_cancel.hide()
 
309
 
 
310
        if account != '':
 
311
            self.cmb_account.get_children()[0].set_text(account)
 
312
 
 
313
        if not self.cancel_clicked:
 
314
            self._check_autologin()
 
315
 
 
316
        self._show_sessions()
 
317
 
 
318
    def __on_session_changed(self, session_combo, name_to_ext):
 
319
 
 
320
        active = session_combo.get_active()
 
321
        model = session_combo.get_model()
 
322
        service = model[active][1]
 
323
        session_id, ext = name_to_ext[service]
 
324
        self._on_new_preferences(self.use_http, self.proxy.use_proxy, self.proxy.host, self.proxy.port,self.proxy.use_auth, self.proxy.user, self.proxy.passwd, session_id, service, ext.SERVICES[service]['host'], ext.SERVICES[service]['port'])
 
325
 
 
326
    def _show_sessions(self):
 
327
 
 
328
        self.new_combo_session(self.session_combo, self.__on_session_changed)
 
329
 
 
330
    def new_combo_session(self, session_combo, on_session_changed):
 
331
        account = self.config.get_or_set('last_logged_account', '')
 
332
        default_session = extension.get_default('session')
 
333
        count=0
 
334
        session_found = False
 
335
 
 
336
        name_to_ext = {}
 
337
 
 
338
        if account in self.accounts:
 
339
            service = self.config.d_user_service.get(account, 'msn')
 
340
        else:
 
341
            service = self.config.service
 
342
 
 
343
        for ext_id, ext in extension.get_extensions('session').iteritems():
 
344
            if default_session.NAME == ext.NAME:
 
345
                default_session_index = count
 
346
 
 
347
            for service_name, service_data in ext.SERVICES.iteritems():
 
348
                if service == service_name:
 
349
                    index = count
 
350
                    session_found = True
 
351
 
 
352
                try:
 
353
                    s_name = getattr(gui.theme, "service_" + service_name) 
 
354
                    image = utils.safe_gtk_pixbuf_load(s_name)
 
355
                except:
 
356
                    image = None
 
357
 
 
358
                session_combo.get_model().append([image, service_name])
 
359
                name_to_ext[service_name] = (ext_id, ext)
 
360
                count += 1
 
361
 
 
362
        if session_found:
 
363
            session_combo.set_active(index)
 
364
        else:
 
365
            session_combo.set_active(default_session_index)
 
366
 
 
367
        session_combo.connect('changed', on_session_changed, name_to_ext)
 
368
 
 
369
        self.__combo_session_list.append(session_combo)
 
370
 
 
371
        return name_to_ext
 
372
        
 
373
    def _check_autologin(self):
 
374
        '''check if autologin is set and can be started'''
 
375
        account = self.config.get_or_set('last_logged_account', '')
 
376
 
 
377
        if account != '' and int(self.config.d_remembers.get(account, 0)) == 3:
 
378
            password = base64.b64decode(self.config.d_accounts[account])
 
379
 
 
380
            self.cmb_account.get_children()[0].set_text(account)
 
381
            self.txt_password.set_text(password)
 
382
 
 
383
            if not self.no_autologin:
 
384
                self.do_connect()
 
385
 
 
386
    def do_connect(self):
 
387
        '''
 
388
        do all the stuffs needed to connect
 
389
        '''
 
390
        self.nicebar.empty_queue()
 
391
        user = self.cmb_account.get_active_text().strip()
 
392
        password = self.txt_password.get_text()
 
393
        account = e3.Account(user, password, self.btn_status.status,
 
394
                self.server_host)
 
395
        remember_password = self.remember_password.get_active()
 
396
        remember_account = self.remember_account.get_active()
 
397
        auto_login = self.auto_login.get_active()
 
398
 
 
399
        if user == '' or password == '':
 
400
            self.show_error(_('user or password fields are empty'))
 
401
            return
 
402
 
 
403
        self._config_account(account, remember_account, remember_password,
 
404
                             auto_login)
 
405
 
 
406
        self.callback(account, self.session_id, self.proxy, self.use_http,
 
407
                self.server_host, self.server_port)
 
408
 
 
409
    def _config_account(self, account, remember_account, remember_password,
 
410
                         auto_login):
 
411
        '''
 
412
        modify the config for the current account before login
 
413
        '''
 
414
 
 
415
        if auto_login or remember_account or remember_password:
 
416
            self.status[account.account] = account.status
 
417
            self.config.last_logged_account = account.account
 
418
 
 
419
        if auto_login:#+1 account,+1 password,+1 autologin =  3
 
420
            self.accounts[account.account] = base64.b64encode(account.password)
 
421
            self.remembers[account.account] = 3
 
422
 
 
423
        elif remember_password:#+1 account,+1 password = 2
 
424
            self.accounts[account.account] = base64.b64encode(account.password)
 
425
            self.remembers[account.account] = 2
 
426
 
 
427
        elif remember_account:#+1 account = 1
 
428
            self.accounts[account.account] = ''
 
429
            self.remembers[account.account] = 1
 
430
 
 
431
        else:#means i have logged with nothing checked
 
432
            self.config.last_logged_account = ''
 
433
 
 
434
        self.config.save(self.config_path)
 
435
 
 
436
    def _on_account_changed(self, entry):
 
437
        '''
 
438
        called when the content of the account entry changes
 
439
        '''
 
440
        self._update_fields(self.cmb_account.get_active_text())
 
441
 
 
442
    def _on_account_key_release(self, entry, event):
 
443
        '''
 
444
        called when a key is released in the account field
 
445
        '''
 
446
        self._update_fields(self.cmb_account.get_active_text())
 
447
        if event.keyval == gtk.keysyms.Tab:
 
448
            self.txt_password.grab_focus()
 
449
 
 
450
    def _update_fields(self, account):
 
451
        '''
 
452
        update the different fields according to the account that is
 
453
        on the account entry
 
454
        '''
 
455
        self._clear_all()
 
456
 
 
457
        if self.txt_password.get_text() == '':
 
458
            self.remember_password.set_sensitive(False)
 
459
            self.auto_login.set_sensitive(False)
 
460
 
 
461
        if account == '':
 
462
            self.remember_account.set_sensitive(False)
 
463
            self.txt_password.set_text('')
 
464
            self.txt_password.set_sensitive(False)
 
465
            return
 
466
 
 
467
        self.remember_account.set_sensitive(True)
 
468
 
 
469
        if account in self.config.d_user_service:
 
470
            service = self.config.d_user_service[account]
 
471
 
 
472
            if service in self.services:
 
473
                service_data = self.services[service]
 
474
                self.server_host = service_data['host']
 
475
                self.server_port = service_data['port']
 
476
                self.config.service = service
 
477
 
 
478
        if account in self.accounts:
 
479
            attr = int(self.remembers[account])
 
480
            self.remember_account.set_sensitive(False)
 
481
            self.forget_me.set_sensitive(True)
 
482
            self.btn_status.set_status(int(self.status[account]))
 
483
 
 
484
            passw = self.accounts[account]
 
485
            avatar_path = self.config_dir.join(self.server_host, account, 'avatars', 'last')
 
486
            self.avatar.set_from_file(avatar_path)
 
487
 
 
488
            if attr == 3:#autologin,password,account checked
 
489
                self.txt_password.set_text(base64.b64decode(passw))
 
490
                self.txt_password.set_sensitive(False)
 
491
                self.auto_login.set_active(True)
 
492
            elif attr == 2:#password,account checked
 
493
                self.txt_password.set_text(base64.b64decode(passw))
 
494
                self.txt_password.set_sensitive(False)
 
495
                self.remember_password.set_active(True)
 
496
            elif attr == 1:#only account checked
 
497
                self.remember_account.set_active(True)
 
498
                self.remember_account.set_sensitive(True)
 
499
                self.remember_password.set_sensitive(False)
 
500
                self.auto_login.set_sensitive(False)
 
501
            else:#if i'm here i have an error
 
502
                self.show_error(_(
 
503
                          'Error while reading user config'))
 
504
                self._clear_all()
 
505
 
 
506
        else:
 
507
           self.avatar.set_from_file(gui.theme.logo)
 
508
 
 
509
    def _clear_all(self):
 
510
        '''
 
511
        clear all login fields and checkbox
 
512
        '''
 
513
        self.remember_account.set_active(False)
 
514
        self.remember_account.set_sensitive(True)
 
515
        self.remember_password.set_active(False)
 
516
        self.remember_password.set_sensitive(True)
 
517
        self.auto_login.set_active(False)
 
518
        self.forget_me.set_sensitive(False)
 
519
        self.btn_status.set_status(e3.status.ONLINE)
 
520
        self.txt_password.set_sensitive(True)
 
521
 
 
522
    def clear_all(self):
 
523
        '''
 
524
        call clear_all and clean also the account combobox
 
525
        '''
 
526
        self._clear_all()
 
527
        self.cmb_account.get_children()[0].set_text('')
 
528
 
 
529
    def show_error(self, reason):
 
530
        '''
 
531
        show an error on the top of the window using nicebar
 
532
        '''
 
533
        self.nicebar.new_message(reason, gtk.STOCK_DIALOG_ERROR)
 
534
 
 
535
    def _reload_account_list(self, *args):
 
536
        '''
 
537
        reload the account list in the combobox
 
538
        '''
 
539
        self.liststore.clear()
 
540
        for mail in sorted(self.accounts):
 
541
            self.liststore.append([mail, utils.scale_nicely(self.pixbuf)])
 
542
 
 
543
        #this resolves a small bug
 
544
        if not len(self.liststore):
 
545
            self.liststore = None
 
546
 
 
547
    def _on_password_key_press(self, widget, event):
 
548
        '''
 
549
        called when a key is pressed on the password field
 
550
        '''
 
551
        self.nicebar.empty_queue()
 
552
        if event.keyval == gtk.keysyms.Return or \
 
553
           event.keyval == gtk.keysyms.KP_Enter:
 
554
            self.do_connect()
 
555
 
 
556
    def _on_password_changed(self, widget):
 
557
        '''
 
558
        called when the password in the combobox changes
 
559
        '''
 
560
        state = (self.txt_password.get_text() != "")
 
561
 
 
562
        self.remember_password.set_sensitive(state)
 
563
        self.auto_login.set_sensitive(state)
 
564
        self.b_connect.set_sensitive(state)
 
565
 
 
566
    def _on_account_key_press(self, widget, event):
 
567
        '''
 
568
        called when a key is pressed on the password field
 
569
        '''
 
570
        self.nicebar.empty_queue()
 
571
        if event.keyval == gtk.keysyms.Return or \
 
572
           event.keyval == gtk.keysyms.KP_Enter:
 
573
            self.txt_password.grab_focus()
 
574
            if not self.txt_password.is_focus():
 
575
                self.do_connect()
 
576
 
 
577
    def _on_forget_me_clicked(self, *args):
 
578
        '''
 
579
        called when the forget me label is clicked
 
580
        '''
 
581
        def _yes_no_cb(response):
 
582
            '''callback from the confirmation dialog'''
 
583
            account = self.cmb_account.get_active_text()
 
584
            if response == stock.YES:
 
585
                try: # Delete user's folder
 
586
                    rmtree(self.config_dir.join(self.server_host, account))
 
587
                except:
 
588
                    self.show_error(_('Error while deleting user'))
 
589
 
 
590
                if account in self.accounts:
 
591
                    del self.accounts[account]
 
592
                if account in self.remembers:
 
593
                    del self.remembers[account]
 
594
                if account in self.status:
 
595
                    del self.status[account]
 
596
                if account == self.config.last_logged_account:
 
597
                    self.config.last_logged_account = ''
 
598
 
 
599
                self.config.save(self.config_path)
 
600
                self._reload_account_list()
 
601
                self.cmb_account.get_children()[0].set_text('')
 
602
 
 
603
        self.dialog.yes_no(
 
604
               _('Are you sure you want to delete the account %s ?') % \
 
605
                      self.cmb_account.get_active_text(), _yes_no_cb)
 
606
 
 
607
    def _on_connect_clicked(self, button):
 
608
        '''
 
609
        called when connect button is clicked
 
610
        '''
 
611
        self.avatar.stop()
 
612
        self.do_connect()
 
613
 
 
614
    def _on_quit(self):
 
615
        '''
 
616
        close emesene
 
617
        '''
 
618
        while gtk.events_pending():
 
619
            gtk.main_iteration(False)
 
620
 
 
621
        sys.exit(0)
 
622
 
 
623
    def _on_remember_account_toggled(self, button):
 
624
        '''
 
625
        called when the remember account check button is toggled
 
626
        '''
 
627
        if not self.remember_account.get_active():
 
628
            self.remember_password.set_active(False)
 
629
 
 
630
    def _on_remember_password_toggled(self, button):
 
631
        '''
 
632
        called when the remember password check button is toggled
 
633
        '''
 
634
        if self.remember_password.get_active():
 
635
            self.remember_account.set_active(True)
 
636
            self.remember_account.set_sensitive(False)
 
637
            self.txt_password.set_sensitive(False)
 
638
        else:
 
639
            self.remember_account.set_sensitive(True)
 
640
            self.txt_password.set_sensitive(True)
 
641
            self.txt_password.set_text('')
 
642
 
 
643
    def _on_auto_login_toggled(self, button):
 
644
        '''
 
645
        called when the auto-login check button is toggled
 
646
        '''
 
647
        if self.auto_login.get_active():
 
648
            self.remember_password.set_active(True)
 
649
            self.remember_account.set_sensitive(False)
 
650
            self.remember_password.set_sensitive(False)
 
651
        else:
 
652
            self.remember_password.set_sensitive(True)
 
653
 
 
654
    def _on_preferences_enter(self, button, event):
 
655
        '''
 
656
        called when the mouse enters the preferences button
 
657
        '''
 
658
        self.img_preferences.set_sensitive(True)
 
659
 
 
660
    def _on_preferences_leave(self, button, event):
 
661
        '''
 
662
        called when the mouse leaves the preferences button
 
663
        '''
 
664
        self.img_preferences.set_sensitive(False)
 
665
 
 
666
    def _on_preferences_selected(self, button):
 
667
        '''
 
668
        called when the user clicks the preference button
 
669
        '''
 
670
        service = self.config.get_or_set('service', 'msn')
 
671
 
 
672
        account = self.cmb_account.get_active_text()
 
673
 
 
674
        if account in self.accounts:
 
675
            service = self.config.d_user_service.get(account, 'msn')
 
676
 
 
677
        extension.get_default('dialog').login_preferences(service,
 
678
            self._on_new_preferences, self.use_http, self.proxy)
 
679
 
 
680
    def _on_new_preferences(self, use_http, use_proxy, proxy_host, proxy_port,
 
681
        use_auth, user, passwd, session_id, service, server_host, server_port):
 
682
        '''
 
683
        called when the user press accept on the preferences dialog
 
684
        '''
 
685
        self.proxy = e3.Proxy(use_proxy, proxy_host, proxy_port, use_auth, user, passwd)
 
686
        self.session_id = session_id
 
687
        self.use_http = use_http
 
688
        self.server_host = server_host
 
689
        self.server_port = server_port
 
690
 
 
691
        account = self.cmb_account.get_active_text()
 
692
 
 
693
        if account in self.accounts:
 
694
            self.config.d_user_service[account] = service
 
695
 
 
696
        self.on_preferences_changed(self.use_http, self.proxy, self.session_id,
 
697
                service)
 
698
        self._on_account_changed(None)
 
699
 
 
700
        def searchService(model, path, iter, user_data):
 
701
                if(model.get(iter,0)[0]==user_data[0]):
 
702
                        user_data[2].set_active(user_data[1])
 
703
                        return True
 
704
                user_data[1]+=1
 
705
                return False
 
706
 
 
707
        i=0
 
708
        
 
709
        for combo in self.__combo_session_list:
 
710
                combo.get_model().foreach(searchService,[service,i,combo])
 
711
 
 
712
class ConnectingWindow(Login):
 
713
    '''
 
714
    widget that represents the GUI interface showed when connecting
 
715
    '''
 
716
    def __init__(self, callback, avatar_path, config):
 
717
        LoginBase.__init__(self, callback)
 
718
 
 
719
        self.callback = callback
 
720
        self.avatar.set_from_file(avatar_path)
 
721
 
 
722
        #for reconnecting
 
723
        self.reconnect_timer_id = None
 
724
 
 
725
        account = config.get_or_set('last_logged_account', '')
 
726
        remembers = config.get_or_set('d_remembers', {})
 
727
 
 
728
        if not (account == ''):
 
729
            attr = int(remembers[account])
 
730
            if attr == 3:#autologin,password,account checked
 
731
                self.auto_login.set_active(True)
 
732
            elif attr == 2:#password,account checked
 
733
                self.remember_password.set_active(True)
 
734
            elif attr == 1:#only account checked
 
735
                self.remember_account.set_active(True)
 
736
 
 
737
            password = base64.b64decode(config.d_accounts.get(account, ""))
 
738
            self.cmb_account.get_children()[0].set_text(account)
 
739
            self.txt_password.set_text(password)
 
740
 
 
741
        #FIXME: If not account remembered, txt_password & cmb_account, left without text.
 
742
        self.cmb_account.set_sensitive(False)
 
743
        self.b_preferences.set_sensitive(False)
 
744
        self.btn_status.set_sensitive(False)
 
745
        self.txt_password.set_sensitive(False)
 
746
        self.nicebar.hide()
 
747
        self.throbber.show()
 
748
        self.label_timer.hide()
 
749
 
 
750
        self.b_connect.set_label(_("Connect now"))
 
751
        self.b_connect.set_sensitive(True)
 
752
        self.b_connect.hide()
 
753
 
 
754
    def _update_fields(self, *args):
 
755
        ''' override the login method with "do nothing" '''
 
756
        return
 
757
 
 
758
    def _on_password_changed(self, widget):
 
759
        ''' overload the login one '''
 
760
        state = 0
 
761
 
 
762
        self.remember_account.set_sensitive(state)
 
763
        self.remember_password.set_sensitive(state)
 
764
        self.auto_login.set_sensitive(state)
 
765
 
 
766
    def _on_cancel_clicked(self, button):
 
767
        '''
 
768
        cause the return to login window
 
769
        '''
 
770
        self.cancel_clicked=True
 
771
        self.avatar.stop()
 
772
        if self.reconnect_timer_id is not None:
 
773
            gobject.source_remove(self.reconnect_timer_id)
 
774
        self.reconnect_timer_id = None
 
775
        self.callback()
 
776
 
 
777
    def _on_connect_now_clicked(self, button, callback, account, session_id,
 
778
                            proxy, use_http, service):
 
779
        '''
 
780
        don't wait for timout to reconnect
 
781
        '''
 
782
        button.hide()
 
783
        self.avatar.stop()
 
784
        gobject.source_remove(self.reconnect_timer_id)
 
785
        self.reconnect_timer_id = None
 
786
        callback(account, session_id, proxy, use_http,\
 
787
                 service[0], service[1], on_reconnect=True)
 
788
 
 
789
    def clear_connect(self):
 
790
        '''
 
791
        clean the connect interface after the reconnect phase
 
792
        '''
 
793
        self.label_timer.hide()
 
794
        self.throbber.show()
 
795
 
 
796
    def on_reconnect(self, callback, account, session_id,
 
797
                     proxy, use_http, service):
 
798
        '''
 
799
        show the reconnect countdown
 
800
        '''
 
801
        self.label_timer.show()
 
802
        self.b_connect.show()
 
803
        self.b_connect.connect('clicked', self._on_connect_now_clicked, callback, \
 
804
                               account, session_id, proxy, use_http, service)
 
805
        self.throbber.hide()
 
806
        self.reconnect_after = 30
 
807
        if self.reconnect_timer_id is None:
 
808
            self.reconnect_timer_id = gobject.timeout_add_seconds(1, \
 
809
                self.update_reconnect_timer, callback, account, session_id,
 
810
                                    proxy, use_http, service)
 
811
 
 
812
        self.update_reconnect_timer(callback, account, session_id,
 
813
                                    proxy, use_http, service)
 
814
 
 
815
    def update_reconnect_timer(self, callback, account, session_id,
 
816
                               proxy, use_http, service):
 
817
        '''
 
818
        updates reconnect label and launches login if counter is 0
 
819
        '''
 
820
        self.reconnect_after -= 1
 
821
        self.label_timer.set_text(_('Reconnecting in %d seconds')\
 
822
                                             % self.reconnect_after )
 
823
        if self.reconnect_after <= 0:
 
824
            gobject.source_remove(self.reconnect_timer_id)
 
825
            self.reconnect_timer_id = None
 
826
            self.b_connect.hide()
 
827
            #do login
 
828
            callback(account, session_id, proxy, use_http,\
 
829
                     service[0], service[1], on_reconnect=True)
 
830
            return False
 
831
        else:
 
832
            return True
 
833