lots of new preference work
This commit is contained in:
parent
4a071ecba1
commit
8a9e732f95
|
@ -331,11 +331,21 @@ class AllTorrents(BaseMode):
|
|||
td = TorrentDetail(self,tid,self.stdscr,self.encoding)
|
||||
component.get("ConsoleUI").set_mode(td)
|
||||
|
||||
def show_preferences(self, core_config):
|
||||
component.stop(["AllTorrentsStateUpdater"])
|
||||
self.stdscr.clear()
|
||||
prefs = Preferences(self,core_config,self.stdscr,self.encoding)
|
||||
component.get("ConsoleUI").set_mode(prefs)
|
||||
def show_preferences(self):
|
||||
def _on_get_config(config):
|
||||
client.core.get_listen_port().addCallback(_on_get_listen_port,config)
|
||||
|
||||
def _on_get_listen_port(port,config):
|
||||
client.core.get_cache_status().addCallback(_on_get_cache_status,port,config)
|
||||
|
||||
def _on_get_cache_status(status,port,config):
|
||||
component.stop(["AllTorrentsStateUpdater"])
|
||||
self.stdscr.clear()
|
||||
prefs = Preferences(self,config,port,status,self.stdscr,self.encoding)
|
||||
component.get("ConsoleUI").set_mode(prefs)
|
||||
|
||||
client.core.get_config().addCallback(_on_get_config)
|
||||
|
||||
|
||||
def __show_events(self):
|
||||
component.stop(["AllTorrentsStateUpdater"])
|
||||
|
@ -619,7 +629,7 @@ class AllTorrents(BaseMode):
|
|||
for l in HELP_LINES:
|
||||
self.popup.add_line(l)
|
||||
elif chr(c) == 'p':
|
||||
client.core.get_config().addCallback(self.show_preferences)
|
||||
self.show_preferences()
|
||||
return
|
||||
elif chr(c) == 'e':
|
||||
self.__show_events()
|
||||
|
|
|
@ -49,6 +49,7 @@ from popup import Popup
|
|||
log = logging.getLogger(__name__)
|
||||
|
||||
class InputField:
|
||||
depend = None
|
||||
# render the input. return number of rows taken up
|
||||
def render(self,screen,row,width,selected,col=1):
|
||||
return 0
|
||||
|
@ -61,6 +62,20 @@ class InputField:
|
|||
def set_value(self, value):
|
||||
pass
|
||||
|
||||
def set_depend(self,i,inverse=False):
|
||||
if not isinstance(i,CheckedInput):
|
||||
raise Exception("Can only depend on CheckedInputs")
|
||||
self.depend = i
|
||||
self.inverse = inverse
|
||||
|
||||
def depend_skip(self):
|
||||
if not self.depend:
|
||||
return False
|
||||
if self.inverse:
|
||||
return self.depend.checked
|
||||
else:
|
||||
return not self.depend.checked
|
||||
|
||||
class CheckedInput(InputField):
|
||||
def __init__(self, parent, message, name, checked=False):
|
||||
self.parent = parent
|
||||
|
@ -92,6 +107,71 @@ class CheckedInput(InputField):
|
|||
def set_value(self, c):
|
||||
self.checked = c
|
||||
|
||||
|
||||
class CheckedPlusInput(InputField):
|
||||
def __init__(self, parent, message, name, child,checked=False):
|
||||
self.parent = parent
|
||||
self.chkd_inact = "[X] %s"%message
|
||||
self.unchkd_inact = "[ ] %s"%message
|
||||
self.chkd_act = "[{!black,white,bold!}X{!white,black!}] %s"%message
|
||||
self.unchkd_act = "[{!black,white,bold!} {!white,black!}] %s"%message
|
||||
self.name = name
|
||||
self.checked = checked
|
||||
self.msglen = len(self.chkd_inact)+1
|
||||
self.child = child
|
||||
self.child_active = False
|
||||
|
||||
def render(self, screen, row, width, active, col=1):
|
||||
isact = active and not self.child_active
|
||||
if self.checked and isact:
|
||||
self.parent.add_string(row,self.chkd_act,screen,col,False,True)
|
||||
elif self.checked:
|
||||
self.parent.add_string(row,self.chkd_inact,screen,col,False,True)
|
||||
elif isact:
|
||||
self.parent.add_string(row,self.unchkd_act,screen,col,False,True)
|
||||
else:
|
||||
self.parent.add_string(row,self.unchkd_inact,screen,col,False,True)
|
||||
|
||||
if active and self.checked and self.child_active:
|
||||
self.parent.add_string(row+1,"(esc to leave)",screen,col,False,True)
|
||||
elif active and self.checked:
|
||||
self.parent.add_string(row+1,"(right arrow to edit)",screen,col,False,True)
|
||||
rows = 2
|
||||
# show child
|
||||
if self.checked:
|
||||
if isinstance(self.child,(TextInput,IntSpinInput,FloatSpinInput)):
|
||||
crows = self.child.render(screen,row,width-self.msglen,self.child_active and active,col+self.msglen,self.msglen)
|
||||
else:
|
||||
crows = self.child.render(screen,row,width-self.msglen,self.child_active and active,col+self.msglen)
|
||||
rows = max(rows,crows)
|
||||
else:
|
||||
self.parent.add_string(row,"(enable to view/edit value)",screen,col+self.msglen,False,True)
|
||||
return rows
|
||||
|
||||
def handle_read(self, c):
|
||||
if self.child_active:
|
||||
if c == 27: # leave child on esc
|
||||
self.child_active = False
|
||||
return
|
||||
# pass keys through to child
|
||||
self.child.handle_read(c)
|
||||
else:
|
||||
if c == 32:
|
||||
self.checked = not self.checked
|
||||
if c == curses.KEY_RIGHT:
|
||||
self.child_active = True
|
||||
|
||||
def get_value(self):
|
||||
return self.checked
|
||||
|
||||
def set_value(self, c):
|
||||
self.checked = c
|
||||
|
||||
def get_child(self):
|
||||
return self.child
|
||||
|
||||
|
||||
|
||||
class IntSpinInput(InputField):
|
||||
def __init__(self, parent, message, name, move_func, value, min_val, max_val):
|
||||
self.parent = parent
|
||||
|
@ -106,7 +186,7 @@ class IntSpinInput(InputField):
|
|||
self.min_val = min_val
|
||||
self.max_val = max_val
|
||||
|
||||
def render(self, screen, row, width, active, col=1):
|
||||
def render(self, screen, row, width, active, col=1, cursor_offset=0):
|
||||
if not active and not self.valstr:
|
||||
self.value = self.initvalue
|
||||
self.valstr = "%d"%self.value
|
||||
|
@ -119,7 +199,7 @@ class IntSpinInput(InputField):
|
|||
self.parent.add_string(row,"%s [ %d ]"%(self.message,self.value),screen,col,False,True)
|
||||
|
||||
if active:
|
||||
self.move_func(row,self.cursor+self.cursoff)
|
||||
self.move_func(row,self.cursor+self.cursoff+cursor_offset)
|
||||
|
||||
return 1
|
||||
|
||||
|
@ -166,6 +246,112 @@ class IntSpinInput(InputField):
|
|||
self.valstr = "%d"%self.value
|
||||
self.cursor = len(self.valstr)
|
||||
|
||||
|
||||
class FloatSpinInput(InputField):
|
||||
def __init__(self, parent, message, name, move_func, value, inc_amt, precision, min_val, max_val):
|
||||
self.parent = parent
|
||||
self.message = message
|
||||
self.name = name
|
||||
self.precision = precision
|
||||
self.inc_amt = inc_amt
|
||||
self.value = round(float(value),self.precision)
|
||||
self.initvalue = self.value
|
||||
self.fmt = "%%.%df"%precision
|
||||
self.valstr = self.fmt%self.value
|
||||
self.cursor = len(self.valstr)
|
||||
self.cursoff = len(self.message)+4 # + 4 for the " [ " in the rendered string
|
||||
self.move_func = move_func
|
||||
self.min_val = min_val
|
||||
self.max_val = max_val
|
||||
self.need_update = False
|
||||
|
||||
def render(self, screen, row, width, active, col=1, cursor_offset=0):
|
||||
if not active and not self.valstr:
|
||||
self.value = self.initvalue
|
||||
self.valstr = self.fmt%self.value
|
||||
self.cursor = len(self.valstr)
|
||||
if not active and self.need_update:
|
||||
self.value = round(float(self.valstr),self.precision)
|
||||
self.valstr = self.fmt%self.value
|
||||
self.cursor = len(self.valstr)
|
||||
if not self.valstr:
|
||||
self.parent.add_string(row,"%s [ ]"%self.message,screen,col,False,True)
|
||||
elif active:
|
||||
self.parent.add_string(row,"%s [ {!black,white,bold!}%s{!white,black!} ]"%(self.message,self.valstr),screen,col,False,True)
|
||||
else:
|
||||
self.parent.add_string(row,"%s [ %s ]"%(self.message,self.valstr),screen,col,False,True)
|
||||
if active:
|
||||
self.move_func(row,self.cursor+self.cursoff+cursor_offset)
|
||||
|
||||
return 1
|
||||
|
||||
def handle_read(self, c):
|
||||
if c == curses.KEY_PPAGE:
|
||||
self.value+=self.inc_amt
|
||||
self.valstr = self.fmt%self.value
|
||||
self.cursor = len(self.valstr)
|
||||
elif c == curses.KEY_NPAGE:
|
||||
self.value-=self.inc_amt
|
||||
self.valstr = self.fmt%self.value
|
||||
self.cursor = len(self.valstr)
|
||||
elif c == curses.KEY_LEFT:
|
||||
self.cursor = max(0,self.cursor-1)
|
||||
elif c == curses.KEY_RIGHT:
|
||||
self.cursor = min(len(self.valstr),self.cursor+1)
|
||||
elif c == curses.KEY_HOME:
|
||||
self.cursor = 0
|
||||
elif c == curses.KEY_END:
|
||||
self.cursor = len(self.value)
|
||||
elif c == curses.KEY_BACKSPACE or c == 127:
|
||||
if self.valstr and self.cursor > 0:
|
||||
self.valstr = self.valstr[:self.cursor - 1] + self.valstr[self.cursor:]
|
||||
self.cursor-=1
|
||||
self.need_update = True
|
||||
elif c == curses.KEY_DC:
|
||||
if self.valstr and self.cursor < len(self.valstr):
|
||||
self.valstr = self.valstr[:self.cursor] + self.valstr[self.cursor+1:]
|
||||
self.need_update = True
|
||||
elif c == 45 and self.cursor == 0 and self.min_val < 0:
|
||||
minus_place = self.valstr.find('-')
|
||||
if minus_place >= 0: return
|
||||
self.valstr = chr(c)+self.valstr
|
||||
self.cursor += 1
|
||||
self.need_update = True
|
||||
elif c == 46:
|
||||
minus_place = self.valstr.find('-')
|
||||
if self.cursor <= minus_place: return
|
||||
point_place = self.valstr.find('.')
|
||||
if point_place >= 0: return
|
||||
if self.cursor == len(self.valstr):
|
||||
self.valstr += chr(c)
|
||||
else:
|
||||
# Insert into string
|
||||
self.valstr = self.valstr[:self.cursor] + chr(c) + self.valstr[self.cursor:]
|
||||
self.need_update = True
|
||||
# Move the cursor forward
|
||||
self.cursor+=1
|
||||
elif (c > 47 and c < 58):
|
||||
minus_place = self.valstr.find('-')
|
||||
if self.cursor <= minus_place: return
|
||||
if self.cursor == len(self.valstr):
|
||||
self.valstr += chr(c)
|
||||
else:
|
||||
# Insert into string
|
||||
self.valstr = self.valstr[:self.cursor] + chr(c) + self.valstr[self.cursor:]
|
||||
self.need_update = True
|
||||
# Move the cursor forward
|
||||
self.cursor+=1
|
||||
|
||||
|
||||
def get_value(self):
|
||||
return self.value
|
||||
|
||||
def set_value(self, val):
|
||||
self.value = round(float(val),self.precision)
|
||||
self.valstr = self.fmt%self.value
|
||||
self.cursor = len(self.valstr)
|
||||
|
||||
|
||||
class SelectInput(InputField):
|
||||
def __init__(self, parent, message, name, opts, vals, selidx):
|
||||
self.parent = parent
|
||||
|
@ -225,23 +411,28 @@ class TextInput(InputField):
|
|||
self.opts = None
|
||||
self.opt_off = 0
|
||||
|
||||
def render(self,screen,row,width,selected,col=1):
|
||||
def render(self,screen,row,width,selected,col=1,cursor_offset=0):
|
||||
if self.message:
|
||||
self.parent.add_string(row,self.message,screen,col,False,True)
|
||||
row += 1
|
||||
if selected:
|
||||
if self.opts:
|
||||
self.parent.add_string(row+2,self.opts[self.opt_off:],screen,col,False,True)
|
||||
self.parent.add_string(row+1,self.opts[self.opt_off:],screen,col,False,True)
|
||||
if self.cursor > (width-3):
|
||||
self.move_func(row+1,width-2)
|
||||
self.move_func(row,width-2)
|
||||
else:
|
||||
self.move_func(row+1,self.cursor+1)
|
||||
self.parent.add_string(row,self.message,screen,col,False,True)
|
||||
self.move_func(row,self.cursor+1+cursor_offset)
|
||||
slen = len(self.value)+3
|
||||
if slen > width:
|
||||
vstr = self.value[(slen-width):]
|
||||
else:
|
||||
vstr = self.value.ljust(width-2)
|
||||
self.parent.add_string(row+1,"{!black,white,bold!}%s"%vstr,screen,col,False,False)
|
||||
self.parent.add_string(row,"{!black,white,bold!}%s"%vstr,screen,col,False,False)
|
||||
|
||||
return 3
|
||||
if self.message:
|
||||
return 3
|
||||
else:
|
||||
return 2
|
||||
|
||||
def get_value(self):
|
||||
return self.value
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
#
|
||||
#
|
||||
|
||||
from deluge.ui.console.modes.input_popup import TextInput,SelectInput,CheckedInput,IntSpinInput
|
||||
from deluge.ui.console.modes.input_popup import TextInput,SelectInput,CheckedInput,IntSpinInput,FloatSpinInput,CheckedPlusInput
|
||||
|
||||
try:
|
||||
import curses
|
||||
|
@ -44,12 +44,17 @@ import logging
|
|||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Header:
|
||||
class NoInput:
|
||||
def depend_skip(self):
|
||||
return False
|
||||
|
||||
class Header(NoInput):
|
||||
def __init__(self, parent, header, space_above, space_below):
|
||||
self.parent = parent
|
||||
self.header = "{!white,black,bold!}%s"%header
|
||||
self.space_above = space_above
|
||||
self.space_below = space_below
|
||||
self.name = header
|
||||
|
||||
def render(self, screen, row, width, active, offset):
|
||||
rows = 1
|
||||
|
@ -60,6 +65,24 @@ class Header:
|
|||
if self.space_below: rows += 1
|
||||
return rows
|
||||
|
||||
class InfoField(NoInput):
|
||||
def __init__(self,parent,label,value,name):
|
||||
self.parent = parent
|
||||
self.label = label
|
||||
self.value = value
|
||||
self.txt = "%s %s"%(label,value)
|
||||
self.name = name
|
||||
|
||||
def render(self, screen, row, width, active, offset):
|
||||
self.parent.add_string(row,self.txt,screen,offset-1,False,True)
|
||||
return 1
|
||||
|
||||
def set_value(self, v):
|
||||
self.value = v
|
||||
if type(v) == float:
|
||||
self.txt = "%s %.2f"%(self.label,self.value)
|
||||
else:
|
||||
self.txt = "%s %s"%(self.label,self.value)
|
||||
|
||||
class BasePane:
|
||||
def __init__(self, offset, parent, width):
|
||||
|
@ -75,26 +98,45 @@ class BasePane:
|
|||
|
||||
def add_config_values(self,conf_dict):
|
||||
for ipt in self.inputs:
|
||||
if not isinstance(ipt,Header):
|
||||
conf_dict[ipt.name] = ipt.get_value()
|
||||
if not isinstance(ipt,NoInput):
|
||||
# gross, have to special case in/out ports since they are tuples
|
||||
if ipt.name in ("listen_ports_to","listen_ports_from",
|
||||
"out_ports_from","out_ports_to"):
|
||||
if ipt.name == "listen_ports_to":
|
||||
conf_dict["listen_ports"] = (self.infrom.get_value(),self.into.get_value())
|
||||
if ipt.name == "out_ports_to":
|
||||
conf_dict["outgoing_ports"] = (self.outfrom.get_value(),self.outto.get_value())
|
||||
else:
|
||||
conf_dict[ipt.name] = ipt.get_value()
|
||||
if hasattr(ipt,"get_child"):
|
||||
c = ipt.get_child()
|
||||
conf_dict[c.name] = c.get_value()
|
||||
|
||||
def update_values(self, conf_dict):
|
||||
for ipt in self.inputs:
|
||||
if not isinstance(ipt,Header):
|
||||
if not isinstance(ipt,NoInput):
|
||||
try:
|
||||
ipt.set_value(conf_dict[ipt.name])
|
||||
except KeyError: # just ignore if it's not in dict
|
||||
pass
|
||||
if hasattr(ipt,"get_child"):
|
||||
try:
|
||||
c = ipt.get_child()
|
||||
c.set_value(conf_dict[c.name])
|
||||
except KeyError: # just ignore if it's not in dict
|
||||
pass
|
||||
|
||||
def render(self, mode, screen, width, active):
|
||||
self._cursor_row = -1
|
||||
if self.active_input < 0:
|
||||
for i,ipt in enumerate(self.inputs):
|
||||
if not isinstance(ipt,Header):
|
||||
if not isinstance(ipt,NoInput):
|
||||
self.active_input = i
|
||||
break
|
||||
crow = 1
|
||||
for i,ipt in enumerate(self.inputs):
|
||||
if ipt.depend_skip():
|
||||
continue
|
||||
act = active and i==self.active_input
|
||||
crow += ipt.render(screen,crow,width, act, self.offset)
|
||||
|
||||
|
@ -104,6 +146,8 @@ class BasePane:
|
|||
else:
|
||||
curses.curs_set(0)
|
||||
|
||||
return crow
|
||||
|
||||
# just handles setting the active input
|
||||
def handle_read(self,c):
|
||||
if not self.inputs: # no inputs added yet
|
||||
|
@ -111,18 +155,20 @@ class BasePane:
|
|||
|
||||
if c == curses.KEY_UP:
|
||||
nc = max(0,self.active_input-1)
|
||||
while isinstance(self.inputs[nc], Header):
|
||||
while isinstance(self.inputs[nc], NoInput) or self.inputs[nc].depend_skip():
|
||||
nc-=1
|
||||
if nc <= 0: break
|
||||
if not isinstance(self.inputs[nc], Header):
|
||||
if not isinstance(self.inputs[nc], NoInput) or self.inputs[nc].depend_skip():
|
||||
self.active_input = nc
|
||||
elif c == curses.KEY_DOWN:
|
||||
ilen = len(self.inputs)
|
||||
nc = min(self.active_input+1,ilen-1)
|
||||
while isinstance(self.inputs[nc], Header):
|
||||
while isinstance(self.inputs[nc], NoInput) or self.inputs[nc].depend_skip():
|
||||
nc+=1
|
||||
if nc >= ilen: break
|
||||
if not isinstance(self.inputs[nc], Header):
|
||||
if nc >= ilen:
|
||||
nc-=1
|
||||
break
|
||||
if not isinstance(self.inputs[nc], NoInput) or self.inputs[nc].depend_skip():
|
||||
self.active_input = nc
|
||||
else:
|
||||
self.inputs[self.active_input].handle_read(c)
|
||||
|
@ -131,6 +177,9 @@ class BasePane:
|
|||
def add_header(self, header, space_above=False, space_below=False):
|
||||
self.inputs.append(Header(self.parent, header, space_above, space_below))
|
||||
|
||||
def add_info_field(self, label, value, name):
|
||||
self.inputs.append(InfoField(self.parent, label, value, name))
|
||||
|
||||
def add_text_input(self, name, msg, dflt_val):
|
||||
self.inputs.append(TextInput(self.parent,self.move,self.width,msg,name,dflt_val,False))
|
||||
|
||||
|
@ -140,9 +189,15 @@ class BasePane:
|
|||
def add_checked_input(self, name, message, checked):
|
||||
self.inputs.append(CheckedInput(self.parent,message,name,checked))
|
||||
|
||||
def add_checkedplus_input(self, name, message, child, checked):
|
||||
self.inputs.append(CheckedPlusInput(self.parent,message,name,child,checked))
|
||||
|
||||
def add_int_spin_input(self, name, message, value, min_val, max_val):
|
||||
self.inputs.append(IntSpinInput(self.parent,message,name,self.move,value,min_val,max_val))
|
||||
|
||||
def add_float_spin_input(self, name, message, value, inc_amt, precision, min_val, max_val):
|
||||
self.inputs.append(FloatSpinInput(self.parent,message,name,self.move,value,inc_amt,precision,min_val,max_val))
|
||||
|
||||
|
||||
class DownloadsPane(BasePane):
|
||||
def __init__(self, offset, parent, width):
|
||||
|
@ -150,13 +205,21 @@ class DownloadsPane(BasePane):
|
|||
|
||||
self.add_header("Folders")
|
||||
self.add_text_input("download_location","Download To:",parent.core_config["download_location"])
|
||||
self.add_header("Allocation")
|
||||
cmptxt = TextInput(self.parent,self.move,self.width,None,"move_completed_path",parent.core_config["move_completed_path"],False)
|
||||
self.add_checkedplus_input("move_completed","Move completed to:",cmptxt,parent.core_config["move_completed"])
|
||||
autotxt = TextInput(self.parent,self.move,self.width,None,"autoadd_location",parent.core_config["autoadd_location"],False)
|
||||
self.add_checkedplus_input("autoadd_enable","Auto add .torrents from:",autotxt,parent.core_config["autoadd_enable"])
|
||||
copytxt = TextInput(self.parent,self.move,self.width,None,"torrentfiles_location",parent.core_config["torrentfiles_location"],False)
|
||||
self.add_checkedplus_input("copy_torrent_file","Copy of .torrent files to:",copytxt,parent.core_config["copy_torrent_file"])
|
||||
self.add_checked_input("del_copy_torrent_file","Delete copy of torrent file on remove",parent.core_config["del_copy_torrent_file"])
|
||||
|
||||
self.add_header("Allocation",True)
|
||||
|
||||
if parent.core_config["compact_allocation"]:
|
||||
alloc_idx = 1
|
||||
else:
|
||||
alloc_idx = 0
|
||||
self.add_select_input("compact_allocation","Allocation:",["Use Full Allocation","Use Compact Allocation"],[False,True],alloc_idx)
|
||||
self.add_select_input("compact_allocation",None,["Use Full Allocation","Use Compact Allocation"],[False,True],alloc_idx)
|
||||
self.add_header("Options",True)
|
||||
self.add_checked_input("prioritize_first_last_pieces","Prioritize first and last pieces of torrent",parent.core_config["prioritize_first_last_pieces"])
|
||||
self.add_checked_input("add_paused","Add torrents in paused state",parent.core_config["add_paused"])
|
||||
|
@ -165,35 +228,91 @@ class DownloadsPane(BasePane):
|
|||
class NetworkPane(BasePane):
|
||||
def __init__(self, offset, parent, width):
|
||||
BasePane.__init__(self,offset,parent,width)
|
||||
self.add_header("Incomming Ports")
|
||||
inrand = CheckedInput(parent,"Use Random Ports Active Port: %d"%parent.active_port,"random_port",parent.core_config["random_port"])
|
||||
self.inputs.append(inrand)
|
||||
listen_ports = parent.core_config["listen_ports"]
|
||||
self.infrom = IntSpinInput(self.parent," From:","listen_ports_from",self.move,listen_ports[0],0,65535)
|
||||
self.infrom.set_depend(inrand,True)
|
||||
self.into = IntSpinInput(self.parent," To: ","listen_ports_to",self.move,listen_ports[1],0,65535)
|
||||
self.into.set_depend(inrand,True)
|
||||
self.inputs.append(self.infrom)
|
||||
self.inputs.append(self.into)
|
||||
|
||||
|
||||
self.add_header("Outgoing Ports",True)
|
||||
outrand = CheckedInput(parent,"Use Random Ports","random_outgoing_ports",parent.core_config["random_outgoing_ports"])
|
||||
self.inputs.append(outrand)
|
||||
out_ports = parent.core_config["outgoing_ports"]
|
||||
self.outfrom = IntSpinInput(self.parent," From:","out_ports_from",self.move,out_ports[0],0,65535)
|
||||
self.outfrom.set_depend(outrand,True)
|
||||
self.outto = IntSpinInput(self.parent," To: ","out_ports_to",self.move,out_ports[1],0,65535)
|
||||
self.outto.set_depend(outrand,True)
|
||||
self.inputs.append(self.outfrom)
|
||||
self.inputs.append(self.outto)
|
||||
|
||||
|
||||
self.add_header("Interface",True)
|
||||
self.add_text_input("listen_interface","IP address of the interface to listen on (leave empty for default):",parent.core_config["listen_interface"])
|
||||
|
||||
self.add_header("TOS",True)
|
||||
self.add_text_input("peer_tos","Peer TOS Byte:",parent.core_config["peer_tos"])
|
||||
|
||||
self.add_header("Network Extras")
|
||||
self.add_checked_input("upnp","UPnP",parent.core_config["upnp"])
|
||||
self.add_checked_input("natpmp","NAT-PMP",parent.core_config["natpmp"])
|
||||
self.add_checked_input("utpex","Peer Exchange",parent.core_config["utpex"])
|
||||
self.add_checked_input("lsd","LSD",parent.core_config["lsd"])
|
||||
self.add_checked_input("dht","DHT",parent.core_config["dht"])
|
||||
|
||||
self.add_header("Encryption",True)
|
||||
self.add_select_input("enc_in_policy","Inbound:",["Forced","Enabled","Disabled"],[0,1,2],parent.core_config["enc_in_policy"])
|
||||
self.add_select_input("enc_out_policy","Outbound:",["Forced","Enabled","Disabled"],[0,1,2],parent.core_config["enc_out_policy"])
|
||||
self.add_select_input("enc_level","Level:",["Handshake","Full Stream","Either"],[0,1,2],parent.core_config["enc_level"])
|
||||
self.add_checked_input("enc_prefer_rc4","Encrypt Entire Stream",parent.core_config["enc_prefer_rc4"])
|
||||
|
||||
|
||||
class BandwidthPane(BasePane):
|
||||
def __init__(self, offset, parent, width):
|
||||
BasePane.__init__(self,offset,parent,width)
|
||||
self.add_header("Global Bandwidth Usage")
|
||||
self.add_int_spin_input("max_connections_global","Maximum Connections:",parent.core_config["max_connections_global"],0,1000)
|
||||
self.add_int_spin_input("max_upload_slots_global","Maximum Upload Slots:",parent.core_config["max_upload_slots_global"],0,1000)
|
||||
#self.add_int_spin_input("max_download_speed","Maximum Download Speed (KiB/s):",-1,0,1000)
|
||||
self.add_int_spin_input("max_connections_global","Maximum Connections:",parent.core_config["max_connections_global"],-1,9000)
|
||||
self.add_int_spin_input("max_upload_slots_global","Maximum Upload Slots:",parent.core_config["max_upload_slots_global"],-1,9000)
|
||||
self.add_float_spin_input("max_download_speed","Maximum Download Speed (KiB/s):",parent.core_config["max_download_speed"],1.0,1,-1.0,60000.0)
|
||||
self.add_float_spin_input("max_upload_speed","Maximum Upload Speed (KiB/s):",parent.core_config["max_upload_speed"],1.0,1,-1.0,60000.0)
|
||||
self.add_int_spin_input("max_half_open_connections","Maximum Half-Open Connections:",parent.core_config["max_half_open_connections"],-1,9999)
|
||||
self.add_int_spin_input("max_connections_per_second","Maximum Connection Attempts per Second:",parent.core_config["max_connections_per_second"],-1,9999)
|
||||
self.add_checked_input("ignore_limits_on_local_network","Ignore limits on local network",parent.core_config["ignore_limits_on_local_network"])
|
||||
self.add_checked_input("rate_limit_ip_overhead","Rate Limit IP Overhead",parent.core_config["rate_limit_ip_overhead"])
|
||||
self.add_header("Per Torrent Bandwidth Usage",True)
|
||||
self.add_int_spin_input("max_connections_per_torrent","Maximum Connections:",parent.core_config["max_connections_per_torrent"],-1,9000)
|
||||
self.add_int_spin_input("max_upload_slots_per_torrent","Maximum Upload Slots:",parent.core_config["max_upload_slots_per_torrent"],-1,9000)
|
||||
self.add_float_spin_input("max_download_speed_per_torrent","Maximum Download Speed (KiB/s):",parent.core_config["max_download_speed_per_torrent"],1.0,1,-1.0,60000.0)
|
||||
self.add_float_spin_input("max_upload_speed_per_torrent","Maximum Upload Speed (KiB/s):",parent.core_config["max_upload_speed_per_torrent"],1.0,1,-1.0,60000.0)
|
||||
|
||||
class InterfacePane(BasePane):
|
||||
def __init__(self, offset, parent, width):
|
||||
BasePane.__init__(self,offset,parent,width)
|
||||
# does classic mode make sense in console?
|
||||
#self.add_header("Classic Mode")
|
||||
#self.add_checked_input("classic_mode","Enable",False)
|
||||
|
||||
self.add_header("Interface Settings Comming Soon")
|
||||
# add title bar control here
|
||||
|
||||
|
||||
class OtherPane(BasePane):
|
||||
def __init__(self, offset, parent, width):
|
||||
BasePane.__init__(self,offset,parent,width)
|
||||
self.add_header("GeoIP Database")
|
||||
self.add_header("System Information")
|
||||
self.add_info_field(" Help us improve Deluge by sending us your","","")
|
||||
self.add_info_field(" Python version, PyGTK version, OS and processor","","")
|
||||
self.add_info_field(" types. Absolutely no other information is sent.","","")
|
||||
self.add_checked_input("send_info","Yes, please send anonymous statistics.",parent.core_config["send_info"])
|
||||
self.add_header("GeoIP Database",True)
|
||||
self.add_text_input("geoip_db_location","Location:",parent.core_config["geoip_db_location"])
|
||||
|
||||
class DaemonPane(BasePane):
|
||||
def __init__(self, offset, parent, width):
|
||||
BasePane.__init__(self,offset,parent,width)
|
||||
self.add_header("Port")
|
||||
self.add_int_spin_input("daemon_port","Daemon Port:",parent.core_config["daemon_port"],0,1000)
|
||||
self.add_int_spin_input("daemon_port","Daemon Port:",parent.core_config["daemon_port"],0,65535)
|
||||
self.add_header("Connections",True)
|
||||
self.add_checked_input("allow_remote","Allow remote connections",parent.core_config["allow_remote"])
|
||||
self.add_header("Other",True)
|
||||
|
@ -202,11 +321,50 @@ class DaemonPane(BasePane):
|
|||
class QueuePane(BasePane):
|
||||
def __init__(self, offset, parent, width):
|
||||
BasePane.__init__(self,offset,parent,width)
|
||||
self.add_header("General")
|
||||
self.add_checked_input("queue_new_to_top","Queue new torrents to top",parent.core_config["queue_new_to_top"])
|
||||
self.add_header("Active Torrents",True)
|
||||
self.add_int_spin_input("max_active_limit","Total active:",parent.core_config["max_active_limit"],-1,9999)
|
||||
self.add_int_spin_input("max_active_downloading","Total active downloading:",parent.core_config["max_active_downloading"],-1,9999)
|
||||
self.add_int_spin_input("max_active_seeding","Total active seeding:",parent.core_config["max_active_seeding"],-1,9999)
|
||||
self.add_checked_input("dont_count_slow_torrents","Do not count slow torrents",parent.core_config["dont_count_slow_torrents"])
|
||||
self.add_header("Seeding",True)
|
||||
self.add_float_spin_input("share_ratio_limit","Share Ratio Limit:",parent.core_config["share_ratio_limit"],1.0,2,-1.0,100.0)
|
||||
self.add_float_spin_input("seed_time_ratio_limit","Share Time Ratio:",parent.core_config["seed_time_ratio_limit"],1.0,2,-1.0,100.0)
|
||||
self.add_int_spin_input("seed_time_limit","Seed time (m):",parent.core_config["seed_time_limit"],-1,10000)
|
||||
seedratio = FloatSpinInput(self.parent,"","stop_seed_ratio",self.move,parent.core_config["stop_seed_ratio"],0.1,2,0.5,100.0)
|
||||
self.add_checkedplus_input("stop_seed_at_ratio","Stop seeding when share ratio reaches:",seedratio,parent.core_config["stop_seed_at_ratio"])
|
||||
self.add_checked_input("remove_seed_at_ratio","Remove torrent when share ratio reached",parent.core_config["remove_seed_at_ratio"])
|
||||
|
||||
class ProxyPane(BasePane):
|
||||
def __init__(self, offset, parent, width):
|
||||
BasePane.__init__(self,offset,parent,width)
|
||||
self.add_header("Proxy Settings Comming Soon")
|
||||
|
||||
class CachePane(BasePane):
|
||||
def __init__(self, offset, parent, width):
|
||||
BasePane.__init__(self,offset,parent,width)
|
||||
self.add_header("Settings")
|
||||
self.add_int_spin_input("cache_size","Cache Size (16 KiB blocks):",parent.core_config["cache_size"],0,99999)
|
||||
self.add_int_spin_input("cache_expiry","Cache Expiry (seconds):",parent.core_config["cache_expiry"],1,32000)
|
||||
self.add_header("Status (press 'r' to refresh status)",True)
|
||||
self.add_header(" Write")
|
||||
self.add_info_field(" Blocks Written:",self.parent.status["blocks_written"],"blocks_written")
|
||||
self.add_info_field(" Writes:",self.parent.status["writes"],"writes")
|
||||
self.add_info_field(" Write Cache Hit Ratio:","%.2f"%self.parent.status["write_hit_ratio"],"write_hit_ratio")
|
||||
self.add_header(" Read")
|
||||
self.add_info_field(" Blocks Read:",self.parent.status["blocks_read"],"blocks_read")
|
||||
self.add_info_field(" Blocks Read hit:",self.parent.status["blocks_read_hit"],"blocks_read_hit")
|
||||
self.add_info_field(" Reads:",self.parent.status["reads"],"reads")
|
||||
self.add_info_field(" Read Cache Hit Ratio:","%.2f"%self.parent.status["read_hit_ratio"],"read_hit_ratio")
|
||||
self.add_header(" Size")
|
||||
self.add_info_field(" Cache Size:",self.parent.status["cache_size"],"cache_size")
|
||||
self.add_info_field(" Read Cache Size:",self.parent.status["read_cache_size"],"read_cache_size")
|
||||
|
||||
def update_cache_status(self, status):
|
||||
for ipt in self.inputs:
|
||||
if isinstance(ipt,InfoField):
|
||||
try:
|
||||
ipt.set_value(status[ipt.name])
|
||||
except KeyError:
|
||||
pass
|
||||
|
|
|
@ -59,7 +59,7 @@ class ZONE:
|
|||
ACTIONS = 2
|
||||
|
||||
class Preferences(BaseMode):
|
||||
def __init__(self, parent_mode, core_config, stdscr, encoding=None):
|
||||
def __init__(self, parent_mode, core_config, active_port, status, stdscr, encoding=None):
|
||||
self.parent_mode = parent_mode
|
||||
self.categories = [_("Downloads"), _("Network"), _("Bandwidth"),
|
||||
_("Interface"), _("Other"), _("Daemon"), _("Queue"), _("Proxy"),
|
||||
|
@ -70,6 +70,8 @@ class Preferences(BaseMode):
|
|||
self.action_input = None
|
||||
|
||||
self.core_config = core_config
|
||||
self.active_port = active_port
|
||||
self.status = status
|
||||
|
||||
self.active_zone = ZONE.CATEGORIES
|
||||
|
||||
|
@ -220,6 +222,9 @@ class Preferences(BaseMode):
|
|||
if self.active_zone < ZONE.CATEGORIES:
|
||||
self.active_zone = ZONE.ACTIONS
|
||||
|
||||
elif c == 114 and isinstance(self.panes[self.cur_cat],CachePane):
|
||||
client.core.get_cache_status().addCallback(self.panes[self.cur_cat].update_cache_status)
|
||||
|
||||
else:
|
||||
if self.active_zone == ZONE.CATEGORIES:
|
||||
self.__category_read(c)
|
||||
|
|
Loading…
Reference in New Issue