Example #1
0
    def _on_send(self, *args):
        if not self._selected_send_account:
            return
        if not app.account_is_connected(self._selected_send_account):
            # If offline or connecting
            ErrorDialog(
                _('Connection not available'),
                _('Please make sure you are connected with \'%s\'.') %
                self._selected_send_account)
            return
        buffer_ = self._ui.input_entry.get_buffer()
        begin_iter, end_iter = buffer_.get_bounds()
        stanza = buffer_.get_text(begin_iter, end_iter, True)
        if stanza:
            try:
                node = nbxmpp.Node(node=stanza)
            except Exception as error:
                ErrorDialog(_('Invalid Node'), str(error))
                return

            if node.getName() in ('message', 'presence', 'iq'):
                # Parse stanza again if its a message, presence or iq and
                # set jabber:client as toplevel namespace
                # Use type Protocol so nbxmpp counts the stanza for
                # stream management
                node = nbxmpp.Protocol(node=stanza,
                                       attrs={'xmlns': 'jabber:client'})
            app.connections[self._selected_send_account].connection.send(node)
            self.last_stanza = stanza
            buffer_.set_text('')
Example #2
0
    def on_server_entry_focus_out(self, widget, event):
        if self.ignore_events:
            return
        (model, iter_) = self.selection.get_selected()
        if not iter_:
            return
        server = widget.get_text()
        if not server:
            return
        if '@' in server:
            ErrorDialog(
                _('Invalid server'),
                _('Character not allowed'),
                transient_for=self._ui.manage_bookmarks_window)
            widget.set_text(server.replace('@', ''))

        room = self._ui.room_entry.get_text().strip()
        if not room:
            return
        room_jid = room + '@' + server.strip()
        try:
            room_jid = helpers.parse_jid(room_jid)
        except helpers.InvalidFormat:
            ErrorDialog(
                _('Invalid server'),
                _('Character not allowed'),
                transient_for=self._ui.manage_bookmarks_window)
            self._ui.server_entry.set_text(
                model[iter_][Row.ROOM_JID].split('@')[1])
            return True
        model[iter_][Row.ROOM_JID] = room_jid
Example #3
0
 def get_send_file_props(self, account, contact, file_path, file_name,
                         file_desc=''):
     """
     Create new file_props object and set initial file transfer
     properties in it
     """
     if os.path.isfile(file_path):
         stat = os.stat(file_path)
     else:
         ErrorDialog(_('Invalid File'), _('File: ') + file_path)
         return None
     if stat[6] == 0:
         ErrorDialog(
             _('Invalid File'),
             _('It is not possible to send empty files'))
         return None
     file_props = FilesProp.getNewFileProp(
         account, sid=helpers.get_random_string_16())
     mod_date = os.path.getmtime(file_path)
     file_props.file_name = file_path
     file_props.name = file_name
     file_props.date = self.__convert_date(mod_date)
     file_props.type_ = 's'
     file_props.desc = file_desc
     file_props.elapsed_time = 0
     file_props.size = stat[6]
     file_props.sender = account
     file_props.receiver = contact
     file_props.tt_account = account
     return file_props
Example #4
0
    def _disco_info_received(self, result):
        if is_error_result(result):
            ErrorDialog(_('Wrong server'),
                        _('%s is not a group chat server') % result.jid,
                        transient_for=self)
            return
        if nbxmpp.NS_MUC not in result.features:
            ErrorDialog(_('Wrong server'),
                        _('%s is not a group chat server') % result.jid,
                        transient_for=self)
            return

        jid = str(result.jid)
        if jid in app.interface.instances[self.account]['disco']:
            app.interface.instances[self.account]['disco'][jid].window.\
                present()
        else:
            try:
                # Object will add itself to the window dict
                ServiceDiscoveryWindow(self.account,
                                       jid,
                                       initial_identities=[
                                           DiscoIdentity(category='conference',
                                                         type='text',
                                                         name=None)
                                       ])
            except GajimGeneralException:
                pass
