📄 settingswindow.py
字号:
# The contents of this file are subject to the BitTorrent Open Source License# Version 1.1 (the License). You may not copy or use this file, in either# source code or executable form, except in compliance with the License. You# may obtain a copy of the License at http://www.bittorrent.com/license/.## Software distributed under the License is distributed on an AS IS basis,# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License# for the specific language governing rights and limitations under the# License.# written by Greg Hazel, based on code by Matt Chisholmfrom __future__ import divisionimport osimport mathimport randomimport wxfrom BitTorrent.translation import _from BitTorrent import app_namefrom BitTorrent.obsoletepythonsupport import setfrom BitTorrent.sparse_set import SparseSetfrom BitTorrent.GUI_wx import VSizer, HSizer, BTDialog, CheckButton, ChooseDirectorySizer, SPACING, ElectroStaticText, IPValidator, PortValidator, text_wrappable, gui_wrapfrom BitTorrent.GUI_wx.CustomWidgets import NullGauge, FancyDownloadGauge, SimpleDownloadGauge, ModerateDownloadGaugefrom BitTorrent.UI import Ratefrom BitTorrent.GUI_wx.LanguageSettings import LanguageSettingsupload_speed_classes = { ( 4, 5):_("dialup" ), ( 6, 14):_("DSL/cable 128Kb up"), ( 15, 29):_("DSL/cable 256Kb up"), ( 30, 91):_("DSL 768Kb up" ), ( 92, 137):_("T1" ), ( 138, 182):_("T1/E1" ), ( 183, 249):_("E1" ), ( 250, 5446):_("T3" ), ( 5447,18871):_("OC3" ), (18872,125e6):_("fast" ), }download_speed_classes = { ( 4, 5):_("dialup" ), ( 6, 46):_("DSL/cable 384Kb down"), ( 47, 93):_("DSL/cable 768Kb down"), ( 93, 182):_("DSL/T1" ), ( 182, 249):_("E1" ), ( 250, 729):_("DSL 6Mb down" ), ( 730, 5442):_("T3" ), ( 5443,18858):_("OC3" ), (18859,125e6):_("fast" ), }class RateSlider(wx.Slider): base = 10 multiplier = 4 max_exponent = 4.49 slider_scale = 1000 # slider goes from 0 to slider_scale * max_exponent backend_conversion = 1024 # slider deals in KB, backend in B def __init__(self, parent, value, speed_classes): self.speed_classes = speed_classes value = self.bytes_to_slider(value) wx.Slider.__init__(self, parent, wx.ID_ANY, value=value, minValue=0, maxValue=self.max_exponent * self.slider_scale) def bytes_to_slider(self, value): value /= self.backend_conversion try: r = math.log(value/self.multiplier, self.base) except OverflowError, e: wx.the_app.logger.error(u'%s (%s, %s, %s)' % (unicode(e.args[0]), value, self.multiplier, self.base), exc_info=sys.exc_info()) return r * self.slider_scale def slider_to_bytes(self, value): r = self.slider_to_kbytes(value) return r * self.backend_conversion def slider_to_kbytes(self, value): value /= self.slider_scale r = int(round(self.base**value * self.multiplier)) return r def slider_to_label(self, value): value = self.slider_to_kbytes(value) conn_type = '' for key, conn in self.speed_classes.iteritems(): min_v, max_v = key if min_v <= value <= max_v: conn_type = ' (%s)' % conn break label = unicode(Rate(value*self.backend_conversion)) + conn_type return labelclass RateSliderBox(wx.StaticBox): def __init__(self, parent, label, key, settings_window, speed_classes): self.key = key self.settings_window = settings_window wx.StaticBox.__init__(self, parent, label=label) self.sizer = wx.StaticBoxSizer(self, wx.VERTICAL) self.text = ElectroStaticText(parent, wx.ID_ANY, 'text') self.setfunc = lambda v : self.settings_window.setfunc(key, v) self.slider = RateSlider(parent, self.settings_window.config[key], speed_classes) self.slider.Bind(wx.EVT_SLIDER, self.OnSlider) self.LoadValue() self.sizer.Add(self.text, proportion=1, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT, border=SPACING) self.sizer.Add(self.slider, proportion=1, flag=wx.GROW|wx.BOTTOM|wx.LEFT|wx.RIGHT, border=SPACING) def LoadValue(self): bytes = self.settings_window.config[self.key] if bytes <= 0: wx.the_app.logger.warning(_("Impractically low rate (%s), fixing") % bytes) self.settings_window.config[self.key] = 4 * 1024 bytes = self.settings_window.config[self.key] self.slider.SetValue(self.slider.bytes_to_slider(bytes)) self.text.SetLabel(self.slider.slider_to_label(self.slider.GetValue())) def OnSlider(self, event): value = event.GetInt() bytes = self.slider.slider_to_bytes(value) self.setfunc(bytes) label = self.slider.slider_to_label(value) self.text.SetLabel(label) def Enable(self, enable): self.text.Enable(enable) self.slider.Enable(enable)class SettingsPanel(wx.Panel): """Base class for settings panels""" label = '' def __init__(self, parent, *a, **k): style = k.get('style', 0) k['style'] = style | wx.CLIP_CHILDREN | wx.TAB_TRAVERSAL # aarrg self.settings_window = parent.GetParent() wx.Panel.__init__(self, parent, *a, **k) parent.AddPage(self, self.label) self.sizer = VSizer() self.SetSizerAndFit(self.sizer)class GeneralSettingsPanel(SettingsPanel): label = _("General") def __init__(self, parent, *a, **k): SettingsPanel.__init__(self, parent, *a, **k) # widgets self.confirm_checkbutton = CheckButton( self, _("Confirm before quitting %s")%app_name, self.settings_window, 'confirm_quit', self.settings_window.config['confirm_quit']) # sizers self.sizer.AddFirst(self.confirm_checkbutton) if os.name == 'nt': # widgets self.enforce_checkbutton = CheckButton( self, _("Enforce .torrent associations on startup"), self.settings_window, 'enforce_association', self.settings_window.config['enforce_association']) self.startup_checkbutton = CheckButton( self, _("Launch BitTorrent when Windows starts"), self.settings_window, 'launch_on_startup', self.settings_window.config['launch_on_startup']) self.start_minimized_checkbutton = CheckButton( self, _("Start minimized"), self.settings_window, 'start_minimized', self.settings_window.config['start_minimized']) self.minimize_checkbutton = CheckButton( self, _("Minimize to the system tray"), self.settings_window, 'minimize_to_tray', self.settings_window.config['minimize_to_tray']) self.quit_checkbutton = CheckButton( self, _("Close to the system tray"), self.settings_window, 'close_to_tray', self.settings_window.config['close_to_tray']) # sizers self.sizer.Add(wx.StaticLine(self, style=wx.LI_HORIZONTAL), flag=wx.GROW) self.sizer.Add(self.enforce_checkbutton) self.sizer.Add(wx.StaticLine(self, style=wx.LI_HORIZONTAL), flag=wx.GROW) self.sizer.Add(self.startup_checkbutton) self.sizer.Add(self.start_minimized_checkbutton) self.sizer.Add(wx.StaticLine(self, style=wx.LI_HORIZONTAL), flag=wx.GROW) self.sizer.Add(self.minimize_checkbutton) self.sizer.Add(self.quit_checkbutton)class SavingSettingsPanel(SettingsPanel): label = _("Saving") def __init__(self, parent, *a, **k): SettingsPanel.__init__(self, parent, *a, **k) # widgets self.ask_checkbutton = CheckButton(self, _("Ask where to save each new download"), self.settings_window, 'ask_for_save', self.settings_window.config['ask_for_save']) self.save_static_box = wx.StaticBox(self, label=_("Move completed downloads to:")) self.save_box = ChooseDirectorySizer(self, self.settings_window.config['save_in'], setfunc = lambda v: self.settings_window.setfunc('save_in', v), editable = False, button_label = _("&Browse")) self.incoming_static_box = wx.StaticBox(self, label=_("Store unfinished downloads in:")) self.incoming_box = ChooseDirectorySizer(self, self.settings_window.config['save_incomplete_in'], setfunc = lambda v: self.settings_window.setfunc('save_incomplete_in', v), editable = False, button_label = _("B&rowse")) # sizers self.save_static_box_sizer = wx.StaticBoxSizer(self.save_static_box, wx.VERTICAL) self.save_static_box_sizer.Add(self.save_box, flag=wx.ALL|wx.GROW, border=SPACING) self.incoming_static_box_sizer = wx.StaticBoxSizer(self.incoming_static_box, wx.VERTICAL) self.incoming_static_box_sizer.Add(self.incoming_box, flag=wx.ALL|wx.GROW, border=SPACING) self.sizer.AddFirst(self.ask_checkbutton) self.sizer.Add(self.save_static_box_sizer, flag=wx.GROW) self.sizer.Add(self.incoming_static_box_sizer, flag=wx.GROW)class NetworkSettingsPanel(SettingsPanel): label = _("Network") def __init__(self, parent, *a, **k): SettingsPanel.__init__(self, parent, *a, **k) if os.name == 'nt': self.autodetect = CheckButton(self, _("Autodetect available bandwidth"), self.settings_window, 'bandwidth_management', self.settings_window.config['bandwidth_management'], self.bandwidth_management_callback ) self.sizer.AddFirst(self.autodetect) self.up_rate_slider = RateSliderBox(self, _("Maximum upload rate"), 'max_upload_rate', self.settings_window, upload_speed_classes) self.sizer.Add(self.up_rate_slider.sizer, flag=wx.GROW) self.down_rate_slider = RateSliderBox(self, _("Average maximum download rate"), 'max_download_rate', self.settings_window, download_speed_classes) self.sizer.Add(self.down_rate_slider.sizer, flag=wx.GROW) if os.name == 'nt': self.bandwidth_management_callback() # Network widgets self.port_box = wx.StaticBox(self, label=_("Look for available port:")) port_text = ElectroStaticText(self, wx.ID_ANY, _("starting at port:") + ' ') port_range = ElectroStaticText(self, wx.ID_ANY, " (1024-65535)") self.port_field = PortValidator(self, 'minport', self.settings_window.config, self.settings_window.setfunc) self.port_field.add_end('maxport') self.upnp = CheckButton(self, _("Enable automatic port mapping")+" (&UPnP)", self.settings_window, 'upnp', self.settings_window.config['upnp'], None) # Network sizers self.port_box_line1 = wx.BoxSizer(wx.HORIZONTAL) self.port_box_line1.Add(port_text , flag=wx.ALIGN_CENTER_VERTICAL, border=SPACING) self.port_box_line1.Add(self.port_field) self.port_box_line1.Add(port_range, flag=wx.ALIGN_CENTER_VERTICAL, border=SPACING) self.port_box_sizer = wx.StaticBoxSizer(self.port_box, wx.VERTICAL) self.port_box_sizer.Add(self.port_box_line1, flag=wx.TOP|wx.LEFT|wx.RIGHT, border=SPACING) self.port_box_sizer.Add(self.upnp, flag=wx.ALL, border=SPACING) self.sizer.Add(self.port_box_sizer, flag=wx.GROW) # debug only code if wx.the_app.config['debug']: # widgets self.ip_box = wx.StaticBox(self, label=_("IP to report to the tracker:"))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -