Newer
Older
## Copyright (C) 2003-2006 Yann Le Boulanger <asterix@lagaule.org>
## Copyright (C) 2005-2006 Nikos Kouremenos <kourem@gmail.com>
## Copyright (C) 2004-2005 Vincent Hanquez <tab@snarc.org>
## Copyright (C) 2005 Dimitur Kirov <dkirov@gmail.com>
## Copyright (C) 2005 Travis Shirk <travis@pobox.com>
## Copyright (C) 2005 Norman Rasmussen <norman@rasmussen.co.za>
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published
## by the Free Software Foundation; version 2 only.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
import sre
import i18n

Yann Leboulanger
committed
# If OPT_RESTART is True - we need restart to use our changed option
# OPT_DESC also should be there
opt_int = [ 'integer', 0 ]
opt_str = [ 'string', 0 ]
opt_bool = [ 'boolean', 0 ]
opt_color = [ 'color', '^(#[0-9a-fA-F]{6})|()$' ]
opt_one_window_types = ['never', 'always', 'peracct', 'pertype']

Yann Leboulanger
committed
'verbose': [ opt_bool, False, '', True ],

Yann Leboulanger
committed
'alwaysauth': [ opt_bool, False ],
'autopopup': [ opt_bool, False ],
'notify_on_signin': [ opt_bool, True ],
'notify_on_signout': [ opt_bool, False ],
'notify_on_new_message': [ opt_bool, True ],

Yann Leboulanger
committed
'autopopupaway': [ opt_bool, False ],
'use_notif_daemon': [ opt_bool, True , _('Use DBus and Notification-Daemon to show notifications') ],

Yann Leboulanger
committed
'ignore_unknown_contacts': [ opt_bool, False ],

Yann Leboulanger
committed
'showoffline': [ opt_bool, False, '', True ],

Yann Leboulanger
committed
'autoaway': [ opt_bool, True ],
'autoawaytime': [ opt_int, 5, _('Time in minutes, after which your status changes to away.') ],
'autoaway_message': [ opt_str, _('Away as a result of being idle') ],

Yann Leboulanger
committed
'autoxa': [ opt_bool, True ],
'autoxatime': [ opt_int, 15, _('Time in minutes, after which your status changes to not available.') ],
'autoxa_message': [ opt_str, _('Not available as a result of being idle') ],

Yann Leboulanger
committed
'ask_online_status': [ opt_bool, False ],
'ask_offline_status': [ opt_bool, False ],
'last_status_msg_online': [ opt_str, '' ],
'last_status_msg_chat': [ opt_str, '' ],
'last_status_msg_away': [ opt_str, '' ],
'last_status_msg_xa': [ opt_str, '' ],
'last_status_msg_dnd': [ opt_str, '' ],
'last_status_msg_invisible': [ opt_str, '' ],
'last_status_msg_offline': [ opt_str, '' ],

Yann Leboulanger
committed
'trayicon': [ opt_bool, True, '', True ],
'iconset': [ opt_str, 'dcraven', '', True ],
'use_transports_iconsets': [ opt_bool, True, '', True ],
'inmsgcolor': [ opt_color, '#a34526', '', True ],
'outmsgcolor': [ opt_color, '#164e6f', '', True ],
'statusmsgcolor': [ opt_color, '#1eaa1e', '', True ],
'markedmsgcolor': [ opt_color, '#ff8080', '', True ],
'urlmsgcolor': [ opt_color, '#0000ff', '', True ],
'collapsed_rows': [ opt_str, '', '', True ],
'roster_theme': [ opt_str, 'gtk+', '', True ],

Yann Leboulanger
committed
'saveposition': [ opt_bool, True ],

Yann Leboulanger
committed
'mergeaccounts': [ opt_bool, False, '', True ],
'sort_by_show': [ opt_bool, True, '', True ],
'use_speller': [ opt_bool, False, ],
'emoticons_theme': [opt_str, 'static', '', True ],

Yann Leboulanger
committed
_('Treat * / _ pairs as possible formatting characters.'), True],
'show_ascii_formatting_chars': [ opt_bool, False , _('If True, do not '
'remove */_ . So *abc* will be bold but with * * not removed.')],

Yann Leboulanger
committed
'sounds_on': [ opt_bool, True ],
# 'aplay', 'play', 'esdplay', 'artsplay' detected first time only
'soundplayer': [ opt_str, '' ],
'openwith': [ opt_str, 'gnome-open' ],
'custombrowser': [ opt_str, 'firefox' ],
'custommailapp': [ opt_str, 'mozilla-thunderbird -compose' ],
'custom_file_manager': [ opt_str, 'xffm' ],

