コード例 #1
0
 def init(self):
     self.description = _('Install and upgrade plugins for Gajim')
     self.config_dialog = PluginInstallerPluginConfigDialog(self)
     self.config_default_values = {
         'check_update': (True, ''),
         'auto_update': (False, ''),
         'auto_update_feedback': (True, '')
     }
     self.gui_extension_points = {'plugin_window': (self.on_activate, None)}
     self.window = None
     self.spinner = None
     self.available_plugins_model = None
     self.timeout_id = 0
     self.connected_ids = {}
コード例 #2
0
    def init(self):
        self.description = _(
            'Flashing keyboard led when there are unread messages.')
        self.config_dialog = FlashingKeyboardPluginConfigDialog(self)
        self.config_default_values = {
            'command1': ("xset led named 'Scroll Lock'", ''),
            'command2': ("xset -led named 'Scroll Lock'", ''),
            'flash': (True, ''),
        }

        self.is_active = None
        self.timeout = 500
        self.timeout_off = int(self.timeout / 2)
        self.id_0 = None
コード例 #3
0
    def _download_image(self, account, attributes, encrypted):
        filepath = attributes['filepaths'][0]
        thumbpath = attributes['filepaths'][1]
        key = attributes['key']
        iv = attributes['iv']
        mem, alt = get_http_file(account, attributes)

        # Decrypt file if necessary
        if encrypted:
            mem = self._aes_decrypt_fast(key, iv, mem)

        try:
            # Write file to harddisk
            self._write_file(filepath, mem)
        except Exception as e:
            GLib.idle_add(
                self._raise_error_dialog, _('Could not save file'),
                _('Exception raised while saving image file'
                  ' (see error log for more information)'))
            log.error(str(e))

        # Create thumbnail, write to disk and return it
        return self._save_thumbnail(thumbpath, mem)
コード例 #4
0
 def init(self):
     self.description = _('Allows you to adjust the height'
                          ' of the new message input field.')
     self.config_dialog = MsgBoxSizePluginConfigDialog(self)
     self.gui_extension_points = {
         'chat_control_base':
         (self.connect_with_chat_control, self.disconnect_from_chat_control)
     }
     self.config_default_values = {
         'Do_not_resize': (False, ''),
         'Minimum_lines': (2, ''),
     }
     self.chat_control = None
     self.controls = []
コード例 #5
0
ファイル: wizard.py プロジェクト: dreamsxin/gajim-plugins
class WelcomePage(Gtk.Box):

    type_ = Gtk.AssistantPageType.INTRO
    title = _('Welcome')
    complete = True

    def __init__(self):
        super().__init__(orientation=Gtk.Orientation.VERTICAL)
        self.set_spacing(18)
        title_label = Gtk.Label(label=_('Setup OpenPGP'))
        text_label = Gtk.Label(
            label=_('Gajim will now try to setup OpenPGP for you'))
        self.add(title_label)
        self.add(text_label)
コード例 #6
0
    def on_preset_button_clicked(self, widget):
        def on_ok(preset_name):
            if preset_name == '':
                return
            preset = {}
            for name in self.plugin.config_default_values:
                if name == 'presets':
                    continue
                widget = self.xml.get_object(name)
                preset[name] = widget.get_text()
            preset = {preset_name: preset}
            presets = dict(list(self.plugin.config['presets'].items()) + \
                list(preset.items()))
            if preset_name not in list(self.plugin.config['presets'].keys()):
                iter_ = self.preset_liststore.append((preset_name, ))
            self.plugin.config['presets'] = presets

        self.set_modal(False)
        InputDialog(_('Save as Preset'),
                    _('Please type a name for this preset'),
                    'default',
                    is_modal=True,
                    ok_handler=on_ok)
コード例 #7
0
        def _try_install(zip_filename):
            try:
                plugin = app.plugin_manager.install_from_zip(zip_filename)
            except PluginsystemError as er_type:
                error_text = str(er_type)
                if error_text == _('Plugin already exists'):
                    _on_plugin_exists(zip_filename)
                    return

                WarningDialog(error_text, '"%s"' % zip_filename, self)
                return
            if not plugin:
                _show_warn_dialog()
                return