Example #5
0
        def _on_accepted(account, contact, file_props, file_path):
            if os.path.exists(file_path):
                app.config.set('last_save_dir', os.path.dirname(file_path))

                # Check if we have write permissions
                if not os.access(file_path, os.W_OK):
                    file_name = GLib.markup_escape_text(
                        os.path.basename(file_path))
                    ErrorDialog(
                        _('Cannot overwrite existing file \'%s\'' % file_name),
                        _('A file with this name already exists and you do '
                          'not have permission to overwrite it.'))
                    return

                stat = os.stat(file_path)
                dl_size = stat.st_size
                file_size = file_props.size
                dl_finished = dl_size >= file_size

                def _on_resume():
                    if not dl_finished:
                        file_props.offset = dl_size
                    self._start_receive(
                        file_path, account, contact, file_props)

                def _on_replace():
                    self._start_receive(
                        file_path, account, contact, file_props)

                def _on_cancel():
                    con.get_module('Bytestream').send_file_rejection(
                        file_props)

                NewConfirmationDialog(
                    _('File Transfer Conflict'),
                    _('File already exists'),
                    _('Resume download or replace file?'),
                    [DialogButton.make('Cancel',
                                       callback=_on_cancel),
                     DialogButton.make('OK',
                                       text=_('Resume _Download'),
                                       callback=_on_resume),
                     DialogButton.make('Accept',
                                       text=_('Replace _File'),
                                       callback=_on_replace)]).show()

            # File does not exist yet
            dirname = os.path.dirname(file_path)
            if not os.access(dirname, os.W_OK) and os.name != 'nt':
                # read-only bit is used to mark special folder under
                # windows, not to mark that a folder is read-only.
                # See ticket #3587
                ErrorDialog(
                    _('Directory \'%s\' is not writable') % dirname,
                    _('You do not have permissions to create files '
                      'in this directory.'))
                return
            self._start_receive(file_path, account, contact, file_props)
Example #6
0
    def _send_single_message(self):
        if not app.account_is_connected(self.account):
            # if offline or connecting
            ErrorDialog(_('Connection not available'),
                        _('Please make sure you are connected with "%s".') %
                        self.account)
            return True
        if isinstance(self._to, list):
            sender_list = []
            for i in self._to:
                if i[0].resource:
                    sender_list.append(i[0].jid + '/' + i[0].resource)
                else:
                    sender_list.append(i[0].jid)
        else:
            sender_list = [j.strip() for j
                           in self._ui.to_entry.get_text().split(',')]

        subject = self._ui.subject_entry.get_text()
        begin, end = self._message_tv_buffer.get_bounds()
        message = self._message_tv_buffer.get_text(begin, end, True)

        recipient_list = []

        for to_whom_jid in sender_list:
            if to_whom_jid in self._completion_dict:
                to_whom_jid = self._completion_dict[to_whom_jid].jid
            try:
                to_whom_jid = helpers.parse_jid(to_whom_jid)
            except helpers.InvalidFormat:
                ErrorDialog(
                    _('Invalid XMPP Address'),
                    _('It is not possible to send a message to %s, this '
                      'XMPP Address is not valid.') % to_whom_jid)
                return True

            if '/announce/' in to_whom_jid:
                con = app.connections[self.account]
                con.get_module('Announce').set_announce(
                    to_whom_jid, subject, message)
                continue

            recipient_list.append(to_whom_jid)

        app.nec.push_outgoing_event(MessageOutgoingEvent(
            None,
            account=self.account,
            jid=recipient_list,
            message=message,
            type_='normal',
            subject=subject))

        self._ui.subject_entry.set_text('') # we sent ok, clear the subject
        self._message_tv_buffer.set_text('') # we sent ok, clear the textview
        return False
 def _before_sendmessage(chat_control):
     account = chat_control.account
     if not chat_control.contact.keyID:
         ErrorDialog(
             _('No OpenPGP key assigned'),
             _('No OpenPGP key is assigned to this contact. So you cannot '
               'encrypt messages with OpenPGP.'))
         chat_control.sendmessage = False
     elif not app.config.get_per('accounts', account, 'keyid'):
         ErrorDialog(
             _('No OpenPGP key assigned'),
             _('No OpenPGP key is assigned to your account. So you cannot '
               'encrypt messages with OpenPGP.'))
         chat_control.sendmessage = False
Example #8
0
 def _check_file(self, filename):
     filesize = os.path.getsize(filename)  # in bytes
     invalid_file = False
     msg = ''
     if os.path.isfile(filename):
         stat = os.stat(filename)
         if stat[6] == 0:
             invalid_file = True
             msg = _('File is empty')
     else:
         invalid_file = True
         msg = _('File does not exist')
     if filesize < 60000:
         file_ = open(filename, "rb")
         img = urllib.parse.quote(base64.standard_b64encode(
             file_.read()), '')
         if len(img) > 60000:
             invalid_file = True
             msg = _('File too big')
         file_.close()
     else:
         invalid_file = True
         msg = _('File too big')
     if invalid_file:
         ErrorDialog(_('Could not load image'), msg)
         return
     return img
