dialogs.py 226 KB
Newer Older
1
# -*- coding: utf-8 -*-
roidelapluie's avatar
roidelapluie committed
2
## src/dialogs.py
Yann Leboulanger's avatar
Yann Leboulanger committed
3
##
roidelapluie's avatar
roidelapluie committed
4
## Copyright (C) 2003-2005 Vincent Hanquez <tab AT snarc.org>
Yann Leboulanger's avatar
Yann Leboulanger committed
5
## Copyright (C) 2003-2010 Yann Leboulanger <asterix AT lagaule.org>
roidelapluie's avatar
roidelapluie committed
6 7 8 9 10 11 12 13 14 15
## Copyright (C) 2005 Alex Mauer <hawke AT hawkesnest.net>
## Copyright (C) 2005-2006 Dimitur Kirov <dkirov AT gmail.com>
##                         Travis Shirk <travis AT pobox.com>
## Copyright (C) 2005-2008 Nikos Kouremenos <kourem AT gmail.com>
## Copyright (C) 2006-2008 Jean-Marie Traissard <jim AT lapin.org>
## Copyright (C) 2007 Lukas Petrovicky <lukas AT petrovicky.net>
## Copyright (C) 2007-2008 Brendan Taylor <whateley AT gmail.com>
##                         Julien Pivotto <roidelapluie AT gmail.com>
##                         Stephan Erb <steve-e AT h3c.de>
## Copyright (C) 2008 Jonathan Schleifer <js-gajim AT webkeks.org>
Yann Leboulanger's avatar
Yann Leboulanger committed
16
##
Yann Leboulanger's avatar
Yann Leboulanger committed
17 18 19
## This file is part of Gajim.
##
## Gajim is free software; you can redistribute it and/or modify
Yann Leboulanger's avatar
Yann Leboulanger committed
20
## it under the terms of the GNU General Public License as published
Yann Leboulanger's avatar
Yann Leboulanger committed
21
## by the Free Software Foundation; version 3 only.
Yann Leboulanger's avatar
Yann Leboulanger committed
22
##
Yann Leboulanger's avatar
Yann Leboulanger committed
23
## Gajim is distributed in the hope that it will be useful,
Yann Leboulanger's avatar
Yann Leboulanger committed
24
## but WITHOUT ANY WARRANTY; without even the implied warranty of
roidelapluie's avatar
roidelapluie committed
25
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Yann Leboulanger's avatar
Yann Leboulanger committed
26 27
## GNU General Public License for more details.
##
Yann Leboulanger's avatar
Yann Leboulanger committed
28
## You should have received a copy of the GNU General Public License
roidelapluie's avatar
roidelapluie committed
29
## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
Yann Leboulanger's avatar
Yann Leboulanger committed
30
##
Yann Leboulanger's avatar
Yann Leboulanger committed
31 32

import gtk
33
import gobject
Yann Leboulanger's avatar
Yann Leboulanger committed
34
import os
35

nkour's avatar
nkour committed
36
import gtkgui_helpers
nkour's avatar
nkour committed
37
import vcard
38
import conversation_textview
39
import message_control
Yann Leboulanger's avatar
Yann Leboulanger committed
40 41 42
import dataforms_widget

from random import randrange
js's avatar
js committed
43
from common import pep
44
from common import ged
45

46
try:
47 48
    import gtkspell
    HAS_GTK_SPELL = True
49
except ImportError:
50
    HAS_GTK_SPELL = False
51

nkour's avatar
nkour committed
52
# those imports are not used in this file, but in files that 'import dialogs'
53
# so they can do dialog.GajimThemesWindow() for example
54
from filetransfers_window import FileTransfersWindow
55
from gajim_themes_window import GajimThemesWindow
56
from advanced_configuration_window import AdvancedConfigurationWindow
57

58
from common import gajim
59
from common import helpers
Yann Leboulanger's avatar
Yann Leboulanger committed
60
from common import dataforms
61
from common.exceptions import GajimGeneralException
Yann Leboulanger's avatar
Yann Leboulanger committed
62

63
class EditGroupsDialog:
64 65 66 67 68 69 70 71
    """
    Class for the edit group dialog window
    """

    def __init__(self, list_):
        """
        list_ is a list of (contact, account) tuples
        """
72 73
        self.xml = gtkgui_helpers.get_gtk_builder('edit_groups_dialog.ui')
        self.dialog = self.xml.get_object('edit_groups_dialog')
74 75 76
        self.dialog.set_transient_for(gajim.interface.roster.window)
        self.list_ = list_
        self.changes_made = False
77
        self.treeview = self.xml.get_object('groups_treeview')
78 79
        if len(list_) == 1:
            contact = list_[0][0]
80
            self.xml.get_object('nickname_label').set_markup(
81
                    _('Contact name: <i>%s</i>') % contact.get_shown_name())
82
            self.xml.get_object('jid_label').set_markup(
83 84
                    _('Jabber ID: <i>%s</i>') % contact.jid)
        else:
85 86 87 88
            self.xml.get_object('nickname_label').set_no_show_all(True)
            self.xml.get_object('nickname_label').hide()
            self.xml.get_object('jid_label').set_no_show_all(True)
            self.xml.get_object('jid_label').hide()
89

90
        self.xml.connect_signals(self)
91 92 93 94 95
        self.init_list()

        self.dialog.show_all()
        if self.changes_made:
            for (contact, account) in self.list_:
Dicson's avatar
Dicson committed
96 97
                gajim.connections[account].update_contact(contact.jid,
                    contact.name, contact.groups)
98 99 100 101 102 103 104 105 106 107

    def on_edit_groups_dialog_response(self, widget, response_id):
        if response_id == gtk.RESPONSE_CLOSE:
            self.dialog.destroy()

    def remove_group(self, group):
        """
        Remove group group from all contacts and all their brothers
        """
        for (contact, account) in self.list_:
Dicson's avatar
Dicson committed
108 109
            gajim.interface.roster.remove_contact_from_groups(contact.jid,
                account, [group])
110 111 112 113 114 115 116 117 118

        # FIXME: Ugly workaround.
        gajim.interface.roster.draw_group(_('General'), account)

    def add_group(self, group):
        """
        Add group group to all contacts and all their brothers
        """
        for (contact, account) in self.list_:
Dicson's avatar
Dicson committed
119 120
            gajim.interface.roster.add_contact_to_groups(contact.jid, account,
                [group])
121

Dicson's avatar
Dicson committed
122 123
        # FIXME: Ugly workaround.
        # Maybe we haven't been in any group (defaults to General)
124 125 126
        gajim.interface.roster.draw_group(_('General'), account)

    def on_add_button_clicked(self, widget):
127
        group = self.xml.get_object('group_entry').get_text().decode('utf-8')
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211
        if not group:
            return
        # Do not allow special groups
        if group in helpers.special_groups:
            return
        # check if it already exists
        model = self.treeview.get_model()
        iter_ = model.get_iter_root()
        while iter_:
            if model.get_value(iter_, 0).decode('utf-8') == group:
                return
            iter_ = model.iter_next(iter_)
        self.changes_made = True
        model.append((group, True, False))
        self.add_group(group)
        self.init_list() # Re-draw list to sort new item

    def group_toggled_cb(self, cell, path):
        self.changes_made = True
        model = self.treeview.get_model()
        if model[path][2]:
            model[path][2] = False
            model[path][1] = True
        else:
            model[path][1] = not model[path][1]
        group = model[path][0].decode('utf-8')
        if model[path][1]:
            self.add_group(group)
        else:
            self.remove_group(group)

    def init_list(self):
        store = gtk.ListStore(str, bool, bool)
        self.treeview.set_model(store)
        for column in self.treeview.get_columns():
            # Clear treeview when re-drawing
            self.treeview.remove_column(column)
        accounts = []
        # Store groups in a list so we can sort them and the number of contacts in
        # it
        groups = {}
        for (contact, account) in self.list_:
            if account not in accounts:
                accounts.append(account)
                for g in gajim.groups[account].keys():
                    if g in groups:
                        continue
                    groups[g] = 0
            c_groups = contact.groups
            for g in c_groups:
                groups[g] += 1
        group_list = []
        # Remove special groups if they are empty
        for group in groups:
            if group not in helpers.special_groups or groups[group] > 0:
                group_list.append(group)
        group_list.sort()
        for group in group_list:
            iter_ = store.append()
            store.set(iter_, 0, group) # Group name
            if groups[group] == 0:
                store.set(iter_, 1, False)
            else:
                store.set(iter_, 1, True)
                if groups[group] == len(self.list_):
                    # all contacts are in this group
                    store.set(iter_, 2, False)
                else:
                    store.set(iter_, 2, True)
        column = gtk.TreeViewColumn(_('Group'))
        column.set_expand(True)
        self.treeview.append_column(column)
        renderer = gtk.CellRendererText()
        column.pack_start(renderer)
        column.set_attributes(renderer, text=0)

        column = gtk.TreeViewColumn(_('In the group'))
        column.set_expand(False)
        self.treeview.append_column(column)
        renderer = gtk.CellRendererToggle()
        column.pack_start(renderer)
        renderer.set_property('activatable', True)
        renderer.connect('toggled', self.group_toggled_cb)
        column.set_attributes(renderer, active=1, inconsistent=2)
212

213
class PassphraseDialog:
214 215 216 217 218
    """
    Class for Passphrase dialog
    """
    def __init__(self, titletext, labeltext, checkbuttontext=None,
    ok_handler=None, cancel_handler=None):
219 220 221
        self.xml = gtkgui_helpers.get_gtk_builder('passphrase_dialog.ui')
        self.window = self.xml.get_object('passphrase_dialog')
        self.passphrase_entry = self.xml.get_object('passphrase_entry')
222 223
        self.passphrase = -1
        self.window.set_title(titletext)
224
        self.xml.get_object('message_label').set_text(labeltext)
225 226 227 228 229

        self.ok = False

        self.cancel_handler = cancel_handler
        self.ok_handler = ok_handler
230
        okbutton = self.xml.get_object('ok_button')
231
        okbutton.connect('clicked', self.on_okbutton_clicked)
232
        cancelbutton = self.xml.get_object('cancel_button')
233 234
        cancelbutton.connect('clicked', self.on_cancelbutton_clicked)

235
        self.xml.connect_signals(self)
236 237 238 239
        self.window.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
        self.window.show_all()

        self.check = bool(checkbuttontext)
240
        checkbutton =   self.xml.get_object('save_passphrase_checkbutton')
241 242 243 244 245 246 247 248 249 250 251 252
        if self.check:
            checkbutton.set_label(checkbuttontext)
        else:
            checkbutton.hide()

    def on_okbutton_clicked(self, widget):
        if not self.ok_handler:
            return

        passph = self.passphrase_entry.get_text().decode('utf-8')

        if self.check:
253
            checked = self.xml.get_object('save_passphrase_checkbutton').\
254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272
                    get_active()
        else:
            checked = False

        self.ok = True

        self.window.destroy()

        if isinstance(self.ok_handler, tuple):
            self.ok_handler[0](passph, checked, *self.ok_handler[1:])
        else:
            self.ok_handler(passph, checked)

    def on_cancelbutton_clicked(self, widget):
        self.window.destroy()

    def on_passphrase_dialog_destroy(self, widget):
        if self.cancel_handler and not self.ok:
            self.cancel_handler()
Yann Leboulanger's avatar
Yann Leboulanger committed
273

274
class ChooseGPGKeyDialog:
275 276 277 278 279 280 281 282
    """
    Class for GPG key dialog
    """

    def __init__(self, title_text, prompt_text, secret_keys, on_response,
                             selected=None):
        '''secret_keys : {keyID: userName, ...}'''
        self.on_response = on_response
283 284
        xml = gtkgui_helpers.get_gtk_builder('choose_gpg_key_dialog.ui')
        self.window = xml.get_object('choose_gpg_key_dialog')
285
        self.window.set_title(title_text)
286 287
        self.keys_treeview = xml.get_object('keys_treeview')
        prompt_label = xml.get_object('prompt_label')
288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336
        prompt_label.set_text(prompt_text)
        model = gtk.ListStore(str, str)
        model.set_sort_func(1, self.sort_keys)
        model.set_sort_column_id(1, gtk.SORT_ASCENDING)
        self.keys_treeview.set_model(model)
        #columns
        renderer = gtk.CellRendererText()
        col = self.keys_treeview.insert_column_with_attributes(-1, _('KeyID'),
                renderer, text=0)
        col.set_sort_column_id(0)
        renderer = gtk.CellRendererText()
        col = self.keys_treeview.insert_column_with_attributes(-1,
                _('Contact name'), renderer, text=1)
        col.set_sort_column_id(1)
        self.keys_treeview.set_search_column(1)
        self.fill_tree(secret_keys, selected)
        self.window.connect('response', self.on_dialog_response)
        self.window.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
        self.window.show_all()

    def sort_keys(self, model, iter1, iter2):
        value1 = model[iter1][1]
        value2 = model[iter2][1]
        if value1 == _('None'):
            return -1
        elif value2 == _('None'):
            return 1
        elif value1 < value2:
            return -1
        return 1

    def on_dialog_response(self, dialog, response):
        selection = self.keys_treeview.get_selection()
        (model, iter_) = selection.get_selected()
        if iter_ and response == gtk.RESPONSE_OK:
            keyID = [ model[iter_][0].decode('utf-8'),
                    model[iter_][1].decode('utf-8') ]
        else:
            keyID = None
        self.on_response(keyID)
        self.window.destroy()

    def fill_tree(self, list_, selected):
        model = self.keys_treeview.get_model()
        for keyID in list_.keys():
            iter_ = model.append((keyID, list_[keyID]))
            if keyID == selected:
                path = model.get_path(iter_)
                self.keys_treeview.set_cursor(path)