コード例 #8
0
ファイル: wizard.py プロジェクト: dreamsxin/gajim-plugins
    def __init__(self):
        super().__init__(orientation=Gtk.Orientation.VERTICAL)
        self.set_spacing(12)
        self.set_homogeneous(True)

        icon = Gtk.Image.new_from_icon_name('object-select-symbolic',
                                            Gtk.IconSize.DIALOG)
        icon.get_style_context().add_class('success-color')
        icon.set_valign(Gtk.Align.END)
        label = Gtk.Label(label=_('Setup successful'))
        label.get_style_context().add_class('bold16')
        label.set_valign(Gtk.Align.START)

        self.add(icon)
        self.add(label)
コード例 #9
0
ファイル: gui.py プロジェクト: bj-h/gajim
    def installed_plugins_toggled_cb(self, cell, path):
        is_active = self.installed_plugins_model[path][Column.ACTIVE]
        plugin = self.installed_plugins_model[path][Column.PLUGIN]

        if is_active:
            app.plugin_manager.deactivate_plugin(plugin)
        else:
            try:
                app.plugin_manager.activate_plugin(plugin)
            except GajimPluginActivateException as e:
                WarningDialog(_('Plugin failed'),
                              str(e),
                              transient_for=self.window)
                return

        self.installed_plugins_model[path][Column.ACTIVE] = not is_active
コード例 #10
0
ファイル: config.py プロジェクト: dreamsxin/gajim-plugins
    def __init__(self, plugin, account):
        Gtk.Box.__init__(self, orientation=Gtk.Orientation.VERTICAL)

        self._con = app.connections[account]
        self._plugin = plugin
        self._label = Gtk.Label()
        self._button = Gtk.Button(label=_('Assign Key'))
        self._button.get_style_context().add_class('suggested-action')
        self._button.set_halign(Gtk.Align.CENTER)
        self._button.set_margin_top(18)
        self._button.connect('clicked', self._on_assign)

        self._load_key()
        self.add(self._label)
        self.add(self._button)
        self.show_all()
コード例 #11
0
 def _on_not_trusted(event):
     NewConfirmationCheckDialog(
         _('Untrusted PGP key'), _('Untrusted PGP key'),
         _('The PGP key used to encrypt this chat is not '
           'trusted. Do you really want to encrypt this '
           'message?'), _('_Do not ask me again'), [
               DialogButton.make(
                   'Cancel', text=_('_No'), callback=event.on_no),
               DialogButton.make(
                   'OK', text=_('_Encrypt Anyway'), callback=event.on_yes)
           ]).show()
コード例 #12
0
ファイル: clients.py プロジェクト: dreamsxin/gajim-plugins
    def get_client_data(self, name, node):
        client_data = self.get(node)
        if client_data is None:
            return _('Unknown'), 'xmpp-client-unknown'

        if client_data.variations is None:
            client_name, icon_name = client_data.default
            return client_name, 'xmpp-client-%s' % icon_name

        variations = get_variations(name)
        for var in variations:
            try:
                return var, 'xmpp-client-%s' % client_data.variations[var]
            except KeyError:
                pass
        client_name, icon_name = client_data.default
        return client_name, 'xmpp-client-%s' % icon_name
コード例 #13
0
    def __init__(self, iter_start, iter_end, buffer_, widget, png_dpi):
        Thread.__init__(self)

        self.code = iter_start.get_text(iter_end)
        self.mark_name = 'LatexRendererMark%s' % str(random.randint(0, 1000))
        self.mark = buffer_.create_mark(self.mark_name, iter_start, True)

        self.buffer_ = buffer_
        self.widget = widget
        self.png_dpi = png_dpi

        # delete code and show message 'processing'
        self.buffer_.delete(iter_start, iter_end)
        # iter_start.forward_char()
        self.buffer_.insert(iter_start, _('Processing LaTeX'))

        self.start()  # start background processing
コード例 #14
0
    def _installed_plugin_toggled(self, _cell, path):
        is_active = self.installed_plugins_model[path][Column.ACTIVE]
        plugin = self.installed_plugins_model[path][Column.PLUGIN]

        if is_active:
            app.plugin_manager.deactivate_plugin(plugin)
        else:
            try:
                app.plugin_manager.activate_plugin(plugin)
            except GajimPluginActivateException as e:
                WarningDialog(_('Plugin failed'), str(e),
                              transient_for=self)
                return

        self._ui.configure_plugin_button.set_sensitive(
            plugin.config_dialog is not None and not is_active)
        self.installed_plugins_model[path][Column.ACTIVE] = not is_active