Example #9
0
File: themes.py Project: bj-h/gajim
    def _on_remove_theme(self, *args):
        store, iter_ = self._theme_treeview.get_selection().get_selected()
        if iter_ is None:
            return

        theme = store[iter_][Column.THEME]
        if theme == app.config.get('roster_theme'):
            ErrorDialog(_('Active Theme'),
                        _('You tried to delete the currently active theme. '
                          'Please switch to a different theme first.'),
                        transient_for=self)
            return

        def _remove_theme():
            app.css_config.remove_theme(theme)
            store.remove(iter_)

            first = store.get_iter_first()
            if first is None:
                self._remove_theme_button.set_sensitive(False)
                self._add_option_button.set_sensitive(False)
                self._clear_options()

        NewConfirmationDialog(
            _('Delete'),
            _('Delete Theme'),
            _('Do you want to permanently delete this theme?'), [
                DialogButton.make('Cancel'),
                DialogButton.make('Delete', callback=_remove_theme)
            ],
            transient_for=self).show()
Example #10
0
 def on_ok_button_clicked(self, widget):
     if self.update_progressbar_timeout_id:
         # Operation in progress
         return
     if not app.account_is_connected(self.account):
         ErrorDialog(
             _('You are not connected to the server'),
             _('Without a connection, you can not publish your contact '
               'information.'),
             transient_for=self)
         return
     vcard_, sha = self.make_vcard()
     nick = vcard_.get('NICKNAME') or None
     app.connections[self.account].get_module('UserNickname').set_nickname(
         nick)
     if not nick:
         nick = app.config.get_per('accounts', self.account, 'name')
     app.nicks[self.account] = nick
     app.connections[self.account].get_module('VCardTemp').send_vcard(
         vcard_, sha)
     self.message_id = self.statusbar.push(self.context_id,
                                           _('Sending profile…'))
     self.progressbar.show()
     self.update_progressbar_timeout_id = GLib.timeout_add(
         100, self.update_progressbar)
Example #11
0
    def send_message(self, message, xhtml=None, process_commands=True,
                     attention=False):
        """
        Call this method to send the message
        """
        message = helpers.remove_invalid_xml_chars(message)
        if not message:
            return

        # We need to make sure that we can still send through the room and that
        # the recipient did not go away
        if self.gc_contact.presence.is_unavailable:
            ErrorDialog(
                _('Sending private message failed'),
                #in second %s code replaces with nickname
                _('You are no longer in group chat "%(room)s" or '
                  '"%(nick)s" has left.') % {
                      'room': self.room_name, 'nick': self.gc_contact.name},
                transient_for=self.parent_win.window)
            return

        ChatControl.send_message(self, message,
                                 xhtml=xhtml,
                                 process_commands=process_commands,
                                 attention=attention)
Example #12
0
    def __init__(self, account):
        # 'account' can be None if we are about to create our first one
        if not account or app.connections[account].connected < 2:
            ErrorDialog(
                _('You are not connected to the server'),
                _('Without a connection, you can not synchronise your contacts.'
                  ))
            raise GajimGeneralException('You are not connected to the server')
        self.account = account
        self.xml = get_builder('synchronise_select_account_dialog.ui')
        self.dialog = self.xml.get_object('synchronise_select_account_dialog')
        self.dialog.set_transient_for(app.get_app_window('AccountsWindow'))
        self.accounts_treeview = self.xml.get_object('accounts_treeview')
        model = Gtk.ListStore(str, str, bool)
        self.accounts_treeview.set_model(model)
        # columns
        renderer = Gtk.CellRendererText()
        self.accounts_treeview.insert_column_with_attributes(-1,
                                                             _('Name'),
                                                             renderer,
                                                             text=0)
        renderer = Gtk.CellRendererText()
        self.accounts_treeview.insert_column_with_attributes(-1,
                                                             _('Server'),
                                                             renderer,
                                                             text=1)

        self.xml.connect_signals(self)
        self.init_accounts()
        self.dialog.show_all()
Example #13
0
 def on_room_entry_changed(self, widget):
     if self.ignore_events:
         return
     (model, iter_) = self.selection.get_selected()
     if not iter_:
         return
     room = widget.get_text()
     if not room:
         return
     if '@' in room:
         room, server = room.split('@', 1)
         widget.set_text(room)
         if server:
             self._ui.server_entry.set_text(server)
         self._ui.server_entry.grab_focus()
     server = self._ui.server_entry.get_text().strip()
     if not server:
         return
     room_jid = room.strip() + '@' + server
     try:
         room_jid = helpers.parse_jid(room_jid)
     except helpers.InvalidFormat:
         ErrorDialog(
             _('Invalid Group Chat'),
             _('Character not allowed'),
             transient_for=self._ui.manage_bookmarks_window)
         return True
     model[iter_][Row.ROOM_JID] = room_jid
Example #14
0
    def on_add_button_clicked(self, widget):
        """
        When Subscribe button is clicked
        """
        jid = self.uid_entry.get_text().strip()
        if not jid:
            ErrorDialog(
                _('%s Missing') % self.uid_label.get_text(),
                _('You must supply the %s of the new contact.' %
                  self.uid_label.get_text()))
            return

        model = self.protocol_combobox.get_model()
        row = self.protocol_combobox.get_active_iter()
        type_ = model[row][2]
        if type_ != 'jabber':
            model = self.protocol_jid_combobox.get_model()
            row = self.protocol_jid_combobox.get_active()
            transport = model[row][0]
            if self.account and not self.jid_escaped:
                self.adding_jid = (jid, transport, type_)
                con = app.connections[self.account]
                con.get_module('Gateway').request_gateway_prompt(
                    transport, jid)
            else:
                jid = jid.replace('@', '%') + '@' + transport
                self._add_jid(jid, type_)
        else:
            self._add_jid(jid, type_)
Example #15
0
    def send_file(self, account, contact, file_path, file_desc=''):
        """
        Start the real transfer(upload) of the file
        """
        if gtkgui_helpers.file_is_locked(file_path):
            pritext = _('Gajim can not read this file')
            sextext = _('Another process is using this file.')
            ErrorDialog(pritext, sextext)
            return

        if isinstance(contact, str):
            if contact.find('/') == -1:
                return
            (jid, resource) = contact.split('/', 1)
            contact = app.contacts.create_contact(jid=jid, account=account,
                                                  resource=resource)
        file_name = os.path.split(file_path)[1]
        file_props = self.get_send_file_props(account, contact, file_path,
                                              file_name, file_desc)
        if file_props is None:
            return False

        app.connections[account].get_module('Jingle').start_file_transfer(
            contact.get_full_jid(), file_props)
        self.add_transfer(account, contact, file_props)

        return True
Example #16
0
    def __init__(self):
        log_db_path = configpaths.get('LOG_DB')
        if not os.path.exists(log_db_path):
            ErrorDialog(_('Cannot find history logs database'),
                        _('%s does not exist.') % log_db_path)
            sys.exit()

        self._ui = get_builder('history_manager.ui')
        Gtk.Window.set_default_icon_list(
            get_app_icon_list(self._ui.history_manager_window))

        self.jids_already_in = []  # holds jids that we already have in DB
        self.AT_LEAST_ONE_DELETION_DONE = False

        self.con = sqlite3.connect(log_db_path,
                                   timeout=20.0,
                                   isolation_level='IMMEDIATE')
        self.con.execute("PRAGMA secure_delete=1")
        self.cur = self.con.cursor()

        self._init_jids_listview()
        self._init_logs_listview()
        self._init_search_results_listview()

        self._fill_jids_listview()

        self._ui.search_entry.grab_focus()

        self._ui.history_manager_window.show_all()

        self._ui.connect_signals(self)
Example #17
0
    def on_calendar_month_changed(self, widget):
        """
        Ask for days in this month, if they have logs it bolds them
        (marks them)
        """
        if not self.jid:
            return
        year, month, _day = widget.get_date()  # integers
        if year < 1900:
            widget.select_month(0, 1900)
            widget.select_day(1)
            return

        widget.clear_marks()
        month = python_month(month)

        try:
            log_days = app.logger.get_days_with_logs(
                self.account, self.jid, year, month)
        except exceptions.PysqliteOperationalError as error:
            ErrorDialog(_('Disk Error'), str(error))
            return

        for date in log_days:
            widget.mark_day(date.day)