337 338


339
class ChangeActivityDialog:
340 341 342 343 344 345 346 347 348
    PAGELIST = ['doing_chores', 'drinking', 'eating', 'exercising', 'grooming',
            'having_appointment', 'inactive', 'relaxing', 'talking', 'traveling',
            'working']

    def __init__(self, on_response, activity=None, subactivity=None, text=''):
        self.on_response = on_response
        self.activity = activity
        self.subactivity = subactivity
        self.text = text
349
        self.xml = gtkgui_helpers.get_gtk_builder('change_activity_dialog.ui')
350
        self.window = self.xml.get_object('change_activity_dialog')
351 352
        self.window.set_transient_for(gajim.interface.roster.window)

353 354 355
        self.checkbutton = self.xml.get_object('enable_checkbutton')
        self.notebook = self.xml.get_object('notebook')
        self.entry = self.xml.get_object('description_entry')
356 357 358 359 360

        rbtns = {}
        group = None

        for category in pep.ACTIVITIES:
361
            item = self.xml.get_object(category + '_image')
362 363 364 365
            item.set_from_pixbuf(
                    gtkgui_helpers.load_activity_icon(category).get_pixbuf())
            item.set_tooltip_text(pep.ACTIVITIES[category]['category'])

366
            vbox = self.xml.get_object(category + '_vbox')
367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414
            vbox.set_border_width(5)

            # Other
            act = category + '_other'

            if group:
                rbtns[act] = gtk.RadioButton(group)
            else:
                rbtns[act] = group = gtk.RadioButton()

            hbox = gtk.HBox(False, 5)
            hbox.pack_start(gtkgui_helpers.load_activity_icon(category), False,
                    False, 0)
            lbl = gtk.Label('<b>' + pep.ACTIVITIES[category]['category'] + '</b>')
            lbl.set_use_markup(True)
            hbox.pack_start(lbl, False, False, 0)
            rbtns[act].add(hbox)
            rbtns[act].connect('toggled', self.on_rbtn_toggled,
                    [category, 'other'])
            vbox.pack_start(rbtns[act], False, False, 0)

            activities = []
            for activity in pep.ACTIVITIES[category]:
                activities.append(activity)
            activities.sort()

            for activity in activities:
                if activity == 'category':
                    continue

                act = category + '_' + activity

                if group:
                    rbtns[act] = gtk.RadioButton(group)
                else:
                    rbtns[act] = group = gtk.RadioButton()

                hbox = gtk.HBox(False, 5)
                hbox.pack_start(gtkgui_helpers.load_activity_icon(category,
                        activity), False, False, 0)
                hbox.pack_start(gtk.Label(pep.ACTIVITIES[category][activity]),
                        False, False, 0)
                rbtns[act].connect('toggled', self.on_rbtn_toggled,
                        [category, activity])
                rbtns[act].add(hbox)
                vbox.pack_start(rbtns[act], False, False, 0)


415 416
        self.default_radio = rbtns['doing_chores_other']

417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434
        if self.activity in pep.ACTIVITIES:
            if not self.subactivity in pep.ACTIVITIES[self.activity]:
                self.subactivity = 'other'

            rbtns[self.activity + '_' + self.subactivity].set_active(True)

            self.checkbutton.set_active(True)
            self.notebook.set_sensitive(True)
            self.entry.set_sensitive(True)

            self.notebook.set_current_page(
                    self.PAGELIST.index(self.activity))

            self.entry.set_text(text)

        else:
            self.checkbutton.set_active(False)

435
        self.xml.connect_signals(self)
436 437 438 439 440 441
        self.window.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
        self.window.show_all()

    def on_enable_checkbutton_toggled(self, widget):
        self.notebook.set_sensitive(widget.get_active())
        self.entry.set_sensitive(widget.get_active())
442 443
        if not self.activity:
            self.default_radio.set_active(True)
444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462

    def on_rbtn_toggled(self, widget, data):
        if widget.get_active():
            self.activity = data[0]
            self.subactivity = data[1]

    def on_ok_button_clicked(self, widget):
        """
        Return activity and messsage (None if no activity selected)
        """
        if self.checkbutton.get_active():
            self.on_response(self.activity, self.subactivity,
                    self.entry.get_text().decode('utf-8'))
        else:
            self.on_response(None, None, '')
        self.window.destroy()

    def on_cancel_button_clicked(self, widget):
        self.window.destroy()
463

464
class ChangeMoodDialog:
465 466 467 468 469 470
    COLS = 11

    def __init__(self, on_response, mood=None, text=''):
        self.on_response = on_response
        self.mood = mood
        self.text = text
471
        self.xml = gtkgui_helpers.get_gtk_builder('change_mood_dialog.ui')
472

473
        self.window = self.xml.get_object('change_mood_dialog')
474 475 476
        self.window.set_transient_for(gajim.interface.roster.window)
        self.window.set_title(_('Set Mood'))

477 478 479
        table = self.xml.get_object('mood_icons_table')
        self.label = self.xml.get_object('mood_label')
        self.entry = self.xml.get_object('description_entry')
480

481
        no_mood_button = self.xml.get_object('no_mood_button')
482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522
        no_mood_button.set_mode(False)
        no_mood_button.connect('clicked',
                self.on_mood_button_clicked, None)

        x = 1
        y = 0
        self.mood_buttons = {}

        # Order them first
        self.MOODS = []
        for mood in pep.MOODS:
            self.MOODS.append(mood)
        self.MOODS.sort()

        for mood in self.MOODS:
            self.mood_buttons[mood] = gtk.RadioButton(no_mood_button)
            self.mood_buttons[mood].set_mode(False)
            self.mood_buttons[mood].add(gtkgui_helpers.load_mood_icon(mood))
            self.mood_buttons[mood].set_relief(gtk.RELIEF_NONE)
            self.mood_buttons[mood].set_tooltip_text(pep.MOODS[mood])
            self.mood_buttons[mood].connect('clicked',
                    self.on_mood_button_clicked, mood)
            table.attach(self.mood_buttons[mood], x, x + 1, y, y + 1)

            # Calculate the next position
            x += 1
            if x >= self.COLS:
                x = 0
                y += 1

        if self.mood in pep.MOODS:
            self.mood_buttons[self.mood].set_active(True)
            self.label.set_text(pep.MOODS[self.mood])
            self.entry.set_sensitive(True)
            if self.text:
                self.entry.set_text(self.text)
        else:
            self.label.set_text(_('None'))
            self.entry.set_text('')
            self.entry.set_sensitive(False)

523
        self.xml.connect_signals(self)
524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544
        self.window.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
        self.window.show_all()

    def on_mood_button_clicked(self, widget, data):
        if data:
            self.label.set_text(pep.MOODS[data])
            self.entry.set_sensitive(True)
        else:
            self.label.set_text(_('None'))
            self.entry.set_text('')
            self.entry.set_sensitive(False)
        self.mood = data

    def on_ok_button_clicked(self, widget):
        '''Return mood and messsage (None if no mood selected)'''
        message = self.entry.get_text().decode('utf-8')
        self.on_response(self.mood, message)
        self.window.destroy()

    def on_cancel_button_clicked(self, widget):
        self.window.destroy()
545

546
class TimeoutDialog:
547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579
    """
    Class designed to be derivated to create timeout'd dialogs (dialogs that
    closes automatically after a timeout)
    """
    def __init__(self, timeout, on_timeout):
        self.countdown_left = timeout
        self.countdown_enabled = True
        self.title_text = ''
        self.on_timeout = on_timeout

    def run_timeout(self):
        if self.countdown_left > 0:
            self.countdown()
            gobject.timeout_add_seconds(1, self.countdown)

    def on_timeout():
        """
        To be implemented in derivated classes
        """
        pass

    def countdown(self):
        if self.countdown_enabled:
            if self.countdown_left <= 0:
                self.on_timeout()
                return False
            self.dialog.set_title('%s [%s]' % (self.title_text,
                    str(self.countdown_left)))
            self.countdown_left -= 1
            return True
        else:
            self.dialog.set_title(self.title_text)
            return False
580 581

class ChangeStatusMessageDialog(TimeoutDialog):
582 583 584 585 586 587 588
    def __init__(self, on_response, show=None, show_pep=True):
        countdown_time = gajim.config.get('change_status_window_timeout')
        TimeoutDialog.__init__(self, countdown_time, self.on_timeout)
        self.show = show
        self.pep_dict = {}
        self.show_pep = show_pep
        self.on_response = on_response
589 590
        self.xml = gtkgui_helpers.get_gtk_builder('change_status_message_dialog.ui')
        self.dialog = self.xml.get_object('change_status_message_dialog')
591 592 593 594 595 596 597 598
        self.dialog.set_transient_for(gajim.interface.roster.window)
        msg = None
        if show:
            uf_show = helpers.get_uf_show(show)
            self.title_text = _('%s Status Message') % uf_show
            msg = gajim.config.get_per('statusmsg', '_last_' + self.show,
                                                               'message')
            self.pep_dict['activity'] = gajim.config.get_per('statusmsg',
Dicson's avatar
Dicson committed
599
                '_last_' + self.show, 'activity')
600
            self.pep_dict['subactivity'] = gajim.config.get_per('statusmsg',
Dicson's avatar
Dicson committed
601
                '_last_' + self.show, 'subactivity')
602
            self.pep_dict['activity_text'] = gajim.config.get_per('statusmsg',
Dicson's avatar
Dicson committed
603
                '_last_' + self.show, 'activity_text')
604
            self.pep_dict['mood'] = gajim.config.get_per('statusmsg',
Dicson's avatar
Dicson committed
605
                '_last_' + self.show, 'mood')
606
            self.pep_dict['mood_text'] = gajim.config.get_per('statusmsg',
Dicson's avatar
Dicson committed
607
                '_last_' + self.show, 'mood_text')
608 609 610 611
        else:
            self.title_text = _('Status Message')
        self.dialog.set_title(self.title_text)

612
        message_textview = self.xml.get_object('message_textview')
613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633
        self.message_buffer = message_textview.get_buffer()
        self.message_buffer.connect('changed', self.on_message_buffer_changed)
        if not msg:
            msg = ''
        msg = helpers.from_one_line(msg)
        self.message_buffer.set_text(msg)

        # have an empty string selectable, so user can clear msg
        self.preset_messages_dict = {'': ['', '', '', '', '', '']}
        for msg_name in gajim.config.get_per('statusmsg'):
            if msg_name.startswith('_last_'):
                continue
            opts = []
            for opt in ['message', 'activity', 'subactivity', 'activity_text',
                                    'mood', 'mood_text']:
                opts.append(gajim.config.get_per('statusmsg', msg_name, opt))
            opts[0] = helpers.from_one_line(opts[0])
            self.preset_messages_dict[msg_name] = opts
        sorted_keys_list = helpers.get_sorted_keys(self.preset_messages_dict)

        self.message_liststore = gtk.ListStore(str) # msg_name
634
        self.message_combobox = self.xml.get_object('message_combobox')
635 636 637 638 639 640 641 642 643 644 645 646
        self.message_combobox.set_model(self.message_liststore)
        cellrenderertext = gtk.CellRendererText()
        self.message_combobox.pack_start(cellrenderertext, True)
        self.message_combobox.add_attribute(cellrenderertext, 'text', 0)
        for msg_name in sorted_keys_list:
            self.message_liststore.append((msg_name,))

        if show_pep:
            self.draw_activity()
            self.draw_mood()
        else:
            # remove acvtivity / mood lines
647 648 649 650 651 652 653 654 655 656
            self.xml.get_object('activity_label').set_no_show_all(True)
            self.xml.get_object('activity_button').set_no_show_all(True)
            self.xml.get_object('mood_label').set_no_show_all(True)
            self.xml.get_object('mood_button').set_no_show_all(True)
            self.xml.get_object('activity_label').hide()
            self.xml.get_object('activity_button').hide()
            self.xml.get_object('mood_label').hide()
            self.xml.get_object('mood_button').hide()

        self.xml.connect_signals(self)
657 658 659 660 661 662 663 664 665
        self.run_timeout()
        self.dialog.connect('response', self.on_dialog_response)
        self.dialog.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
        self.dialog.show_all()

    def draw_activity(self):
        """
        Set activity button
        """