コード例 #15
0
    def do_draw(self, widget, cr):
        cr.set_source_rgb(1.0, 1.0, 1.0)

        layout = PangoCairo.create_layout(cr)
        text_height = layout.get_pixel_extents()[1].height

        (width, height) = self.win.get_size()

        row_height = (height - text_height) // self.rows
        col_width = width // self.cols

        cr.set_source_rgb(0, 0, 0)
        cr.set_line_width(2)
        for x in range(1, self.cols):
            cr.move_to(col_width * x, 0)
            cr.line_to(col_width * x, height - text_height)
        for x in range(1, self.rows):
            cr.move_to(0, row_height * x)
            cr.line_to(width, row_height * x)
        cr.stroke()

        cr.move_to(0, height - text_height)
        if self.state == 'None':
            if self.session.is_my_turn():
                txt = _('It\'s your turn')
            else:
                txt = _('It\'s %(name)s\'s turn') % {'name': self.session.name}
        elif self.state == 'won':
            txt = _('You won !')
        elif self.state == 'lost':
            txt = _('You lost !')
        elif self.state == 'resign':  # Other part resigned
            txt = _('%(name)s capitulated') % {'name': self.session.name}
        elif self.state == 'cheated':  # Other part cheated
            txt = _('%(name)s cheated') % {'name': self.session.name}
        else:  # Draw
            txt = _('It\'s a draw')
        layout.set_text(txt, -1)
        # Inform Pango to re-layout the text with the new transformation
        PangoCairo.update_layout(cr, layout)
        PangoCairo.show_layout(cr, layout)

        for i in range(self.rows):
            for j in range(self.cols):
                if self.board[i][j] == 'x':
                    self.draw_x(cr, i, j, row_height, col_width)
                elif self.board[i][j] == 'o':
                    self.draw_o(cr, i, j, row_height, col_width)
コード例 #16
0
 def stop_whiteboard(self, reason=None):
     conn = app.connections[self.chat_control.account]
     self.sid = None
     session = conn.get_module('Jingle').get_jingle_session(self.jid,
                                                            media='xhtml')
     if session:
         session.end_session()
     self.enable_action(False)
     if reason:
         txt = _('Whiteboard stopped: %(reason)s') % {'reason': reason}
         self.chat_control.add_status_message(txt)
     if not self.whiteboard:
         return
     hbox = self.chat_control.xml.get_object('chat_control_hbox')
     if self.whiteboard.hbox in hbox.get_children():
         if hasattr(self.whiteboard, 'hbox'):
             hbox.remove(self.whiteboard.hbox)
             self.whiteboard = None
コード例 #17
0
    def init(self):
        self.description = _('Clickable nicknames '
                             'in the conversation textview.')
        self.config_dialog = None
        self.gui_extension_points = {
            'chat_control_base':
            (self.connect_with_chat_control, self.disconnect_from_chat_control)
        }

        self.is_active = None
        self.gc_controls = {}

        self.tag_names = []
        colors = app.config.get('gc_nicknames_colors')
        colors = colors.split(':')
        for i, color in enumerate(colors):
            tagname = 'gc_nickname_color_' + str(i)
            self.tag_names.append(tagname)
コード例 #18
0
ファイル: plugin.py プロジェクト: dreamsxin/gajim-plugins
    def create_button(self):

        actions_hbox = self.chat_control.xml.get_object('hbox')
        self.button = Gtk.MenuButton(label=None, stock=None, use_underline=True)
        self.button.get_style_context().add_class(
            'chatcontrol-actionbar-button')
        self.button.set_property('relief', Gtk.ReliefStyle.NONE)
        self.button.set_property('can-focus', False)
        img = Gtk.Image()
        img_path = self.plugin.local_file_path('quick_replies.png')
        pixbuf = GdkPixbuf.Pixbuf.new_from_file(img_path)
        img.set_from_pixbuf(pixbuf)
        self.button.set_image(img)
        self.button.set_tooltip_text(_('Quick replies'))
        actions_hbox.pack_start(self.button, False, False , 0)
        actions_hbox.reorder_child(self.button,
            len(actions_hbox.get_children()) - 2)
        self.button.show()
コード例 #19
0
    def on_test_button_clicked(self, widget):
        """
        performs very simple checks (check if executable is in PATH)
        """
        self.show_result(_('Test Latex Binary'))
        exitcode = try_run(['latex', '-version'], None)
        if exitcode != 0:
            self.show_result(_('  No LaTeX binary found in PATH'))
        else:
            self.show_result(_('  OK'))

        self.show_result(_('Test dvipng'))
        exitcode = try_run(['dvipng', '--version'], None)
        if exitcode != 0:
            self.show_result(_('  No dvipng binary found in PATH'))
        else:
            self.show_result(_('  OK'))

        self.show_result(_('Test ImageMagick'))
        exitcode = try_run(['convert', '-version'], None)
        if exitcode != 0:
            self.show_result(_('  No convert binary found in PATH'))
        else:
            self.show_result(_('  OK'))
コード例 #20
0
    def init(self):
        self.description = _('Allows to block some kind of incoming messages')
        self.config_dialog = AntiSpamPluginConfigDialog(self)

        self.gui_extension_points = {}

        self.events_handlers = {
            'atom-entry-received':
            (ged.POSTCORE, self._nec_atom_entry_received),
            'message-received':
            (ged.PRECORE, self._nec_message_received_received),
            'decrypted-message-received':
            (ged.PRECORE, self._nec_decrypted_message_received_received),
            'subscribe-presence-received':
            (ged.POSTCORE, self._nec_subscribe_presence_received),
            'message-outgoing': (ged.OUT_PRECORE, self._nec_message_outgoing)
        }

        self.config_default_values = {
            'block_pubsub_messages':
            (False,
             'If True, Gajim will block incoming messages from pubsub.'),
            'disable_xhtml_muc': (False, ''),
            'disable_xhtml_pm': (False, ''),
            'block_subscription_requests': (False, ''),
            'msgtxt_limit': (-1, ''),
            'msgtxt_question': ('Please answer: 12 x 12 =', ''),
            'msgtxt_answer': ('', ''),
            'antispam_for_conference': (False, ''),
            'conference_white_list': ([], ''),  # conference private chat jid's
            'block_domains':
            ('', ''),  # comma separated list of domain names to block
        }

        # List of outgoing jid's
        # Needs to avoid chat of two anti spam plugins
        # Contain all jid's where are you initiate a chat
        self.outgoing_jids = []

        self.block_domains = [
            h.strip() for h in self.config['block_domains'].split(",")
            if len(h.strip())
        ]
コード例 #21
0
    def install_from_zip(self, zip_filename, owerwrite=None):
        '''
        Install plugin from zip and return plugin
        '''
        try:
            zip_file = zipfile.ZipFile(zip_filename)
        except zipfile.BadZipfile:
            # it is not zip file
            raise PluginsystemError(_('Archive corrupted'))
        except IOError:
            raise PluginsystemError(_('Archive empty'))

        if zip_file.testzip():
            # CRC error
            raise PluginsystemError(_('Archive corrupted'))

        dirs = []
        manifest = None
        for filename in zip_file.namelist():
            if filename.startswith('.') or filename.startswith('/') or \
            ('/' not in filename):
                # members not safe
                raise PluginsystemError(_('Archive is malformed'))
            if filename.endswith('/') and filename.find('/', 0, -1) < 0:
                dirs.append(filename.strip('/'))
            if 'manifest.ini' in filename.split('/')[1]:
                manifest = True
        if not manifest:
            return
        if len(dirs) > 1:
            raise PluginsystemError(_('Archive is malformed'))

        user_dir = configpaths.get('PLUGINS_USER')
        plugin_dir = os.path.join(user_dir, dirs[0])

        if os.path.isdir(plugin_dir):
            # Plugin dir already exists
            if not owerwrite:
                raise PluginsystemError(_('Plugin already exists'))
            self.uninstall_plugin(self.get_plugin_by_path(plugin_dir))

        zip_file.extractall(user_dir)
        zip_file.close()

        plugins = self.scan_dir_for_plugins(plugin_dir, package=True)
        if not plugins:
            return
        self.add_plugin(plugins[0])
        plugin = self.plugins[-1]
        return plugin
コード例 #22
0
 def init(self):
     self.description = _('Allows user to tweak roster window appearance '
                          '(eg. make it compact).')
     self.config_default_values = {
         'hide_status_combo': (False, ''),
         'use_ctr_m': (False, ''),
         'menu_visible': (True, ''),
         'quick_status': (False, ''),
         'contact_status_subs': (False, ''),
     }
     self.events_handlers = {
         'our-show': (ged.GUI2, self.our_show),
         'pep-received': (ged.GUI2, self.pep_received)
     }
     self.gui_extension_points = {
         'roster_draw_contact':
         (self.roster_draw_contact, self.disconnect_roster_draw_contact),
     }
     self.roster = app.interface.roster
     self.config_dialog = RosterTweaksPluginConfigDialog(self)