Example #18
0
 def on_ok(target_path):
     dirname = os.path.dirname(target_path)
     if not os.access(dirname, os.W_OK):
         ErrorDialog(_('Directory \'%s\' is not writable') % dirname,
                     _('You do not have the proper permissions to '
                       'create files in this directory.'),
                     transient_for=app.app.get_active_window())
         return
     shutil.copy(filepath, target_path)
Example #19
0
    def _items_received(self, result):
        if is_error_result(result):
            ErrorDialog('Error', to_user_string(result))
            return

        jid = result.jid.getBare()
        for item in result.items:
            if item.jid == jid and item.node is not None:
                self.treestore.append([item.node])
Example #20
0
 def show_stopped(self, jid, file_props, error_msg=''):
     if file_props.type_ == 'r':
         file_name = os.path.basename(file_props.file_name)
     else:
         file_name = file_props.name
     sectext = '\t' + _('Filename: %s') % GLib.markup_escape_text(file_name)
     sectext += '\n\t' + _('Recipient: %s') % jid
     if error_msg:
         sectext += '\n\t' + _('Error message: %s') % error_msg
     ErrorDialog(_('File transfer stopped'), sectext)
     self._ui.transfers_list.get_selection().unselect_all()
Example #21
0
    def _on_create_clicked(self, *args):
        if not app.account_is_connected(self._account):
            ErrorDialog(_('Not Connected'),
                        _('You have to be connected to create a group chat.'))
            return

        room_jid = self._ui.address_entry.get_text()

        self._set_processing_state(True)
        con = app.connections[self._account]
        con.get_module('Discovery').disco_info(
            room_jid, callback=self._disco_info_received)
Example #22
0
 def _on_send(self, *args):
     if not app.account_is_connected(self.account):
         # If offline or connecting
         ErrorDialog(
             _('Connection not available'),
             _('Please make sure you are connected with \'%s\'.') %
             self.account)
         return
     buffer_ = self._ui.input_entry.get_buffer()
     begin_iter, end_iter = buffer_.get_bounds()
     stanza = buffer_.get_text(begin_iter, end_iter, True)
     if stanza:
         try:
             node = nbxmpp.Protocol(node=stanza)
             if node.getNamespace() == UNDECLARED:
                 node.setNamespace(nbxmpp.NS_CLIENT)
         except Exception as error:
             ErrorDialog(_('Invalid Node'), str(error))
             return
         app.connections[self.account].connection.send(node)
         self.last_stanza = stanza
         buffer_.set_text('')
Example #23
0
    def _on_save_avatar(file_path):
        if os.path.exists(file_path):
            # Check if we have write permissions
            if not os.access(file_path, os.W_OK):
                file_name = os.path.basename(file_path)
                ErrorDialog(
                    _('Cannot overwrite existing file \'%s\'' % file_name),
                    _('A file with this name already exists and you do '
                      'not have permission to overwrite it.'))
                return

        app.config.set('last_save_dir', os.path.dirname(file_path))
        if isinstance(avatar, str):
            # We got a SHA
            pixbuf = app.interface.avatar_storage.pixbuf_from_filename(avatar)
        else:
            # We got a pixbuf
            pixbuf = avatar
        extension = os.path.splitext(file_path)[1]
        if not extension:
            # Silently save as Jpeg image
            image_format = 'png'
            file_path += '.png'
        else:
            image_format = extension[1:]  # remove leading dot

        # Save image
        try:
            pixbuf.savev(file_path, image_format, [], [])
        except Exception as error:
            log.error('Error saving avatar: %s', error)
            if os.path.exists(file_path):
                os.remove(file_path)
            new_file_path = '.'.join(file_path.split('.')[:-1]) + '.png'

            def _on_ok(file_path, pixbuf):
                pixbuf.savev(file_path, 'png', [], [])

            NewConfirmationDialog(
                _('Error While Saving'), _('Extension not supported'),
                _('Image cannot be saved in %(type)s format.\n'
                  'Save as %(new_filename)s?') % {
                      'type': image_format,
                      'new_filename': new_file_path
                  }, [
                      DialogButton.make('Cancel'),
                      DialogButton.make('OK',
                                        text=_('_Save'),
                                        callback=_on_ok,
                                        args=[new_file_path, pixbuf])
                  ]).show()