nkour
committed
'gc_refer_to_nick_char': [opt_str, ','],
'gc_proposed_nick_char': [opt_str, '_'],
'msgwin-x-position': [opt_int, -1], # Default is to let the window manager decide
'msgwin-y-position': [opt_int, -1], # Default is to let the window manager decide
'msgwin-width': [opt_int, 480],
'msgwin-height': [opt_int, 440],
'chat-msgwin-x-position': [opt_int, -1], # Default is to let the window manager decide
'chat-msgwin-y-position': [opt_int, -1], # Default is to let the window manager decide
'chat-msgwin-width': [opt_int, 480],
'chat-msgwin-height': [opt_int, 440],
'gc-msgwin-x-position': [opt_int, -1], # Default is to let the window manager decide
'gc-msgwin-y-position': [opt_int, -1], # Default is to let the window manager decide
'gc-msgwin-width': [opt_int, 480],
'gc-msgwin-height': [opt_int, 440],
'single-msg-x-position': [opt_int, 0],
'single-msg-y-position': [opt_int, 0],
'single-msg-width': [opt_int, 400],
'single-msg-height': [opt_int, 280],
'roster_x-position': [ opt_int, 0 ],
'roster_y-position': [ opt_int, 0 ],
'roster_width': [ opt_int, 150 ],
'roster_height': [ opt_int, 400 ],
'latest_disco_addresses': [ opt_str, '' ],
'recently_groupchat': [ opt_str, '' ],
'before_time': [ opt_str, '[' ],
'after_time': [ opt_str, ']' ],
'before_nickname': [ opt_str, '' ],
'after_nickname': [ opt_str, ':' ],
'send_os_info': [ opt_bool, True ],
'notify_on_new_gmail_email': [ opt_bool, True ],

Yann Leboulanger
committed
'usegpg': [ opt_bool, False, '', True ],
'use_gpg_agent': [ opt_bool, False ],
'change_roster_title': [ opt_bool, True, _('Add * and [n] in roster title?')],
'restore_lines': [opt_int, 4, _('How many lines to remember from previous conversation when a chat tab/window is reopened.')],
'restore_timeout': [opt_int, 60, _('How many minutes should last lines from previous conversation last.')],
'send_on_ctrl_enter': [opt_bool, False, _('Send message on Ctrl+Enter and with Enter make new line (Mirabilis ICQ Client default behaviour).')],
'key_up_lines': [opt_int, 25, _('How many lines to store for Ctrl+KeyUP.')],
'always_compact_view_chat': [opt_bool, False, _('Use compact view when you open a chat window')],
'always_compact_view_gc': [opt_bool, False, _('Use compact view when you open a group chat window')],
'search_engine': [opt_str, 'http://www.google.com/search?&q=%s&sourceid=gajim'],
'dictionary_url': [opt_str, 'WIKTIONARY', _("Either custom url with %s in it where %s is the word/phrase or 'WIKTIONARY' which means use wiktionary.")],
'always_english_wikipedia': [opt_bool, False],
'always_english_wiktionary': [opt_bool, True],

Yann Leboulanger
committed
'remote_control': [opt_bool, True, _('If checked, Gajim can be controlled remotely using gajim-remote.'), True],
'chat_state_notifications': [opt_str, 'all'], # 'all', 'composing_only', 'disabled'

Yann Leboulanger
committed
'autodetect_browser_mailer': [opt_bool, False, '', True],
'print_ichat_every_foo_minutes': [opt_int, 5],
'confirm_close_muc': [opt_bool, True, _('Ask before closing a group chat tab/window.')],
'confirm_close_muc_rooms': [opt_str, '', _('Always ask before closing group chat tab/window in this space separated list of room jids.')],
'noconfirm_close_muc_rooms': [opt_str, '', _('Never ask before closing group chat tab/window in this space separated list of room jids.')],

Yann Leboulanger
committed
'notify_on_file_complete': [opt_bool, True],
'file_transfers_port': [opt_int, 28011],
'ft_override_host_to_send': [opt_str, '', _('Overrides the host we send for File Transfer in case of address translation/port forwarding.')],
'use_kib_mib': [opt_bool, False, _('IEC standard says KiB = 1024 bytes, KB = 1000 bytes.')],
'notify_on_all_muc_messages': [opt_bool, False],
'trayicon_notification_on_new_messages': [opt_bool, True],
'last_save_dir': [opt_str, ''],
'last_send_dir': [opt_str, ''],
'last_emoticons_dir': [opt_str, ''],
'last_sounds_dir': [opt_str, ''],