666 667
        img = self.xml.get_object('activity_image')
        label = self.xml.get_object('activity_button_label')
668 669
        if 'activity' in self.pep_dict and self.pep_dict['activity'] in \
           pep.ACTIVITIES:
670 671
            if 'subactivity' in self.pep_dict and self.pep_dict['subactivity'] \
            in pep.ACTIVITIES[self.pep_dict['activity']]:
672
                img.set_from_pixbuf(gtkgui_helpers.load_activity_icon(
673 674
                    self.pep_dict['activity'], self.pep_dict['subactivity']).\
                        get_pixbuf())
675 676
            else:
                img.set_from_pixbuf(gtkgui_helpers.load_activity_icon(
677
                    self.pep_dict['activity']).get_pixbuf())
678 679 680 681 682 683 684 685 686 687 688 689
            if self.pep_dict['activity_text']:
                label.set_text(self.pep_dict['activity_text'])
            else:
                label.set_text('')
        else:
            img.set_from_pixbuf(None)
            label.set_text('')

    def draw_mood(self):
        """
        Set mood button
        """
690 691
        img = self.xml.get_object('mood_image')
        label = self.xml.get_object('mood_button_label')
692
        if 'mood' in self.pep_dict and self.pep_dict['mood'] in pep.MOODS:
693
            img.set_from_pixbuf(gtkgui_helpers.load_mood_icon(
694
                self.pep_dict['mood']).get_pixbuf())
695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715
            if self.pep_dict['mood_text']:
                label.set_text(self.pep_dict['mood_text'])
            else:
                label.set_text('')
        else:
            img.set_from_pixbuf(None)
            label.set_text('')

    def on_timeout(self):
        # Prevent GUI freeze when the combobox menu is opened on close
        self.message_combobox.popdown()
        self.dialog.response(gtk.RESPONSE_OK)

    def on_dialog_response(self, dialog, response):
        if response == gtk.RESPONSE_OK:
            beg, end = self.message_buffer.get_bounds()
            message = self.message_buffer.get_text(beg, end).decode('utf-8')\
                    .strip()
            message = helpers.remove_invalid_xml_chars(message)
            msg = helpers.to_one_line(message)
            if self.show:
Dicson's avatar
Dicson committed
716 717
                gajim.config.set_per('statusmsg', '_last_' + self.show,
                    'message', msg)
718 719
                if self.show_pep:
                    gajim.config.set_per('statusmsg', '_last_' + self.show,
Dicson's avatar
Dicson committed
720
                        'activity', self.pep_dict['activity'])
721
                    gajim.config.set_per('statusmsg', '_last_' + self.show,
Dicson's avatar
Dicson committed
722
                        'subactivity', self.pep_dict['subactivity'])
723
                    gajim.config.set_per('statusmsg', '_last_' + self.show,
Dicson's avatar
Dicson committed
724
                        'activity_text', self.pep_dict['activity_text'])
725
                    gajim.config.set_per('statusmsg', '_last_' + self.show,
Dicson's avatar
Dicson committed
726 727 728
                        'mood', self.pep_dict['mood'])
                    gajim.config.set_per('statusmsg', '_last_' + self.show,
                        'mood_text', self.pep_dict['mood_text'])
729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763
        else:
            message = None # user pressed Cancel button or X wm button
        self.dialog.destroy()
        self.on_response(message, self.pep_dict)

    def on_message_combobox_changed(self, widget):
        self.countdown_enabled = False
        model = widget.get_model()
        active = widget.get_active()
        if active < 0:
            return None
        name = model[active][0].decode('utf-8')
        self.message_buffer.set_text(self.preset_messages_dict[name][0])
        self.pep_dict['activity'] = self.preset_messages_dict[name][1]
        self.pep_dict['subactivity'] = self.preset_messages_dict[name][2]
        self.pep_dict['activity_text'] = self.preset_messages_dict[name][3]
        self.pep_dict['mood'] = self.preset_messages_dict[name][4]
        self.pep_dict['mood_text'] = self.preset_messages_dict[name][5]
        self.draw_activity()
        self.draw_mood()

    def on_change_status_message_dialog_key_press_event(self, widget, event):
        self.countdown_enabled = False
        if event.keyval == gtk.keysyms.Return or \
           event.keyval == gtk.keysyms.KP_Enter: # catch CTRL+ENTER
            if (event.state & gtk.gdk.CONTROL_MASK):
                self.dialog.response(gtk.RESPONSE_OK)
                # Stop the event
                return True

    def on_message_buffer_changed(self, widget):
        self.countdown_enabled = False
        self.toggle_sensitiviy_of_save_as_preset()

    def toggle_sensitiviy_of_save_as_preset(self):
764
        btn = self.xml.get_object('save_as_preset_button')
765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781
        if self.message_buffer.get_char_count() == 0:
            btn.set_sensitive(False)
        else:
            btn.set_sensitive(True)

    def on_save_as_preset_button_clicked(self, widget):
        self.countdown_enabled = False
        start_iter, finish_iter = self.message_buffer.get_bounds()
        status_message_to_save_as_preset = self.message_buffer.get_text(
                start_iter, finish_iter)
        def on_ok(msg_name):
            msg_text = status_message_to_save_as_preset.decode('utf-8')
            msg_text_1l = helpers.to_one_line(msg_text)
            if not msg_name: # msg_name was ''
                msg_name = msg_text_1l.decode('utf-8')

            def on_ok2():
Dicson's avatar
Dicson committed
782 783 784 785 786 787 788
                self.preset_messages_dict[msg_name] = [
                    msg_text, self.pep_dict.get('activity'),
                    self.pep_dict.get('subactivity'),
                    self.pep_dict.get('activity_text'),
                    self.pep_dict.get('mood'), self.pep_dict.get('mood_text')]
                gajim.config.set_per('statusmsg', msg_name, 'message',
                    msg_text_1l)
789
                gajim.config.set_per('statusmsg', msg_name, 'activity',
Dicson's avatar
Dicson committed
790
                    self.pep_dict.get('activity'))
791
                gajim.config.set_per('statusmsg', msg_name, 'subactivity',
Dicson's avatar
Dicson committed
792
                    self.pep_dict.get('subactivity'))
793
                gajim.config.set_per('statusmsg', msg_name, 'activity_text',
Dicson's avatar
Dicson committed
794
                    self.pep_dict.get('activity_text'))
795
                gajim.config.set_per('statusmsg', msg_name, 'mood',
Dicson's avatar
Dicson committed
796
                    self.pep_dict.get('mood'))
