root/branches/gajim_0.7.1/src/dialogs.py

Revision 1827, 26.5 kB (checked in by asterix, 4 years ago)

typo

Line 
1##      dialogs.py
2##
3## Gajim Team:
4##      - Yann Le Boulanger <asterix@lagaule.org>
5##      - Vincent Hanquez <tab@snarc.org>
6##      - Nikos Kouremenos <kourem@gmail.com>
7##
8##      Copyright (C) 2003-2005 Gajim Team
9##
10## This program is free software; you can redistribute it and/or modify
11## it under the terms of the GNU General Public License as published
12## by the Free Software Foundation; version 2 only.
13##
14## This program is distributed in the hope that it will be useful,
15## but WITHOUT ANY WARRANTY; without even the implied warranty of
16## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17## GNU General Public License for more details.
18##
19
20import gtk
21import gtk.glade
22import gobject
23import os
24
25from vcard import Vcard_window
26from advanced import Advanced_configuration_window
27from gajim import User
28from common import gajim
29from common import helpers
30from common import i18n
31
32_ = i18n._
33APP = i18n.APP
34gtk.glade.bindtextdomain (APP, i18n.DIR)
35gtk.glade.textdomain (APP)
36
37GTKGUI_GLADE = 'gtkgui.glade'
38
39class Edit_groups_dialog:
40        '''Class for the edit group dialog window'''
41        def __init__(self, user, account, plugin):
42                self.xml = gtk.glade.XML(GTKGUI_GLADE, 'edit_groups_dialog', APP)
43                self.dialog = self.xml.get_widget('edit_groups_dialog')
44                self.plugin = plugin
45                self.account = account
46                self.user = user
47                self.changes_made = False
48                self.list = self.xml.get_widget('groups_treeview')
49                self.xml.get_widget('nickname_label').set_markup(
50                        _("Contact's name: <i>%s</i>") % user.name)
51                self.xml.get_widget('jid_label').set_markup(
52                        _('JID: <i>%s</i>') % user.jid)
53                self.xml.signal_autoconnect(self)
54                self.dialog.show_all()
55                self.init_list()
56
57        def run(self):
58                self.dialog.run()
59                self.dialog.destroy()
60                if self.changes_made:
61                        gajim.connections[self.account].update_user(self.user.jid,
62                                self.user.name, self.user.groups)
63
64        def update_user(self):
65                self.plugin.roster.remove_user(self.user, self.account)
66                self.plugin.roster.add_user_to_roster(self.user.jid, self.account)
67
68        def on_add_button_clicked(self, widget):
69                group = self.xml.get_widget('group_entry').get_text()
70                if not group:
71                        return
72                # check if it already exists
73                model = self.list.get_model()
74                iter = model.get_iter_root()
75                while iter:
76                        if model.get_value(iter, 0) == group:
77                                return
78                        iter = model.iter_next(iter)
79                self.changes_made = True
80                model.append((group, True))
81                self.user.groups.append(group)
82                self.update_user()
83
84        def group_toggled_cb(self, cell, path):
85                self.changes_made = True
86                model = self.list.get_model()
87                if model[path][1] and len(self.user.groups) == 1: # we try to remove
88                                                                                                                                                  # the last group
89                        Error_dialog(_('A contact must belong at least to one group'))
90                        return
91                model[path][1] = not model[path][1]
92                if model[path][1]:
93                        self.user.groups.append(model[path][0])
94                else:
95                        self.user.groups.remove(model[path][0])
96                self.update_user()
97
98        def init_list(self):
99                store = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_BOOLEAN)
100                self.list.set_model(store)
101                for g in self.plugin.roster.groups[self.account].keys():
102                        if g in ['Transports', 'not in the roster']:
103                                continue
104                        iter = store.append()
105                        store.set(iter, 0, g)
106                        if g in self.user.groups:
107                                store.set(iter, 1, True)
108                        else:
109                                store.set(iter, 1, False)
110                column = gtk.TreeViewColumn(_('Group'))
111                self.list.append_column(column)
112                renderer = gtk.CellRendererText()
113                column.pack_start(renderer)
114                column.set_attributes(renderer, text = 0)
115               
116                column = gtk.TreeViewColumn(_('In the group'))
117                self.list.append_column(column)
118                renderer = gtk.CellRendererToggle()
119                column.pack_start(renderer)
120                renderer.set_property('activatable', True)
121                renderer.connect('toggled', self.group_toggled_cb)
122                column.set_attributes(renderer, active = 1)
123
124class Passphrase_dialog:
125        '''Class for Passphrase dialog'''
126        def run(self):
127                '''Wait for OK button to be pressed and return passphrase/password'''
128                rep = self.window.run()
129                if rep == gtk.RESPONSE_OK:
130                        passphrase = self.passphrase_entry.get_text()
131                else:
132                        passphrase = -1
133                save_passphrase_checkbutton = self.xml.\
134                        get_widget('save_passphrase_checkbutton')
135                self.window.destroy()
136                return passphrase, save_passphrase_checkbutton.get_active()
137
138        def __init__(self, titletext, labeltext, checkbuttontext):
139                self.xml = gtk.glade.XML(GTKGUI_GLADE, 'passphrase_dialog', APP)
140                self.window = self.xml.get_widget('passphrase_dialog')
141                self.passphrase_entry = self.xml.get_widget('passphrase_entry')
142                self.passphrase = -1
143                self.window.set_title(titletext)
144                self.xml.get_widget('message_label').set_text(labeltext)
145                self.xml.get_widget('save_passphrase_checkbutton').set_label(checkbuttontext)
146                self.xml.signal_autoconnect(self)
147                self.window.show_all()
148
149class choose_gpg_key_dialog:
150        '''Class for GPG key dialog'''
151        def run(self):
152                '''Wait for Ok button to be pressed and return the selected key'''
153                rep = self.window.run()
154                if rep == gtk.RESPONSE_OK:
155                        selection = self.keys_treeview.get_selection()
156                        (model, iter) = selection.get_selected()
157                        keyID = [model.get_value(iter, 0), model.get_value(iter, 1)]
158                else:
159                        keyID = -1
160                self.window.destroy()
161                return keyID
162
163        def fill_tree(self, list, selected):
164                model = self.keys_treeview.get_model()
165                for keyID in list.keys():
166                        iter = model.append((keyID, list[keyID]))
167                        if keyID == selected:
168                                path = model.get_path(iter)
169                                self.keys_treeview.set_cursor(path)
170       
171        def __init__(self, secret_keys, selected = None):
172                #list : {keyID: userName, ...}
173                xml = gtk.glade.XML(GTKGUI_GLADE, 'choose_gpg_key_dialog', APP)
174                self.window = xml.get_widget('choose_gpg_key_dialog')
175                self.keys_treeview = xml.get_widget('keys_treeview')
176                model = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
177                self.keys_treeview.set_model(model)
178                #columns
179                renderer = gtk.CellRendererText()
180                self.keys_treeview.insert_column_with_attributes(-1, _('KeyID'),
181                        renderer, text = 0)
182                renderer = gtk.CellRendererText()
183                self.keys_treeview.insert_column_with_attributes(-1, _('User name'),
184                        renderer, text = 1)
185                self.fill_tree(secret_keys, selected)
186
187                self.window.show_all()
188
189class Change_status_message_dialog:
190        def __init__(self, plugin, show):
191                self.xml = gtk.glade.XML(GTKGUI_GLADE, 'change_status_message_dialog', APP)
192                self.window = self.xml.get_widget('change_status_message_dialog')
193                uf_show = helpers.get_uf_show(show)
194                self.window.set_title(_('%s Status Message') % uf_show)
195               
196                message_textview = self.xml.get_widget('message_textview')
197                self.message_buffer = message_textview.get_buffer()
198                self.message_buffer.set_text(gajim.config.get('last_status_msg'))
199                self.values = {'':''}
200                for msg in gajim.config.get_per('statusmsg'):
201                        self.values[msg] = gajim.config.get_per('statusmsg', msg, 'message')
202                liststore = gtk.ListStore(str, str)
203                message_comboboxentry = self.xml.get_widget('message_comboboxentry')
204                message_comboboxentry.set_model(liststore)
205                message_comboboxentry.set_text_column(0)
206                for val in self.values.keys():
207                        message_comboboxentry.append_text(val)
208                self.xml.signal_autoconnect(self)
209                self.window.show_all()
210
211        def run(self):
212                '''Wait for OK button to be pressed and return status messsage'''
213                rep = self.window.run()
214                if rep == gtk.RESPONSE_OK:
215                        beg, end = self.message_buffer.get_bounds()
216                        message = self.message_buffer.get_text(beg, end, 0).strip()
217                        #FIXME: support more than one line
218                        gajim.config.set('last_status_msg', message)
219                else:
220                        message = -1
221                self.window.destroy()
222                return message
223
224        def on_message_comboboxentry_changed(self, widget, data = None):
225                model = widget.get_model()
226                active = widget.get_active()
227                if active < 0:
228                        return None
229                name = model[active][0]
230                self.message_buffer.set_text(self.values[name])
231       
232        def on_change_status_message_dialog_key_press_event(self, widget, event):
233                if event.keyval == gtk.keysyms.Return or \
234                event.keyval == gtk.keysyms.KP_Enter:  # catch CTRL+ENTER
235                        if (event.state & gtk.gdk.CONTROL_MASK):
236                                self.window.response(gtk.RESPONSE_OK)
237
238class Add_new_contact_window:
239        '''Class for Add_new_contact_window'''
240        def __init__(self, plugin, account, jid = None):
241                if gajim.connections[account].connected < 2:
242                        Error_dialog(_('You must be connected to add a contact'))
243                        return
244                self.plugin = plugin
245                self.account = account
246                self.xml = gtk.glade.XML(GTKGUI_GLADE, 'add_new_contact_window', APP)
247                self.window = self.xml.get_widget('add_new_contact_window')
248                self.uid_entry = self.xml.get_widget('uid_entry')
249                self.protocol_combobox = self.xml.get_widget('protocol_combobox')
250                self.jid_entry = self.xml.get_widget('jid_entry')
251                self.nickname_entry = self.xml.get_widget('nickname_entry')
252                self.old_uid_value = ''
253                liststore = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
254                liststore.append(['Jabber', ''])
255                self.agents = ['Jabber']
256                jid_agents = []
257                for j in self.plugin.roster.contacts[account]:
258                        user = self.plugin.roster.contacts[account][j][0]
259                        if 'Transports' in user.groups and user.show != 'offline' and \
260                                        user.show != 'error':
261                                jid_agents.append(j)
262                for a in jid_agents:
263                        if a.find('aim') > -1:
264                                name = 'AIM'
265                        elif a.find('icq') > -1:
266                                name = 'ICQ'
267                        elif a.find('msn') > -1:
268                                name = 'MSN'
269                        elif a.find('yahoo') > -1:
270                                name = 'Yahoo!'
271                        else:
272                                name = a
273                        iter = liststore.append([name, a])
274                        self.agents.append(name)
275               
276                self.protocol_combobox.set_model(liststore)
277                self.protocol_combobox.set_active(0)
278                self.fill_jid()
279                if jid:
280                        self.jid_entry.set_text(jid)
281                        jid_splited = jid.split('@')
282                        if jid_splited[1] in jid_agents:
283                                uid = jid_splited[0].replace('%', '@')
284                                self.uid_entry.set_text(uid)
285                                self.protocol_combobox.set_active(jid_agents.index(jid_splited[1]) + 1)
286                        else:
287                                self.uid_entry.set_text(jid)
288                                self.protocol_combobox.set_active(0)
289                        self.set_nickname()
290
291                self.group_comboboxentry = self.xml.get_widget('group_comboboxentry')
292                liststore = gtk.ListStore(str)
293                self.group_comboboxentry.set_model(liststore)
294                for g in self.plugin.roster.groups[account].keys():
295                        if g != 'not in the roster' and g != 'Transports':
296                                self.group_comboboxentry.append_text(g)
297
298                self.xml.signal_autoconnect(self)
299                self.window.show_all()
300
301        def on_add_new_contact_window_key_press_event(self, widget, event):
302                if event.keyval == gtk.keysyms.Escape: # ESCAPE
303                        self.window.destroy()
304
305        def on_cancel_button_clicked(self, widget):
306                '''When Cancel button is clicked'''
307                self.window.destroy()
308
309        def on_subscribe_button_clicked(self, widget):
310                '''When Subscribe button is clicked'''
311                jid = self.jid_entry.get_text()
312                nickname = self.nickname_entry.get_text()
313                if not jid:
314                        return
315                if jid.find('@') < 0:
316                        Error_dialog(_("The contact's name must be something like login@hostname"))
317                        return
318                message_buffer = self.xml.get_widget('message_textview').get_buffer()
319                start_iter = message_buffer.get_start_iter()
320                end_iter = message_buffer.get_end_iter()
321                message = message_buffer.get_text(start_iter, end_iter, 0)
322                group = self.group_comboboxentry.child.get_text()
323                self.plugin.roster.req_sub(self, jid, message, self.account, group,
324                        nickname)
325                if self.xml.get_widget('auto_authorize_checkbutton').get_active():
326                        gajim.connections[self.account].send_authorization(jid)
327                self.window.destroy()
328               
329        def fill_jid(self):
330                model = self.protocol_combobox.get_model()
331                index = self.protocol_combobox.get_active()
332                jid = self.uid_entry.get_text().strip()
333                if index > 0: # it's not jabber but a transport
334                        jid = jid.replace('@', '%')
335                agent = model[index][1]
336                if agent:
337                        jid += '@' + agent
338                self.jid_entry.set_text(jid)
339
340        def on_protocol_combobox_changed(self, widget):
341                self.fill_jid()
342
343        def guess_agent(self):
344                uid = self.uid_entry.get_text()
345                model = self.protocol_combobox.get_model()
346               
347                #If login contains only numbers, it's probably an ICQ number
348                if uid.isdigit():
349                        if 'ICQ' in self.agents:
350                                self.protocol_combobox.set_active(self.agents.index('ICQ'))
351                                return
352
353        def set_nickname(self):
354                uid = self.uid_entry.get_text()
355                nickname = self.nickname_entry.get_text()
356                if nickname == self.old_uid_value:
357                        self.nickname_entry.set_text(uid.split('@')[0])
358                       
359        def on_uid_entry_changed(self, widget):
360                uid = self.uid_entry.get_text()
361                self.guess_agent()
362                self.set_nickname()
363                self.fill_jid()
364                self.old_uid_value = uid.split('@')[0]
365
366class About_dialog:
367        '''Class for about dialog'''
368        def __init__(self):
369                if gtk.pygtk_version < (2, 6, 0) or gtk.gtk_version < (2, 6, 0):
370                        #FIXME: when 0.7.1 is out fix this [add version in _]
371                        Information_dialog(_('Gajim - a GTK+ Jabber client') + '\nVersion %s' \
372                        % gajim.version)
373                        return
374
375                dlg = gtk.AboutDialog()
376                dlg.set_name('Gajim')
377                dlg.set_version(gajim.version)
378                s = u'Copyright \xa9 2003-2005 Gajim Team'
379                dlg.set_copyright(s)
380                text = open('../COPYING').read()
381                dlg.set_license(text)
382
383                dlg.set_comments(_('A GTK jabber client'))
384                dlg.set_website('http://www.gajim.org')
385
386                authors = ['Yann Le Boulanger <asterix@lagaule.org>', 'Vincent Hanquez <tab@snarc.org>', 'Nikos Kouremenos <kourem@gmail.com>', 'Alex Podaras <bigpod@gmail.com>']
387                dlg.set_authors(authors)
388
389                pixbuf = gtk.gdk.pixbuf_new_from_file(os.path.join(gajim.DATA_DIR, 'pixmaps/gajim.png'))                       
390
391                dlg.set_logo(pixbuf)
392                dlg.set_translator_credits(_('translator_credits'))
393
394                rep = dlg.run()
395                dlg.destroy()
396
397class Confirmation_dialog:
398        '''Class for confirmation dialog'''
399        def get_response(self):
400                response = self.dialog.run()
401                self.dialog.destroy()
402                return response
403
404        def __init__(self, label):
405                self.dialog = gtk.MessageDialog(None,
406                        gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
407                        gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO, label)
408
409class Warning_dialog:
410        '''Class for warning dialog'''
411        def on_response(self, dialog, response_id):
412                dialog.destroy()
413
414        def __init__(self, label):
415                dialog = gtk.MessageDialog(None,
416                        gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
417                        gtk.MESSAGE_WARNING, gtk.BUTTONS_CLOSE, label)
418                dialog.connect('response', self.on_response)
419                dialog.show()
420
421class Information_dialog:
422        '''Class for information dialog'''
423        def on_response(self, dialog, response_id):
424                dialog.destroy()
425
426        def __init__(self, label):
427                dialog = gtk.MessageDialog(None,
428                        gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
429                        gtk.MESSAGE_INFO, gtk.BUTTONS_CLOSE, label)
430                dialog.connect('response', self.on_response)
431                dialog.show()
432
433class Input_dialog:
434        '''Class for Input dialog'''
435        def __init__(self, title, label_str, input_str = None):
436                xml = gtk.glade.XML(GTKGUI_GLADE, 'input_dialog', APP)
437                self.dialog = xml.get_widget('input_dialog')
438                label = xml.get_widget('label')
439                self.input_entry = xml.get_widget('input_entry')
440                self.dialog.set_title(title)
441                label.set_text(label_str)
442                if input_str:
443                        self.input_entry.set_text(input_str)
444                        self.input_entry.select_region(0, -1) # select all     
445       
446class Error_dialog:
447        '''Class for error dialog'''
448        def on_response(self, dialog, response_id):
449                dialog.destroy()
450
451        def __init__(self, label):
452                dialog = gtk.MessageDialog(None,
453                        gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
454                        gtk.MESSAGE_ERROR, gtk.BUTTONS_CLOSE, label)
455                dialog.connect('response', self.on_response)
456                dialog.show()
457
458class Subscription_request_window:
459        def __init__(self, plugin, jid, text, account):
460                xml = gtk.glade.XML(GTKGUI_GLADE, 'subscription_request_window', APP)
461                self.window = xml.get_widget('subscription_request_window')
462                self.plugin = plugin
463                self.jid = jid
464                self.account = account
465                xml.get_widget('from_label').set_text(
466                        _('Subscription request from %s') % self.jid)
467                xml.get_widget('message_textview').get_buffer().set_text(text)
468                xml.signal_autoconnect(self)
469                self.window.show_all()
470
471        def on_close_button_clicked(self, widget):
472                self.window.destroy()
473               
474        def on_authorize_button_clicked(self, widget):
475                '''accept the request'''
476                gajim.connections[self.account].send_authorization(self.jid)
477                self.window.destroy()
478                if not self.plugin.roster.contacts[self.account].has_key(self.jid):
479                        Add_new_contact_window(self.plugin, self.account, self.jid)
480
481        def on_contact_info_button_clicked(self, widget):
482                '''ask vcard'''
483                if self.plugin.windows[self.account]['infos'].has_key(self.jid):
484                        self.plugin.windows[self.account]['infos'][self.jid].window.present()
485                else:
486                        self.plugin.windows[self.account]['infos'][self.jid] = \
487                                Vcard_window(self.jid, self.plugin, self.account, True)
488                        #remove the publish / retrieve buttons
489                        vcard_xml = self.plugin.windows[self.account]['infos'][self.jid].xml
490                        hbuttonbox = vcard_xml.get_widget('information_hbuttonbox')
491                        children = hbuttonbox.get_children()
492                        hbuttonbox.remove(children[0])
493                        hbuttonbox.remove(children[1])
494                        vcard_xml.get_widget('nickname_label').set_text(self.jid)
495                        gajim.connections[self.account].request_vcard(self.jid)
496       
497        def on_deny_button_clicked(self, widget):
498                '''refuse the request'''
499                gajim.connections[self.account].refuse_authorization(self.jid)
500                self.window.destroy()
501
502class Join_groupchat_window:
503        def __init__(self, plugin, account, server = '', room = ''):
504                self.plugin = plugin
505                self.account = account
506                if gajim.connections[account].connected < 2:
507                        Error_dialog(_('You must be connected to join a groupchat'))
508                        raise RuntimeError, 'You must be connected to join a groupchat'
509
510                self.xml = gtk.glade.XML(GTKGUI_GLADE, 'join_groupchat_window', APP)
511                self.window = self.xml.get_widget('join_groupchat_window')
512                self.xml.get_widget('server_entry').set_text(server)
513                self.xml.get_widget('room_entry').set_text(room)
514                self.xml.get_widget('nickname_entry').set_text(
515                                                self.plugin.nicks[self.account])
516                self.xml.signal_autoconnect(self)
517                self.plugin.windows[account]['join_gc'] = self #now add us to open windows
518                our_jid = gajim.config.get_per('accounts', self.account, 'name') + '@' + \
519                        gajim.config.get_per('accounts', self.account, 'hostname')
520                if len(gajim.connections) > 1:
521                        title = _('Join Groupchat as ') + our_jid
522                else:
523                        title = _('Join Groupchat')
524                self.window.set_title(title)
525
526                self.recently_combobox = self.xml.get_widget('recently_combobox')
527                liststore = gtk.ListStore(str)
528                self.recently_combobox.set_model(liststore)
529                cell = gtk.CellRendererText()
530                self.recently_combobox.pack_start(cell, True)
531                self.recently_combobox.add_attribute(cell, 'text', 0)
532                self.recently_groupchat = gajim.config.get('recently_groupchat').split()
533                for g in self.recently_groupchat:
534                        self.recently_combobox.append_text(g)
535
536                self.window.show_all()
537
538        def on_join_groupchat_window_destroy(self, widget):
539                '''close window'''
540                del self.plugin.windows[self.account]['join_gc'] # remove us from open windows
541
542        def on_join_groupchat_window_key_press_event(self, widget, event):
543                if event.keyval == gtk.keysyms.Escape: # ESCAPE
544                        widget.destroy()
545
546        def on_recently_combobox_changed(self, widget):
547                model = widget.get_model()
548                iter = widget.get_active_iter()
549                gid = model.get_value(iter, 0)
550                self.xml.get_widget('room_entry').set_text(gid.split('@')[0])
551                self.xml.get_widget('server_entry').set_text(gid.split('@'