Yann Leboulanger
committed
'tabs_always_visible': [opt_bool, False, _('Show tab when only one conversation?'), '', True],
'tabs_border': [opt_bool, False, _('Show tab border if one conversation?')],
'tabs_close_button': [opt_bool, True, _('Show close button in tab?')],
'chat_avatar_width': [opt_int, 52],
'chat_avatar_height': [opt_int, 52],
'roster_avatar_width': [opt_int, 32],
'roster_avatar_height': [opt_int, 32],
'tooltip_avatar_width': [opt_int, 125],
'tooltip_avatar_height': [opt_int, 125],
'vcard_avatar_width': [opt_int, 200],
'vcard_avatar_height': [opt_int, 200],
'notification_position_x': [opt_int, -1],
'notification_position_y': [opt_int, -1],
'notification_avatar_width': [opt_int, 48],
'notification_avatar_height': [opt_int, 48],
'muc_highlight_words': [opt_str, '', _('A semicolon-separated list of words that will be highlighted in multi-user chat.')],
'quit_on_roster_x_button': [opt_bool, False, _('If True, quits Gajim when X button of Window Manager is clicked. This setting is taken into account only if trayicon is used.')],
'set_xmpp://_handler_everytime': [opt_bool, False, _('If True, Gajim registers for xmpp:// on each startup.')],
'show_unread_tab_icon': [opt_bool, False, _('If True, Gajim will display an icon on each tab containing unread messages. Depending on the theme, this icon may be animated.')],

Yann Leboulanger
committed
'show_status_msgs_in_roster': [opt_bool, True, _('If True, Gajim will display the status message, if not empty, for every contact under the contact name in roster window'), True],
'show_avatars_in_roster': [opt_bool, True, '', True],
'ask_avatars_on_startup': [opt_bool, True, _('If True, Gajim will ask for avatar each contact that did not have an avatar last time or has one cached that is too old.')],
#FIXME: remove you and make it Gajim will not; and/or his or *her* status messages
'print_status_in_chats': [opt_bool, True, _('If False, you will no longer see status line in chats when a contact changes his or her status and/or his status message.')],
'log_contact_status_changes': [opt_bool, False],

nkour
committed
'restored_messages_color': [opt_str, 'grey'],
'roster_window_skip_taskbar': [opt_bool, False],
'use_urgency_hint': [opt_bool, True, _('If True and installed GTK+ and PyGTK versions are at least 2.8, make the window flash (the default behaviour in most Window Managers) when holding pending events.')],
'notification_timeout': [opt_int, 5],
'send_sha_in_gc_presence': [opt_bool, True, _('Jabberd1.4 does not like sha info when one join a password protected room. Turn this option to False to stop sending sha info in groupchat presences')],
'one_message_window': [opt_str, 'always',
_('Controls the window where new messages are placed.\n\'always\' - All messages are sent to a single window.\n\'never\' - All messages get their own window.\n\'peracct\' - Messages for each account are sent to a specific window.\n\'pertype\' - Each message type (e.g., chats vs. groupchats) are sent to a specific window. Note, changing this option requires restarting Gajim before the changes will take effect')],
'show_avatar_in_chat': [opt_bool, True, _('If False, you will no longer see the avatar in the chat window')],

nicfit
committed
'escape_key_closes': [opt_bool, True, _('If True, pressing the escape key closes a tab/window')],

Yann Leboulanger
committed
'name': [ opt_str, '', '', True ],
'hostname': [ opt_str, '', '', True ],

Yann Leboulanger
committed
'savepass': [ opt_bool, False ],

Yann Leboulanger
committed
'resource': [ opt_str, 'gajim', '', True ],
'priority': [ opt_int, 5, '', True ],
'autoconnect': [ opt_bool, False, '', True ],
'autoreconnect': [ opt_bool, True ],

nkour
committed
'active': [ opt_bool, True],

Yann Leboulanger
committed
'proxy': [ opt_str, '', '', True ],
'keyid': [ opt_str, '', '', True ],
'keyname': [ opt_str, '', '', True ],
'usessl': [ opt_bool, False, '', True ],
'use_srv': [ opt_bool, True, '', True ],
'use_custom_host': [ opt_bool, False, '', True ],
'custom_port': [ opt_int, 5222, '', True ],
'custom_host': [ opt_str, '', '', True ],
'savegpgpass': [ opt_bool, False, '', True ],