コード例 #23
0
    def send_question(self, obj, jid):
        if obj.mtype != 'chat' and obj.mtype != 'normal':
            log.info('Anti_spam wrong message type: %s', obj.mtype)
            return

        question = self.config['msgtxt_question']
        log.info('Anti_spam enabled for %s, question: %s', jid, question)
        message = _('Antispam enabled. Please answer the question. The message must only ' + \
                    'contain the answer. (Messages sent before the correct answer, will be lost): ') \
                    + question

        if obj.mtype == 'chat':
            stanza = nbxmpp.Message(to=jid, body=message, typ=obj.mtype)
        else:  # for 'normal' type
            stanza = nbxmpp.Message(to=jid,
                                    body=message,
                                    subject='Antispam enabled',
                                    typ=obj.mtype)

        app.connections[obj.conn.name].connection.send(stanza)
コード例 #24
0
ファイル: gui.py プロジェクト: bj-h/gajim
        def _try_install(zip_filename):
            try:
                plugin = app.plugin_manager.install_from_zip(zip_filename)
            except PluginsystemError as er_type:
                error_text = str(er_type)
                if error_text == _('Plugin already exists'):
                    _on_plugin_exists(zip_filename)
                    return

                WarningDialog(error_text, '"%s"' % zip_filename, self.window)
                return
            if not plugin:
                show_warn_dialog()
                return
            model = self.installed_plugins_model
            iter_ = model.append([
                plugin, plugin.name, False, plugin.activatable,
                self.get_plugin_icon(plugin)
            ])
            sel = self.installed_plugins_treeview.get_selection()
            sel.select_iter(iter_)
コード例 #25
0
ファイル: gui_for_me.py プロジェクト: dreamsxin/gajim-plugins
 def create_buttons(self):
     # create /me button
     actions_hbox = self.chat_control.xml.get_object('hbox')
     self.button = Gtk.Button(label=None, stock=None, use_underline=False)
     self.button.get_style_context().add_class(
         'chatcontrol-actionbar-button')
     self.button.set_relief(Gtk.ReliefStyle.NONE)
     self.button.set_property('can-focus', False)
     img = Gtk.Image()
     img_path = self.plugin.local_file_path('gui_for_me.png')
     pixbuf = GdkPixbuf.Pixbuf.new_from_file(img_path)
     img.set_from_pixbuf(pixbuf)
     self.button.set_image(img)
     self.button.set_tooltip_text(_('Insert /me to conversation input box,'
         ' at cursor position'))
     actions_hbox.pack_start(self.button, False, False , 0)
     actions_hbox.reorder_child(self.button,
         len(actions_hbox.get_children()) - 3)
     id_ = self.button.connect('clicked', self.on_me_button_clicked)
     self.chat_control.handlers[id_] = self.button
     self.button.show()
コード例 #26
0
    def init(self):
        self.description = _('PGP encryption as per XEP-0027')
        if ERROR_MSG:
            self.activatable = False
            self.available_text = ERROR_MSG
            return
        self.config_dialog = None
        self.encryption_name = 'PGP'
        self.allow_zeroconf = True
        self.gui_extension_points = {
            'encrypt' + self.encryption_name: (self._encrypt_message, None),
            'decrypt': (self._message_received, None),
            'send_message' + self.encryption_name: (
                self._before_sendmessage, None),
            'encryption_dialog' + self.encryption_name: (
                self.on_encryption_button_clicked, None),
            'encryption_state' + self.encryption_name: (
                self.encryption_state, None)}

        self.decrypt_queue = queue.Queue()
        self.thread = None
コード例 #27
0
    def _display_installed_plugin_info(self, plugin):
        self._ui.plugin_name_label.set_text(plugin.name)
        self._ui.plugin_version_label.set_text(plugin.version)
        self._ui.plugin_authors_label.set_text(plugin.authors)
        markup = '<a href="%s">%s</a>' % (plugin.homepage, plugin.homepage)
        self._ui.plugin_homepage_linkbutton.set_markup(markup)

        if plugin.available_text:
            text = _('Warning: %s') % plugin.available_text
            self._ui.available_text_label.set_text(text)
            self._ui.available_text.show()
            # Workaround for https://bugzilla.gnome.org/show_bug.cgi?id=710888
            self._ui.available_text.queue_resize()
        else:
            self._ui.available_text.hide()

        self._ui.description.set_text(plugin.description)

        self._ui.uninstall_plugin_button.set_sensitive(True)
        self._ui.configure_plugin_button.set_sensitive(
            plugin.config_dialog is not None and plugin.active)