Example #24
0
 def on_BDAY_entry_focus_out_event(self, widget, event):
     txt = widget.get_text()
     if not txt:
         return
     try:
         time.strptime(txt, '%Y-%m-%d')
     except ValueError:
         if not widget.is_focus():
             pritext = _('Wrong date format')
             ErrorDialog(pritext,
                         _('Format of the date must be YYYY-MM-DD'),
                         transient_for=self)
             GLib.idle_add(widget.grab_focus)
         return True
Example #25
0
 def on_new_privacy_list_button_clicked(self, widget):
     name = self.new_privacy_list_entry.get_text()
     if not name:
         ErrorDialog(_('Invalid List Name'),
                     _('You must enter a name to create a privacy list.'),
                     transient_for=self.window)
         return
     key_name = 'privacy_list_%s' % name
     if key_name in app.interface.instances[self.account]:
         app.interface.instances[self.account][key_name].window.present()
     else:
         app.interface.instances[self.account][key_name] = \
             PrivacyListWindow(self.account, name, 'NEW')
     self.new_privacy_list_entry.set_text('')
Example #26
0
    def _before_sendmessage(chat_control):
        account = chat_control.account
        jid = chat_control.contact.jid

        con = app.connections[account]
        try:
            valid = con.get_module('PGPLegacy').has_valid_key_assigned(jid)
        except KeyMismatch as announced_key_id:
            ErrorDialog(
                _('PGP Key mismatch'),
                _('The contact\'s key (%s) <b>does not match</b> the key '
                  'assigned in Gajim.') % announced_key_id)
            chat_control.sendmessage = False
            return

        if not valid:
            ErrorDialog(_('No OpenPGP key assigned'),
                        _('No OpenPGP key is assigned to this contact.'))
            chat_control.sendmessage = False
        elif con.get_module('PGPLegacy').get_own_key_data() is None:
            ErrorDialog(_('No OpenPGP key assigned'),
                        _('No OpenPGP key is assigned to your account.'))
            chat_control.sendmessage = False
Example #27
0
File: themes.py Project: bj-h/gajim
    def _on_theme_name_edit(self, renderer, path, new_name):
        iter_ = self._theme_store.get_iter(path)
        old_name = self._theme_store[iter_][Column.THEME]

        if new_name == 'default':
            ErrorDialog(_('Invalid Name'),
                        _('Name <b>default</b> is not allowed'),
                        transient_for=self)
            return

        if ' ' in new_name:
            ErrorDialog(_('Invalid Name'),
                        _('Spaces are not allowed'),
                        transient_for=self)
            return

        if new_name == '':
            return

        result = app.css_config.rename_theme(old_name, new_name)
        if result is False:
            return

        self._theme_store.set_value(iter_, Column.THEME, new_name)
Example #28
0
    def _before_sendmessage(self, chat_control):
        account = chat_control.account
        jid = chat_control.contact.jid
        con = app.connections[account]

        if not con.get_module('OpenPGP').secret_key_available:
            from openpgp.gtk.wizard import KeyWizard
            KeyWizard(self, account, chat_control)
            return

        keys = con.get_module('OpenPGP').get_keys(jid)
        if not keys:
            ErrorDialog(_('Not Trusted'),
                        _('There was no trusted and active key found'))
            chat_control.sendmessage = False
Example #29
0
    def save_account(self, login, server, savepass, password, anonymous=False):
        if self.account in app.connections:
            ErrorDialog(
                _('Account name is in use'),
                _('You already have an account using this name.'))
            return
        con = connection.Connection(self.account)
        con.password = password

        config = self.get_config(login, server, savepass, password, anonymous)

        if not self.modify:
            con.new_account(self.account, config)
            return
        app.connections[self.account] = con
        self.create_vars(config)
Example #30
0
 def on_nick_entry_changed(self, widget):
     if self.ignore_events:
         return
     (model, iter_) = self.selection.get_selected()
     if iter_:
         nick = self._ui.nick_entry.get_text()
         try:
             nick = helpers.parse_resource(nick)
         except helpers.InvalidFormat:
             ErrorDialog(
                 _('Invalid nickname'),
                 _('Character not allowed'),
                 transient_for=self._ui.manage_bookmarks_window)
             self._ui.nick_entry.set_text(model[iter_][Row.NICK])
             return True
         model[iter_][Row.NICK] = nick