797
                gajim.config.set_per('statusmsg', msg_name, 'mood_text',
Dicson's avatar
Dicson committed
798
                    self.pep_dict.get('mood_text'))
799 800
            if msg_name in self.preset_messages_dict:
                ConfirmationDialog(_('Overwrite Status Message?'),
Dicson's avatar
Dicson committed
801 802
                    _('This name is already used. Do you want to overwrite this '
                    'status message?'), on_response_ok=on_ok2)
803 804 805 806 807 808 809
                return
            gajim.config.add_per('statusmsg', msg_name)
            on_ok2()
            iter_ = self.message_liststore.append((msg_name,))
            # select in combobox the one we just saved
            self.message_combobox.set_active_iter(iter_)
        InputDialog(_('Save as Preset Status Message'),
Dicson's avatar
Dicson committed
810 811
            _('Please type a name for this status message'), is_modal=False,
            ok_handler=on_ok)
812 813 814 815 816 817 818 819 820

    def on_activity_button_clicked(self, widget):
        self.countdown_enabled = False
        def on_response(activity, subactivity, text):
            self.pep_dict['activity'] = activity or ''
            self.pep_dict['subactivity'] = subactivity or ''
            self.pep_dict['activity_text'] = text
            self.draw_activity()
        ChangeActivityDialog(on_response, self.pep_dict['activity'],
Dicson's avatar
Dicson committed
821
            self.pep_dict['subactivity'], self.pep_dict['activity_text'])
822 823 824 825 826 827 828 829 830

    def on_mood_button_clicked(self, widget):
        self.countdown_enabled = False
        def on_response(mood, text):
            self.pep_dict['mood'] = mood or ''
            self.pep_dict['mood_text'] = text
            self.draw_mood()
        ChangeMoodDialog(on_response, self.pep_dict['mood'],
                                         self.pep_dict['mood_text'])
831

832
class AddNewContactWindow:
833 834 835 836 837
    """
    Class for AddNewContactWindow
    """

    uid_labels = {'jabber': _('Jabber ID:'),
838 839 840 841 842
        'aim': _('AIM Address:'),
        'gadu-gadu': _('GG Number:'),
        'icq': _('ICQ Number:'),
        'msn': _('MSN Address:'),
        'yahoo': _('Yahoo! Address:')}
843 844 845

    def __init__(self, account=None, jid=None, user_nick=None, group=None):
        self.account = account
846
        self.adding_jid = False
847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867
        if account is None:
            # fill accounts with active accounts
            accounts = []
            for account in gajim.connections.keys():
                if gajim.connections[account].connected > 1:
                    accounts.append(account)
            if not accounts:
                return
            if len(accounts) == 1:
                self.account = account
        else:
            accounts = [self.account]
        if self.account:
            location = gajim.interface.instances[self.account]
        else:
            location = gajim.interface.instances
        if 'add_contact' in location:
            location['add_contact'].window.present()
            # An instance is already opened
            return
        location['add_contact'] = self
868 869 870
        self.xml = gtkgui_helpers.get_gtk_builder('add_new_contact_window.ui')
        self.xml.connect_signals(self)
        self.window = self.xml.get_object('add_new_contact_window')
871
        for w in ('account_combobox', 'account_hbox', 'account_label',
872 873 874 875 876 877
        'uid_label', 'uid_entry', 'protocol_combobox', 'protocol_jid_combobox',
        'protocol_hbox', 'nickname_entry', 'message_scrolledwindow',
        'save_message_checkbutton', 'register_hbox', 'subscription_table',
        'add_button', 'message_textview', 'connected_label',
        'group_comboboxentry', 'auto_authorize_checkbutton'):
            self.__dict__[w] = self.xml.get_object(w)
878
        if account and len(gajim.connections) >= 2:
879 880
            self.default_desc = _('Please fill in the data of the contact you '
                'want to add in account %s') % account
881
        else:
882 883 884
            self.default_desc = _('Please fill in the data of the contact you '
                'want to add')
        self.xml.get_object('prompt_label').set_text(self.default_desc)
885
        self.agents = {'jabber': []}
886
        self.gateway_prompt = {}
887 888 889 890 891 892 893 894 895 896 897 898
        # types to which we are not subscribed but account has an agent for it
        self.available_types = []
        for acct in accounts:
            for j in gajim.contacts.get_jid_list(acct):
                if gajim.jid_is_transport(j):
                    type_ = gajim.get_transport_name_from_jid(j, False)
                    if not type_:
                        continue
                    if type_ in self.agents:
                        self.agents[type_].append(j)
                    else:
                        self.agents[type_] = [j]
899
                    self.gateway_prompt[j] = {'desc': None, 'prompt': None}
900 901 902 903 904 905 906 907 908
        # Now add the one to which we can register
        for acct in accounts:
            for type_ in gajim.connections[acct].available_transports:
                if type_ in self.agents:
                    continue
                self.agents[type_] = []
                for jid_ in gajim.connections[acct].available_transports[type_]:
                    if not jid_ in self.agents[type_]:
                        self.agents[type_].append(jid_)
909 910
                        self.gateway_prompt[jid_] = {'desc': None,
                            'prompt': None}
911 912 913 914 915 916 917 918 919 920 921 922
                self.available_types.append(type_)
        # Combobox with transport/jabber icons
        liststore = gtk.ListStore(str, gtk.gdk.Pixbuf, str)
        cell = gtk.CellRendererPixbuf()
        self.protocol_combobox.pack_start(cell, False)
        self.protocol_combobox.add_attribute(cell, 'pixbuf', 1)
        cell = gtk.CellRendererText()
        cell.set_property('xpad', 5)
        self.protocol_combobox.pack_start(cell, True)
        self.protocol_combobox.add_attribute(cell, 'text', 0)
        self.protocol_combobox.set_model(liststore)
        uf_type = {'jabber': 'Jabber', 'aim': 'AIM', 'gadu-gadu': 'Gadu Gadu',
923
            'icq': 'ICQ', 'msn': 'MSN', 'yahoo': 'Yahoo'}
924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939
        # Jabber as first
        img = gajim.interface.jabber_state_images['16']['online']
        liststore.append(['Jabber', img.get_pixbuf(), 'jabber'])
        for type_ in self.agents:
            if type_ == 'jabber':
                continue
            imgs = gajim.interface.roster.transports_state_images
            img = None
            if type_ in imgs['16'] and 'online' in imgs['16'][type_]:
                img = imgs['16'][type_]['online']
                if type_ in uf_type:
                    liststore.append([uf_type[type_], img.get_pixbuf(), type_])
                else:
                    liststore.append([type_, img.get_pixbuf(), type_])
            else:
                liststore.append([type_, img, type_])