コード例 #28
0
def check_state(key_id, account):
    error = None
    if key_id.endswith('MISMATCH'):
        verification_status = _('''Contact's identity NOT verified''')
        info = _('The contact\'s key (%s) <b>does not match</b> the key '
                 'assigned in Gajim.') % key_id[:8]
    elif not key_id:
        # No key assigned nor a key is used by remote contact
        verification_status = _('No OpenPGP key assigned')
        info = _('No OpenPGP key is assigned to this contact. So you cannot'
                 ' encrypt messages.')
    else:
        error = app.connections[account].gpg.encrypt('test', [key_id])[1]
        if error:
            verification_status = _('''Contact's identity NOT verified''')
            info = _('OpenPGP key is assigned to this contact, but <b>you '
                     'do not trust their key</b>, so message <b>cannot</b> be '
                     'encrypted. Use your OpenPGP client to trust their key.')
        else:
            verification_status = _('''Contact's identity verified''')
            info = _('OpenPGP Key is assigned to this contact, and you '
                     'trust their key, so messages will be encrypted.')
    return (verification_status, info)
コード例 #29
0
    def init(self):
        self.description = _('Highlights message entry field in chat window '
                             'when given length of message is exceeded.')
        self.config_dialog = LengthNotifierPluginConfigDialog(self)

        self.gui_extension_points = {
            'chat_control':
            (self.connect_with_chat_control, self.disconnect_from_chat_control)
        }

        self.config_default_values = {
            'MESSAGE_WARNING_LENGTH':
            (140, 'Message length at which notification is invoked.'),
            'WARNING_COLOR':
            ('#F0DB3E',
             'Background color of text entry field in chat window when notification is invoked.'
             ),
            'JIDS':
            ([],
             'JabberIDs that plugin should be used with (eg. restrict only to one microblogging bot). If empty plugin is used with every JID. [not implemented]'
             )
        }
コード例 #30
0
ファイル: plugin.py プロジェクト: dreamsxin/gajim-plugins
 def init(self):
     self.description = _('Clickable Juick links , Juick nicks, '
         'preview Juick picturs.\nThe key combination alt + up in the '
         'textbox allow insert the number of last message '
         '(comment or topic).')
     self.config_dialog = JuickPluginConfigDialog(self)
     self.gui_extension_points = {
             'chat_control_base': (self.connect_with_chat_control,
                                    self.disconnect_from_chat_control),
             'print_special_text': (self.print_special_text,
                                    self.print_special_text1),}
     self.config_default_values = {'SHOW_AVATARS': (False, ''),
                 'AVATAR_SIZE': (20, 'Avatar size(10-32)'),
                 'avatars_old': (2419200, 'Update avatars '
                     'who are older 28 days'),
                 'SHOW_PREVIEW': (False, ''),
                 'PREVIEW_SIZE': (150, 'Preview size(10-512)'),
                 'LINK_COLOR': ('#B8833E', 'Juick link color'),
                 'SHOW_TAG_BUTTON': (True, ''),
                 'ONLY_AUTHOR_AVATAR': (True, ''),
                 'ONLY_FIRST_AVATAR': (False, ''),
                 'MENUITEM1': ('tune', ''), 'MENUITEM_TEXT1': ('*tune', ''),
                 'MENUITEM2': ('geo', ''), 'MENUITEM_TEXT2': ('*geo', ''),
                 'MENUITEM3': ('gajim', ''),
                 'MENUITEM_TEXT3': ('*gajim', ''),
                 'MENUITEM4': ('me', ''), 'MENUITEM_TEXT4': ('/me', ''),
                 'MENUITEM5': ('', ''), 'MENUITEM_TEXT5': ('', ''),
                 'MENUITEM6': ('', ''), 'MENUITEM_TEXT6': ('', ''),
                 'MENUITEM7': ('', ''), 'MENUITEM_TEXT7': ('', ''),
                 'MENUITEM8': ('', ''), 'MENUITEM_TEXT8': ('', ''),
                 'MENUITEM9': ('', ''), 'MENUITEM_TEXT9': ('', ''),
                 'MENUITEM10': ('', ''), 'MENUITEM_TEXT10': ('', ''), }
     self.chat_control = None
     self.controls = []
     self.conn = None
     self.cache_path = os.path.join(configpaths.get('AVATAR'), 'juick')
     if not os.path.isdir(self.cache_path):
         os.makedirs(self.cache_path)