2019-01-09 22:59:03 +00:00
from . import ClientCaches
from . import ClientConstants as CC
from . import ClientData
from . import ClientGUICommon
from . import ClientGUIDialogs
from . import ClientGUIListCtrl
from . import ClientGUIMenus
from . import ClientGUIScrolledPanels
from . import ClientGUIShortcuts
from . import ClientGUITime
from . import ClientGUITopLevelWindows
from . import ClientParsing
from . import HydrusConstants as HC
from . import HydrusData
from . import HydrusExceptions
from . import HydrusGlobals as HG
from . import HydrusNetworking
from . import HydrusText
2017-03-08 23:23:12 +00:00
import os
2017-03-02 02:14:56 +00:00
import wx
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
2018-08-01 20:44:57 +00:00
columns = [ ( ' max allowed ' , 14 ) , ( ' every ' , 16 ) ]
2018-10-17 21:00:09 +00:00
self . _listctrl = ClientGUIListCtrl . BetterListCtrl ( listctrl_panel , ' bandwidth_rules ' , 8 , 10 , columns , 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 ( ) )
self . _listctrl . Sort ( 0 )
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 )
with ClientGUITopLevelWindows . DialogEdit ( self , ' edit rule ' ) as dlg :
panel = self . _EditPanel ( dlg , rule )
dlg . SetPanel ( panel )
if dlg . ShowModal ( ) == wx . ID_OK :
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
with ClientGUITopLevelWindows . DialogEdit ( self , ' edit rule ' ) as dlg :
panel = self . _EditPanel ( dlg , rule )
dlg . SetPanel ( panel )
if dlg . ShowModal ( ) == wx . ID_OK :
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 )
self . _bandwidth_type . Append ( ' data ' , HC . BANDWIDTH_TYPE_DATA )
self . _bandwidth_type . Append ( ' requests ' , HC . BANDWIDTH_TYPE_REQUESTS )
self . _bandwidth_type . Bind ( wx . EVT_CHOICE , self . EventBandwidth )
2018-03-14 21:01:02 +00:00
self . _max_allowed_bytes = BytesControl ( self )
self . _max_allowed_requests = wx . SpinCtrl ( 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
self . _bandwidth_type . SelectClientData ( bandwidth_type )
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 :
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
#
hbox = wx . BoxSizer ( wx . HORIZONTAL )
2018-03-14 21:01:02 +00:00
hbox . Add ( self . _max_allowed_bytes , CC . FLAGS_VCENTER )
hbox . Add ( self . _max_allowed_requests , CC . FLAGS_VCENTER )
2018-01-03 22:37:30 +00:00
hbox . Add ( self . _bandwidth_type , CC . FLAGS_VCENTER )
2018-03-14 21:01:02 +00:00
hbox . Add ( ClientGUICommon . BetterStaticText ( self , ' every ' ) , CC . FLAGS_VCENTER )
2018-01-03 22:37:30 +00:00
hbox . Add ( self . _time_delta , CC . FLAGS_VCENTER )
2017-03-02 02:14:56 +00:00
self . SetSizer ( hbox )
2018-03-14 21:01:02 +00:00
def _UpdateEnabled ( self ) :
2017-03-02 02:14:56 +00:00
bandwidth_type = self . _bandwidth_type . GetChoice ( )
if bandwidth_type == HC . BANDWIDTH_TYPE_DATA :
2018-03-14 21:01:02 +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 :
2018-03-14 21:01:02 +00:00
self . _max_allowed_bytes . Hide ( )
self . _max_allowed_requests . Show ( )
2017-03-02 02:14:56 +00:00
2018-03-14 21:01:02 +00:00
self . Layout ( )
2017-03-02 02:14:56 +00:00
def EventBandwidth ( self , event ) :
2018-03-14 21:01:02 +00:00
self . _UpdateEnabled ( )
2017-03-02 02:14:56 +00:00
def GetValue ( self ) :
bandwidth_type = self . _bandwidth_type . GetChoice ( )
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 :
max_allowed = self . _max_allowed_requests . GetValue ( )
2017-03-02 02:14:56 +00:00
return ( bandwidth_type , time_delta , max_allowed )
2017-03-08 23:23:12 +00:00
2018-03-14 21:01:02 +00:00
class BytesControl ( wx . Panel ) :
def __init__ ( self , parent , initial_value = 65536 ) :
wx . Panel . __init__ ( self , parent )
2018-03-22 00:03:33 +00:00
self . _spin = wx . SpinCtrl ( self , min = 0 , max = 1048576 )
2018-05-16 20:09:50 +00:00
width = ClientGUICommon . ConvertTextToPixelWidth ( self . _spin , 12 )
2018-03-22 00:03:33 +00:00
self . _spin . SetSize ( ( width , - 1 ) )
2018-03-14 21:01:02 +00:00
self . _unit = ClientGUICommon . BetterChoice ( self )
self . _unit . Append ( ' B ' , 1 )
self . _unit . Append ( ' KB ' , 1024 )
self . _unit . Append ( ' MB ' , 1024 * 1024 )
self . _unit . Append ( ' GB ' , 1024 * 1024 * 1024 )
#
self . SetValue ( initial_value )
#
hbox = wx . BoxSizer ( wx . HORIZONTAL )
hbox . Add ( self . _spin , CC . FLAGS_VCENTER )
hbox . Add ( self . _unit , CC . FLAGS_VCENTER )
self . SetSizer ( hbox )
2018-04-25 22:07:52 +00:00
def Bind ( self , event_type , callback ) :
self . _spin . Bind ( wx . EVT_SPINCTRL , callback )
self . _unit . Bind ( wx . EVT_CHOICE , callback )
def Disable ( self ) :
self . _spin . Disable ( )
self . _unit . Disable ( )
def Enable ( self ) :
self . _spin . Enable ( )
self . _unit . Enable ( )
2018-03-14 21:01:02 +00:00
def GetSeparatedValue ( self ) :
return ( self . _spin . GetValue ( ) , self . _unit . GetChoice ( ) )
def GetValue ( self ) :
return self . _spin . GetValue ( ) * self . _unit . GetChoice ( )
def SetSeparatedValue ( self , value , unit ) :
return ( self . _spin . SetValue ( value ) , self . _unit . SelectClientData ( unit ) )
def SetValue ( self , value ) :
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
self . _spin . SetValue ( value )
self . _unit . SelectClientData ( unit )
2018-10-17 21:00:09 +00:00
class EditStringConverterPanel ( ClientGUIScrolledPanels . EditPanel ) :
2018-03-14 21:01:02 +00:00
2018-10-17 21:00:09 +00:00
def __init__ ( self , parent , string_converter , example_string_override = None ) :
2018-03-14 21:01:02 +00:00
2018-10-17 21:00:09 +00:00
ClientGUIScrolledPanels . EditPanel . __init__ ( self , parent )
2018-03-14 21:01:02 +00:00
2018-10-17 21:00:09 +00:00
transformations_panel = ClientGUIListCtrl . BetterListCtrlPanel ( self )
2018-03-14 21:01:02 +00:00
2018-10-17 21:00:09 +00:00
columns = [ ( ' # ' , 3 ) , ( ' transformation ' , 30 ) , ( ' result ' , - 1 ) ]
2018-03-14 21:01:02 +00:00
2018-10-17 21:00:09 +00:00
self . _transformations = ClientGUIListCtrl . BetterListCtrl ( transformations_panel , ' string_converter_transformations ' , 7 , 35 , columns , self . _ConvertTransformationToListCtrlTuples , delete_key_callback = self . _DeleteTransformation , activation_callback = self . _EditTransformation )
2018-03-14 21:01:02 +00:00
2018-10-17 21:00:09 +00:00
transformations_panel . SetListCtrl ( self . _transformations )
2018-03-14 21:01:02 +00:00
2018-10-17 21:00:09 +00:00
transformations_panel . AddButton ( ' add ' , self . _AddTransformation )
transformations_panel . AddButton ( ' edit ' , self . _EditTransformation , enabled_only_on_selection = True )
transformations_panel . AddDeleteButton ( )
2018-03-14 21:01:02 +00:00
2018-10-17 21:00:09 +00:00
transformations_panel . AddSeparator ( )
2018-03-14 21:01:02 +00:00
2018-10-17 21:00:09 +00:00
transformations_panel . AddButton ( ' move up ' , self . _MoveUp , enabled_check_func = self . _CanMoveUp )
transformations_panel . AddButton ( ' move down ' , self . _MoveDown , enabled_check_func = self . _CanMoveDown )
2018-03-14 21:01:02 +00:00
2018-10-17 21:00:09 +00:00
self . _example_string = wx . TextCtrl ( self )
2018-03-14 21:01:02 +00:00
#
2018-10-17 21:00:09 +00:00
self . _transformations . AddDatas ( [ ( i + 1 , transformation_type , data ) for ( i , ( transformation_type , data ) ) in enumerate ( string_converter . transformations ) ] )
2018-03-14 21:01:02 +00:00
2018-10-17 21:00:09 +00:00
if example_string_override is None :
2018-03-14 21:01:02 +00:00
2018-10-17 21:00:09 +00:00
self . _example_string . SetValue ( string_converter . example_string )
2018-03-14 21:01:02 +00:00
else :
2018-10-17 21:00:09 +00:00
self . _example_string . SetValue ( example_string_override )
2018-03-14 21:01:02 +00:00
2018-10-17 21:00:09 +00:00
self . _transformations . UpdateDatas ( ) # to refresh, now they are all in the list
2018-03-14 21:01:02 +00:00
2018-10-17 21:00:09 +00:00
self . _transformations . Sort ( 0 )
2018-03-14 21:01:02 +00:00
2018-10-17 21:00:09 +00:00
#
2018-04-25 22:07:52 +00:00
2018-10-17 21:00:09 +00:00
rows = [ ]
2018-04-25 22:07:52 +00:00
2018-10-17 21:00:09 +00:00
rows . append ( ( ' example string: ' , self . _example_string ) )
2018-04-25 22:07:52 +00:00
2018-10-17 21:00:09 +00:00
gridbox = ClientGUICommon . WrapInGrid ( self , rows )
2018-03-14 21:01:02 +00:00
2018-10-17 21:00:09 +00:00
vbox = wx . BoxSizer ( wx . VERTICAL )
2018-03-14 21:01:02 +00:00
2018-10-17 21:00:09 +00:00
vbox . Add ( transformations_panel , CC . FLAGS_EXPAND_BOTH_WAYS )
2019-05-22 22:35:06 +00:00
vbox . Add ( gridbox , CC . FLAGS_EXPAND_SIZER_PERPENDICULAR )
2018-03-22 00:03:33 +00:00
2018-10-17 21:00:09 +00:00
self . SetSizer ( vbox )
2018-03-22 00:03:33 +00:00
2018-10-17 21:00:09 +00:00
#
self . _example_string . Bind ( wx . EVT_TEXT , self . EventUpdate )
2018-03-22 00:03:33 +00:00
2018-03-14 21:01:02 +00:00
2018-10-17 21:00:09 +00:00
def _AddTransformation ( self ) :
2018-03-14 21:01:02 +00:00
2018-10-17 21:00:09 +00:00
transformation_type = ClientParsing . STRING_TRANSFORMATION_APPEND_TEXT
data = ' extra text '
with ClientGUITopLevelWindows . DialogEdit ( self , ' edit transformation ' , frame_key = ' deeply_nested_dialog ' ) as dlg :
2018-03-14 21:01:02 +00:00
2018-10-17 21:00:09 +00:00
panel = self . _TransformationPanel ( dlg , transformation_type , data )
2018-03-14 21:01:02 +00:00
2018-10-17 21:00:09 +00:00
dlg . SetPanel ( panel )
2018-03-14 21:01:02 +00:00
2018-10-17 21:00:09 +00:00
if dlg . ShowModal ( ) == wx . ID_OK :
number = self . _transformations . GetItemCount ( ) + 1
( transformation_type , data ) = panel . GetValue ( )
enumerated_transformation = ( number , transformation_type , data )
self . _transformations . AddDatas ( ( enumerated_transformation , ) )
2018-03-14 21:01:02 +00:00
2018-10-17 21:00:09 +00:00
self . _transformations . UpdateDatas ( ) # need to refresh string after the insertion, so the new row can be included in the parsing calcs
2017-03-22 22:38:15 +00:00
2018-10-17 21:00:09 +00:00
self . _transformations . Sort ( )
2017-07-27 00:47:13 +00:00
2018-10-17 21:00:09 +00:00
def _CanMoveDown ( self ) :
2018-08-01 20:44:57 +00:00
2018-10-17 21:00:09 +00:00
selected_data = self . _transformations . GetData ( only_selected = True )
2017-03-22 22:38:15 +00:00
2018-10-17 21:00:09 +00:00
if len ( selected_data ) == 1 :
( number , transformation_type , data ) = selected_data [ 0 ]
if number < self . _transformations . GetItemCount ( ) :
return True
2017-07-27 00:47:13 +00:00
2018-10-17 21:00:09 +00:00
return False
2017-03-22 22:38:15 +00:00
2018-10-17 21:00:09 +00:00
def _CanMoveUp ( self ) :
2017-03-22 22:38:15 +00:00
2018-10-17 21:00:09 +00:00
selected_data = self . _transformations . GetData ( only_selected = True )
2017-12-06 22:06:56 +00:00
2018-10-17 21:00:09 +00:00
if len ( selected_data ) == 1 :
( number , transformation_type , data ) = selected_data [ 0 ]
if number > 1 :
return True
2017-03-22 22:38:15 +00:00
2018-10-17 21:00:09 +00:00
return False
2017-03-22 22:38:15 +00:00
2018-10-17 21:00:09 +00:00
def _ConvertTransformationToListCtrlTuples ( self , transformation ) :
2017-03-22 22:38:15 +00:00
2018-10-17 21:00:09 +00:00
( number , transformation_type , data ) = transformation
2017-03-22 22:38:15 +00:00
2018-10-17 21:00:09 +00:00
pretty_number = HydrusData . ToHumanInt ( number )
2019-01-09 22:59:03 +00:00
pretty_transformation = ClientParsing . StringConverter . TransformationToString ( ( transformation_type , data ) )
2017-03-22 22:38:15 +00:00
2018-10-17 21:00:09 +00:00
string_converter = self . _GetValue ( )
2017-12-06 22:06:56 +00:00
2018-10-17 21:00:09 +00:00
try :
pretty_result = ClientParsing . MakeParsedTextPretty ( string_converter . Convert ( self . _example_string . GetValue ( ) , number ) )
except HydrusExceptions . StringConvertException as e :
pretty_result = str ( e )
2017-12-06 22:06:56 +00:00
2018-10-17 21:00:09 +00:00
display_tuple = ( pretty_number , pretty_transformation , pretty_result )
sort_tuple = ( number , number , number )
2017-12-06 22:06:56 +00:00
return ( display_tuple , sort_tuple )
2018-10-17 21:00:09 +00:00
def _DeleteTransformation ( self ) :
2017-03-22 22:38:15 +00:00
2018-10-17 21:00:09 +00:00
if len ( self . _transformations . GetData ( only_selected = True ) ) > 0 :
2017-03-22 22:38:15 +00:00
2018-10-17 21:00:09 +00:00
with ClientGUIDialogs . DialogYesNo ( self , ' Delete all selected? ' ) as dlg :
2017-03-22 22:38:15 +00:00
2018-10-17 21:00:09 +00:00
if dlg . ShowModal ( ) == wx . ID_YES :
2017-03-22 22:38:15 +00:00
2018-10-17 21:00:09 +00:00
self . _transformations . DeleteSelected ( )
2017-03-22 22:38:15 +00:00
2018-10-17 21:00:09 +00:00
# now we need to shuffle up any missing numbers
num_rows = self . _transformations . GetItemCount ( )
i = 1
search_i = i
2017-03-22 22:38:15 +00:00
2018-10-17 21:00:09 +00:00
while i < = num_rows :
2017-03-22 22:38:15 +00:00
2018-10-17 21:00:09 +00:00
try :
transformation = self . _GetTransformation ( search_i )
if search_i != i :
self . _transformations . DeleteDatas ( ( transformation , ) )
( search_i , transformation_type , data ) = transformation
transformation = ( i , transformation_type , data )
self . _transformations . AddDatas ( ( transformation , ) )
i + = 1
search_i = i
2017-03-22 22:38:15 +00:00
2018-10-17 21:00:09 +00:00
except HydrusExceptions . DataMissing :
search_i + = 1
2017-03-22 22:38:15 +00:00
2018-10-17 21:00:09 +00:00
self . _transformations . UpdateDatas ( )
self . _transformations . Sort ( )
2017-03-22 22:38:15 +00:00
2018-10-17 21:00:09 +00:00
def _EditTransformation ( self ) :
2017-03-22 22:38:15 +00:00
2018-10-17 21:00:09 +00:00
selected_data = self . _transformations . GetData ( only_selected = True )
for enumerated_transformation in selected_data :
2017-03-22 22:38:15 +00:00
2018-10-17 21:00:09 +00:00
( number , transformation_type , data ) = enumerated_transformation
2017-03-22 22:38:15 +00:00
2018-10-17 21:00:09 +00:00
with ClientGUITopLevelWindows . DialogEdit ( self , ' edit transformation ' , frame_key = ' deeply_nested_dialog ' ) as dlg :
panel = self . _TransformationPanel ( dlg , transformation_type , data )
dlg . SetPanel ( panel )
2017-03-22 22:38:15 +00:00
if dlg . ShowModal ( ) == wx . ID_OK :
2018-10-17 21:00:09 +00:00
self . _transformations . DeleteDatas ( ( enumerated_transformation , ) )
2017-03-22 22:38:15 +00:00
2018-10-17 21:00:09 +00:00
( transformation_type , data ) = panel . GetValue ( )
2017-03-22 22:38:15 +00:00
2018-10-17 21:00:09 +00:00
enumerated_transformation = ( number , transformation_type , data )
2017-03-22 22:38:15 +00:00
2018-10-17 21:00:09 +00:00
self . _transformations . AddDatas ( ( enumerated_transformation , ) )
2017-03-22 22:38:15 +00:00
else :
2017-12-06 22:06:56 +00:00
break
2017-03-22 22:38:15 +00:00
2018-10-17 21:00:09 +00:00
self . _transformations . UpdateDatas ( )
self . _transformations . Sort ( )
def _GetTransformation ( self , desired_number ) :
for transformation in self . _transformations . GetData ( ) :
2017-03-22 22:38:15 +00:00
2018-10-17 21:00:09 +00:00
( number , transformation_type , data ) = transformation
2017-03-22 22:38:15 +00:00
2018-10-17 21:00:09 +00:00
if number == desired_number :
return transformation
2017-12-06 22:06:56 +00:00
2018-10-17 21:00:09 +00:00
raise HydrusExceptions . DataMissing ( )
2017-03-22 22:38:15 +00:00
2018-10-17 21:00:09 +00:00
def _GetValue ( self ) :
2017-03-22 22:38:15 +00:00
2018-10-17 21:00:09 +00:00
enumerated_transformations = list ( self . _transformations . GetData ( ) )
2017-03-22 22:38:15 +00:00
2018-10-17 21:00:09 +00:00
enumerated_transformations . sort ( )
2017-03-22 22:38:15 +00:00
2018-10-17 21:00:09 +00:00
transformations = [ ( transformation_type , data ) for ( number , transformation_type , data ) in enumerated_transformations ]
2017-07-05 21:09:28 +00:00
2018-10-17 21:00:09 +00:00
example_string = self . _example_string . GetValue ( )
2017-07-05 21:09:28 +00:00
2018-10-17 21:00:09 +00:00
string_converter = ClientParsing . StringConverter ( transformations , example_string )
2017-07-12 20:03:45 +00:00
2018-10-17 21:00:09 +00:00
return string_converter
2017-08-16 21:58:06 +00:00
2018-10-17 21:00:09 +00:00
def _MoveDown ( self ) :
2017-07-12 20:03:45 +00:00
2018-10-17 21:00:09 +00:00
selected_transformation = self . _transformations . GetData ( only_selected = True ) [ 0 ]
2017-07-12 20:03:45 +00:00
2018-10-17 21:00:09 +00:00
( number , transformation_type , data ) = selected_transformation
2017-07-05 21:09:28 +00:00
2018-10-17 21:00:09 +00:00
swap_transformation = self . _GetTransformation ( number + 1 )
2017-07-05 21:09:28 +00:00
2018-10-17 21:00:09 +00:00
self . _SwapTransformations ( selected_transformation , swap_transformation )
2017-07-05 21:09:28 +00:00
2018-10-17 21:00:09 +00:00
self . _transformations . UpdateDatas ( )
2017-07-05 21:09:28 +00:00
2018-10-17 21:00:09 +00:00
self . _transformations . Sort ( )
2017-07-05 21:09:28 +00:00
2018-10-17 21:00:09 +00:00
def _MoveUp ( self ) :
2017-07-12 20:03:45 +00:00
2018-10-17 21:00:09 +00:00
selected_transformation = self . _transformations . GetData ( only_selected = True ) [ 0 ]
2017-07-12 20:03:45 +00:00
2018-10-17 21:00:09 +00:00
( number , transformation_type , data ) = selected_transformation
2017-07-12 20:03:45 +00:00
2018-10-17 21:00:09 +00:00
swap_transformation = self . _GetTransformation ( number - 1 )
2017-07-12 20:03:45 +00:00
2018-10-17 21:00:09 +00:00
self . _SwapTransformations ( selected_transformation , swap_transformation )
2017-07-05 21:09:28 +00:00
2018-10-17 21:00:09 +00:00
self . _transformations . UpdateDatas ( )
2017-07-05 21:09:28 +00:00
2018-10-17 21:00:09 +00:00
self . _transformations . Sort ( )
2017-07-05 21:09:28 +00:00
2018-10-17 21:00:09 +00:00
def _SwapTransformations ( self , one , two ) :
2018-09-19 21:54:51 +00:00
2018-10-17 21:00:09 +00:00
selected_data = self . _transformations . GetData ( only_selected = True )
2018-09-19 21:54:51 +00:00
2018-10-17 21:00:09 +00:00
one_selected = one in selected_data
two_selected = two in selected_data
self . _transformations . DeleteDatas ( ( one , two ) )
( number_1 , transformation_type_1 , data_1 ) = one
( number_2 , transformation_type_2 , data_2 ) = two
one = ( number_2 , transformation_type_1 , data_1 )
two = ( number_1 , transformation_type_2 , data_2 )
self . _transformations . AddDatas ( ( one , two ) )
if one_selected :
2018-09-19 21:54:51 +00:00
2018-10-17 21:00:09 +00:00
self . _transformations . SelectDatas ( ( one , ) )
2018-09-19 21:54:51 +00:00
2018-10-17 21:00:09 +00:00
if two_selected :
2018-09-19 21:54:51 +00:00
2018-10-17 21:00:09 +00:00
self . _transformations . SelectDatas ( ( two , ) )
2018-09-19 21:54:51 +00:00
2018-10-17 21:00:09 +00:00
def EventUpdate ( self , event ) :
2018-09-19 21:54:51 +00:00
2018-10-17 21:00:09 +00:00
self . _transformations . UpdateDatas ( )
2018-09-19 21:54:51 +00:00
2018-10-17 21:00:09 +00:00
def GetValue ( self ) :
2017-08-30 20:27:47 +00:00
2018-10-17 21:00:09 +00:00
string_converter = self . _GetValue ( )
try :
2017-08-30 20:27:47 +00:00
2018-10-17 21:00:09 +00:00
string_converter . Convert ( self . _example_string . GetValue ( ) )
2017-08-30 20:27:47 +00:00
2018-10-17 21:00:09 +00:00
except HydrusExceptions . StringConvertException :
2017-08-30 20:27:47 +00:00
2018-10-17 21:00:09 +00:00
raise HydrusExceptions . VetoException ( ' Please enter an example text that can be converted! ' )
2017-08-30 20:27:47 +00:00
2018-10-17 21:00:09 +00:00
return string_converter
2017-08-30 20:27:47 +00:00
2018-10-17 21:00:09 +00:00
class _TransformationPanel ( ClientGUIScrolledPanels . EditPanel ) :
2017-07-05 21:09:28 +00:00
2018-10-17 21:00:09 +00:00
def __init__ ( self , parent , transformation_type , data ) :
2017-07-12 20:03:45 +00:00
2018-10-17 21:00:09 +00:00
ClientGUIScrolledPanels . EditPanel . __init__ ( self , parent )
2017-07-05 21:09:28 +00:00
2018-10-17 21:00:09 +00:00
self . _transformation_type = ClientGUICommon . BetterChoice ( self )
2017-07-05 21:09:28 +00:00
2018-10-17 21:00:09 +00:00
for t_type in ( ClientParsing . STRING_TRANSFORMATION_REMOVE_TEXT_FROM_BEGINNING , ClientParsing . STRING_TRANSFORMATION_REMOVE_TEXT_FROM_END , ClientParsing . STRING_TRANSFORMATION_CLIP_TEXT_FROM_BEGINNING , ClientParsing . STRING_TRANSFORMATION_CLIP_TEXT_FROM_END , ClientParsing . STRING_TRANSFORMATION_PREPEND_TEXT , ClientParsing . STRING_TRANSFORMATION_APPEND_TEXT , ClientParsing . STRING_TRANSFORMATION_ENCODE , ClientParsing . STRING_TRANSFORMATION_DECODE , ClientParsing . STRING_TRANSFORMATION_REVERSE , ClientParsing . STRING_TRANSFORMATION_REGEX_SUB , ClientParsing . STRING_TRANSFORMATION_DATE_DECODE , ClientParsing . STRING_TRANSFORMATION_INTEGER_ADDITION ) :
2017-07-05 21:09:28 +00:00
2018-10-17 21:00:09 +00:00
self . _transformation_type . Append ( ClientParsing . transformation_type_str_lookup [ t_type ] , t_type )
2017-07-05 21:09:28 +00:00
2018-10-17 21:00:09 +00:00
self . _data_text = wx . TextCtrl ( self )
self . _data_number = wx . SpinCtrl ( self , min = 0 , max = 65535 )
self . _data_encoding = ClientGUICommon . BetterChoice ( self )
self . _data_regex_pattern = wx . TextCtrl ( self )
self . _data_regex_repl = wx . TextCtrl ( self )
self . _data_date_link = ClientGUICommon . BetterHyperLink ( self , ' link to date info ' , ' https://docs.python.org/2/library/datetime.html#strftime-strptime-behavior ' )
self . _data_timezone = ClientGUICommon . BetterChoice ( self )
self . _data_timezone_offset = wx . SpinCtrl ( self , min = - 86400 , max = 86400 )
for e in ( ' hex ' , ' base64 ' ) :
2017-07-05 21:09:28 +00:00
2018-10-17 21:00:09 +00:00
self . _data_encoding . Append ( e , e )
2017-07-05 21:09:28 +00:00
2018-10-17 21:00:09 +00:00
self . _data_timezone . Append ( ' GMT ' , HC . TIMEZONE_GMT )
self . _data_timezone . Append ( ' Local ' , HC . TIMEZONE_LOCAL )
self . _data_timezone . Append ( ' Offset ' , HC . TIMEZONE_OFFSET )
2017-07-05 21:09:28 +00:00
2018-10-17 21:00:09 +00:00
#
2017-07-12 20:03:45 +00:00
2018-10-17 21:00:09 +00:00
self . _transformation_type . SelectClientData ( transformation_type )
2017-07-12 20:03:45 +00:00
2018-10-17 21:00:09 +00:00
self . _UpdateDataControls ( )
2018-08-08 20:29:54 +00:00
2018-10-17 21:00:09 +00:00
#
if transformation_type in ( ClientParsing . STRING_TRANSFORMATION_DECODE , ClientParsing . STRING_TRANSFORMATION_ENCODE ) :
2017-07-12 20:03:45 +00:00
2018-10-17 21:00:09 +00:00
self . _data_encoding . SelectClientData ( data )
2017-07-12 20:03:45 +00:00
2018-10-17 21:00:09 +00:00
elif transformation_type == ClientParsing . STRING_TRANSFORMATION_REGEX_SUB :
( pattern , repl ) = data
self . _data_regex_pattern . SetValue ( pattern )
self . _data_regex_repl . SetValue ( repl )
elif transformation_type == ClientParsing . STRING_TRANSFORMATION_DATE_DECODE :
( phrase , timezone_type , timezone_offset ) = data
self . _data_text . SetValue ( phrase )
self . _data_timezone . SelectClientData ( timezone_type )
self . _data_timezone_offset . SetValue ( timezone_offset )
elif data is not None :
if isinstance ( data , int ) :
2017-07-12 20:03:45 +00:00
2018-10-17 21:00:09 +00:00
self . _data_number . SetValue ( data )
else :
self . _data_text . SetValue ( data )
2017-07-12 20:03:45 +00:00
2018-08-08 20:29:54 +00:00
2018-10-17 21:00:09 +00:00
#
2018-08-08 20:29:54 +00:00
2018-10-17 21:00:09 +00:00
rows = [ ]
2018-08-08 20:29:54 +00:00
2018-10-17 21:00:09 +00:00
rows . append ( ( ' string data: ' , self . _data_text ) )
rows . append ( ( ' number data: ' , self . _data_number ) )
rows . append ( ( ' encoding data: ' , self . _data_encoding ) )
rows . append ( ( ' regex pattern: ' , self . _data_regex_pattern ) )
rows . append ( ( ' regex replacement: ' , self . _data_regex_repl ) )
rows . append ( ( ' date info: ' , self . _data_date_link ) )
rows . append ( ( ' date timezone: ' , self . _data_timezone ) )
rows . append ( ( ' timezone offset: ' , self . _data_timezone_offset ) )
2018-08-08 20:29:54 +00:00
2018-10-17 21:00:09 +00:00
gridbox = ClientGUICommon . WrapInGrid ( self , rows )
vbox = wx . BoxSizer ( wx . VERTICAL )
vbox . Add ( self . _transformation_type , CC . FLAGS_EXPAND_PERPENDICULAR )
vbox . Add ( gridbox , CC . FLAGS_EXPAND_SIZER_PERPENDICULAR )
self . SetSizer ( vbox )
#
self . _transformation_type . Bind ( wx . EVT_CHOICE , self . EventChoice )
self . _data_timezone . Bind ( wx . EVT_CHOICE , self . EventChoice )
def _UpdateDataControls ( self ) :
self . _data_text . Disable ( )
self . _data_number . Disable ( )
self . _data_encoding . Disable ( )
self . _data_regex_pattern . Disable ( )
self . _data_regex_repl . Disable ( )
self . _data_timezone . Disable ( )
self . _data_timezone_offset . Disable ( )
transformation_type = self . _transformation_type . GetChoice ( )
if transformation_type in ( ClientParsing . STRING_TRANSFORMATION_ENCODE , ClientParsing . STRING_TRANSFORMATION_DECODE ) :
2017-07-05 21:09:28 +00:00
2018-10-17 21:00:09 +00:00
self . _data_encoding . Enable ( )
2018-08-08 20:29:54 +00:00
2018-10-17 21:00:09 +00:00
elif transformation_type in ( ClientParsing . STRING_TRANSFORMATION_PREPEND_TEXT , ClientParsing . STRING_TRANSFORMATION_APPEND_TEXT , ClientParsing . STRING_TRANSFORMATION_DATE_DECODE ) :
2017-07-05 21:09:28 +00:00
2018-10-17 21:00:09 +00:00
self . _data_text . Enable ( )
if transformation_type == ClientParsing . STRING_TRANSFORMATION_DATE_DECODE :
self . _data_timezone . Enable ( )
if self . _data_timezone . GetChoice ( ) == HC . TIMEZONE_OFFSET :
self . _data_timezone_offset . Enable ( )
elif transformation_type in ( ClientParsing . STRING_TRANSFORMATION_REMOVE_TEXT_FROM_BEGINNING , ClientParsing . STRING_TRANSFORMATION_REMOVE_TEXT_FROM_END , ClientParsing . STRING_TRANSFORMATION_CLIP_TEXT_FROM_BEGINNING , ClientParsing . STRING_TRANSFORMATION_CLIP_TEXT_FROM_END , ClientParsing . STRING_TRANSFORMATION_INTEGER_ADDITION ) :
self . _data_number . Enable ( )
if transformation_type == ClientParsing . STRING_TRANSFORMATION_INTEGER_ADDITION :
self . _data_number . SetMin ( - 65535 )
else :
self . _data_number . SetMin ( 0 )
elif transformation_type == ClientParsing . STRING_TRANSFORMATION_REGEX_SUB :
self . _data_regex_pattern . Enable ( )
self . _data_regex_repl . Enable ( )
2017-07-05 21:09:28 +00:00
2018-10-17 21:00:09 +00:00
def EventChoice ( self , event ) :
self . _UpdateDataControls ( )
2017-07-05 21:09:28 +00:00
2018-10-17 21:00:09 +00:00
def GetValue ( self ) :
2017-07-05 21:09:28 +00:00
2018-10-17 21:00:09 +00:00
transformation_type = self . _transformation_type . GetChoice ( )
if transformation_type in ( ClientParsing . STRING_TRANSFORMATION_ENCODE , ClientParsing . STRING_TRANSFORMATION_DECODE ) :
2017-07-05 21:09:28 +00:00
2018-10-17 21:00:09 +00:00
data = self . _data_encoding . GetChoice ( )
2017-07-05 21:09:28 +00:00
2018-10-17 21:00:09 +00:00
elif transformation_type in ( ClientParsing . STRING_TRANSFORMATION_PREPEND_TEXT , ClientParsing . STRING_TRANSFORMATION_APPEND_TEXT ) :
2017-07-05 21:09:28 +00:00
2018-10-17 21:00:09 +00:00
data = self . _data_text . GetValue ( )
elif transformation_type in ( ClientParsing . STRING_TRANSFORMATION_REMOVE_TEXT_FROM_BEGINNING , ClientParsing . STRING_TRANSFORMATION_REMOVE_TEXT_FROM_END , ClientParsing . STRING_TRANSFORMATION_CLIP_TEXT_FROM_BEGINNING , ClientParsing . STRING_TRANSFORMATION_CLIP_TEXT_FROM_END , ClientParsing . STRING_TRANSFORMATION_INTEGER_ADDITION ) :
data = self . _data_number . GetValue ( )
elif transformation_type == ClientParsing . STRING_TRANSFORMATION_REGEX_SUB :
pattern = self . _data_regex_pattern . GetValue ( )
repl = self . _data_regex_repl . GetValue ( )
data = ( pattern , repl )
elif transformation_type == ClientParsing . STRING_TRANSFORMATION_DATE_DECODE :
2017-07-05 21:09:28 +00:00
2018-10-17 21:00:09 +00:00
phrase = self . _data_text . GetValue ( )
timezone_time = self . _data_timezone . GetChoice ( )
timezone_offset = self . _data_timezone_offset . GetValue ( )
data = ( phrase , timezone_time , timezone_offset )
else :
data = None
return ( transformation_type , data )
2017-07-05 21:09:28 +00:00
2018-10-17 21:00:09 +00:00
class EditStringMatchPanel ( ClientGUIScrolledPanels . EditPanel ) :
def __init__ ( self , parent , string_match = None ) :
2017-07-05 21:09:28 +00:00
2018-10-17 21:00:09 +00:00
ClientGUIScrolledPanels . EditPanel . __init__ ( self , parent )
if string_match is None :
2017-07-05 21:09:28 +00:00
2018-10-17 21:00:09 +00:00
string_match = ClientParsing . StringMatch ( )
2017-07-05 21:09:28 +00:00
2018-10-17 21:00:09 +00:00
self . _match_type = ClientGUICommon . BetterChoice ( self )
2017-07-05 21:09:28 +00:00
2018-10-17 21:00:09 +00:00
self . _match_type . Append ( ' any characters ' , ClientParsing . STRING_MATCH_ANY )
self . _match_type . Append ( ' fixed characters ' , ClientParsing . STRING_MATCH_FIXED )
self . _match_type . Append ( ' character set ' , ClientParsing . STRING_MATCH_FLEXIBLE )
self . _match_type . Append ( ' regex ' , ClientParsing . STRING_MATCH_REGEX )
self . _match_value_text_input = wx . TextCtrl ( self )
self . _match_value_flexible_input = ClientGUICommon . BetterChoice ( self )
self . _match_value_flexible_input . Append ( ' alphabetic characters (a-zA-Z) ' , ClientParsing . ALPHA )
self . _match_value_flexible_input . Append ( ' alphanumeric characters (a-zA-Z0-9) ' , ClientParsing . ALPHANUMERIC )
self . _match_value_flexible_input . Append ( ' numeric characters (0-9) ' , ClientParsing . NUMERIC )
self . _min_chars = ClientGUICommon . NoneableSpinCtrl ( self , min = 1 , max = 65535 , unit = ' characters ' , none_phrase = ' no limit ' )
self . _max_chars = ClientGUICommon . NoneableSpinCtrl ( self , min = 1 , max = 65535 , unit = ' characters ' , none_phrase = ' no limit ' )
self . _example_string = wx . TextCtrl ( self )
self . _example_string_matches = ClientGUICommon . BetterStaticText ( self )
#
self . SetValue ( string_match )
#
rows = [ ]
rows . append ( ( ' match type: ' , self . _match_type ) )
rows . append ( ( ' match text: ' , self . _match_value_text_input ) )
rows . append ( ( ' match value (character set): ' , self . _match_value_flexible_input ) )
rows . append ( ( ' minumum allowed number of characters: ' , self . _min_chars ) )
rows . append ( ( ' maximum allowed number of characters: ' , self . _max_chars ) )
rows . append ( ( ' example string: ' , self . _example_string ) )
gridbox = ClientGUICommon . WrapInGrid ( self , rows )
vbox = wx . BoxSizer ( wx . VERTICAL )
2019-05-22 22:35:06 +00:00
vbox . Add ( gridbox , CC . FLAGS_EXPAND_SIZER_PERPENDICULAR )
2018-10-17 21:00:09 +00:00
vbox . Add ( self . _example_string_matches , CC . FLAGS_EXPAND_PERPENDICULAR )
self . SetSizer ( vbox )
#
self . _match_type . Bind ( wx . EVT_CHOICE , self . EventUpdate )
self . _match_value_text_input . Bind ( wx . EVT_TEXT , self . EventUpdate )
self . _match_value_flexible_input . Bind ( wx . EVT_CHOICE , self . EventUpdate )
self . _min_chars . Bind ( wx . EVT_SPINCTRL , self . EventUpdate )
self . _max_chars . Bind ( wx . EVT_SPINCTRL , self . EventUpdate )
self . _example_string . Bind ( wx . EVT_TEXT , self . EventUpdate )
2017-07-12 20:03:45 +00:00
2017-07-05 21:09:28 +00:00
2018-10-17 21:00:09 +00:00
def _GetValue ( self ) :
2017-08-16 21:58:06 +00:00
2018-10-17 21:00:09 +00:00
match_type = self . _match_type . GetChoice ( )
if match_type == ClientParsing . STRING_MATCH_ANY :
match_value = ' '
elif match_type == ClientParsing . STRING_MATCH_FLEXIBLE :
match_value = self . _match_value_flexible_input . GetChoice ( )
else :
match_value = self . _match_value_text_input . GetValue ( )
min_chars = self . _min_chars . GetValue ( )
max_chars = self . _max_chars . GetValue ( )
example_string = self . _example_string . GetValue ( )
string_match = ClientParsing . StringMatch ( match_type = match_type , match_value = match_value , min_chars = min_chars , max_chars = max_chars , example_string = example_string )
return string_match
2017-08-16 21:58:06 +00:00
2018-10-17 21:00:09 +00:00
def _UpdateControls ( self ) :
2017-07-05 21:09:28 +00:00
2018-10-17 21:00:09 +00:00
match_type = self . _match_type . GetChoice ( )
if match_type == ClientParsing . STRING_MATCH_ANY :
2018-08-01 20:44:57 +00:00
2018-10-17 21:00:09 +00:00
self . _match_value_text_input . Disable ( )
self . _match_value_flexible_input . Disable ( )
elif match_type == ClientParsing . STRING_MATCH_FLEXIBLE :
self . _match_value_text_input . Disable ( )
self . _match_value_flexible_input . Enable ( )
2017-07-19 21:21:41 +00:00
2018-08-01 20:44:57 +00:00
else :
2017-07-19 21:21:41 +00:00
2018-10-17 21:00:09 +00:00
self . _match_value_text_input . Enable ( )
self . _match_value_flexible_input . Disable ( )
if match_type == ClientParsing . STRING_MATCH_FIXED :
self . _min_chars . SetValue ( None )
self . _max_chars . SetValue ( None )
self . _min_chars . Disable ( )
self . _max_chars . Disable ( )
2019-01-09 22:59:03 +00:00
self . _example_string . ChangeValue ( self . _match_value_text_input . GetValue ( ) )
2018-10-17 21:00:09 +00:00
self . _example_string_matches . SetLabelText ( ' ' )
else :
self . _min_chars . Enable ( )
self . _max_chars . Enable ( )
string_match = self . _GetValue ( )
try :
2018-08-01 20:44:57 +00:00
2018-10-17 21:00:09 +00:00
string_match . Test ( self . _example_string . GetValue ( ) )
2018-08-01 20:44:57 +00:00
2018-10-17 21:00:09 +00:00
self . _example_string_matches . SetLabelText ( ' Example matches ok! ' )
self . _example_string_matches . SetForegroundColour ( ( 0 , 128 , 0 ) )
except HydrusExceptions . StringMatchException as e :
2019-01-09 22:59:03 +00:00
reason = str ( e )
2018-10-17 21:00:09 +00:00
self . _example_string_matches . SetLabelText ( ' Example does not match - ' + reason )
self . _example_string_matches . SetForegroundColour ( ( 128 , 0 , 0 ) )
2018-08-01 20:44:57 +00:00
2017-07-27 00:47:13 +00:00
2017-07-05 21:09:28 +00:00
2018-10-17 21:00:09 +00:00
def EventUpdate ( self , event ) :
2017-07-05 21:09:28 +00:00
2018-10-17 21:00:09 +00:00
self . _UpdateControls ( )
2017-08-30 20:27:47 +00:00
2018-10-17 21:00:09 +00:00
event . Skip ( )
def GetValue ( self ) :
string_match = self . _GetValue ( )
try :
2017-07-05 21:09:28 +00:00
2018-10-17 21:00:09 +00:00
string_match . Test ( self . _example_string . GetValue ( ) )
except HydrusExceptions . StringMatchException :
raise HydrusExceptions . VetoException ( ' Please enter an example text that matches the given rules! ' )
2017-07-05 21:09:28 +00:00
2018-10-17 21:00:09 +00:00
return string_match
2018-02-07 23:40:33 +00:00
2018-10-17 21:00:09 +00:00
def SetValue ( self , string_match ) :
( match_type , match_value , min_chars , max_chars , example_string ) = string_match . ToTuple ( )
self . _match_type . SelectClientData ( match_type )
if match_type == ClientParsing . STRING_MATCH_FLEXIBLE :
self . _match_value_flexible_input . SelectClientData ( match_value )
else :
self . _match_value_flexible_input . SelectClientData ( ClientParsing . ALPHA )
self . _match_value_text_input . SetValue ( match_value )
self . _min_chars . SetValue ( min_chars )
self . _max_chars . SetValue ( max_chars )
self . _example_string . SetValue ( example_string )
self . _UpdateControls ( )
2018-02-07 23:40:33 +00:00
2018-10-17 21:00:09 +00:00
class NoneableBytesControl ( wx . Panel ) :
def __init__ ( self , parent , initial_value = 65536 , none_label = ' no limit ' ) :
2018-02-07 23:40:33 +00:00
2018-10-17 21:00:09 +00:00
wx . Panel . __init__ ( self , parent )
2018-02-07 23:40:33 +00:00
2018-10-17 21:00:09 +00:00
self . _bytes = BytesControl ( self )
self . _none_checkbox = wx . CheckBox ( self , label = none_label )
#
self . SetValue ( initial_value )
#
hbox = wx . BoxSizer ( wx . HORIZONTAL )
hbox . Add ( self . _bytes , CC . FLAGS_SIZER_VCENTER )
hbox . Add ( self . _none_checkbox , CC . FLAGS_VCENTER )
self . SetSizer ( hbox )
#
self . _none_checkbox . Bind ( wx . EVT_CHECKBOX , self . EventNoneChecked )
2018-02-07 23:40:33 +00:00
2018-10-17 21:00:09 +00:00
def _UpdateEnabled ( self ) :
2018-02-07 23:40:33 +00:00
2018-10-17 21:00:09 +00:00
if self . _none_checkbox . GetValue ( ) :
2018-02-07 23:40:33 +00:00
2018-10-17 21:00:09 +00:00
self . _bytes . Disable ( )
2018-02-07 23:40:33 +00:00
2018-10-17 21:00:09 +00:00
else :
2018-02-07 23:40:33 +00:00
2018-10-17 21:00:09 +00:00
self . _bytes . Enable ( )
2018-02-07 23:40:33 +00:00
2018-10-17 21:00:09 +00:00
def EventNoneChecked ( self , event ) :
self . _UpdateEnabled ( )
def Bind ( self , event_type , callback ) :
self . _bytes . Bind ( wx . EVT_SPINCTRL , callback )
self . _none_checkbox . Bind ( wx . EVT_CHECKBOX , callback )
def GetValue ( self ) :
if self . _none_checkbox . GetValue ( ) :
2018-02-07 23:40:33 +00:00
2018-10-17 21:00:09 +00:00
return None
else :
return self . _bytes . GetValue ( )
2018-02-07 23:40:33 +00:00
2018-10-17 21:00:09 +00:00
def SetToolTip ( self , text ) :
2018-02-07 23:40:33 +00:00
2018-10-17 21:00:09 +00:00
wx . Panel . SetToolTip ( self , text )
for c in self . GetChildren ( ) :
c . SetToolTip ( text )
2018-02-07 23:40:33 +00:00
def SetValue ( self , value ) :
2018-10-17 21:00:09 +00:00
if value is None :
self . _none_checkbox . SetValue ( True )
else :
self . _none_checkbox . SetValue ( False )
self . _bytes . SetValue ( value )
self . _UpdateEnabled ( )
class NetworkJobControl ( wx . Panel ) :
def __init__ ( self , parent ) :
wx . Panel . __init__ ( self , parent , style = wx . BORDER_DOUBLE )
self . _network_job = None
self . _download_started = False
self . _auto_override_bandwidth_rules = False
self . _left_text = ClientGUICommon . BetterStaticText ( self , style = wx . ST_ELLIPSIZE_END )
self . _right_text = ClientGUICommon . BetterStaticText ( self , style = wx . ALIGN_RIGHT )
self . _last_right_min_width = ( - 1 , - 1 )
self . _gauge = ClientGUICommon . Gauge ( self )
self . _cog_button = ClientGUICommon . BetterBitmapButton ( self , CC . GlobalBMPs . cog , self . _ShowCogMenu )
self . _cancel_button = ClientGUICommon . BetterBitmapButton ( self , CC . GlobalBMPs . stop , self . Cancel )
#
self . _Update ( )
#
st_hbox = wx . BoxSizer ( wx . HORIZONTAL )
st_hbox . Add ( self . _left_text , CC . FLAGS_EXPAND_BOTH_WAYS )
st_hbox . Add ( self . _right_text , CC . FLAGS_VCENTER )
left_vbox = wx . BoxSizer ( wx . VERTICAL )
left_vbox . Add ( st_hbox , CC . FLAGS_EXPAND_SIZER_BOTH_WAYS )
left_vbox . Add ( self . _gauge , CC . FLAGS_EXPAND_PERPENDICULAR )
hbox = wx . BoxSizer ( wx . HORIZONTAL )
hbox . Add ( left_vbox , CC . FLAGS_EXPAND_SIZER_BOTH_WAYS )
hbox . Add ( self . _cog_button , CC . FLAGS_VCENTER )
hbox . Add ( self . _cancel_button , CC . FLAGS_VCENTER )
self . SetSizer ( hbox )
def _ShowCogMenu ( self ) :
menu = wx . Menu ( )
if self . _network_job is not None :
if self . _network_job . ObeysBandwidth ( ) :
ClientGUIMenus . AppendMenuItem ( self , menu , ' override bandwidth rules for this job ' , ' Tell the current job to ignore existing bandwidth rules and go ahead anyway. ' , self . _network_job . OverrideBandwidth )
if not self . _network_job . TokensOK ( ) :
ClientGUIMenus . AppendMenuItem ( self , menu , ' override gallery slot requirements for this job ' , ' Force-allow this download to proceed, ignoring the normal gallery wait times. ' , self . _network_job . OverrideToken )
ClientGUIMenus . AppendSeparator ( menu )
ClientGUIMenus . AppendMenuCheckItem ( self , 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 )
HG . client_controller . PopupMenu ( self . _cog_button , menu )
def _OverrideBandwidthIfAppropriate ( self ) :
if self . _network_job is None or self . _network_job . NoEngineYet ( ) :
return
else :
if self . _auto_override_bandwidth_rules and HydrusData . TimeHasPassed ( self . _network_job . GetCreationTime ( ) + 5 ) :
self . _network_job . OverrideBandwidth ( )
def _Update ( self ) :
if self . _network_job is None or self . _network_job . NoEngineYet ( ) :
self . _left_text . SetLabelText ( ' ' )
self . _right_text . SetLabelText ( ' ' )
self . _gauge . SetRange ( 1 )
self . _gauge . SetValue ( 0 )
can_cancel = False
else :
if self . _network_job . IsDone ( ) :
can_cancel = False
else :
can_cancel = True
( status_text , current_speed , bytes_read , bytes_to_read ) = self . _network_job . GetStatus ( )
self . _left_text . SetLabelText ( status_text )
if not self . _download_started and current_speed > 0 :
self . _download_started = True
speed_text = ' '
if self . _download_started and not self . _network_job . HasError ( ) :
if bytes_read is not None :
if bytes_to_read is not None and bytes_read != bytes_to_read :
speed_text + = HydrusData . ConvertValueRangeToBytes ( bytes_read , bytes_to_read )
else :
2019-01-09 22:59:03 +00:00
speed_text + = HydrusData . ToHumanBytes ( bytes_read )
2018-10-17 21:00:09 +00:00
if current_speed != bytes_to_read : # if it is a real quick download, just say its size
2019-01-09 22:59:03 +00:00
speed_text + = ' ' + HydrusData . ToHumanBytes ( current_speed ) + ' /s '
2018-10-17 21:00:09 +00:00
self . _right_text . SetLabelText ( speed_text )
right_width = ClientGUICommon . ConvertTextToPixelWidth ( self . _right_text , len ( speed_text ) )
right_min_size = ( right_width , - 1 )
if right_min_size != self . _last_right_min_width :
self . _last_right_min_width = right_min_size
self . _right_text . SetMinSize ( right_min_size )
self . Layout ( )
self . _gauge . SetRange ( bytes_to_read )
self . _gauge . SetValue ( bytes_read )
if can_cancel :
if not self . _cancel_button . IsEnabled ( ) :
self . _cancel_button . Enable ( )
else :
if self . _cancel_button . IsEnabled ( ) :
self . _cancel_button . Disable ( )
def Cancel ( self ) :
if self . _network_job is not None :
2018-10-31 21:41:14 +00:00
self . _network_job . Cancel ( ' Cancelled by user. ' )
2018-10-17 21:00:09 +00:00
def ClearNetworkJob ( self ) :
self . SetNetworkJob ( None )
def FlipAutoOverrideBandwidth ( self ) :
self . _auto_override_bandwidth_rules = not self . _auto_override_bandwidth_rules
def SetNetworkJob ( self , network_job ) :
if network_job is None :
if self . _network_job is not None :
self . _network_job = None
self . _Update ( )
HG . client_controller . gui . UnregisterUIUpdateWindow ( self )
else :
if self . _network_job != network_job :
self . _network_job = network_job
self . _download_started = False
HG . client_controller . gui . RegisterUIUpdateWindow ( self )
def TIMERUIUpdate ( self ) :
self . _OverrideBandwidthIfAppropriate ( )
if HG . client_controller . gui . IShouldRegularlyUpdate ( self ) :
self . _Update ( )
( StringConverterEvent , EVT_STRING_CONVERTER ) = wx . lib . newevent . NewCommandEvent ( )
class StringConverterButton ( ClientGUICommon . BetterButton ) :
def __init__ ( self , parent , string_converter ) :
ClientGUICommon . BetterButton . __init__ ( self , parent , ' edit string converter ' , self . _Edit )
self . _string_converter = string_converter
self . _example_string_override = None
self . _UpdateLabel ( )
def _Edit ( self ) :
with ClientGUITopLevelWindows . DialogEdit ( self , ' edit string converter ' , frame_key = ' deeply_nested_dialog ' ) as dlg :
panel = EditStringConverterPanel ( dlg , self . _string_converter , example_string_override = self . _example_string_override )
dlg . SetPanel ( panel )
if dlg . ShowModal ( ) == wx . ID_OK :
self . _string_converter = panel . GetValue ( )
self . _UpdateLabel ( )
wx . QueueEvent ( self . GetEventHandler ( ) , StringConverterEvent ( - 1 ) )
def _UpdateLabel ( self ) :
num_rules = len ( self . _string_converter . transformations )
if num_rules == 0 :
label = ' no string transformations '
else :
label = HydrusData . ToHumanInt ( num_rules ) + ' string transformations '
self . SetLabelText ( label )
def GetValue ( self ) :
return self . _string_converter
def SetExampleString ( self , example_string ) :
self . _example_string_override = example_string
def SetValue ( self , string_converter ) :
self . _string_converter = string_converter
self . _UpdateLabel ( )
class StringMatchButton ( ClientGUICommon . BetterButton ) :
def __init__ ( self , parent , string_match ) :
ClientGUICommon . BetterButton . __init__ ( self , parent , ' edit string match ' , self . _Edit )
self . _string_match = string_match
self . _UpdateLabel ( )
def _Edit ( self ) :
with ClientGUITopLevelWindows . DialogEdit ( self , ' edit string match ' , frame_key = ' deeply_nested_dialog ' ) as dlg :
panel = EditStringMatchPanel ( dlg , self . _string_match )
dlg . SetPanel ( panel )
if dlg . ShowModal ( ) == wx . ID_OK :
self . _string_match = panel . GetValue ( )
self . _UpdateLabel ( )
def _UpdateLabel ( self ) :
2019-01-09 22:59:03 +00:00
label = self . _string_match . ToString ( )
2018-10-17 21:00:09 +00:00
self . SetLabelText ( label )
def GetValue ( self ) :
return self . _string_match
def SetValue ( self , string_match ) :
self . _string_match = string_match
self . _UpdateLabel ( )
2018-11-14 23:10:55 +00:00
class StringMatchToStringMatchDictControl ( wx . Panel ) :
def __init__ ( self , parent , initial_dict , min_height = 10 , key_name = ' key ' ) :
wx . Panel . __init__ ( self , parent )
self . _key_name = key_name
listctrl_panel = ClientGUIListCtrl . BetterListCtrlPanel ( self )
columns = [ ( self . _key_name , 20 ) , ( ' matching ' , - 1 ) ]
self . _listctrl = ClientGUIListCtrl . BetterListCtrl ( listctrl_panel , ' key_to_string_match ' , min_height , 36 , columns , self . _ConvertDataToListCtrlTuples , use_simple_delete = True , activation_callback = self . _Edit )
listctrl_panel . SetListCtrl ( self . _listctrl )
listctrl_panel . AddButton ( ' add ' , self . _Add )
listctrl_panel . AddButton ( ' edit ' , self . _Edit , enabled_only_on_selection = True )
listctrl_panel . AddDeleteButton ( )
#
2019-01-09 22:59:03 +00:00
self . _listctrl . AddDatas ( list ( initial_dict . items ( ) ) )
2018-11-14 23:10:55 +00:00
self . _listctrl . Sort ( )
#
vbox = wx . BoxSizer ( wx . VERTICAL )
vbox . Add ( listctrl_panel , CC . FLAGS_EXPAND_BOTH_WAYS )
self . SetSizer ( vbox )
def _ConvertDataToListCtrlTuples ( self , data ) :
( key_string_match , value_string_match ) = data
2019-01-09 22:59:03 +00:00
pretty_key = key_string_match . ToString ( )
pretty_value = value_string_match . ToString ( )
2018-11-14 23:10:55 +00:00
display_tuple = ( pretty_key , pretty_value )
sort_tuple = ( pretty_key , pretty_value )
return ( display_tuple , sort_tuple )
def _Add ( self ) :
with ClientGUITopLevelWindows . DialogEdit ( self , ' edit ' + self . _key_name ) as dlg :
string_match = ClientParsing . StringMatch ( )
panel = EditStringMatchPanel ( dlg , string_match )
dlg . SetPanel ( panel )
if dlg . ShowModal ( ) == wx . ID_OK :
key_string_match = panel . GetValue ( )
else :
return
with ClientGUITopLevelWindows . DialogEdit ( self , ' edit match ' ) as dlg :
string_match = ClientParsing . StringMatch ( )
panel = EditStringMatchPanel ( dlg , string_match )
dlg . SetPanel ( panel )
if dlg . ShowModal ( ) == wx . ID_OK :
value_string_match = panel . GetValue ( )
data = ( key_string_match , value_string_match )
self . _listctrl . AddDatas ( ( data , ) )
def _Edit ( self ) :
for data in self . _listctrl . GetData ( only_selected = True ) :
( key_string_match , value_string_match ) = data
with ClientGUITopLevelWindows . DialogEdit ( self , ' edit ' + self . _key_name ) as dlg :
panel = EditStringMatchPanel ( dlg , key_string_match )
dlg . SetPanel ( panel )
if dlg . ShowModal ( ) == wx . ID_OK :
key_string_match = panel . GetValue ( )
else :
break
with ClientGUITopLevelWindows . DialogEdit ( self , ' edit match ' ) as dlg :
panel = EditStringMatchPanel ( dlg , value_string_match )
dlg . SetPanel ( panel )
if dlg . ShowModal ( ) == wx . ID_OK :
value_string_match = panel . GetValue ( )
else :
break
self . _listctrl . DeleteDatas ( ( data , ) )
edited_data = ( key_string_match , value_string_match )
self . _listctrl . AddDatas ( ( edited_data , ) )
self . _listctrl . Sort ( )
def GetValue ( self ) :
value_dict = dict ( self . _listctrl . GetData ( ) )
return value_dict
2018-10-17 21:00:09 +00:00
class StringToStringDictButton ( ClientGUICommon . BetterButton ) :
def __init__ ( self , parent , label ) :
ClientGUICommon . BetterButton . __init__ ( self , parent , label , self . _Edit )
self . _value = { }
def _Edit ( self ) :
with ClientGUITopLevelWindows . DialogEdit ( self , ' edit string dictionary ' ) as dlg :
panel = ClientGUIScrolledPanels . EditSingleCtrlPanel ( dlg )
control = StringToStringDictControl ( panel , self . _value )
panel . SetControl ( control )
dlg . SetPanel ( panel )
if dlg . ShowModal ( ) == wx . ID_OK :
self . _value = control . GetValue ( )
def GetValue ( self ) :
return self . _value
def SetValue ( self , value ) :
self . _value = value
class StringToStringDictControl ( wx . Panel ) :
def __init__ ( self , parent , initial_dict , min_height = 10 , key_name = ' key ' , value_name = ' value ' ) :
wx . Panel . __init__ ( self , parent )
self . _key_name = key_name
self . _value_name = value_name
listctrl_panel = ClientGUIListCtrl . BetterListCtrlPanel ( self )
columns = [ ( self . _key_name , 20 ) , ( self . _value_name , - 1 ) ]
self . _listctrl = ClientGUIListCtrl . BetterListCtrl ( listctrl_panel , ' key_to_value ' , min_height , 36 , columns , self . _ConvertDataToListCtrlTuples , use_simple_delete = True , activation_callback = self . _Edit )
listctrl_panel . SetListCtrl ( self . _listctrl )
listctrl_panel . AddButton ( ' add ' , self . _Add )
listctrl_panel . AddButton ( ' edit ' , self . _Edit , enabled_only_on_selection = True )
listctrl_panel . AddDeleteButton ( )
#
2019-01-09 22:59:03 +00:00
self . _listctrl . AddDatas ( list ( initial_dict . items ( ) ) )
2018-10-17 21:00:09 +00:00
self . _listctrl . Sort ( )
#
vbox = wx . BoxSizer ( wx . VERTICAL )
vbox . Add ( listctrl_panel , CC . FLAGS_EXPAND_BOTH_WAYS )
self . SetSizer ( vbox )
def _ConvertDataToListCtrlTuples ( self , data ) :
( key , value ) = data
display_tuple = ( key , value )
sort_tuple = ( key , value )
return ( display_tuple , sort_tuple )
def _Add ( self ) :
with ClientGUIDialogs . DialogTextEntry ( self , ' enter the ' + self . _key_name , allow_blank = False ) as dlg :
if dlg . ShowModal ( ) == wx . ID_OK :
key = dlg . GetValue ( )
if key in self . _GetExistingKeys ( ) :
wx . MessageBox ( ' That ' + self . _key_name + ' already exists! ' )
return
with ClientGUIDialogs . DialogTextEntry ( self , ' enter the ' + self . _value_name , allow_blank = True ) as dlg :
if dlg . ShowModal ( ) == wx . ID_OK :
value = dlg . GetValue ( )
data = ( key , value )
self . _listctrl . AddDatas ( ( data , ) )
def _Edit ( self ) :
for data in self . _listctrl . GetData ( only_selected = True ) :
( key , value ) = data
with ClientGUIDialogs . DialogTextEntry ( self , ' edit the ' + self . _key_name , default = key , allow_blank = False ) as dlg :
if dlg . ShowModal ( ) == wx . ID_OK :
edited_key = dlg . GetValue ( )
if edited_key != key and edited_key in self . _GetExistingKeys ( ) :
wx . MessageBox ( ' That ' + self . _key_name + ' already exists! ' )
break
else :
break
with ClientGUIDialogs . DialogTextEntry ( self , ' edit the ' + self . _value_name , default = value , allow_blank = True ) as dlg :
if dlg . ShowModal ( ) == wx . ID_OK :
edited_value = dlg . GetValue ( )
else :
break
self . _listctrl . DeleteDatas ( ( data , ) )
edited_data = ( edited_key , edited_value )
self . _listctrl . AddDatas ( ( edited_data , ) )
self . _listctrl . Sort ( )
def _GetExistingKeys ( self ) :
return { key for ( key , value ) in self . _listctrl . GetData ( ) }
def GetValue ( self ) :
value_dict = dict ( self . _listctrl . GetData ( ) )
return value_dict
class StringToStringMatchDictControl ( wx . Panel ) :
def __init__ ( self , parent , initial_dict , min_height = 10 , key_name = ' key ' ) :
wx . Panel . __init__ ( self , parent )
self . _key_name = key_name
listctrl_panel = ClientGUIListCtrl . BetterListCtrlPanel ( self )
columns = [ ( self . _key_name , 20 ) , ( ' matching ' , - 1 ) ]
self . _listctrl = ClientGUIListCtrl . BetterListCtrl ( listctrl_panel , ' key_to_string_match ' , min_height , 36 , columns , self . _ConvertDataToListCtrlTuples , use_simple_delete = True , activation_callback = self . _Edit )
listctrl_panel . SetListCtrl ( self . _listctrl )
listctrl_panel . AddButton ( ' add ' , self . _Add )
listctrl_panel . AddButton ( ' edit ' , self . _Edit , enabled_only_on_selection = True )
listctrl_panel . AddDeleteButton ( )
#
2019-01-09 22:59:03 +00:00
self . _listctrl . AddDatas ( list ( initial_dict . items ( ) ) )
2018-10-17 21:00:09 +00:00
self . _listctrl . Sort ( )
#
vbox = wx . BoxSizer ( wx . VERTICAL )
vbox . Add ( listctrl_panel , CC . FLAGS_EXPAND_BOTH_WAYS )
self . SetSizer ( vbox )
def _ConvertDataToListCtrlTuples ( self , data ) :
( key , string_match ) = data
2019-01-09 22:59:03 +00:00
pretty_string_match = string_match . ToString ( )
2018-10-17 21:00:09 +00:00
display_tuple = ( key , pretty_string_match )
sort_tuple = ( key , pretty_string_match )
return ( display_tuple , sort_tuple )
def _Add ( self ) :
with ClientGUIDialogs . DialogTextEntry ( self , ' enter the ' + self . _key_name , allow_blank = False ) as dlg :
if dlg . ShowModal ( ) == wx . ID_OK :
key = dlg . GetValue ( )
if key in self . _GetExistingKeys ( ) :
wx . MessageBox ( ' That ' + self . _key_name + ' already exists! ' )
return
with ClientGUITopLevelWindows . DialogEdit ( self , ' edit match ' ) as dlg :
string_match = ClientParsing . StringMatch ( )
panel = EditStringMatchPanel ( dlg , string_match )
dlg . SetPanel ( panel )
if dlg . ShowModal ( ) == wx . ID_OK :
string_match = panel . GetValue ( )
data = ( key , string_match )
self . _listctrl . AddDatas ( ( data , ) )
def _Edit ( self ) :
for data in self . _listctrl . GetData ( only_selected = True ) :
( key , string_match ) = data
with ClientGUIDialogs . DialogTextEntry ( self , ' edit the ' + self . _key_name , default = key , allow_blank = False ) as dlg :
if dlg . ShowModal ( ) == wx . ID_OK :
edited_key = dlg . GetValue ( )
if edited_key != key and edited_key in self . _GetExistingKeys ( ) :
wx . MessageBox ( ' That ' + self . _key_name + ' already exists! ' )
break
else :
break
with ClientGUITopLevelWindows . DialogEdit ( self , ' edit match ' ) as dlg :
string_match = ClientParsing . StringMatch ( )
panel = EditStringMatchPanel ( dlg , string_match )
dlg . SetPanel ( panel )
if dlg . ShowModal ( ) == wx . ID_OK :
edited_string_match = panel . GetValue ( )
else :
break
self . _listctrl . DeleteDatas ( ( data , ) )
edited_data = ( edited_key , edited_string_match )
self . _listctrl . AddDatas ( ( edited_data , ) )
self . _listctrl . Sort ( )
def _GetExistingKeys ( self ) :
return { key for ( key , value ) in self . _listctrl . GetData ( ) }
def GetValue ( self ) :
value_dict = dict ( self . _listctrl . GetData ( ) )
return value_dict
2018-02-07 23:40:33 +00:00
2018-05-16 20:09:50 +00:00
class TextAndPasteCtrl ( wx . Panel ) :
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
wx . Panel . __init__ ( self , parent )
self . _text_input = wx . TextCtrl ( self , style = wx . TE_PROCESS_ENTER )
self . _text_input . Bind ( wx . EVT_KEY_DOWN , self . EventKeyDown )
self . _paste_button = ClientGUICommon . BetterBitmapButton ( self , CC . GlobalBMPs . paste , self . _Paste )
self . _paste_button . SetToolTip ( ' Paste multiple inputs from the clipboard. Assumes the texts are newline-separated. ' )
#
hbox = wx . BoxSizer ( wx . HORIZONTAL )
hbox . Add ( self . _text_input , CC . FLAGS_EXPAND_BOTH_WAYS )
hbox . Add ( self . _paste_button , CC . FLAGS_VCENTER )
self . SetSizer ( hbox )
def _Paste ( self ) :
raw_text = HG . client_controller . GetClipboardText ( )
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 :
wx . MessageBox ( ' I could not understand what was in the clipboard ' )
def EventKeyDown ( self , event ) :
( modifier , key ) = ClientGUIShortcuts . ConvertKeyEventToSimpleTuple ( event )
if key in ( wx . WXK_RETURN , wx . WXK_NUMPAD_ENTER ) :
text = self . _text_input . GetValue ( )
2019-02-27 23:03:30 +00:00
text = HydrusText . StripIOInputLine ( text )
2018-12-05 22:35:30 +00:00
if text == ' ' and not self . _allow_empty_input :
2018-05-16 20:09:50 +00:00
2018-08-08 20:29:54 +00:00
return
2018-05-16 20:09:50 +00:00
2018-08-08 20:29:54 +00:00
self . _add_callable ( ( text , ) )
2018-05-16 20:09:50 +00:00
self . _text_input . SetValue ( ' ' )
else :
event . Skip ( )
def GetValue ( self ) :
return self . _text_input . GetValue ( )
def SetValue ( self , text ) :
self . _text_input . SetValue ( text )