Added language option to Preferences

Changing translation tested and works on:

* Windows 7
* OSX 10.8
* Ubuntu 13.04

* Updated the OSX menubar to gtkbuilder
* Added language names to the Language dropdown in Preferences
This commit is contained in:
bendikro 2014-01-13 01:48:00 +01:00 committed by Calum Lind
parent d260f6506f
commit 7c808ab4b4
8 changed files with 593 additions and 259 deletions

View file

@ -115,6 +115,7 @@ FILE_PRIORITY = {
"Highest Priority": 7
}
def get_version():
"""
Returns the program version from the egg metadata
@ -125,9 +126,11 @@ def get_version():
"""
return pkg_resources.require("Deluge")[0].version
def get_default_config_dir(filename=None):
"""
:param filename: if None, only the config path is returned, if provided, a path including the filename will be returned
:param filename: if None, only the config path is returned, if provided,
a path including the filename will be returned
:type filename: string
:returns: a file path to the config directory and optional filename
:rtype: string
@ -139,7 +142,8 @@ def get_default_config_dir(filename=None):
appDataPath = os.environ.get("APPDATA")
if not appDataPath:
import _winreg
hkey = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders")
hkey = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER,
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders")
appDataReg = _winreg.QueryValueEx(hkey, "AppData")
appDataPath = appDataReg[0]
_winreg.CloseKey(hkey)
@ -154,6 +158,7 @@ def get_default_config_dir(filename=None):
log.error("Unable to use default config directory, exiting... (%s)", e)
sys.exit(1)
def get_default_download_dir():
"""
:returns: the default download directory
@ -168,8 +173,7 @@ def get_default_download_dir():
try:
for line in open(userdir_file, 'r'):
if not line.startswith('#') and 'XDG_DOWNLOAD_DIR' in line:
download_dir = os.path.expandvars(\
line.partition("=")[2].rstrip().strip('"'))
download_dir = os.path.expandvars(line.partition("=")[2].rstrip().strip('"'))
if os.path.isdir(download_dir):
return download_dir
except IOError:
@ -177,6 +181,7 @@ def get_default_download_dir():
return os.environ.get("HOME")
def windows_check():
"""
Checks if the current platform is Windows
@ -187,6 +192,7 @@ def windows_check():
"""
return platform.system() in ('Windows', 'Microsoft')
def vista_check():
"""
Checks if the current platform is Windows Vista
@ -197,6 +203,7 @@ def vista_check():
"""
return platform.release() == "Vista"
def osx_check():
"""
Checks if the current platform is Mac OS X
@ -207,6 +214,7 @@ def osx_check():
"""
return platform.system() == "Darwin"
def get_pixmap(fname):
"""
Provides easy access to files in the deluge/ui/data/pixmaps folder within the Deluge egg
@ -219,6 +227,7 @@ def get_pixmap(fname):
"""
return resource_filename("deluge", os.path.join("ui", "data", "pixmaps", fname))
def resource_filename(module, path):
# While developing, if there's a second deluge package, installed globally
# and another in develop mode somewhere else, while pkg_resources.require("Deluge")
@ -230,6 +239,7 @@ def resource_filename(module, path):
pkg_resources._manager, os.path.join(*(module.split('.')+[path]))
)
def open_file(path):
"""
Opens a file or folder using the system configured program
@ -245,6 +255,7 @@ def open_file(path):
else:
subprocess.Popen(["xdg-open", "%s" % path])
def open_url_in_browser(url):
"""
Opens a url in the desktop's default browser
@ -263,12 +274,14 @@ kib_txt = "KiB"
mib_txt = "MiB"
gib_txt = "GiB"
def translate_strings():
byte_txt = _("Bytes")
kib_txt = _("KiB")
mib_txt = _("MiB")
gib_txt = _("GiB")
def fsize(fsize_b):
"""
Formats the bytes value into a string with KiB, MiB or GiB units
@ -296,6 +309,7 @@ def fsize(fsize_b):
else:
return "%d %s" % (fsize_b, byte_txt)
def fsize_short(fsize_b):
"""
Formats the bytes value into a string with K, M or G units
@ -320,6 +334,7 @@ def fsize_short(fsize_b):
fsize_gb = fsize_mb / 1024.0
return "%.1f %s" % (fsize_gb, _("G"))
def fpcnt(dec):
"""
Formats a string to display a percentage with two decimal places
@ -337,6 +352,7 @@ def fpcnt(dec):
"""
return '%.2f%%' % (dec * 100)
def fspeed(bps):
"""
Formats a string to display a transfer speed utilizing :func:`fsize`
@ -361,6 +377,7 @@ def fspeed(bps):
fspeed_gb = fspeed_mb / 1024.0
return "%.1f %s" % (fspeed_gb, _("GiB/s"))
def fpeer(num_peers, total_peers):
"""
Formats a string to show 'num_peers' ('total_peers')
@ -385,6 +402,7 @@ def fpeer(num_peers, total_peers):
else:
return "%d" % num_peers
def ftime(seconds):
"""
Formats a string to show time in a human readable form
@ -424,6 +442,7 @@ def ftime(seconds):
weeks = weeks % 52
return '%dy %dw' % (years, weeks)
def fdate(seconds):
"""
Formats a date time string in the locale's date representation based on the systems timezone
@ -438,6 +457,7 @@ def fdate(seconds):
return ""
return time.strftime("%x %X", time.localtime(seconds))
def is_url(url):
"""
A simple test to check if the URL is valid
@ -455,6 +475,7 @@ def is_url(url):
"""
return url.partition('://')[0] in ("http", "https", "ftp", "udp")
def is_magnet(uri):
"""
A check to determine if a uri is a valid bittorrent magnet uri
@ -476,6 +497,7 @@ def is_magnet(uri):
return True
return False
def create_magnet_uri(infohash, name=None, trackers=[]):
"""
Creates a magnet uri
@ -501,6 +523,7 @@ def create_magnet_uri(infohash, name=None, trackers=[]):
return uri
def get_path_size(path):
"""
Gets the size in bytes of 'path'
@ -524,6 +547,7 @@ def get_path_size(path):
dir_size += os.path.getsize(filename)
return dir_size
def free_space(path):
"""
Gets the free space available at 'path'
@ -547,6 +571,7 @@ def free_space(path):
block_size = disk_data.f_frsize
return disk_data.f_bavail * block_size
def is_ip(ip):
"""
A simple test to see if 'ip' is valid
@ -585,6 +610,7 @@ def is_ip(ip):
except socket.error:
return False
def path_join(*parts):
"""
An implementation of os.path.join that always uses / for the separator
@ -611,6 +637,7 @@ XML_ESCAPES = (
("'", ''')
)
def xml_decode(string):
"""
Unescape a string that was previously encoded for use within xml.
@ -624,6 +651,7 @@ def xml_decode(string):
string = string.replace(escape, char)
return string
def xml_encode(string):
"""
Escape a string for use within an xml element or attribute.
@ -637,6 +665,7 @@ def xml_encode(string):
string = string.replace(char, escape)
return string
def decode_string(s, encoding="utf8"):
"""
Decodes a string and return unicode. If it cannot decode using
@ -672,6 +701,7 @@ def decode_string(s, encoding="utf8"):
pass
return u''
def utf8_encoded(s, encoding="utf8"):
"""
Returns a utf8 encoded string of s
@ -690,6 +720,7 @@ def utf8_encoded(s, encoding="utf8"):
s = s.encode("utf8")
return s
class VersionSplit(object):
"""
Used for comparing version numbers.
@ -715,8 +746,8 @@ class VersionSplit(object):
# Check for PEP 386 compliant version
match = re.search(VERSION_RE, ver)
if match:
group = [(x if x is not None else '') for x in match.group(1,2,3,4,8)]
vs = [''.join(group[0:2]),''.join(group[2:4]), group[4].lstrip('.')]
group = [(x if x is not None else '') for x in match.group(1, 2, 3, 4, 8)]
vs = [''.join(group[0:2]), ''.join(group[2:4]), group[4].lstrip('.')]
else:
ver = ver.lower()
vs = ver.replace("_", "-").split("-")
@ -759,8 +790,10 @@ AUTH_LEVEL_NORMAL = 5
AUTH_LEVEL_ADMIN = 10
AUTH_LEVEL_DEFAULT = AUTH_LEVEL_NORMAL
def create_auth_file():
import stat, configmanager
import stat
import configmanager
auth_file = configmanager.get_config_dir("auth")
# Check for auth file and create if necessary
if not os.path.exists(auth_file):
@ -771,8 +804,10 @@ def create_auth_file():
# Change the permissions on the file so only this user can read/write it
os.chmod(auth_file, stat.S_IREAD | stat.S_IWRITE)
def create_localclient_account(append=False):
import configmanager, random
import configmanager
import random
auth_file = configmanager.get_config_dir("auth")
if not os.path.exists(auth_file):
create_auth_file()
@ -792,31 +827,137 @@ def create_localclient_account(append=False):
fd.close()
def get_translations_path():
"""Get the absolute path to the directory containing translation files"""
return resource_filename("deluge", "i18n")
def set_env_variable(name, value):
'''
:param name: environment variable name
:param value: environment variable value
This function ensures that changes to an environment variable are applied
to each copy of the environment variables used by a process. Starting from
Python 2.4, os.environ changes only apply to the copy Python keeps (os.environ)
and are no longer automatically applied to the other copies for the process.
On Microsoft Windows, each process has multiple copies of the environment
variables, one managed by the OS and one managed by the C library. We also
need to take care of the fact that the C library used by Python is not
necessarily the same as the C library used by pygtk and friends. This because
the latest releases of pygtk and friends are built with mingw32 and are thus
linked against msvcrt.dll. The official gtk+ binaries have always been built
in this way.
Basen on _putenv in TransUtils.py from sourceforge project gramps
http://sourceforge.net/p/gramps/code/HEAD/tree/branches/maintenance/gramps32/src/TransUtils.py
'''
# Update Python's copy of the environment variables
os.environ[name] = value
if windows_check():
from ctypes import windll
from ctypes import cdll
from ctypes.util import find_msvcrt
# Update the copy maintained by Windows (so SysInternals Process Explorer sees it)
try:
result = windll.kernel32.SetEnvironmentVariableW(name, value)
if result == 0:
raise Warning
except Exception:
log.warning('Failed to set Env Var \'%s\' (\'kernel32.SetEnvironmentVariableW\')' % name)
else:
log.debug('Set Env Var \'%s\' to \'%s\' (\'kernel32.SetEnvironmentVariableW\')' % (name, value))
# Update the copy maintained by msvcrt (used by gtk+ runtime)
try:
result = cdll.msvcrt._putenv('%s=%s' % (name, value))
if result != 0:
raise Warning
except Exception:
log.warning('Failed to set Env Var \'%s\' (\'msvcrt._putenv\')' % name)
else:
log.debug('Set Env Var \'%s\' to \'%s\' (\'msvcrt._putenv\')' % (name, value))
# Update the copy maintained by whatever c runtime is used by Python
try:
msvcrt = find_msvcrt()
msvcrtname = str(msvcrt).split('.')[0] if '.' in msvcrt else str(msvcrt)
result = cdll.LoadLibrary(msvcrt)._putenv('%s=%s' % (name, value))
if result != 0:
raise Warning
except Exception:
log.warning('Failed to set Env Var \'%s\' (\'%s._putenv\')' % (name, msvcrtname))
else:
log.debug('Set Env Var \'%s\' to \'%s\' (\'%s._putenv\')' % (name, value, msvcrtname))
def set_language(lang):
"""
Set the language to use.
gettext and GtkBuilder will load the translations from the specified
language.
:param lang: the language, e.g. "en", "de" or "en_GB"
:type lang: str
"""
lang = str(lang)
# Necessary to set there environment variables for GtkBuilder
set_env_variable('LANGUAGE', lang) # Windows/Linux
set_env_variable('LANG', lang) # For OSX
translations_path = get_translations_path()
ro = gettext.translation("deluge", localedir=translations_path, languages=[lang])
ro.install()
# Initialize gettext
def setup_translations(setup_pygtk=False):
translations_path = resource_filename("deluge", "i18n")
def setup_translations(setup_gettext=True, setup_pygtk=False):
translations_path = get_translations_path()
domain = "deluge"
log.info("Setting up translations from %s", translations_path)
try:
if hasattr(locale, "bindtextdomain"):
locale.bindtextdomain("deluge", translations_path)
if hasattr(locale, "textdomain"):
locale.textdomain("deluge")
gettext.install("deluge", translations_path, unicode=True)
if setup_pygtk:
# Even though we're not using glade anymore, let's set it up so that
# plugins still using it get properly translated.
if setup_pygtk:
try:
log.info("Setting up GTK translations from %s", translations_path)
if windows_check():
import ctypes
libintl = ctypes.cdll.intl
libintl.bindtextdomain(domain, translations_path.encode(sys.getfilesystemencoding()))
libintl.textdomain(domain)
libintl.bind_textdomain_codeset(domain, "UTF-8")
libintl.gettext.restype = ctypes.c_char_p
# Use glade for plugins that still uses it
import gtk
import gtk.glade
gtk.glade.bindtextdomain("deluge", translations_path)
gtk.glade.textdomain("deluge")
gtk.glade.bindtextdomain(domain, translations_path)
gtk.glade.textdomain(domain)
except Exception, e:
log.error("Unable to initialize glade translation!")
log.exception(e)
if setup_gettext:
try:
if hasattr(locale, "bindtextdomain"):
locale.bindtextdomain(domain, translations_path)
if hasattr(locale, "textdomain"):
locale.textdomain(domain)
gettext.bindtextdomain(domain, translations_path)
gettext.bind_textdomain_codeset(domain, 'UTF-8')
gettext.textdomain(domain)
gettext.install(domain, translations_path, unicode=True)
except Exception, e:
log.error("Unable to initialize gettext/locale!")
log.exception(e)
import __builtin__
__builtin__.__dict__["_"] = lambda x: x
translate_strings()
except Exception, e:
log.error("Unable to initialize gettext/locale!")
log.exception(e)
import __builtin__
__builtin__.__dict__["_"] = lambda x: x
def unicode_argv():
""" Gets sys.argv as list of unicode objects on any platform."""

View file

@ -64,8 +64,6 @@ def version_callback(option, opt_str, value, parser):
def start_ui():
"""Entry point for ui script"""
deluge.common.setup_translations()
# Setup the argument parser
parser = OptionParser(usage="%prog [options] [actions]")
parser.add_option("-v", "--version", action="callback", callback=version_callback,

View file

@ -320,6 +320,14 @@
</row>
</data>
</object>
<object class="GtkListStore" id="liststore8">
<columns>
<!-- column-name language_code -->
<column type="gchararray"/>
<!-- column-name language_name -->
<column type="gchararray"/>
</columns>
</object>
<object class="GtkDialog" id="pref_dialog">
<property name="can_focus">False</property>
<property name="border_width">5</property>
@ -344,7 +352,6 @@
<child>
<object class="GtkButton" id="button_cancel">
<property name="label">gtk-cancel</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
@ -360,7 +367,6 @@
<child>
<object class="GtkButton" id="button_apply">
<property name="label">gtk-apply</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
@ -376,7 +382,6 @@
<child>
<object class="GtkButton" id="button_ok">
<property name="label">gtk-ok</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
@ -492,7 +497,6 @@
<child>
<object class="GtkRadioButton" id="radio_classic">
<property name="label" translatable="yes">Standalone</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
@ -509,7 +513,6 @@
<child>
<object class="GtkRadioButton" id="radio_thinclient">
<property name="label" translatable="yes">Thin Client</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
@ -566,7 +569,6 @@
<child>
<object class="GtkCheckButton" id="chk_show_rate_in_title">
<property name="label" translatable="yes">Show session speed in titlebar</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
@ -581,7 +583,6 @@
<child>
<object class="GtkCheckButton" id="chk_focus_main_window_on_add">
<property name="label" translatable="yes">Focus window when adding torrent</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
@ -594,35 +595,6 @@
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="piecesbar_toggle">
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="tooltip_text" translatable="yes">Besides being experimental, using the pieces bar
will increase the bandwidth used between client
and daemon(does not apply in classic mode).
Use at your own risk if you wish to help us debug
this new feature.</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="on_piecesbar_toggle_toggled" swapped="no"/>
<child>
<object class="GtkLabel" id="label62">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Show a pieces bar in the torrent's
status tab (&lt;b&gt;EXPERIMENTAL!!!&lt;/b&gt;)</property>
<property name="use_markup">True</property>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkExpander" id="piecebar_colors_expander">
<property name="can_focus">True</property>
@ -652,7 +624,6 @@ status tab (&lt;b&gt;EXPERIMENTAL!!!&lt;/b&gt;)</property>
</child>
<child>
<object class="GtkColorButton" id="completed_color">
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
@ -663,7 +634,7 @@ status tab (&lt;b&gt;EXPERIMENTAL!!!&lt;/b&gt;)</property>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="x_options"></property>
<property name="x_options"/>
</packing>
</child>
<child>
@ -681,7 +652,6 @@ status tab (&lt;b&gt;EXPERIMENTAL!!!&lt;/b&gt;)</property>
</child>
<child>
<object class="GtkColorButton" id="downloading_color">
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
@ -694,7 +664,7 @@ status tab (&lt;b&gt;EXPERIMENTAL!!!&lt;/b&gt;)</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options"></property>
<property name="x_options"/>
</packing>
</child>
<child>
@ -712,7 +682,6 @@ status tab (&lt;b&gt;EXPERIMENTAL!!!&lt;/b&gt;)</property>
</child>
<child>
<object class="GtkColorButton" id="waiting_color">
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
@ -725,7 +694,7 @@ status tab (&lt;b&gt;EXPERIMENTAL!!!&lt;/b&gt;)</property>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options"></property>
<property name="x_options"/>
</packing>
</child>
<child>
@ -743,7 +712,6 @@ status tab (&lt;b&gt;EXPERIMENTAL!!!&lt;/b&gt;)</property>
</child>
<child>
<object class="GtkColorButton" id="missing_color">
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
@ -756,13 +724,12 @@ status tab (&lt;b&gt;EXPERIMENTAL!!!&lt;/b&gt;)</property>
<property name="right_attach">2</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="x_options"></property>
<property name="x_options"/>
</packing>
</child>
<child>
<object class="GtkButton" id="revert_color_completed">
<property name="label">gtk-revert-to-saved</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can_focus">True</property>
@ -775,13 +742,12 @@ status tab (&lt;b&gt;EXPERIMENTAL!!!&lt;/b&gt;)</property>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="x_options"></property>
<property name="x_options"/>
</packing>
</child>
<child>
<object class="GtkButton" id="revert_color_downloading">
<property name="label">gtk-revert-to-saved</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can_focus">True</property>
@ -796,13 +762,12 @@ status tab (&lt;b&gt;EXPERIMENTAL!!!&lt;/b&gt;)</property>
<property name="right_attach">3</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options"></property>
<property name="x_options"/>
</packing>
</child>
<child>
<object class="GtkButton" id="revert_color_waiting">
<property name="label">gtk-revert-to-saved</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can_focus">True</property>
@ -817,13 +782,12 @@ status tab (&lt;b&gt;EXPERIMENTAL!!!&lt;/b&gt;)</property>
<property name="right_attach">3</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options"></property>
<property name="x_options"/>
</packing>
</child>
<child>
<object class="GtkButton" id="revert_color_missing">
<property name="label">gtk-revert-to-saved</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can_focus">True</property>
@ -838,7 +802,7 @@ status tab (&lt;b&gt;EXPERIMENTAL!!!&lt;/b&gt;)</property>
<property name="right_attach">3</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="x_options"></property>
<property name="x_options"/>
</packing>
</child>
</object>
@ -859,6 +823,34 @@ status tab (&lt;b&gt;EXPERIMENTAL!!!&lt;/b&gt;)</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="piecesbar_toggle">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="tooltip_text" translatable="yes">Besides being experimental, using the pieces bar
will increase the bandwidth used between client
and daemon(does not apply in classic mode).
Use at your own risk if you wish to help us debug
this new feature.</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="on_piecesbar_toggle_toggled" swapped="no"/>
<child>
<object class="GtkLabel" id="label62">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Show a pieces bar in the torrent's
status tab (&lt;b&gt;EXPERIMENTAL!!!&lt;/b&gt;)</property>
<property name="use_markup">True</property>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
</child>
</object>
@ -901,7 +893,6 @@ status tab (&lt;b&gt;EXPERIMENTAL!!!&lt;/b&gt;)</property>
<child>
<object class="GtkCheckButton" id="chk_show_dialog">
<property name="label" translatable="yes">Always show</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
@ -921,7 +912,6 @@ status tab (&lt;b&gt;EXPERIMENTAL!!!&lt;/b&gt;)</property>
<child>
<object class="GtkCheckButton" id="chk_focus_dialog">
<property name="label" translatable="yes">Bring the dialog to focus</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
@ -977,7 +967,6 @@ status tab (&lt;b&gt;EXPERIMENTAL!!!&lt;/b&gt;)</property>
<child>
<object class="GtkCheckButton" id="chk_use_tray">
<property name="label" translatable="yes">Enable system tray icon</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="receives_default">False</property>
@ -999,7 +988,6 @@ status tab (&lt;b&gt;EXPERIMENTAL!!!&lt;/b&gt;)</property>
<child>
<object class="GtkCheckButton" id="chk_min_on_close">
<property name="label" translatable="yes">Minimize to tray on close</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can_focus">False</property>
@ -1023,7 +1011,6 @@ status tab (&lt;b&gt;EXPERIMENTAL!!!&lt;/b&gt;)</property>
<child>
<object class="GtkCheckButton" id="chk_start_in_tray">
<property name="label" translatable="yes">Start in tray</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can_focus">False</property>
@ -1047,7 +1034,6 @@ status tab (&lt;b&gt;EXPERIMENTAL!!!&lt;/b&gt;)</property>
<child>
<object class="GtkCheckButton" id="chk_enable_appindicator">
<property name="label" translatable="yes">Enable Application Indicator</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can_focus">False</property>
@ -1072,7 +1058,6 @@ status tab (&lt;b&gt;EXPERIMENTAL!!!&lt;/b&gt;)</property>
<child>
<object class="GtkCheckButton" id="chk_lock_tray">
<property name="label" translatable="yes">Password protect system tray</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can_focus">True</property>
@ -1164,6 +1149,74 @@ status tab (&lt;b&gt;EXPERIMENTAL!!!&lt;/b&gt;)</property>
<property name="position">5</property>
</packing>
</child>
<child>
<object class="GtkFrame" id="frame2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label_xalign">0</property>
<property name="shadow_type">none</property>
<child>
<object class="GtkAlignment" id="alignment2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="left_padding">12</property>
<child>
<object class="GtkHBox" id="hbox8">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkCheckButton" id="checkbutton_language">
<property name="label" translatable="yes">System Default</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="on_checkbutton_language_toggled" swapped="no"/>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkComboBox" id="combobox_language">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="model">liststore8</property>
<property name="active">0</property>
<child>
<object class="GtkCellRendererText" id="cellrenderertext8"/>
<attributes>
<attribute name="text">1</attribute>
</attributes>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
</child>
<child type="label">
<object class="GtkLabel" id="label5">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">&lt;b&gt;Languge&lt;/b&gt;</property>
<property name="use_markup">True</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">6</property>
</packing>
</child>
</object>
</child>
</object>
@ -1249,7 +1302,6 @@ status tab (&lt;b&gt;EXPERIMENTAL!!!&lt;/b&gt;)</property>
<child>
<object class="GtkCheckButton" id="chk_move_completed">
<property name="label" translatable="yes">Move completed to:</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
@ -1265,7 +1317,6 @@ status tab (&lt;b&gt;EXPERIMENTAL!!!&lt;/b&gt;)</property>
<child>
<object class="GtkCheckButton" id="chk_copy_torrent_file">
<property name="label" translatable="yes">Copy of .torrent files to:</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
@ -1281,7 +1332,6 @@ status tab (&lt;b&gt;EXPERIMENTAL!!!&lt;/b&gt;)</property>
<child>
<object class="GtkCheckButton" id="chk_del_copy_torrent_file">
<property name="label" translatable="yes">Delete copy of torrent file on remove</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
@ -1407,7 +1457,6 @@ status tab (&lt;b&gt;EXPERIMENTAL!!!&lt;/b&gt;)</property>
<child>
<object class="GtkRadioButton" id="radio_full_allocation">
<property name="label" translatable="yes">Use Full Allocation</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
@ -1425,7 +1474,6 @@ status tab (&lt;b&gt;EXPERIMENTAL!!!&lt;/b&gt;)</property>
<child>
<object class="GtkRadioButton" id="radio_compact_allocation">
<property name="label" translatable="yes">Use Compact Allocation</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
@ -1482,7 +1530,6 @@ status tab (&lt;b&gt;EXPERIMENTAL!!!&lt;/b&gt;)</property>
<child>
<object class="GtkCheckButton" id="chk_prioritize_first_last_pieces">
<property name="label" translatable="yes">Prioritize first and last pieces of torrent</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
@ -1498,7 +1545,6 @@ status tab (&lt;b&gt;EXPERIMENTAL!!!&lt;/b&gt;)</property>
<child>
<object class="GtkCheckButton" id="chk_sequential_download">
<property name="label" translatable="yes">Sequential download</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
@ -1519,7 +1565,6 @@ used sparingly.</property>
<child>
<object class="GtkCheckButton" id="chk_add_paused">
<property name="label" translatable="yes">Add torrents in Paused state</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
@ -1763,7 +1808,6 @@ used sparingly.</property>
<child>
<object class="GtkCheckButton" id="chk_random_port">
<property name="label" translatable="yes">Random</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
@ -1838,7 +1882,6 @@ used sparingly.</property>
<child>
<object class="GtkButton" id="button_testport">
<property name="label" translatable="yes">Test Active Port</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
@ -1990,7 +2033,6 @@ used sparingly.</property>
<child>
<object class="GtkCheckButton" id="chk_random_outgoing_ports">
<property name="label" translatable="yes">Random</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
@ -2213,7 +2255,6 @@ used sparingly.</property>
<child>
<object class="GtkCheckButton" id="chk_upnp">
<property name="label" translatable="yes">UPnP</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
@ -2229,7 +2270,6 @@ used sparingly.</property>
<child>
<object class="GtkCheckButton" id="chk_natpmp">
<property name="label" translatable="yes">NAT-PMP</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
@ -2247,7 +2287,6 @@ used sparingly.</property>
<child>
<object class="GtkCheckButton" id="chk_utpex">
<property name="label" translatable="yes">Peer Exchange</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
@ -2264,7 +2303,6 @@ used sparingly.</property>
<child>
<object class="GtkCheckButton" id="chk_lt_tex">
<property name="label" translatable="yes">Tracker Exchange</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
@ -2283,7 +2321,6 @@ used sparingly.</property>
<child>
<object class="GtkCheckButton" id="chk_lsd">
<property name="label" translatable="yes">LSD</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
@ -2299,7 +2336,6 @@ used sparingly.</property>
<child>
<object class="GtkCheckButton" id="chk_dht">
<property name="label" translatable="yes">DHT</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
@ -2709,7 +2745,6 @@ Requires a Hex value.</property>
<child>
<object class="GtkCheckButton" id="chk_ignore_limits_on_local_network">
<property name="label" translatable="yes">Ignore limits on local network</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
@ -2732,7 +2767,6 @@ Requires a Hex value.</property>
<child>
<object class="GtkCheckButton" id="chk_rate_limit_ip_overhead">
<property name="label" translatable="yes">Rate limit IP overhead</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
@ -3045,7 +3079,6 @@ Requires a Hex value.</property>
<child>
<object class="GtkCheckButton" id="chk_show_new_releases">
<property name="label" translatable="yes">Be alerted about new releases</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
@ -3121,7 +3154,6 @@ Requires a Hex value.</property>
<child>
<object class="GtkCheckButton" id="chk_send_info">
<property name="label" translatable="yes">Yes, please send anonymous statistics</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
@ -3255,7 +3287,6 @@ Requires a Hex value.</property>
<property name="layout_style">start</property>
<child>
<object class="GtkButton" id="button_associate_magnet">
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
@ -3468,7 +3499,6 @@ Requires a Hex value.</property>
<child>
<object class="GtkCheckButton" id="chk_allow_remote_connections">
<property name="label" translatable="yes">Allow Remote Connections</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
@ -3510,7 +3540,6 @@ Requires a Hex value.</property>
<child>
<object class="GtkCheckButton" id="chk_new_releases">
<property name="label" translatable="yes">Periodically check the website for new releases</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
@ -3573,7 +3602,6 @@ Requires a Hex value.</property>
<child>
<object class="GtkButton" id="accounts_add">
<property name="label">gtk-add</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
@ -3589,7 +3617,6 @@ Requires a Hex value.</property>
<child>
<object class="GtkButton" id="accounts_edit">
<property name="label">gtk-edit</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can_focus">True</property>
@ -3606,7 +3633,6 @@ Requires a Hex value.</property>
<child>
<object class="GtkButton" id="accounts_delete">
<property name="label">gtk-delete</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can_focus">True</property>
@ -3743,7 +3769,6 @@ Requires a Hex value.</property>
<child>
<object class="GtkCheckButton" id="chk_queue_new_top">
<property name="label" translatable="yes">Queue new torrents to top</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
@ -3816,7 +3841,7 @@ Requires a Hex value.</property>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="x_options"></property>
<property name="x_options"/>
</packing>
</child>
<child>
@ -3837,7 +3862,7 @@ Requires a Hex value.</property>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options"></property>
<property name="x_options"/>
</packing>
</child>
<child>
@ -3882,7 +3907,7 @@ Requires a Hex value.</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options"></property>
<property name="x_options"/>
</packing>
</child>
<child>
@ -3908,7 +3933,6 @@ Requires a Hex value.</property>
<child>
<object class="GtkCheckButton" id="chk_dont_count_slow_torrents">
<property name="label" translatable="yes">Do not count slow torrents</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
@ -3923,7 +3947,6 @@ Requires a Hex value.</property>
<child>
<object class="GtkCheckButton" id="chk_auto_manage_prefer_seeds">
<property name="label" translatable="yes">Prefer Seeding over Downloading</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
@ -4033,7 +4056,7 @@ Requires a Hex value.</property>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="x_options"></property>
<property name="x_options"/>
</packing>
</child>
<child>
@ -4054,7 +4077,7 @@ Requires a Hex value.</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options"></property>
<property name="x_options"/>
</packing>
</child>
<child>
@ -4074,7 +4097,7 @@ Requires a Hex value.</property>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options"></property>
<property name="x_options"/>
</packing>
</child>
</object>
@ -4092,7 +4115,6 @@ Requires a Hex value.</property>
<child>
<object class="GtkCheckButton" id="chk_seed_ratio">
<property name="label" translatable="yes">Stop seeding when share ratio reaches:</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
@ -4140,7 +4162,6 @@ Requires a Hex value.</property>
<child>
<object class="GtkCheckButton" id="chk_remove_ratio">
<property name="label" translatable="yes">Remove torrent when share ratio reached</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can_focus">True</property>
@ -4412,7 +4433,7 @@ Requires a Hex value.</property>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
<property name="y_options"/>
</packing>
</child>
<child>
@ -4424,7 +4445,7 @@ Requires a Hex value.</property>
</object>
<packing>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
<property name="y_options"/>
</packing>
</child>
<child>
@ -4617,7 +4638,7 @@ Requires a Hex value.</property>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
<property name="y_options"/>
</packing>
</child>
<child>
@ -4629,7 +4650,7 @@ Requires a Hex value.</property>
</object>
<packing>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
<property name="y_options"/>
</packing>
</child>
<child>
@ -4822,7 +4843,7 @@ Requires a Hex value.</property>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
<property name="y_options"/>
</packing>
</child>
<child>
@ -4834,7 +4855,7 @@ Requires a Hex value.</property>
</object>
<packing>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
<property name="y_options"/>
</packing>
</child>
<child>
@ -4901,7 +4922,7 @@ Requires a Hex value.</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
<property name="y_options"/>
</packing>
</child>
<child>
@ -4934,7 +4955,7 @@ Requires a Hex value.</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
<property name="y_options"/>
</packing>
</child>
<child>
@ -4965,7 +4986,7 @@ Requires a Hex value.</property>
<property name="top_attach">4</property>
<property name="bottom_attach">5</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
<property name="y_options"/>
</packing>
</child>
<child>
@ -5030,7 +5051,7 @@ Requires a Hex value.</property>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
<property name="y_options"/>
</packing>
</child>
<child>
@ -5042,7 +5063,7 @@ Requires a Hex value.</property>
</object>
<packing>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
<property name="y_options"/>
</packing>
</child>
<child>
@ -5056,7 +5077,7 @@ Requires a Hex value.</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
<property name="y_options"/>
</packing>
</child>
</object>
@ -5219,7 +5240,7 @@ Requires a Hex value.</property>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="x_options"></property>
<property name="x_options"/>
</packing>
</child>
<child>
@ -5241,7 +5262,7 @@ Requires a Hex value.</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options"></property>
<property name="x_options"/>
</packing>
</child>
</object>
@ -5349,7 +5370,7 @@ Requires a Hex value.</property>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="x_options"></property>
<property name="x_options"/>
</packing>
</child>
<child>
@ -5363,7 +5384,7 @@ Requires a Hex value.</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options"></property>
<property name="x_options"/>
</packing>
</child>
<child>
@ -5377,7 +5398,7 @@ Requires a Hex value.</property>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options"></property>
<property name="x_options"/>
</packing>
</child>
</object>
@ -5468,7 +5489,7 @@ Requires a Hex value.</property>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="x_options"></property>
<property name="x_options"/>
</packing>
</child>
<child>
@ -5482,7 +5503,7 @@ Requires a Hex value.</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options"></property>
<property name="x_options"/>
</packing>
</child>
<child>
@ -5496,7 +5517,7 @@ Requires a Hex value.</property>
<property name="right_attach">2</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="x_options"></property>
<property name="x_options"/>
</packing>
</child>
<child>
@ -5524,7 +5545,7 @@ Requires a Hex value.</property>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options"></property>
<property name="x_options"/>
</packing>
</child>
</object>
@ -5600,7 +5621,7 @@ Requires a Hex value.</property>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="x_options"></property>
<property name="x_options"/>
</packing>
</child>
<child>
@ -5614,7 +5635,7 @@ Requires a Hex value.</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options"></property>
<property name="x_options"/>
</packing>
</child>
</object>
@ -5646,7 +5667,6 @@ Requires a Hex value.</property>
<child>
<object class="GtkButton" id="button_cache_refresh">
<property name="label">gtk-refresh</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
@ -5820,7 +5840,7 @@ Requires a Hex value.</property>
<property name="right_attach">2</property>
<property name="top_attach">4</property>
<property name="bottom_attach">5</property>
<property name="y_options"></property>
<property name="y_options"/>
</packing>
</child>
<child>
@ -5834,7 +5854,7 @@ Requires a Hex value.</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="y_options"></property>
<property name="y_options"/>
</packing>
</child>
<child>
@ -5846,7 +5866,7 @@ Requires a Hex value.</property>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="y_options"></property>
<property name="y_options"/>
</packing>
</child>
<child>
@ -5875,7 +5895,7 @@ Requires a Hex value.</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
<property name="y_options"/>
</packing>
</child>
<child>
@ -5887,7 +5907,7 @@ Requires a Hex value.</property>
</object>
<packing>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
<property name="y_options"/>
</packing>
</child>
<child>
@ -5929,7 +5949,7 @@ Requires a Hex value.</property>
<property name="right_attach">2</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="y_options"></property>
<property name="y_options"/>
</packing>
</child>
<child>
@ -5943,7 +5963,7 @@ Requires a Hex value.</property>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="y_options"></property>
<property name="y_options"/>
</packing>
</child>
</object>
@ -5984,7 +6004,6 @@ Requires a Hex value.</property>
<property name="layout_style">center</property>
<child>
<object class="GtkButton" id="button_plugin_install">
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
@ -6031,7 +6050,6 @@ Requires a Hex value.</property>
</child>
<child>
<object class="GtkButton" id="button_rescan_plugins">
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
@ -6089,7 +6107,6 @@ Requires a Hex value.</property>
<property name="can_focus">False</property>
<child>
<object class="GtkButton" id="button_find_plugins">
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>

View file

@ -114,8 +114,8 @@ DEFAULT_PREFS = {
"pref_dialog_width": None,
"pref_dialog_height": None,
"window_pane_position": -1,
"tray_download_speed_list" : [5.0, 10.0, 30.0, 80.0, 300.0],
"tray_upload_speed_list" : [5.0, 10.0, 30.0, 80.0, 300.0],
"tray_download_speed_list": [5.0, 10.0, 30.0, 80.0, 300.0],
"tray_upload_speed_list": [5.0, 10.0, 30.0, 80.0, 300.0],
"connection_limit_list": [50, 100, 200, 300, 500],
"enabled_plugins": [],
"show_connection_manager_on_start": True,
@ -151,18 +151,23 @@ DEFAULT_PREFS = {
"pieces_color_downloading": [65535, 55255, 0],
"pieces_color_completed": [4883, 26985, 56540],
"focus_main_window_on_add": True,
"language": None,
}
class GtkUI(object):
def __init__(self, args):
self.daemon_bps = (0,0,0)
self.daemon_bps = (0, 0, 0)
# Setup btkbuilder/glade translation
deluge.common.setup_translations(setup_gettext=False, setup_pygtk=True)
# Setup signals
try:
import gnome.ui
import gnome
self.gnome_prog = gnome.init("Deluge", deluge.common.get_version())
self.gnome_client = gnome.ui.master_client()
def on_die(*args):
reactor.stop()
self.gnome_client.connect("die", on_die)
@ -174,6 +179,7 @@ class GtkUI(object):
from win32api import SetConsoleCtrlHandler
from win32con import CTRL_CLOSE_EVENT
from win32con import CTRL_SHUTDOWN_EVENT
def win_handler(ctrl_type):
log.debug("ctrl_type: %s", ctrl_type)
if ctrl_type in (CTRL_CLOSE_EVENT, CTRL_SHUTDOWN_EVENT):
@ -184,11 +190,11 @@ class GtkUI(object):
if deluge.common.osx_check() and gtk.gdk.WINDOWING == "quartz":
import gtkosx_application
self.osxapp = gtkosx_application.gtkosx_application_get()
def on_die(*args):
reactor.stop()
self.osxapp.connect("NSApplicationWillTerminate", on_die)
# Set process name again to fix gtk issue
setproctitle(getproctitle())
@ -207,6 +213,10 @@ class GtkUI(object):
# shutdown the daemon.
self.started_in_classic = self.config["classic_mode"]
# Set language
if not self.config["language"] is None:
deluge.common.set_language(self.config["language"])
# Start the IPC Interface before anything else.. Just in case we are
# already running.
self.queuedtorrents = QueuedTorrents()
@ -215,7 +225,6 @@ class GtkUI(object):
# Initialize gdk threading
gtk.gdk.threads_init()
# We make sure that the UI components start once we get a core URI
client.set_disconnect_callback(self.__on_disconnect)
@ -327,8 +336,8 @@ You will either need to stop the daemon or turn off Classic Mode to continue."))
except ImportError, e:
if "No module named libtorrent" in e.message:
d = dialogs.YesNoDialog(
_("Enable Thin Client Mode?"),
_("Thin client mode is only available because libtorrent is not installed.\n\n\
_("Enable Thin Client Mode?"),
_("Thin client mode is only available because libtorrent is not installed.\n\n\
To use Deluge standalone (Classic mode) please install libtorrent.")).run()
self.started_in_classic = False
d.addCallback(on_dialog_response)
@ -344,10 +353,12 @@ To use Deluge standalone (Classic mode) please install libtorrent.")).run()
_("Error Starting Core"),
_("There was an error starting the core component which is required to run Deluge in Classic Mode.\n\n\
Please see the details below for more information."), details=traceback.format_exc(tb[2])).run()
def on_ed_response(response):
d = dialogs.YesNoDialog(
_("Turn off Classic Mode?"),
_("Since there was an error starting in Classic Mode would you like to continue by turning it off?")).run()
_("Since there was an error starting in Classic Mode would you like to continue by turning it off?")
).run()
self.started_in_classic = False
d.addCallback(on_dialog_response)
ed.addCallback(on_ed_response)
@ -406,6 +417,7 @@ Please see the details below for more information."), details=traceback.format_e
dialog = dialogs.AuthenticationDialog(
reason.value.message, reason.value.username
)
def dialog_finished(response_id, host, port):
if response_id == gtk.RESPONSE_OK:
reactor.callLater(
@ -446,7 +458,6 @@ Please see the details below for more information."), details=traceback.format_e
reactor.simulate()
self.connectionmanager.show()
def __on_disconnect(self):
"""
Called when disconnected from the daemon. We basically just stop all

View file

@ -17,9 +17,9 @@
#
# You should have received a copy of the GNU General Public License
# along with deluge. If not, write to:
# The Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor
# Boston, MA 02110-1301, USA.
# The Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor
# Boston, MA 02110-1301, USA.
#
# In addition, as a special exception, the copyright holders give
# permission to link the code of portions of this program with the OpenSSL
@ -32,66 +32,69 @@
# statement from all source files in the program, then also delete it here.
#
#
import gtk, gtk.glade
import gtk
from deluge.configmanager import ConfigManager
def accel_swap(item, group, skey, smod, dkey, dmod):
item.remove_accelerator(group, ord(skey), smod)
item.add_accelerator("activate", group, ord(dkey), dmod, gtk.ACCEL_VISIBLE)
item.remove_accelerator(group, ord(skey), smod)
item.add_accelerator("activate", group, ord(dkey), dmod, gtk.ACCEL_VISIBLE)
def accel_meta(item, group, key):
accel_swap(item, group, key, gtk.gdk.CONTROL_MASK, key, gtk.gdk.META_MASK)
accel_swap(item, group, key, gtk.gdk.CONTROL_MASK, key, gtk.gdk.META_MASK)
def menubar_osx(gtkui, osxapp):
window = gtkui.mainwindow
glade = window.main_glade
menubar = glade.get_widget("menubar")
group = gtk.accel_groups_from_object(window.window)[0]
window = gtkui.mainwindow
main_builder = window.get_builder()
menubar = main_builder.get_object("menubar")
group = gtk.accel_groups_from_object(window.window)[0]
config = ConfigManager("gtkui.conf")
config = ConfigManager("gtkui.conf")
# NOTE: accel maps doesn't work with glade file format
# because of libglade not setting MenuItem accel groups
# That's why we remove / set accelerators by hand... (dirty)
# Clean solution: migrate glades files to gtkbuilder format
file_menu = glade.get_widget("menu_file").get_submenu()
file_items = file_menu.get_children()
accel_meta(file_items[0], group, 'o')
accel_meta(file_items[1], group, 'n')
quit_all_item = file_items[3]
accel_swap(quit_all_item, group, 'q', gtk.gdk.SHIFT_MASK | gtk.gdk.CONTROL_MASK,
'q', gtk.gdk.SHIFT_MASK | gtk.gdk.META_MASK)
for item in range(2, len(file_items)): # remove quits
file_menu.remove(file_items[item])
# NOTE: accel maps doesn't work with glade file format
# because of libglade not setting MenuItem accel groups
# That's why we remove / set accelerators by hand... (dirty)
# Clean solution: migrate glades files to gtkbuilder format
file_menu = main_builder.get_object("menu_file").get_submenu()
file_items = file_menu.get_children()
accel_meta(file_items[0], group, 'o')
accel_meta(file_items[1], group, 'n')
quit_all_item = file_items[3]
accel_swap(quit_all_item, group, 'q', gtk.gdk.SHIFT_MASK | gtk.gdk.CONTROL_MASK,
'q', gtk.gdk.SHIFT_MASK | gtk.gdk.META_MASK)
for item in range(2, len(file_items)): # remove quits
file_menu.remove(file_items[item])
menu_widget = glade.get_widget("menu_edit")
edit_menu = menu_widget.get_submenu()
edit_items = edit_menu.get_children()
pref_item = edit_items[0]
accel_swap(pref_item, group, 'p', gtk.gdk.CONTROL_MASK, ',', gtk.gdk.META_MASK)
edit_menu.remove(pref_item)
menu_widget = main_builder.get_object("menu_edit")
edit_menu = menu_widget.get_submenu()
edit_items = edit_menu.get_children()
pref_item = edit_items[0]
accel_swap(pref_item, group, 'p', gtk.gdk.CONTROL_MASK, ',', gtk.gdk.META_MASK)
edit_menu.remove(pref_item)
conn_item = edit_items[1]
accel_meta(conn_item, group, 'm')
edit_menu.remove(conn_item)
conn_item = edit_items[1]
accel_meta(conn_item, group, 'm')
edit_menu.remove(conn_item)
menubar.remove(menu_widget)
menubar.remove(menu_widget)
help_menu = glade.get_widget("menu_help").get_submenu()
help_items = help_menu.get_children()
about_item = help_items[4]
help_menu.remove(about_item)
help_menu.remove(help_items[3]) # separator
help_menu = main_builder.get_object("menu_help").get_submenu()
help_items = help_menu.get_children()
about_item = help_items[4]
help_menu.remove(about_item)
help_menu.remove(help_items[3]) # separator
menubar.hide()
osxapp.set_menu_bar(menubar)
# populate app menu
osxapp.insert_app_menu_item(about_item, 0)
osxapp.insert_app_menu_item(gtk.SeparatorMenuItem(), 1)
osxapp.insert_app_menu_item(pref_item, 2)
if not config["classic_mode"]:
osxapp.insert_app_menu_item(conn_item, 3)
if quit_all_item.get_visible():
osxapp.insert_app_menu_item(gtk.SeparatorMenuItem(), 4)
osxapp.insert_app_menu_item(quit_all_item, 5)
menubar.hide()
osxapp.set_menu_bar(menubar)
# populate app menu
osxapp.insert_app_menu_item(about_item, 0)
osxapp.insert_app_menu_item(gtk.SeparatorMenuItem(), 1)
osxapp.insert_app_menu_item(pref_item, 2)
if not config["classic_mode"]:
osxapp.insert_app_menu_item(conn_item, 3)
if quit_all_item.get_visible():
osxapp.insert_app_menu_item(gtk.SeparatorMenuItem(), 4)
osxapp.insert_app_menu_item(quit_all_item, 5)

View file

@ -62,6 +62,7 @@ COLOR_STATES = {
"completed": COLOR_COMPLETED
}
class Preferences(component.Component):
def __init__(self):
component.Component.__init__(self, "Preferences")
@ -180,6 +181,7 @@ class Preferences(component.Component):
"on_missing_color_set": self._on_missing_color_set,
"on_revert_color_missing_clicked": self._on_revert_color_missing_clicked,
"on_pref_dialog_configure_event": self.on_pref_dialog_configure_event,
"on_checkbutton_language_toggled": self._on_checkbutton_language_toggled,
})
from deluge.ui.gtkui.gtkui import DEFAULT_PREFS
@ -193,6 +195,7 @@ class Preferences(component.Component):
self.enabled_plugins = []
self.setup_path_choosers()
self.load_languages()
def setup_path_choosers(self):
self.download_location_hbox = self.builder.get_object("hbox_download_to_path_chooser")
@ -210,6 +213,31 @@ class Preferences(component.Component):
self.copy_torrents_to_hbox.add(self.copy_torrent_files_path_chooser)
self.copy_torrents_to_hbox.show_all()
def load_languages(self):
from deluge.ui import languages # Import here so that gettext has been setup first
translations_path = deluge.common.get_translations_path()
for root, dirs, files in os.walk(translations_path):
# Get the dirs
break
self.language_combo = self.builder.get_object("combobox_language")
self.language_checkbox = self.builder.get_object("checkbutton_language")
lang_model = self.language_combo.get_model()
index = -1
for i, lang_code in enumerate(sorted(dirs)):
name = "%s (Language name missing)" % lang_code
if lang_code in languages.LANGUAGES:
name = languages.LANGUAGES[lang_code]
lang_model.append([lang_code, name])
if self.gtkui_config["language"] == lang_code:
index = i
if self.gtkui_config["language"] is None:
self.language_checkbox.set_active(True)
self.language_combo.set_sensitive(False)
elif index != -1:
self.language_combo.set_active(index)
def __del__(self):
del self.gtkui_config
@ -260,9 +288,9 @@ class Preferences(component.Component):
self.liststore.foreach(check_row, name)
# Remove the page and row
if self.page_num_to_remove != None:
if self.page_num_to_remove is not None:
self.notebook.remove_page(self.page_num_to_remove)
if self.iter_to_remove != None:
if self.iter_to_remove is not None:
self.liststore.remove(self.iter_to_remove)
# We need to re-adjust the index values for the remaining pages
@ -273,7 +301,7 @@ class Preferences(component.Component):
"""Page should be the string in the left list.. ie, 'Network' or
'Bandwidth'"""
self.window_open = True
if page != None:
if page is not None:
for (index, string) in self.liststore:
if page == string:
self.treeview.get_selection().select_path(index)
@ -321,7 +349,7 @@ class Preferences(component.Component):
self._show()
def _show(self):
self.is_connected = self.core_config != {} and self.core_config != None
self.is_connected = self.core_config != {} and self.core_config is not None
core_widgets = {
"chk_move_completed": ("active", "move_completed"),
"chk_copy_torrent_file": ("active", "copy_torrent_file"),
@ -430,7 +458,7 @@ class Preferences(component.Component):
elif type(value) is str:
value = self.core_config[value]
elif modifier:
value = {"active": False, "not_active": False, "value": 0, "text": "", "path_chooser": "" }[modifier]
value = {"active": False, "not_active": False, "value": 0, "text": "", "path_chooser": ""}[modifier]
if modifier == "active":
widget.set_active(value)
@ -644,8 +672,7 @@ class Preferences(component.Component):
self.builder.get_object("chk_enable_appindicator").get_active()
new_gtkui_config["lock_tray"] = \
self.builder.get_object("chk_lock_tray").get_active()
passhex = sha_hash(\
self.builder.get_object("txt_tray_password").get_text()).hexdigest()
passhex = sha_hash(self.builder.get_object("txt_tray_password").get_text()).hexdigest()
if passhex != "c07eb5a8c0dc7bb81c217b67f11c3b7a5e95ffd7":
new_gtkui_config["tray_password"] = passhex
@ -723,6 +750,29 @@ class Preferences(component.Component):
# Run plugin hook to apply preferences
component.get("PluginManager").run_on_apply_prefs()
# Lanuage
if self.language_checkbox.get_active():
new_gtkui_config["language"] = None
else:
active = self.language_combo.get_active()
if active == -1:
dialog = dialogs.InformationDialog(
_("Attention"),
_("You must choose a language")
)
dialog.run()
return
else:
model = self.language_combo.get_model()
new_gtkui_config["language"] = model.get(model.get_iter(active), 0)[0]
if new_gtkui_config["language"] != self.gtkui_config["language"]:
dialog = dialogs.InformationDialog(
_("Attention"),
_("You must now restart the deluge UI for the changes to take effect.")
)
dialog.run()
# GtkUI
for key in new_gtkui_config.keys():
# The values do not match so this needs to be updated
@ -751,7 +801,7 @@ class Preferences(component.Component):
# Re-show the dialog to make sure everything has been updated
self.show()
if classic_mode_was_set == True and new_gtkui_in_classic_mode == False:
if classic_mode_was_set and not new_gtkui_in_classic_mode:
def on_response(response):
if response == gtk.RESPONSE_NO:
# Set each changed config value in the core
@ -766,7 +816,7 @@ class Preferences(component.Component):
_("Your current session will be stopped. Continue?")
)
dialog.run().addCallback(on_response)
elif classic_mode_was_set == False and new_gtkui_in_classic_mode == True:
elif not classic_mode_was_set and new_gtkui_in_classic_mode:
dialog = dialogs.InformationDialog(
_("Attention"),
_("You must now restart the deluge UI")
@ -807,7 +857,7 @@ class Preferences(component.Component):
def load_pref_dialog_state(self):
w = self.gtkui_config["pref_dialog_width"]
h = self.gtkui_config["pref_dialog_height"]
if w != None and h != None:
if w is not None and h is not None:
self.pref_dialog.resize(w, h)
def on_pref_dialog_configure_event(self, widget, event):
@ -827,25 +877,25 @@ class Preferences(component.Component):
}
dependents = {
"chk_show_dialog": {"chk_focus_dialog": True},
"chk_random_port": {"spin_port_min": False,
"spin_port_max": False},
"chk_random_outgoing_ports": {"spin_outgoing_port_min": False,
"spin_outgoing_port_max": False},
"chk_use_tray": {"chk_min_on_close": True,
"chk_start_in_tray": True,
"chk_enable_appindicator": True,
"chk_lock_tray": True},
"chk_lock_tray": {"txt_tray_password": True,
"password_label": True},
"radio_open_folder_custom": {"combo_file_manager": False,
"txt_open_folder_location": True},
"chk_move_completed" : {"move_completed_path_chooser" : True},
"chk_copy_torrent_file" : {"torrentfiles_location_path_chooser" : True,
"chk_del_copy_torrent_file" : True},
"chk_seed_ratio" : {"spin_share_ratio": True,
"chk_remove_ratio" : True}
}
"chk_show_dialog": {"chk_focus_dialog": True},
"chk_random_port": {"spin_port_min": False,
"spin_port_max": False},
"chk_random_outgoing_ports": {"spin_outgoing_port_min": False,
"spin_outgoing_port_max": False},
"chk_use_tray": {"chk_min_on_close": True,
"chk_start_in_tray": True,
"chk_enable_appindicator": True,
"chk_lock_tray": True},
"chk_lock_tray": {"txt_tray_password": True,
"password_label": True},
"radio_open_folder_custom": {"combo_file_manager": False,
"txt_open_folder_location": True},
"chk_move_completed": {"move_completed_path_chooser": True},
"chk_copy_torrent_file": {"torrentfiles_location_path_chooser": True,
"chk_del_copy_torrent_file": True},
"chk_seed_ratio": {"spin_share_ratio": True,
"chk_remove_ratio": True}
}
def update_dependent_widgets(name, value):
dependency = dependents[name]
@ -935,11 +985,13 @@ class Preferences(component.Component):
def _on_button_plugin_install_clicked(self, widget):
log.debug("_on_button_plugin_install_clicked")
chooser = gtk.FileChooserDialog(_("Select the Plugin"),
chooser = gtk.FileChooserDialog(
_("Select the Plugin"),
self.pref_dialog,
gtk.FILE_CHOOSER_ACTION_OPEN,
buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN,
gtk.RESPONSE_OK))
gtk.RESPONSE_OK)
)
chooser.set_transient_for(self.pref_dialog)
chooser.set_select_multiple(False)
@ -1029,7 +1081,6 @@ class Preferences(component.Component):
def _on_button_associate_magnet_clicked(self, widget):
common.associate_magnet_links(True)
def _get_accounts_tab_data(self):
def on_ok(accounts):
self.accounts_frame.show()
@ -1151,7 +1202,7 @@ class Preferences(component.Component):
dialogs.ErrorDialog(
_("Error Updating Account"),
_("An error ocurred while updating account"),
parent=self.pref_dialog, details=failure.getErrorMessage()
parent=self.pref_dialog, details=failure.getErrorMessage()
).run()
if response_id == gtk.RESPONSE_OK:
@ -1207,6 +1258,9 @@ class Preferences(component.Component):
colors_widget = self.builder.get_object("piecebar_colors_expander")
colors_widget.set_visible(widget.get_active())
def _on_checkbutton_language_toggled(self, widget):
self.language_combo.set_sensitive(not self.language_checkbox.get_active())
def _on_completed_color_set(self, widget):
self.__set_color("completed")

105
deluge/ui/languages.py Normal file
View file

@ -0,0 +1,105 @@
#
# languages.py
#
# This file is public domain.
#
# Language code for this installation. All choices can be found here:
# http://www.i18nguy.com/unicode/language-identifiers.html
LANGUAGE_CODE = 'en-us'
# Languages we provide translations for, out of the box.
LANGUAGES = {
'af': _('Afrikaans'),
'ar': _('Arabic'),
'ast': _('Asturian'),
'az': _('Azerbaijani'),
'bg': _('Bulgarian'),
'be': _('Belarusian'),
'bn': _('Bengali'),
'br': _('Breton'),
'bs': _('Bosnian'),
'ca': _('Catalan'),
'cs': _('Czech'),
'cy': _('Welsh'),
'da': _('Danish'),
'de': _('German'),
'el': _('Greek'),
'en': _('English'),
'en_AU': _('English (Australia)'),
'en_CA': _('English (Canada)'),
'en_GB': _('English (United Kingdom)'),
'eo': _('Esperanto'),
'es': _('Spanish'),
'es-ar': _('Argentinian Spanish'),
'es-mx': _('Mexican Spanish'),
'es-ni': _('Nicaraguan Spanish'),
'es-ve': _('Venezuelan Spanish'),
'et': _('Estonian'),
'eu': _('Basque'),
'fa': _('Persian'),
'fi': _('Finnish'),
'fr': _('French'),
'fy': _('Frisian'),
'ga': _('Irish'),
'gl': _('Galician'),
'he': _('Hebrew'),
'hi': _('Hindi'),
'hr': _('Croatian'),
'hu': _('Hungarian'),
'ia': _('Interlingua'),
'id': _('Indonesian'),
'is': _('Icelandic'),
'it': _('Italian'),
'ja': _('Japanese'),
'ka': _('Georgian'),
'kk': _('Kazakh'),
'km': _('Khmer'),
'kn': _('Kannada'),
'ko': _('Korean'),
'la': _('Latin'),
'lb': _('Luxembourgish'),
'lt': _('Lithuanian'),
'lv': _('Latvian'),
'mk': _('Macedonian'),
'ml': _('Malayalam'),
'mn': _('Mongolian'),
'ms': _('Mayaly'),
'my': _('Burmese'),
'nb': _('Norwegian Bokmal'),
'ne': _('Nepali'),
'nds': _('Low German'),
'nl': _('Dutch'),
'nn': _('Norwegian Nynorsk'),
'os': _('Ossetic'),
'pa': _('Punjabi'),
'pl': _('Polish'),
'pms': _('Piedmontese'),
'pt': _('Portuguese'),
'pt_BR': _('Brazilian Portuguese'),
'ro': _('Romanian'),
'ru': _('Russian'),
'sk': _('Slovak'),
'sl': _('Slovenian'),
'sq': _('Albanian'),
'sr': _('Serbian'),
'sr-latn': _('Serbian Latin'),
'sv': _('Swedish'),
'sw': _('Swahili'),
'ta': _('Tamil'),
'te': _('Telugu'),
'th': _('Thai'),
'tl': _('Tagalog'),
'tlh': _('Klingon'),
'tr': _('Turkish'),
'tt': _('Tatar'),
'udm': _('Udmurt'),
'uk': _('Ukrainian'),
'ur': _('Urdu'),
'vi': _('Vietnamese'),
'zh_CN': _('Chinese (Simplified)'),
'zh_HK': _('Chinese (Hong Kong)'),
'zh-hans': _('Simplified Chinese'),
'zh-hant': _('Traditional Chinese'),
'zh_TW': _('Chinese (Taiwan)'),
}

View file

@ -47,6 +47,7 @@ try:
except ImportError:
setproctitle = lambda t: None
def version_callback(option, opt_str, value, parser):
print os.path.basename(sys.argv[0]) + ": " + deluge.common.get_version()
try:
@ -64,20 +65,16 @@ if 'dev' not in deluge.common.get_version():
import warnings
warnings.filterwarnings('ignore', category=DeprecationWarning, module='twisted')
class _UI(object):
def __init__(self, name="gtk"):
self.__name = name
if name == "gtk":
deluge.common.setup_translations(setup_pygtk=True)
else:
deluge.common.setup_translations()
self.__parser = OptionParser(usage="%prog [options] [actions]")
self.__parser.add_option("-v", "--version", action="callback", callback=version_callback,
help="Show program's version number and exit")
group = OptionGroup(self.__parser, _("Common Options"))
group = OptionGroup(self.__parser, "Common Options")
group.add_option("-c", "--config", dest="config",
help="Set the config folder location", action="store", type="str")
group.add_option("-l", "--logfile", dest="logfile",
@ -133,6 +130,9 @@ class _UI(object):
log.error("There was an error setting the config dir! Exiting..")
sys.exit(1)
# Setup gettext
deluge.common.setup_translations()
setproctitle("deluge-%s" % self.__name)
log.info("Deluge ui %s", deluge.common.get_version())
@ -140,12 +140,16 @@ class _UI(object):
log.debug("args: %s", self.__args)
log.info("Starting %s ui..", self.__name)
class UI:
def __init__(self, options, args, ui_args):
import logging
log = logging.getLogger(__name__)
log.debug("UI init..")
# Setup gettext
deluge.common.setup_translations()
# Set the config directory
deluge.configmanager.set_config_dir(options.config)
@ -181,7 +185,8 @@ class UI:
stack = traceback.extract_tb(tb)
last_frame = stack[-1]
if last_frame[0] == __file__:
log.error("Unable to find the requested UI: %s. Please select a different UI with the '-u' option or alternatively use the '-s' option to select a different default UI.", selected_ui)
log.error("Unable to find the requested UI: %s. Please select a different UI with the '-u' option \
or alternatively use the '-s' option to select a different default UI.", selected_ui)
else:
log.exception(e)
log.error("There was an error whilst launching the request UI: %s", selected_ui)