Yann Leboulanger
committed
'sync_with_global_status': [ opt_bool, False, ],
'attached_gpg_keys': [ opt_str, '' ],
'keep_alives_enabled': [ opt_bool, True],
# send keepalive every N seconds of inactivity
'keep_alive_every_foo_secs': [ opt_int, 55 ],
# try for 2 minutes before giving up (aka. timeout after those seconds)
'try_connecting_for_foo_secs': [ opt_int, 60 ],
'http_auth': [opt_str, 'ask'], # yes, no, ask
'dont_ack_subscription': [opt_bool, False, _('Jabberd2 workaround')],
# proxy65 for FT
'file_transfer_proxies': [opt_str,
'proxy.jabber.org, proxy.netlab.cz, transfer.jabber.freenet.de'],
'use_ft_proxies': [opt_bool, True, _('If checked, Gajim will use your IP and proxies defined in file_transfer_proxies option for file transfer.'), True],
'msgwin-x-position': [opt_int, -1], # Default is to let the wm decide
'msgwin-y-position': [opt_int, -1], # Default is to let the wm decide
'msgwin-width': [opt_int, 480],
'msgwin-height': [opt_int, 440],
}, {}),
'statusmsg': ({
'message': [ opt_str, '' ],
}, {}),

Yann Leboulanger
committed
'soundevents': ({
'enabled': [ opt_bool, True ],
'path': [ opt_str, '' ],
}, {}),
'proxies': ({
'type': [ opt_str, 'http' ],
'host': [ opt_str, '' ],
'port': [ opt_int, 3128 ],
'user': [ opt_str, '' ],

Yann Leboulanger
committed
'accounttextcolor': [ opt_color, 'black', '', True ],
'accountbgcolor': [ opt_color, 'white', '', True ],
'accountfont': [ opt_str, '', '', True ],
'accountfontattrs': [ opt_str, 'B', '', True ],
'grouptextcolor': [ opt_color, 'black', '', True ],
'groupbgcolor': [ opt_color, 'white', '', True ],
'groupfont': [ opt_str, '', '', True ],
'groupfontattrs': [ opt_str, 'I', '', True ],
'contacttextcolor': [ opt_color, 'black', '', True ],
'contactbgcolor': [ opt_color, 'white', '', True ],
'contactfont': [ opt_str, '', '', True ],
'contactfontattrs': [ opt_str, '', '', True ],
'bannertextcolor': [ opt_color, 'black', '', True ],
'bannerbgcolor': [ opt_color, '', '', True ],
'bannerfont': [ opt_str, '', '', True ],
'bannerfontattrs': [ opt_str, 'B', '', True ],
# http://www.pitt.edu/~nisg/cis/web/cgi/rgb.html
# FIXME: not black but the default color from gtk+ theme
'state_active_color': [ opt_color, 'black' ],
'state_inactive_color': [ opt_color, 'grey62' ],
'state_composing_color': [ opt_color, 'green4' ],
'state_paused_color': [ opt_color, 'mediumblue' ],
'state_gone_color': [ opt_color, 'grey' ],

Yann Leboulanger
committed
'state_muc_msg_color': [ opt_color, 'mediumblue' ],
'state_muc_directed_msg_color': [ opt_color, 'red2' ],

Yann Leboulanger
committed
statusmsg_default = {
_('Back soon'): _('Back in some minutes.'),
_('Eating'): _("I'm eating, so leave me a message."),
_('Movie'): _("I'm watching a movie."),
_('Working'): _("I'm working."),
_('Phone'): _("I'm on the phone."),
_('Out'): _("I'm out enjoying life"),

Yann Leboulanger
committed
}
soundevents_default = {
'first_message_received': [ True, '../data/sounds/message1.wav' ],
'next_message_received': [ True, '../data/sounds/message2.wav' ],
'contact_connected': [ True, '../data/sounds/connected.wav' ],
'contact_disconnected': [ True, '../data/sounds/disconnected.wav' ],
'message_sent': [ True, '../data/sounds/sent.wav' ],
'muc_message_highlight': [ True, '../data/sounds/gc_message1.wav', _('Sound to play when a MUC message contains one of the words in muc_highlight_words, or when a MUC message contains your nickname.')],
'muc_message_received': [ True, '../data/sounds/gc_message2.wav', _('Sound to play when any MUC message arrives. (This setting is taken into account only if notify_on_all_muc_messages is True)') ],

Yann Leboulanger
committed
}
# sorted alphanum
'gtk+': [ '', '', '', 'B', '', '','', 'I', '', '', '', '', '','' ],
_('green'): [ '', '#94aa8c', '', 'B', '#0000ff', '#eff3e7',
'', 'I', '#000000', '', '', '', '',
'#94aa8c' ],
_('grocery'): [ '', '#6bbe18', '', 'B', '#12125a', '#ceefad',
'', 'I', '#000000', '#efb26b', '', '', '',
'#108abd' ],
_('human'): [ '', '#996442', '', 'B', '#ab5920', '#e3ca94',
'', 'I', '#000000', '', '', '', '',
_('marine'): [ '', '#918caa', '', 'B', '', '#e9e7f3',
'', 'I', '#000000', '', '', '', '',
'#918caa' ],
def foreach(self, cb, data = None):
cb(data, opt, None, self.__options[opt])
cb(data, opt, None, None)
dict = self.__options_per_key[opt][1]
for opt2 in dict.keys():
cb(data, opt2, [opt], None)
cb(data, opt3, [opt, opt2], dict[opt2][opt3])
def is_valid_int(self, val):
try:
ival = int(val)
except:
return None
return ival
if val == 'True':
return True
elif val == 'False':
return False
else:
ival = self.is_valid_int(val)
if ival:
return True
elif ival is None:
return None
if type[0] == 'boolean':
return self.is_valid_bool(val)
elif type[0] == 'integer':
return self.is_valid_int(val)
elif type[0] == 'string':
return self.is_valid_string(val)
else:
if sre.match(type[1], val):
return val
else:
return None
def set(self, optname, value):
if not self.__options.has_key(optname):
# raise RuntimeError, 'option %s does not exist' % optname
return
value = self.is_valid(opt[OPT_TYPE], value)
if value is None:
# raise RuntimeError, 'value of %s cannot be None' % optname
return
def get(self, optname = None):
if not optname:
return self.__options.keys()

Yann Leboulanger
committed
if not self.__options.has_key(optname):

Yann Leboulanger
committed
return self.__options[optname][OPT_VAL]
def get_desc(self, optname):
if not self.__options.has_key(optname):
return None
if len(self.__options[optname]) > OPT_DESC:
return self.__options[optname][OPT_DESC]

Yann Leboulanger
committed
def get_restart(self, optname):
if not self.__options.has_key(optname):
return None
if len(self.__options[optname]) > OPT_RESTART:
return self.__options[optname][OPT_RESTART]
def add_per(self, typename, name): # per_group_of_option
# raise RuntimeError, 'option %s does not exist' % typename
return
# we already have added group name before
def del_per(self, typename, name, subname = None): # per_group_of_option
# raise RuntimeError, 'option %s does not exist' % typename
return
del opt[1][name]
# if subname is specified, delete the item in the group.
elif opt[1][name].has_key(subname):
del opt[1][name][subname]
def set_per(self, optname, key, subname, value): # per_group_of_option
# raise RuntimeError, 'option %s does not exist' % optname
return
dict = self.__options_per_key[optname][1]
if not dict.has_key(key):
# raise RuntimeError, '%s is not a key of %s' % (key, dict)
return
# raise RuntimeError, '%s is not a key of %s' % (subname, obj)
return
value = self.is_valid(subobj[OPT_TYPE], value)
if value is None:
# raise RuntimeError, '%s of %s cannot be None' % optname
return
def get_per(self, optname, key = None, subname = None): # per_group_of_option
if not key:
return dict.keys()
if not dict.has_key(key):
return None
obj = dict[key]
if not subname:
return obj
if not obj.has_key(subname):
return None
return obj[subname][OPT_VAL]

Yann Leboulanger
committed
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
def get_desc_per(self, optname, key = None, subname = None):
if not self.__options_per_key.has_key(optname):
return None
dict = self.__options_per_key[optname][1]
if not key:
return None
if not dict.has_key(key):
return None
obj = dict[key]
if not subname:
return None
if not obj.has_key(subname):
return None
if len(obj[subname]) > OPT_DESC:
return obj[subname][OPT_DESC]
return None
def get_restart_per(self, optname, key = None, subname = None):
if not self.__options_per_key.has_key(optname):
return False
dict = self.__options_per_key[optname][1]
if not key:
return False
if not dict.has_key(key):
return False
obj = dict[key]
if not subname:
return False
if not obj.has_key(subname):
return False
if len(obj[subname]) > OPT_RESTART:
return obj[subname][OPT_RESTART]
return False

Yann Leboulanger
committed
#init default values
for event in self.soundevents_default:
default = self.soundevents_default[event]
self.add_per('soundevents', event)
self.set_per('soundevents', event, 'enabled', default[0])
self.set_per('soundevents', event, 'path', default[1])