2020-05-13 19:03:16 +00:00
import typing
2019-11-14 03:56:30 +00:00
from qtpy import QtCore as QC
from qtpy import QtWidgets as QW
2020-04-22 21:00:35 +00:00
from hydrus . core import HydrusConstants as HC
from hydrus . core import HydrusData
from hydrus . core import HydrusExceptions
from hydrus . core import HydrusGlobals as HG
from hydrus . core import HydrusNetworking
from hydrus . core import HydrusText
from hydrus . client import ClientConstants as CC
from hydrus . client . gui import ClientGUICommon
from hydrus . client . gui import ClientGUICore as CGC
from hydrus . client . gui import ClientGUIFunctions
from hydrus . client . gui import ClientGUIMenus
from hydrus . client . gui import ClientGUIScrolledPanels
from hydrus . client . gui import ClientGUITime
2020-04-29 21:44:12 +00:00
from hydrus . client . gui import ClientGUITopLevelWindowsPanels
2020-04-22 21:00:35 +00:00
from hydrus . client . gui import QtPorting as QP
2020-07-15 20:52:09 +00:00
from hydrus . client . gui . lists import ClientGUIListConstants as CGLC
from hydrus . client . gui . lists import ClientGUIListCtrl
2017-03-02 02:14:56 +00:00
class BandwidthRulesCtrl ( ClientGUICommon . StaticBox ) :
def __init__ ( self , parent , bandwidth_rules ) :
ClientGUICommon . StaticBox . __init__ ( self , parent , ' bandwidth rules ' )
2017-10-18 19:41:25 +00:00
listctrl_panel = ClientGUIListCtrl . BetterListCtrlPanel ( self )
2017-03-02 02:14:56 +00:00
2020-07-15 20:52:09 +00:00
# example for later:
'''
def sort_call ( desired_columns , rule ) :
( bandwidth_type , time_delta , max_allowed ) = rule
sort_time_delta = SafeNoneInt ( time_delta )
result = { }
result [ CGLC . COLUMN_LIST_BANDWIDTH_RULES . MAX_ALLOWED ] = max_allowed
result [ CGLC . COLUMN_LIST_BANDWIDTH_RULES . EVERY ] = sort_time_delta
return result
2018-08-01 20:44:57 +00:00
2020-07-15 20:52:09 +00:00
def display_call ( desired_columns , rule ) :
( bandwidth_type , time_delta , max_allowed ) = rule
if bandwidth_type == HC . BANDWIDTH_TYPE_DATA :
pretty_max_allowed = HydrusData . ToHumanBytes ( max_allowed )
elif bandwidth_type == HC . BANDWIDTH_TYPE_REQUESTS :
pretty_max_allowed = ' {} requests ' . format ( HydrusData . ToHumanInt ( max_allowed ) )
pretty_time_delta = HydrusData . TimeDeltaToPrettyTimeDelta ( time_delta )
result = { }
result [ CGLC . COLUMN_LIST_BANDWIDTH_RULES . MAX_ALLOWED ] = pretty_max_allowed
result [ CGLC . COLUMN_LIST_BANDWIDTH_RULES . EVERY ] = pretty_time_delta
return result
'''
self . _listctrl = ClientGUIListCtrl . BetterListCtrl ( listctrl_panel , CGLC . COLUMN_LIST_BANDWIDTH_RULES . ID , 8 , self . _ConvertRuleToListCtrlTuples , use_simple_delete = True , activation_callback = self . _Edit )
2017-07-27 00:47:13 +00:00
listctrl_panel . SetListCtrl ( self . _listctrl )
listctrl_panel . AddButton ( ' add ' , self . _Add )
listctrl_panel . AddButton ( ' edit ' , self . _Edit , enabled_only_on_selection = True )
2018-10-17 21:00:09 +00:00
listctrl_panel . AddDeleteButton ( )
2017-03-02 02:14:56 +00:00
#
2017-10-18 19:41:25 +00:00
self . _listctrl . AddDatas ( bandwidth_rules . GetRules ( ) )
2020-07-15 20:52:09 +00:00
self . _listctrl . Sort ( )
2017-03-02 02:14:56 +00:00
#
2018-01-03 22:37:30 +00:00
self . Add ( listctrl_panel , CC . FLAGS_EXPAND_BOTH_WAYS )
2017-03-02 02:14:56 +00:00
def _Add ( self ) :
rule = ( HC . BANDWIDTH_TYPE_DATA , None , 1024 * 1024 * 100 )
2020-04-29 21:44:12 +00:00
with ClientGUITopLevelWindowsPanels . DialogEdit ( self , ' edit rule ' ) as dlg :
2017-03-02 02:14:56 +00:00
panel = self . _EditPanel ( dlg , rule )
dlg . SetPanel ( panel )
2019-11-14 03:56:30 +00:00
if dlg . exec ( ) == QW . QDialog . Accepted :
2017-03-02 02:14:56 +00:00
new_rule = panel . GetValue ( )
2017-10-18 19:41:25 +00:00
self . _listctrl . AddDatas ( ( new_rule , ) )
2017-03-02 02:14:56 +00:00
2017-10-18 19:41:25 +00:00
self . _listctrl . Sort ( )
2017-03-02 02:14:56 +00:00
2018-10-17 21:00:09 +00:00
def _ConvertRuleToListCtrlTuples ( self , rule ) :
2017-03-02 02:14:56 +00:00
( bandwidth_type , time_delta , max_allowed ) = rule
2018-07-04 20:48:28 +00:00
pretty_time_delta = HydrusData . TimeDeltaToPrettyTimeDelta ( time_delta )
2017-03-02 02:14:56 +00:00
if bandwidth_type == HC . BANDWIDTH_TYPE_DATA :
2019-01-09 22:59:03 +00:00
pretty_max_allowed = HydrusData . ToHumanBytes ( max_allowed )
2017-03-02 02:14:56 +00:00
elif bandwidth_type == HC . BANDWIDTH_TYPE_REQUESTS :
2018-07-04 20:48:28 +00:00
pretty_max_allowed = HydrusData . ToHumanInt ( max_allowed ) + ' requests '
2017-03-02 02:14:56 +00:00
2019-01-09 22:59:03 +00:00
sort_time_delta = ClientGUIListCtrl . SafeNoneInt ( time_delta )
sort_tuple = ( max_allowed , sort_time_delta )
2018-03-14 21:01:02 +00:00
display_tuple = ( pretty_max_allowed , pretty_time_delta )
2017-10-18 19:41:25 +00:00
return ( display_tuple , sort_tuple )
2017-03-02 02:14:56 +00:00
def _Edit ( self ) :
2017-10-18 19:41:25 +00:00
selected_rules = self . _listctrl . GetData ( only_selected = True )
2017-03-02 02:14:56 +00:00
2017-10-18 19:41:25 +00:00
for rule in selected_rules :
2017-03-02 02:14:56 +00:00
2020-04-29 21:44:12 +00:00
with ClientGUITopLevelWindowsPanels . DialogEdit ( self , ' edit rule ' ) as dlg :
2017-03-02 02:14:56 +00:00
panel = self . _EditPanel ( dlg , rule )
dlg . SetPanel ( panel )
2019-11-14 03:56:30 +00:00
if dlg . exec ( ) == QW . QDialog . Accepted :
2017-03-02 02:14:56 +00:00
edited_rule = panel . GetValue ( )
2017-10-18 19:41:25 +00:00
self . _listctrl . DeleteDatas ( ( rule , ) )
2017-03-02 02:14:56 +00:00
2017-10-18 19:41:25 +00:00
self . _listctrl . AddDatas ( ( edited_rule , ) )
2017-03-02 02:14:56 +00:00
else :
break
2017-10-18 19:41:25 +00:00
self . _listctrl . Sort ( )
2017-03-02 02:14:56 +00:00
def GetValue ( self ) :
bandwidth_rules = HydrusNetworking . BandwidthRules ( )
2017-10-18 19:41:25 +00:00
for rule in self . _listctrl . GetData ( ) :
( bandwidth_type , time_delta , max_allowed ) = rule
2017-03-02 02:14:56 +00:00
bandwidth_rules . AddRule ( bandwidth_type , time_delta , max_allowed )
return bandwidth_rules
class _EditPanel ( ClientGUIScrolledPanels . EditPanel ) :
def __init__ ( self , parent , rule ) :
ClientGUIScrolledPanels . EditPanel . __init__ ( self , parent )
self . _bandwidth_type = ClientGUICommon . BetterChoice ( self )
2019-11-14 03:56:30 +00:00
self . _bandwidth_type . addItem ( ' data ' , HC . BANDWIDTH_TYPE_DATA )
self . _bandwidth_type . addItem ( ' requests ' , HC . BANDWIDTH_TYPE_REQUESTS )
2017-03-02 02:14:56 +00:00
2019-11-14 03:56:30 +00:00
self . _bandwidth_type . currentIndexChanged . connect ( self . _UpdateEnabled )
2017-03-02 02:14:56 +00:00
2018-03-14 21:01:02 +00:00
self . _max_allowed_bytes = BytesControl ( self )
2019-11-14 03:56:30 +00:00
self . _max_allowed_requests = QP . MakeQSpinBox ( self , min = 1 , max = 1048576 )
2017-03-02 02:14:56 +00:00
2018-03-14 21:01:02 +00:00
self . _time_delta = ClientGUITime . TimeDeltaButton ( self , min = 1 , days = True , hours = True , minutes = True , seconds = True , monthly_allowed = True )
2017-03-02 02:14:56 +00:00
#
( bandwidth_type , time_delta , max_allowed ) = rule
2019-07-24 21:39:02 +00:00
self . _bandwidth_type . SetValue ( bandwidth_type )
2017-03-02 02:14:56 +00:00
self . _time_delta . SetValue ( time_delta )
if bandwidth_type == HC . BANDWIDTH_TYPE_DATA :
2018-03-14 21:01:02 +00:00
self . _max_allowed_bytes . SetValue ( max_allowed )
else :
2019-11-14 03:56:30 +00:00
self . _max_allowed_requests . setValue ( max_allowed )
2017-03-02 02:14:56 +00:00
2018-03-14 21:01:02 +00:00
self . _UpdateEnabled ( )
2017-03-02 02:14:56 +00:00
#
2019-11-14 03:56:30 +00:00
hbox = QP . HBoxLayout ( )
2017-03-02 02:14:56 +00:00
2019-11-14 03:56:30 +00:00
QP . AddToLayout ( hbox , self . _max_allowed_bytes , CC . FLAGS_VCENTER )
QP . AddToLayout ( hbox , self . _max_allowed_requests , CC . FLAGS_VCENTER )
QP . AddToLayout ( hbox , self . _bandwidth_type , CC . FLAGS_VCENTER )
QP . AddToLayout ( hbox , ClientGUICommon . BetterStaticText ( self , ' every ' ) , CC . FLAGS_VCENTER )
QP . AddToLayout ( hbox , self . _time_delta , CC . FLAGS_VCENTER )
2017-03-02 02:14:56 +00:00
2019-11-14 03:56:30 +00:00
self . widget ( ) . setLayout ( hbox )
2017-03-02 02:14:56 +00:00
2018-03-14 21:01:02 +00:00
def _UpdateEnabled ( self ) :
2017-03-02 02:14:56 +00:00
2019-07-24 21:39:02 +00:00
bandwidth_type = self . _bandwidth_type . GetValue ( )
2017-03-02 02:14:56 +00:00
if bandwidth_type == HC . BANDWIDTH_TYPE_DATA :
2019-11-14 03:56:30 +00:00
self . _max_allowed_bytes . show ( )
self . _max_allowed_requests . hide ( )
2017-03-02 02:14:56 +00:00
elif bandwidth_type == HC . BANDWIDTH_TYPE_REQUESTS :
2019-11-14 03:56:30 +00:00
self . _max_allowed_bytes . hide ( )
self . _max_allowed_requests . show ( )
2017-03-02 02:14:56 +00:00
def GetValue ( self ) :
2019-07-24 21:39:02 +00:00
bandwidth_type = self . _bandwidth_type . GetValue ( )
2017-03-02 02:14:56 +00:00
time_delta = self . _time_delta . GetValue ( )
if bandwidth_type == HC . BANDWIDTH_TYPE_DATA :
2018-03-14 21:01:02 +00:00
max_allowed = self . _max_allowed_bytes . GetValue ( )
elif bandwidth_type == HC . BANDWIDTH_TYPE_REQUESTS :
2019-11-14 03:56:30 +00:00
max_allowed = self . _max_allowed_requests . value ( )
2017-03-02 02:14:56 +00:00
return ( bandwidth_type , time_delta , max_allowed )
2017-03-08 23:23:12 +00:00
2019-11-14 03:56:30 +00:00
class BytesControl ( QW . QWidget ) :
valueChanged = QC . Signal ( )
2018-03-14 21:01:02 +00:00
def __init__ ( self , parent , initial_value = 65536 ) :
2019-11-14 03:56:30 +00:00
QW . QWidget . __init__ ( self , parent )
2018-03-22 00:03:33 +00:00
2019-11-14 03:56:30 +00:00
self . _spin = QP . MakeQSpinBox ( self , min = 0 , max = 1048576 )
2018-03-14 21:01:02 +00:00
self . _unit = ClientGUICommon . BetterChoice ( self )
2019-11-14 03:56:30 +00:00
self . _unit . addItem ( ' B ' , 1 )
self . _unit . addItem ( ' KB ' , 1024 )
self . _unit . addItem ( ' MB ' , 1024 * 1024 )
self . _unit . addItem ( ' GB ' , 1024 * 1024 * 1024 )
2018-03-14 21:01:02 +00:00
#
self . SetValue ( initial_value )
#
2019-11-14 03:56:30 +00:00
hbox = QP . HBoxLayout ( )
2018-04-25 22:07:52 +00:00
2019-11-14 03:56:30 +00:00
QP . AddToLayout ( hbox , self . _spin , CC . FLAGS_VCENTER )
QP . AddToLayout ( hbox , self . _unit , CC . FLAGS_VCENTER )
2018-04-25 22:07:52 +00:00
2019-11-14 03:56:30 +00:00
self . setLayout ( hbox )
2018-04-25 22:07:52 +00:00
2019-11-14 03:56:30 +00:00
self . _spin . valueChanged . connect ( self . _HandleValueChanged )
self . _unit . currentIndexChanged . connect ( self . _HandleValueChanged )
2018-04-25 22:07:52 +00:00
2019-11-14 03:56:30 +00:00
def _HandleValueChanged ( self , val ) :
2018-04-25 22:07:52 +00:00
2019-11-14 03:56:30 +00:00
self . valueChanged . emit ( )
2018-04-25 22:07:52 +00:00
2018-03-14 21:01:02 +00:00
def GetSeparatedValue ( self ) :
2019-11-14 03:56:30 +00:00
return ( self . _spin . value ( ) , self . _unit . GetValue ( ) )
2018-03-14 21:01:02 +00:00
def GetValue ( self ) :
2019-11-14 03:56:30 +00:00
return self . _spin . value ( ) * self . _unit . GetValue ( )
2018-03-14 21:01:02 +00:00
def SetSeparatedValue ( self , value , unit ) :
2019-11-14 03:56:30 +00:00
return ( self . _spin . setValue ( value ) , self . _unit . SetValue ( unit ) )
2018-03-14 21:01:02 +00:00
2020-05-13 19:03:16 +00:00
def SetValue ( self , value : int ) :
2018-03-14 21:01:02 +00:00
max_unit = 1024 * 1024 * 1024
unit = 1
while value % 1024 == 0 and unit < max_unit :
2019-01-09 22:59:03 +00:00
value / / = 1024
2018-03-14 21:01:02 +00:00
unit * = 1024
2019-11-14 03:56:30 +00:00
self . _spin . setValue ( value )
2019-07-24 21:39:02 +00:00
self . _unit . SetValue ( unit )
2018-03-14 21:01:02 +00:00
2020-05-13 19:03:16 +00:00
class NoneableBytesControl ( QW . QWidget ) :
valueChanged = QC . Signal ( )
2018-03-14 21:01:02 +00:00
2020-05-13 19:03:16 +00:00
def __init__ ( self , parent , initial_value = 65536 , none_label = ' no limit ' ) :
2018-03-14 21:01:02 +00:00
2020-05-13 19:03:16 +00:00
QW . QWidget . __init__ ( self , parent )
2018-03-14 21:01:02 +00:00
2020-05-13 19:03:16 +00:00
self . _bytes = BytesControl ( self )
2018-03-14 21:01:02 +00:00
2020-05-13 19:03:16 +00:00
self . _none_checkbox = QW . QCheckBox ( none_label , self )
2018-03-14 21:01:02 +00:00
2020-05-13 19:03:16 +00:00
#
2018-03-14 21:01:02 +00:00
2020-05-13 19:03:16 +00:00
self . SetValue ( initial_value )
2018-03-14 21:01:02 +00:00
2020-05-13 19:03:16 +00:00
#
2018-03-14 21:01:02 +00:00
2020-05-13 19:03:16 +00:00
hbox = QP . HBoxLayout ( )
2018-03-14 21:01:02 +00:00
2020-05-13 19:03:16 +00:00
QP . AddToLayout ( hbox , self . _bytes , CC . FLAGS_SIZER_VCENTER )
QP . AddToLayout ( hbox , self . _none_checkbox , CC . FLAGS_VCENTER )
2018-03-14 21:01:02 +00:00
2020-05-13 19:03:16 +00:00
self . setLayout ( hbox )
2018-03-14 21:01:02 +00:00
#
2020-05-13 19:03:16 +00:00
self . _none_checkbox . clicked . connect ( self . _UpdateEnabled )
self . _bytes . valueChanged . connect ( self . _HandleValueChanged )
self . _none_checkbox . clicked . connect ( self . _HandleValueChanged )
2018-03-14 21:01:02 +00:00
2020-05-13 19:03:16 +00:00
def _UpdateEnabled ( self ) :
if self . _none_checkbox . isChecked ( ) :
2018-03-14 21:01:02 +00:00
2020-05-13 19:03:16 +00:00
self . _bytes . setEnabled ( False )
2018-03-14 21:01:02 +00:00
else :
2020-05-13 19:03:16 +00:00
self . _bytes . setEnabled ( True )
2018-03-14 21:01:02 +00:00
2020-05-13 19:03:16 +00:00
def _HandleValueChanged ( self ) :
2018-04-25 22:07:52 +00:00
2020-05-13 19:03:16 +00:00
self . valueChanged . emit ( )
2018-03-14 21:01:02 +00:00
2020-05-13 19:03:16 +00:00
def GetValue ( self ) :
2018-03-14 21:01:02 +00:00
2020-05-13 19:03:16 +00:00
if self . _none_checkbox . isChecked ( ) :
return None
else :
return self . _bytes . GetValue ( )
2018-03-22 00:03:33 +00:00
2020-05-13 19:03:16 +00:00
def setToolTip ( self , text ) :
2018-03-22 00:03:33 +00:00
2020-05-13 19:03:16 +00:00
QW . QWidget . setToolTip ( self , text )
2018-10-17 21:00:09 +00:00
2020-05-13 19:03:16 +00:00
for c in self . children ( ) :
if isinstance ( c , QW . QWidget ) :
c . setToolTip ( text )
2018-03-22 00:03:33 +00:00
2018-03-14 21:01:02 +00:00
2020-05-13 19:03:16 +00:00
def SetValue ( self , value ) :
2018-10-17 21:00:09 +00:00
2020-05-13 19:03:16 +00:00
if value is None :
2020-02-05 22:55:21 +00:00
2020-05-13 19:03:16 +00:00
self . _none_checkbox . setChecked ( True )
2020-02-05 22:55:21 +00:00
2020-05-13 19:03:16 +00:00
else :
2020-02-05 22:55:21 +00:00
2020-05-13 19:03:16 +00:00
self . _none_checkbox . setChecked ( False )
2020-02-05 22:55:21 +00:00
2020-05-13 19:03:16 +00:00
self . _bytes . SetValue ( value )
2020-02-05 22:55:21 +00:00
2020-05-13 19:03:16 +00:00
self . _UpdateEnabled ( )
2018-03-14 21:01:02 +00:00
2020-05-13 19:03:16 +00:00
class NetworkJobControl ( QW . QFrame ) :
def __init__ ( self , parent ) :
2017-03-22 22:38:15 +00:00
2020-05-13 19:03:16 +00:00
QW . QFrame . __init__ ( self , parent )
2017-07-27 00:47:13 +00:00
2020-05-13 19:03:16 +00:00
self . setFrameStyle ( QW . QFrame . Box | QW . QFrame . Raised )
2018-08-01 20:44:57 +00:00
2020-05-13 19:03:16 +00:00
self . _network_job = None
self . _download_started = False
2017-03-22 22:38:15 +00:00
2020-05-13 19:03:16 +00:00
self . _auto_override_bandwidth_rules = False
2017-07-27 00:47:13 +00:00
2020-05-13 19:03:16 +00:00
self . _left_text = ClientGUICommon . BetterStaticText ( self , ellipsize_end = True )
self . _right_text = ClientGUICommon . BetterStaticText ( self )
self . _right_text . setAlignment ( QC . Qt . AlignRight | QC . Qt . AlignVCenter )
2017-03-22 22:38:15 +00:00
2020-05-13 19:03:16 +00:00
self . _last_right_min_width = 0
2017-03-22 22:38:15 +00:00
2020-05-13 19:03:16 +00:00
self . _gauge = ClientGUICommon . Gauge ( self )
2017-12-06 22:06:56 +00:00
2020-05-13 19:03:16 +00:00
self . _cog_button = ClientGUICommon . BetterBitmapButton ( self , CC . global_pixmaps ( ) . cog , self . _ShowCogMenu )
self . _cancel_button = ClientGUICommon . BetterBitmapButton ( self , CC . global_pixmaps ( ) . stop , self . Cancel )
2017-03-22 22:38:15 +00:00
2020-05-13 19:03:16 +00:00
#
2017-03-22 22:38:15 +00:00
2020-05-13 19:03:16 +00:00
self . _Update ( )
2017-03-22 22:38:15 +00:00
2020-05-13 19:03:16 +00:00
#
2017-03-22 22:38:15 +00:00
2020-05-13 19:03:16 +00:00
st_hbox = QP . HBoxLayout ( )
2017-03-22 22:38:15 +00:00
2020-05-13 19:03:16 +00:00
QP . AddToLayout ( st_hbox , self . _left_text , CC . FLAGS_EXPAND_BOTH_WAYS )
QP . AddToLayout ( st_hbox , self . _right_text , CC . FLAGS_VCENTER )
2017-12-06 22:06:56 +00:00
2020-05-13 19:03:16 +00:00
left_vbox = QP . VBoxLayout ( )
2017-12-06 22:06:56 +00:00
2020-05-13 19:03:16 +00:00
QP . AddToLayout ( left_vbox , st_hbox , CC . FLAGS_EXPAND_SIZER_PERPENDICULAR )
QP . AddToLayout ( left_vbox , self . _gauge , CC . FLAGS_EXPAND_BOTH_WAYS )
2017-12-06 22:06:56 +00:00
2020-05-13 19:03:16 +00:00
hbox = QP . HBoxLayout ( )
QP . AddToLayout ( hbox , left_vbox , CC . FLAGS_EXPAND_SIZER_BOTH_WAYS )
QP . AddToLayout ( hbox , self . _cog_button , CC . FLAGS_VCENTER )
QP . AddToLayout ( hbox , self . _cancel_button , CC . FLAGS_VCENTER )
self . setLayout ( hbox )
2017-12-06 22:06:56 +00:00
2020-05-13 19:03:16 +00:00
def _ShowCogMenu ( self ) :
2017-03-22 22:38:15 +00:00
2020-05-13 19:03:16 +00:00
menu = QW . QMenu ( )
if self . _network_job is not None :
2017-03-22 22:38:15 +00:00
2020-05-13 19:03:16 +00:00
if self . _network_job . CurrentlyWaitingOnConnectionError ( ) :
ClientGUIMenus . AppendMenuItem ( menu , ' reattempt connection now ' , ' Stop waiting on a connection error and reattempt the job now. ' , self . _network_job . OverrideConnectionErrorWait )
2019-07-24 21:39:02 +00:00
2020-05-13 19:03:16 +00:00
if self . _network_job . CurrentlyWaitingOnServersideBandwidth ( ) :
ClientGUIMenus . AppendMenuItem ( menu , ' reattempt request now (server reports low bandwidth) ' , ' Stop waiting on a serverside bandwidth delay and reattempt the job now. ' , self . _network_job . OverrideServersideBandwidthWait )
2019-07-24 21:39:02 +00:00
2020-05-13 19:03:16 +00:00
if self . _network_job . ObeysBandwidth ( ) :
ClientGUIMenus . AppendMenuItem ( menu , ' override bandwidth rules for this job ' , ' Tell the current job to ignore existing bandwidth rules and go ahead anyway. ' , self . _network_job . OverrideBandwidth )
2019-07-24 21:39:02 +00:00
2020-05-13 19:03:16 +00:00
if not self . _network_job . TokensOK ( ) :
2017-03-22 22:38:15 +00:00
2020-05-13 19:03:16 +00:00
ClientGUIMenus . AppendMenuItem ( menu , ' override gallery slot requirements for this job ' , ' Force-allow this download to proceed, ignoring the normal gallery wait times. ' , self . _network_job . OverrideToken )
2017-03-22 22:38:15 +00:00
2020-05-13 19:03:16 +00:00
ClientGUIMenus . AppendSeparator ( menu )
2017-03-22 22:38:15 +00:00
2020-05-13 19:03:16 +00:00
ClientGUIMenus . AppendMenuCheckItem ( menu , ' auto-override bandwidth rules for all jobs here after five seconds ' , ' Ignore existing bandwidth rules for all jobs under this control, instead waiting a flat five seconds. ' , self . _auto_override_bandwidth_rules , self . FlipAutoOverrideBandwidth )
2018-10-17 21:00:09 +00:00
2020-05-13 19:03:16 +00:00
CGC . core ( ) . PopupMenu ( self . _cog_button , menu )
2018-10-17 21:00:09 +00:00
2020-05-13 19:03:16 +00:00
def _OverrideBandwidthIfAppropriate ( self ) :
2017-03-22 22:38:15 +00:00
2020-05-13 19:03:16 +00:00
if self . _network_job is None or self . _network_job . NoEngineYet ( ) :
2017-03-22 22:38:15 +00:00
2020-05-13 19:03:16 +00:00
return
else :
if self . _auto_override_bandwidth_rules and HydrusData . TimeHasPassed ( self . _network_job . GetCreationTime ( ) + 5 ) :
2018-10-17 21:00:09 +00:00
2020-05-13 19:03:16 +00:00
self . _network_job . OverrideBandwidth ( )
2017-03-22 22:38:15 +00:00
2020-05-13 19:03:16 +00:00
def _Update ( self ) :
2018-10-17 21:00:09 +00:00
2020-05-13 19:03:16 +00:00
if self . _network_job is None or self . _network_job . NoEngineYet ( ) :
2017-03-22 22:38:15 +00:00
2020-05-13 19:03:16 +00:00
self . _left_text . setText ( ' ' )
self . _right_text . setText ( ' ' )
self . _gauge . SetRange ( 1 )
self . _gauge . SetValue ( 0 )
2017-03-22 22:38:15 +00:00
2020-05-13 19:03:16 +00:00
can_cancel = False
else :
if self . _network_job . IsDone ( ) :
2020-02-05 22:55:21 +00:00
2020-05-13 19:03:16 +00:00
can_cancel = False
2020-02-05 22:55:21 +00:00
2020-05-13 19:03:16 +00:00
else :
2020-02-05 22:55:21 +00:00
2020-05-13 19:03:16 +00:00
can_cancel = True
2020-02-05 22:55:21 +00:00
2020-05-13 19:03:16 +00:00
( status_text , current_speed , bytes_read , bytes_to_read ) = self . _network_job . GetStatus ( )
self . _left_text . setText ( status_text )
if not self . _download_started and current_speed > 0 :
2018-10-17 21:00:09 +00:00
2020-05-13 19:03:16 +00:00
self . _download_started = True
2018-10-17 21:00:09 +00:00
2020-05-13 19:03:16 +00:00
speed_text = ' '
if self . _download_started and not self . _network_job . HasError ( ) :
2017-03-22 22:38:15 +00:00
2020-05-13 19:03:16 +00:00
if bytes_read is not None :
2017-03-22 22:38:15 +00:00
2020-05-13 19:03:16 +00:00
if bytes_to_read is not None and bytes_read != bytes_to_read :
speed_text + = HydrusData . ConvertValueRangeToBytes ( bytes_read , bytes_to_read )
else :
speed_text + = HydrusData . ToHumanBytes ( bytes_read )
2017-03-22 22:38:15 +00:00
2020-05-13 19:03:16 +00:00
if current_speed != bytes_to_read : # if it is a real quick download, just say its size
2017-03-22 22:38:15 +00:00
2020-05-13 19:03:16 +00:00
speed_text + = ' ' + HydrusData . ToHumanBytes ( current_speed ) + ' /s '
2017-03-22 22:38:15 +00:00
2020-05-13 19:03:16 +00:00
self . _right_text . setText ( speed_text )
2017-03-22 22:38:15 +00:00
2020-05-13 19:03:16 +00:00
right_width = ClientGUIFunctions . ConvertTextToPixelWidth ( self . _right_text , len ( speed_text ) )
right_min_width = right_width
2017-03-22 22:38:15 +00:00
2020-05-13 19:03:16 +00:00
if right_min_width != self . _last_right_min_width :
2018-10-17 21:00:09 +00:00
2020-05-13 19:03:16 +00:00
self . _last_right_min_width = right_min_width
self . _right_text . setMinimumWidth ( right_min_width )
2018-10-17 21:00:09 +00:00
2017-12-06 22:06:56 +00:00
2020-05-13 19:03:16 +00:00
self . _gauge . SetRange ( bytes_to_read )
self . _gauge . SetValue ( bytes_read )
2017-12-06 22:06:56 +00:00
2020-05-13 19:03:16 +00:00
if can_cancel :
if not self . _cancel_button . isEnabled ( ) :
self . _cancel_button . setEnabled ( True )
else :
if self . _cancel_button . isEnabled ( ) :
self . _cancel_button . setEnabled ( False )
2017-03-22 22:38:15 +00:00
2020-05-13 19:03:16 +00:00
def Cancel ( self ) :
2017-07-05 21:09:28 +00:00
2020-05-13 19:03:16 +00:00
if self . _network_job is not None :
self . _network_job . Cancel ( ' Cancelled by user. ' )
2017-07-05 21:09:28 +00:00
2020-05-13 19:03:16 +00:00
def ClearNetworkJob ( self ) :
2017-07-12 20:03:45 +00:00
2020-05-13 19:03:16 +00:00
self . SetNetworkJob ( None )
2017-08-16 21:58:06 +00:00
2018-10-17 21:00:09 +00:00
2020-05-13 19:03:16 +00:00
def FlipAutoOverrideBandwidth ( self ) :
2017-07-12 20:03:45 +00:00
2020-05-13 19:03:16 +00:00
self . _auto_override_bandwidth_rules = not self . _auto_override_bandwidth_rules
2017-07-05 21:09:28 +00:00
2020-05-13 19:03:16 +00:00
def SetNetworkJob ( self , network_job ) :
2017-07-05 21:09:28 +00:00
2020-05-13 19:03:16 +00:00
if network_job is None :
2018-10-17 21:00:09 +00:00
2020-05-13 19:03:16 +00:00
if self . _network_job is not None :
2018-10-17 21:00:09 +00:00
2020-05-13 19:03:16 +00:00
self . _network_job = None
2018-10-17 21:00:09 +00:00
2020-05-13 19:03:16 +00:00
self . _Update ( )
2018-10-17 21:00:09 +00:00
2020-05-13 19:03:16 +00:00
HG . client_controller . gui . UnregisterUIUpdateWindow ( self )
2018-10-17 21:00:09 +00:00
2020-05-13 19:03:16 +00:00
else :
2018-10-17 21:00:09 +00:00
2020-05-13 19:03:16 +00:00
if self . _network_job != network_job :
2018-10-17 21:00:09 +00:00
2020-05-13 19:03:16 +00:00
self . _network_job = network_job
self . _download_started = False
2018-10-17 21:00:09 +00:00
2020-05-13 19:03:16 +00:00
HG . client_controller . gui . RegisterUIUpdateWindow ( self )
2018-10-17 21:00:09 +00:00
2020-05-13 19:03:16 +00:00
def TIMERUIUpdate ( self ) :
2018-10-17 21:00:09 +00:00
2020-05-13 19:03:16 +00:00
self . _OverrideBandwidthIfAppropriate ( )
2018-10-17 21:00:09 +00:00
2020-05-13 19:03:16 +00:00
if HG . client_controller . gui . IShouldRegularlyUpdate ( self ) :
2018-10-17 21:00:09 +00:00
2020-05-13 19:03:16 +00:00
self . _Update ( )
2018-10-17 21:00:09 +00:00
2018-02-07 23:40:33 +00:00
2019-11-14 03:56:30 +00:00
class TextAndPasteCtrl ( QW . QWidget ) :
2018-05-16 20:09:50 +00:00
2018-08-08 20:29:54 +00:00
def __init__ ( self , parent , add_callable , allow_empty_input = False ) :
2018-05-16 20:09:50 +00:00
self . _add_callable = add_callable
2018-08-08 20:29:54 +00:00
self . _allow_empty_input = allow_empty_input
2018-05-16 20:09:50 +00:00
2019-11-14 03:56:30 +00:00
QW . QWidget . __init__ ( self , parent )
2018-05-16 20:09:50 +00:00
2019-11-14 03:56:30 +00:00
self . _text_input = QW . QLineEdit ( self )
self . _text_input . installEventFilter ( ClientGUICommon . TextCatchEnterEventFilter ( self . _text_input , self . EnterText ) )
2018-05-16 20:09:50 +00:00
2020-03-11 21:52:11 +00:00
self . _paste_button = ClientGUICommon . BetterBitmapButton ( self , CC . global_pixmaps ( ) . paste , self . _Paste )
2019-11-14 03:56:30 +00:00
self . _paste_button . setToolTip ( ' Paste multiple inputs from the clipboard. Assumes the texts are newline-separated. ' )
2018-05-16 20:09:50 +00:00
2020-07-08 22:00:33 +00:00
self . setFocusProxy ( self . _text_input )
2018-05-16 20:09:50 +00:00
#
2019-11-14 03:56:30 +00:00
hbox = QP . HBoxLayout ( )
2018-05-16 20:09:50 +00:00
2019-11-14 03:56:30 +00:00
QP . AddToLayout ( hbox , self . _text_input , CC . FLAGS_EXPAND_BOTH_WAYS )
QP . AddToLayout ( hbox , self . _paste_button , CC . FLAGS_VCENTER )
2018-05-16 20:09:50 +00:00
2019-11-14 03:56:30 +00:00
self . setLayout ( hbox )
2018-05-16 20:09:50 +00:00
def _Paste ( self ) :
2019-06-19 22:08:48 +00:00
try :
raw_text = HG . client_controller . GetClipboardText ( )
except HydrusExceptions . DataMissing as e :
2019-11-14 03:56:30 +00:00
QW . QMessageBox . critical ( self , ' Error ' , str ( e ) )
2019-06-19 22:08:48 +00:00
return
2018-05-16 20:09:50 +00:00
try :
2018-08-08 20:29:54 +00:00
texts = [ text for text in HydrusText . DeserialiseNewlinedTexts ( raw_text ) ]
if not self . _allow_empty_input :
texts = [ text for text in texts if text != ' ' ]
2018-05-16 20:09:50 +00:00
if len ( texts ) > 0 :
self . _add_callable ( texts )
except :
2019-11-14 03:56:30 +00:00
QW . QMessageBox . critical ( self , ' Error ' , ' I could not understand what was in the clipboard ' )
2018-05-16 20:09:50 +00:00
2019-11-14 03:56:30 +00:00
def EnterText ( self ) :
2018-05-16 20:09:50 +00:00
2019-11-14 03:56:30 +00:00
text = self . _text_input . text ( )
2018-05-16 20:09:50 +00:00
2019-11-14 03:56:30 +00:00
text = HydrusText . StripIOInputLine ( text )
if text == ' ' and not self . _allow_empty_input :
2018-05-16 20:09:50 +00:00
2019-11-14 03:56:30 +00:00
return
2018-05-16 20:09:50 +00:00
2019-11-14 03:56:30 +00:00
self . _add_callable ( ( text , ) )
self . _text_input . setText ( ' ' )
2018-05-16 20:09:50 +00:00
def GetValue ( self ) :
2019-11-14 03:56:30 +00:00
return self . _text_input . text ( )
def setPlaceholderText ( self , text ) :
self . _text_input . setPlaceholderText ( text )
2018-05-16 20:09:50 +00:00
def SetValue ( self , text ) :
2019-11-14 03:56:30 +00:00
self . _text_input . setText ( text )
2018-05-16 20:09:50 +00:00