940 941 942
            if account:
                for service in self.agents[type_]:
                    gajim.connections[account].request_gateway_prompt(service)
943 944 945 946 947 948 949 950 951 952 953 954 955
        self.protocol_combobox.set_active(0)
        self.auto_authorize_checkbutton.show()
        liststore = gtk.ListStore(str)
        self.protocol_jid_combobox.set_model(liststore)
        if jid:
            type_ = gajim.get_transport_name_from_jid(jid)
            if not type_:
                type_ = 'jabber'
            if type_ == 'jabber':
                self.uid_entry.set_text(jid)
            else:
                uid, transport = gajim.get_name_and_server_from_jid(jid)
                self.uid_entry.set_text(uid.replace('%', '@', 1))
956
            # set protocol_combobox
957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995
            model = self.protocol_combobox.get_model()
            iter_ = model.get_iter_first()
            i = 0
            while iter_:
                if model[iter_][2] == type_:
                    self.protocol_combobox.set_active(i)
                    break
                iter_ = model.iter_next(iter_)
                i += 1

            # set protocol_jid_combobox
            self.protocol_jid_combobox.set_active(0)
            model = self.protocol_jid_combobox.get_model()
            iter_ = model.get_iter_first()
            i = 0
            while iter_:
                if model[iter_][0] == transport:
                    self.protocol_jid_combobox.set_active(i)
                    break
                iter_ = model.iter_next(iter_)
                i += 1
            if user_nick:
                self.nickname_entry.set_text(user_nick)
            self.nickname_entry.grab_focus()
        else:
            self.uid_entry.grab_focus()
        group_names = []
        for acct in accounts:
            for g in gajim.groups[acct].keys():
                if g not in helpers.special_groups and g not in group_names:
                    group_names.append(g)
        group_names.sort()
        i = 0
        for g in group_names:
            self.group_comboboxentry.append_text(g)
            if group == g:
                self.group_comboboxentry.set_active(i)
            i += 1

996
        self.window.set_transient_for(gajim.interface.roster.window)
997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008
        self.window.show_all()

        if self.account:
            self.account_label.hide()
            self.account_hbox.hide()
        else:
            liststore = gtk.ListStore(str, str)
            for acct in accounts:
                liststore.append([acct, acct])
            self.account_combobox.set_model(liststore)
            self.account_combobox.set_active(0)

1009 1010 1011
        if self.account:
            message_buffer = self.message_textview.get_buffer()
            message_buffer.set_text(helpers.get_subscription_request_msg(
1012
                self.account))
1013

1014 1015
        gajim.ged.register_event_handler('gateway-prompt-received', ged.GUI1,
            self._nec_gateway_prompt_received)
1016 1017 1018
        gajim.ged.register_event_handler('presence-received', ged.GUI1,
            self._nec_presence_received)

1019 1020 1021 1022 1023 1024
    def on_add_new_contact_window_destroy(self, widget):
        if self.account:
            location = gajim.interface.instances[self.account]
        else:
            location = gajim.interface.instances
        del location['add_contact']
1025 1026
        gajim.ged.remove_event_handler('presence-received', ged.GUI1,
            self._nec_presence_received)
1027 1028
        gajim.ged.remove_event_handler('gateway-prompt-received', ged.GUI1,
            self._nec_gateway_prompt_received)
1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056

    def on_register_button_clicked(self, widget):
        jid = self.protocol_jid_combobox.get_active_text().decode('utf-8')
        gajim.connections[self.account].request_register_agent_info(jid)

    def on_add_new_contact_window_key_press_event(self, widget, event):
        if event.keyval == gtk.keysyms.Escape: # ESCAPE
            self.window.destroy()

    def on_cancel_button_clicked(self, widget):
        """
        When Cancel button is clicked
        """
        self.window.destroy()

    def on_add_button_clicked(self, widget):
        """
        When Subscribe button is clicked
        """
        jid = self.uid_entry.get_text().decode('utf-8').strip()
        if not jid:
            return

        model = self.protocol_combobox.get_model()
        iter_ = self.protocol_combobox.get_active_iter()
        type_ = model[iter_][2]
        if type_ != 'jabber':
            transport = self.protocol_jid_combobox.get_active_text().decode(
1057
                'utf-8')
1058
            if self.account:
1059
                self.adding_jid = (jid, transport, type_)
1060 1061 1062 1063
                gajim.connections[self.account].request_gateway_prompt(
                    transport, jid)
            else:
                jid = jid.replace('@', '%') + '@' + transport
1064
                self._add_jid(jid, type_)
1065
        else:
1066
            self._add_jid(jid, type_)
1067

1068
    def _add_jid(self, jid, type_):
1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099
        # check if jid is conform to RFC and stringprep it
        try:
            jid = helpers.parse_jid(jid)
        except helpers.InvalidFormat, s:
            pritext = _('Invalid User ID')
            ErrorDialog(pritext, str(s))
            return

        # No resource in jid
        if jid.find('/') >= 0:
            pritext = _('Invalid User ID')
            ErrorDialog(pritext, _('The user ID must not contain a resource.'))
            return

        if jid == gajim.get_jid_from_account(self.account):
            pritext = _('Invalid User ID')
            ErrorDialog(pritext, _('You cannot add yourself to your roster.'))
            return

        nickname = self.nickname_entry.get_text().decode('utf-8') or ''
        # get value of account combobox, if account was not specified
        if not self.account:
            model = self.account_combobox.get_model()
            index = self.account_combobox.get_active()
            self.account = model[index][1]

        # Check if jid is already in roster
        if jid in gajim.contacts.get_jid_list(self.account):
            c = gajim.contacts.get_first_contact_from_jid(self.account, jid)
            if _('Not in Roster') not in c.groups and c.sub in ('both', 'to'):
                ErrorDialog(_('Contact already in roster'),
1100
                    _('This contact is already listed in your roster.'))
1101 1102 1103 1104 1105 1106 1107
                return

        if type_ == 'jabber':
            message_buffer = self.message_textview.get_buffer()
            start_iter = message_buffer.get_start_iter()
            end_iter = message_buffer.get_end_iter()
            message = message_buffer.get_text(start_iter, end_iter).decode('utf-8')
1108 1109
            if self.save_message_checkbutton.get_active():
                gajim.config.set_per('accounts', self.account,
1110
                    'subscription_request_msg', message)
1111 1112 1113 1114 1115 1116 1117 1118
        else:
            message= ''
        group = self.group_comboboxentry.child.get_text().decode('utf-8')
        groups = []
        if group:
            groups = [group]
        auto_auth = self.auto_authorize_checkbutton.get_active()
        gajim.interface.roster.req_sub(self, jid, message, self.account,
1119
            groups=groups, nickname=nickname, auto_auth=auto_auth)
1120 1121
        self.window.destroy()

1122 1123 1124 1125 1126 1127 1128
    def on_account_combobox_changed(self, widget):
        model = widget.get_model()
        iter_ = widget.get_active_iter()
        account = model[iter_][0]
        message_buffer = self.message_textview.get_buffer()
        message_buffer.set_text(helpers.get_subscription_request_msg(account))

1129 1130 1131
    def on_protocol_jid_combobox_changed(self, widget):
        model = widget.get_model()
        iter_ = widget.get_active_iter()
1132 1133
        if not iter_:
            return
1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154
        jid_ = model[iter_][0]
        model = self.protocol_combobox.get_model()
        iter_ = self.protocol_combobox.get_active_iter()
        type_ = model[iter_][2]
        desc = None
        if self.agents[type_] and jid_ in self.gateway_prompt:
            desc = self.gateway_prompt[jid_]['desc']
        if not desc:
            desc = self.default_desc
        self.xml.get_object('prompt_label').set_text(desc)

        prompt = None
        if self.agents[type_] and jid_ in self.gateway_prompt:
            prompt = self.gateway_prompt[jid_]['prompt']
        if not prompt:
            if type_ in self.uid_labels:
                prompt = self.uid_labels[type_]
            else:
                prompt = _('User ID:')
        self.uid_label.set_text(prompt)

1155 1156 1157 1158 1159 1160 1161 1162 1163 1164
    def on_protocol_combobox_changed(self, widget):
        model = widget.get_model()
        iter_ = widget.get_active_iter()
        type_ = model[iter_][2]
        model = self.protocol_jid_combobox.get_model()
        model.clear()
        if len(self.agents[type_]):
            for jid_ in self.agents[type_]:
                model.append([jid_])
            self.protocol_jid_combobox.set_active(0)
1165 1166 1167 1168 1169 1170 1171 1172
        desc = None
        if self.agents[type_]:
            jid_ = self.agents[type_][0]
            if jid_ in self.gateway_prompt:
                desc = self.gateway_prompt[jid_]['desc']
        if not desc:
            desc = self.default_desc
        self.xml.get_object('prompt_label').set_text(desc)
1173 1174 1175 1176
        if len(self.agents[type_]) > 1:
            self.protocol_jid_combobox.show()
        else:
            self.protocol_jid_combobox.hide()
1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188
        prompt = None
        if self.agents[type_]:
            jid_ = self.agents[type_][0]
            if jid_ in self.gateway_prompt:
                prompt = self.gateway_prompt[jid_]['prompt']
        if not prompt:
            if type_ in self.uid_labels:
                prompt = self.uid_labels[type_]
            else:
                prompt = _('User ID:')
        self.uid_label.set_text(prompt)

1189 1190
        if type_ == 'jabber':
            self.message_scrolledwindow.show()
1191
            self.save_message_checkbutton.show()
1192 1193
        else:
            self.message_scrolledwindow.hide()
1194
            self.save_message_checkbutton.hide()
1195 1196 1197 1198 1199 1200 1201 1202 1203 1204
        if type_ in self.available_types:
            self.register_hbox.show()
            self.auto_authorize_checkbutton.hide()
            self.connected_label.hide()
            self.subscription_table.hide()
            self.add_button.set_sensitive(False)
        else:
            self.register_hbox.hide()
            if type_ != 'jabber':
                jid = self.protocol_jid_combobox.get_active_text()
1205 1206
                contact = gajim.contacts.get_first_contact_from_jid(
                    self.account, jid)
1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231
                if contact.show in ('offline', 'error'):
                    self.subscription_table.hide()
                    self.connected_label.show()
                    self.add_button.set_sensitive(False)
                    self.auto_authorize_checkbutton.hide()
                    return
            self.subscription_table.show()
            self.auto_authorize_checkbutton.show()
            self.connected_label.hide()
            self.add_button.set_sensitive(True)

    def transport_signed_in(self, jid):
        if self.protocol_jid_combobox.get_active_text() == jid:
            self.register_hbox.hide()
            self.connected_label.hide()
            self.subscription_table.show()
            self.auto_authorize_checkbutton.show()
            self.add_button.set_sensitive(True)

    def transport_signed_out(self, jid):
        if self.protocol_jid_combobox.get_active_text() == jid:
            self.subscription_table.hide()
            self.auto_authorize_checkbutton.hide()
            self.connected_label.show()
            self.add_button.set_sensitive(False)
Yann Leboulanger's avatar
Yann Leboulanger committed
1232

1233 1234 1235 1236 1237 1238 1239
    def _nec_presence_received(self, obj):
        if gajim.jid_is_transport(obj.jid):
            if obj.old_show == 0 and obj.new_show > 1:
                self.transport_signed_in(obj.jid)
            elif obj.old_show > 1 and obj.new_show == 0:
                self.transport_signed_out(obj.jid)

1240
    def _nec_gateway_prompt_received(self, obj):
1241
        if self.adding_jid:
1242
            jid, transport, type_ = self.adding_jid
1243
            if obj.prompt_jid:
1244
                self._add_jid(obj.prompt_jid, type_)
1245 1246
            else:
                jid = jid.replace('@', '%') + '@' + transport
1247
                self._add_jid(jid, type_)
1248
        elif obj.jid in self.gateway_prompt:
1249 1250 1251 1252
            if obj.desc:
                self.gateway_prompt[obj.jid]['desc'] = obj.desc
            if obj.prompt:
                self.gateway_prompt[obj.jid]['prompt'] = obj.prompt
1253

nkour's avatar
nkour committed
1254
class AboutDialog:
1255 1256 1257 1258 1259 1260 1261 1262 1263
    """
    Class for about dialog
    """

    def __init__(self):
        dlg = gtk.AboutDialog()
        dlg.set_transient_for(gajim.interface.roster.window)
        dlg.set_name('Gajim')
        dlg.set_version(gajim.version)
1264
        s = u'Copyright © 2003-2010 Gajim Team'
1265 1266 1267 1268 1269 1270
        dlg.set_copyright(s)
        copying_file_path = self.get_path('COPYING')
        if copying_file_path:
            text = open(copying_file_path).read()
            dlg.set_license(text)