2019-01-09 22:59:03 +00:00
from . import HydrusConstants as HC
from . import ClientConstants as CC
from . import ClientData
from . import ClientDefaults
from . import ClientDownloading
from . import ClientDragDrop
from . import ClientExporting
from . import ClientCaches
from . import ClientFiles
from . import ClientGUIACDropdown
from . import ClientGUIFrames
from . import ClientGUICommon
from . import ClientGUIDialogsQuick
2019-06-26 21:27:18 +00:00
from . import ClientGUIFunctions
2019-01-09 22:59:03 +00:00
from . import ClientGUIImport
from . import ClientGUIListBoxes
from . import ClientGUIListCtrl
from . import ClientGUIPredicates
from . import ClientGUIShortcuts
from . import ClientGUITime
from . import ClientGUITopLevelWindows
from . import ClientImporting
2019-02-27 23:03:30 +00:00
from . import ClientTags
2019-01-09 22:59:03 +00:00
from . import ClientThreading
2013-02-19 00:11:43 +00:00
import collections
2014-01-01 20:01:00 +00:00
import gc
2019-01-09 22:59:03 +00:00
from . import HydrusExceptions
from . import HydrusFileHandling
from . import HydrusNATPunch
from . import HydrusNetwork
from . import HydrusPaths
from . import HydrusSerialisable
from . import HydrusTags
from . import HydrusThreading
2013-06-12 22:53:31 +00:00
import itertools
2013-02-19 00:11:43 +00:00
import os
import random
import re
2019-01-09 22:59:03 +00:00
import queue
2013-08-14 20:21:49 +00:00
import shutil
2013-11-20 21:12:21 +00:00
import stat
2013-07-17 20:56:13 +00:00
import string
2013-09-11 21:28:19 +00:00
import threading
2013-02-19 00:11:43 +00:00
import time
import traceback
import wx
2016-03-23 19:42:56 +00:00
import wx . lib . agw . customtreectrl
2013-02-19 00:11:43 +00:00
import yaml
2019-01-09 22:59:03 +00:00
from . import HydrusData
from . import ClientSearch
from . import HydrusGlobals as HG
2013-02-19 00:11:43 +00:00
# Option Enums
ID_NULL = wx . NewId ( )
ID_TIMER_UPDATE = wx . NewId ( )
2017-03-02 02:14:56 +00:00
def SelectServiceKey ( service_types = HC . ALL_SERVICES , service_keys = None , unallowed = None ) :
2013-02-19 00:11:43 +00:00
2014-08-27 22:15:22 +00:00
if service_keys is None :
2013-02-19 00:11:43 +00:00
2017-06-28 20:23:21 +00:00
services = HG . client_controller . services_manager . GetServices ( service_types )
2013-02-19 00:11:43 +00:00
2014-09-17 21:28:26 +00:00
service_keys = [ service . GetServiceKey ( ) for service in services ]
2013-02-19 00:11:43 +00:00
2017-03-02 02:14:56 +00:00
if unallowed is not None :
service_keys . difference_update ( unallowed )
2013-02-19 00:11:43 +00:00
2017-03-02 02:14:56 +00:00
if len ( service_keys ) == 0 :
return None
2014-08-27 22:15:22 +00:00
elif len ( service_keys ) == 1 :
2013-02-19 00:11:43 +00:00
2014-08-27 22:15:22 +00:00
( service_key , ) = service_keys
2013-02-19 00:11:43 +00:00
2014-08-27 22:15:22 +00:00
return service_key
2013-02-19 00:11:43 +00:00
else :
2017-06-28 20:23:21 +00:00
services = { HG . client_controller . services_manager . GetService ( service_key ) for service_key in service_keys }
2013-02-19 00:11:43 +00:00
2018-08-08 20:29:54 +00:00
choice_tuples = [ ( service . GetName ( ) , service . GetServiceKey ( ) ) for service in services ]
2014-08-27 22:15:22 +00:00
2018-11-14 23:10:55 +00:00
try :
2013-02-19 00:11:43 +00:00
2018-11-14 23:10:55 +00:00
service_key = ClientGUIDialogsQuick . SelectFromList ( HG . client_controller . GetGUI ( ) , ' select service ' , choice_tuples )
return service_key
except HydrusExceptions . CancelledException :
return None
2013-02-19 00:11:43 +00:00
class Dialog ( wx . Dialog ) :
def __init__ ( self , parent , title , style = wx . DEFAULT_DIALOG_STYLE | wx . RESIZE_BORDER , position = ' topleft ' ) :
2013-07-31 21:26:38 +00:00
if parent is not None and position == ' topleft ' :
2013-02-19 00:11:43 +00:00
2016-01-13 22:08:19 +00:00
if isinstance ( parent , wx . TopLevelWindow ) :
parent_tlp = parent
else :
parent_tlp = parent . GetTopLevelParent ( )
2015-02-25 19:34:30 +00:00
2018-01-03 22:37:30 +00:00
( pos_x , pos_y ) = parent_tlp . GetPosition ( )
2013-02-19 00:11:43 +00:00
2016-06-22 20:59:24 +00:00
pos = ( pos_x + 50 , pos_y + 50 )
2013-02-19 00:11:43 +00:00
2016-01-13 22:08:19 +00:00
else :
pos = wx . DefaultPosition
2015-08-26 21:18:39 +00:00
if not HC . PLATFORM_LINUX and parent is not None :
style | = wx . FRAME_FLOAT_ON_PARENT
2013-02-19 00:11:43 +00:00
wx . Dialog . __init__ ( self , parent , title = title , style = style , pos = pos )
2017-12-06 22:06:56 +00:00
self . _new_options = HG . client_controller . new_options
2016-06-29 19:55:46 +00:00
2016-08-10 19:04:08 +00:00
self . SetBackgroundColour ( wx . SystemSettings . GetColour ( wx . SYS_COLOUR_FRAMEBK ) )
2013-02-19 00:11:43 +00:00
2017-11-15 22:35:49 +00:00
self . SetIcon ( HG . client_controller . frame_icon )
2013-02-19 00:11:43 +00:00
2019-02-27 23:03:30 +00:00
self . Bind ( wx . EVT_CHAR_HOOK , self . EventCharHook )
2013-07-24 20:26:00 +00:00
2015-08-26 21:18:39 +00:00
if parent is not None and position == ' center ' :
wx . CallAfter ( self . Center )
2014-02-05 20:54:28 +00:00
2017-05-10 21:33:58 +00:00
HG . client_controller . ResetIdleTimer ( )
2014-12-03 22:56:40 +00:00
2013-07-24 20:26:00 +00:00
2019-02-27 23:03:30 +00:00
def EventCharHook ( self , event ) :
( modifier , key ) = ClientGUIShortcuts . ConvertKeyEventToSimpleTuple ( event )
if key == wx . WXK_ESCAPE :
self . EndModal ( wx . ID_CANCEL )
else :
event . Skip ( )
2019-01-09 22:59:03 +00:00
def SetInitialSize ( self , size ) :
( width , height ) = size
2015-01-07 23:09:00 +00:00
2016-12-21 22:30:54 +00:00
( display_width , display_height ) = ClientGUITopLevelWindows . GetDisplaySize ( self )
2015-11-11 21:20:41 +00:00
width = min ( display_width , width )
height = min ( display_height , height )
2015-01-07 23:09:00 +00:00
wx . Dialog . SetInitialSize ( self , ( width , height ) )
min_width = min ( 240 , width )
2015-11-18 22:44:07 +00:00
min_height = min ( 240 , height )
2015-01-07 23:09:00 +00:00
self . SetMinSize ( ( min_width , min_height ) )
2013-03-15 02:38:12 +00:00
class DialogChooseNewServiceMethod ( Dialog ) :
def __init__ ( self , parent ) :
2015-05-20 21:31:40 +00:00
Dialog . __init__ ( self , parent , ' how to set up the account? ' , position = ' center ' )
2013-07-31 21:26:38 +00:00
2015-05-20 21:31:40 +00:00
register_message = ' I want to initialise a new account with the server. I have a registration key (a key starting with \' r \' ). '
2013-03-15 02:38:12 +00:00
2015-05-20 21:31:40 +00:00
self . _register = wx . Button ( self , label = register_message )
self . _register . Bind ( wx . EVT_BUTTON , self . EventRegister )
2013-03-15 02:38:12 +00:00
2015-05-20 21:31:40 +00:00
setup_message = ' The account is already initialised; I just want to add it to this client. I have a normal access key. '
2013-03-15 02:38:12 +00:00
2015-05-20 21:31:40 +00:00
self . _setup = wx . Button ( self , id = wx . ID_OK , label = setup_message )
2013-07-31 21:26:38 +00:00
2015-05-20 21:31:40 +00:00
vbox = wx . BoxSizer ( wx . VERTICAL )
2018-01-03 22:37:30 +00:00
vbox . Add ( self . _register , CC . FLAGS_EXPAND_PERPENDICULAR )
vbox . Add ( wx . StaticText ( self , label = ' -or- ' , style = wx . ALIGN_CENTER ) , CC . FLAGS_EXPAND_PERPENDICULAR )
vbox . Add ( self . _setup , CC . FLAGS_EXPAND_PERPENDICULAR )
2015-05-20 21:31:40 +00:00
self . SetSizer ( vbox )
( x , y ) = self . GetEffectiveMinSize ( )
self . SetInitialSize ( ( x , y ) )
2013-03-15 02:38:12 +00:00
2013-07-24 20:26:00 +00:00
self . _should_register = False
2013-03-15 02:38:12 +00:00
2013-07-31 21:26:38 +00:00
wx . CallAfter ( self . _register . SetFocus )
2013-03-15 02:38:12 +00:00
def EventRegister ( self , event ) :
2013-07-24 20:26:00 +00:00
self . _should_register = True
2013-03-15 02:38:12 +00:00
self . EndModal ( wx . ID_OK )
2019-05-22 22:35:06 +00:00
def GetRegister ( self ) :
return self . _should_register
2013-03-15 02:38:12 +00:00
2013-11-27 18:27:11 +00:00
class DialogGenerateNewAccounts ( Dialog ) :
2014-08-27 22:15:22 +00:00
def __init__ ( self , parent , service_key ) :
2013-11-27 18:27:11 +00:00
2015-12-09 23:16:41 +00:00
Dialog . __init__ ( self , parent , ' configure new accounts ' )
2013-11-27 18:27:11 +00:00
2015-12-09 23:16:41 +00:00
self . _service_key = service_key
2013-11-27 18:27:11 +00:00
2015-12-09 23:16:41 +00:00
self . _num = wx . SpinCtrl ( self , min = 1 , max = 10000 , size = ( 80 , - 1 ) )
2013-11-27 18:27:11 +00:00
2017-03-02 02:14:56 +00:00
self . _account_types = ClientGUICommon . BetterChoice ( self )
2013-11-27 18:27:11 +00:00
2017-03-02 02:14:56 +00:00
self . _lifetime = ClientGUICommon . BetterChoice ( self )
2015-12-09 23:16:41 +00:00
2019-05-22 22:35:06 +00:00
self . _ok = wx . Button ( self , id = wx . ID_OK , label = ' OK ' )
2015-12-09 23:16:41 +00:00
self . _ok . Bind ( wx . EVT_BUTTON , self . EventOK )
self . _ok . SetForegroundColour ( ( 0 , 128 , 0 ) )
self . _cancel = wx . Button ( self , id = wx . ID_CANCEL , label = ' Cancel ' )
self . _cancel . SetForegroundColour ( ( 128 , 0 , 0 ) )
#
self . _num . SetValue ( 1 )
2017-06-28 20:23:21 +00:00
service = HG . client_controller . services_manager . GetService ( service_key )
2015-12-09 23:16:41 +00:00
response = service . Request ( HC . GET , ' account_types ' )
account_types = response [ ' account_types ' ]
2017-03-02 02:14:56 +00:00
for account_type in account_types :
self . _account_types . Append ( account_type . GetTitle ( ) , account_type )
self . _account_types . Select ( 0 )
2017-03-15 20:13:04 +00:00
for ( s , value ) in HC . lifetimes :
2017-03-02 02:14:56 +00:00
2017-03-15 20:13:04 +00:00
self . _lifetime . Append ( s , value )
2017-03-02 02:14:56 +00:00
2015-12-09 23:16:41 +00:00
self . _lifetime . SetSelection ( 3 ) # one year
2013-11-27 18:27:11 +00:00
2015-12-09 23:16:41 +00:00
#
ctrl_box = wx . BoxSizer ( wx . HORIZONTAL )
2018-01-03 22:37:30 +00:00
ctrl_box . Add ( ClientGUICommon . BetterStaticText ( self , ' generate ' ) , CC . FLAGS_VCENTER )
ctrl_box . Add ( self . _num , CC . FLAGS_VCENTER )
ctrl_box . Add ( self . _account_types , CC . FLAGS_VCENTER )
ctrl_box . Add ( ClientGUICommon . BetterStaticText ( self , ' accounts, to expire in ' ) , CC . FLAGS_VCENTER )
ctrl_box . Add ( self . _lifetime , CC . FLAGS_VCENTER )
2013-11-27 18:27:11 +00:00
2015-12-09 23:16:41 +00:00
b_box = wx . BoxSizer ( wx . HORIZONTAL )
2018-01-03 22:37:30 +00:00
b_box . Add ( self . _ok , CC . FLAGS_VCENTER )
b_box . Add ( self . _cancel , CC . FLAGS_VCENTER )
2013-11-27 18:27:11 +00:00
2015-12-09 23:16:41 +00:00
vbox = wx . BoxSizer ( wx . VERTICAL )
2018-01-03 22:37:30 +00:00
vbox . Add ( ctrl_box , CC . FLAGS_EXPAND_SIZER_PERPENDICULAR )
vbox . Add ( b_box , CC . FLAGS_BUTTON_SIZER )
2015-12-09 23:16:41 +00:00
self . SetSizer ( vbox )
( x , y ) = self . GetEffectiveMinSize ( )
self . SetInitialSize ( ( x , y ) )
2013-11-27 18:27:11 +00:00
wx . CallAfter ( self . _ok . SetFocus )
def EventOK ( self , event ) :
num = self . _num . GetValue ( )
2019-07-24 21:39:02 +00:00
account_type = self . _account_types . GetValue ( )
2017-03-02 02:14:56 +00:00
account_type_key = account_type . GetAccountTypeKey ( )
2013-11-27 18:27:11 +00:00
2019-07-24 21:39:02 +00:00
lifetime = self . _lifetime . GetValue ( )
2013-11-27 18:27:11 +00:00
2017-03-02 02:14:56 +00:00
if lifetime is None :
expires = None
else :
expires = HydrusData . GetNow ( ) + lifetime
2013-11-27 18:27:11 +00:00
2017-06-28 20:23:21 +00:00
service = HG . client_controller . services_manager . GetService ( self . _service_key )
2013-11-27 18:27:11 +00:00
try :
2017-03-15 20:13:04 +00:00
request_args = { ' num ' : num , ' account_type_key ' : account_type_key }
if expires is not None :
request_args [ ' expires ' ] = expires
2013-11-27 18:27:11 +00:00
2014-01-29 21:59:42 +00:00
response = service . Request ( HC . GET , ' registration_keys ' , request_args )
2013-11-27 18:27:11 +00:00
registration_keys = response [ ' registration_keys ' ]
2016-11-02 21:09:14 +00:00
ClientGUIFrames . ShowKeys ( ' registration ' , registration_keys )
2013-11-27 18:27:11 +00:00
2017-03-02 02:14:56 +00:00
finally :
self . EndModal ( wx . ID_OK )
2013-11-27 18:27:11 +00:00
2014-07-09 22:15:14 +00:00
class DialogInputLocalBooruShare ( Dialog ) :
def __init__ ( self , parent , share_key , name , text , timeout , hashes , new_share = False ) :
2015-12-09 23:16:41 +00:00
Dialog . __init__ ( self , parent , ' configure local booru share ' )
2014-07-09 22:15:14 +00:00
2015-12-09 23:16:41 +00:00
self . _name = wx . TextCtrl ( self )
2014-07-09 22:15:14 +00:00
2016-11-02 21:09:14 +00:00
self . _text = ClientGUICommon . SaneMultilineTextCtrl ( self )
2015-12-09 23:16:41 +00:00
self . _text . SetMinSize ( ( - 1 , 100 ) )
message = ' expires in '
self . _timeout_number = ClientGUICommon . NoneableSpinCtrl ( self , message , none_phrase = ' no expiration ' , max = 1000000 , multiplier = 1 )
self . _timeout_multiplier = ClientGUICommon . BetterChoice ( self )
self . _timeout_multiplier . Append ( ' minutes ' , 60 )
self . _timeout_multiplier . Append ( ' hours ' , 60 * 60 )
self . _timeout_multiplier . Append ( ' days ' , 60 * 60 * 24 )
self . _copy_internal_share_link = wx . Button ( self , label = ' copy internal share link ' )
self . _copy_internal_share_link . Bind ( wx . EVT_BUTTON , self . EventCopyInternalShareURL )
self . _copy_external_share_link = wx . Button ( self , label = ' copy external share link ' )
self . _copy_external_share_link . Bind ( wx . EVT_BUTTON , self . EventCopyExternalShareURL )
self . _ok = wx . Button ( self , id = wx . ID_OK , label = ' ok ' )
self . _ok . SetForegroundColour ( ( 0 , 128 , 0 ) )
self . _cancel = wx . Button ( self , id = wx . ID_CANCEL , label = ' cancel ' )
self . _cancel . SetForegroundColour ( ( 128 , 0 , 0 ) )
#
self . _share_key = share_key
self . _name . SetValue ( name )
self . _text . SetValue ( text )
if timeout is None :
2014-07-09 22:15:14 +00:00
2015-12-09 23:16:41 +00:00
self . _timeout_number . SetValue ( None )
2014-07-09 22:15:14 +00:00
2019-07-24 21:39:02 +00:00
self . _timeout_multiplier . SetValue ( 60 )
2014-07-09 22:15:14 +00:00
2015-12-09 23:16:41 +00:00
else :
2014-07-09 22:15:14 +00:00
2018-02-14 21:47:18 +00:00
time_left = HydrusData . GetTimeDeltaUntilTime ( timeout )
2014-07-09 22:15:14 +00:00
2015-12-09 23:16:41 +00:00
if time_left < 60 * 60 * 12 : time_value = 60
elif time_left < 60 * 60 * 24 * 7 : time_value = 60 * 60
else : time_value = 60 * 60 * 24
2014-07-09 22:15:14 +00:00
2019-01-09 22:59:03 +00:00
self . _timeout_number . SetValue ( time_left / / time_value )
2014-07-09 22:15:14 +00:00
2019-07-24 21:39:02 +00:00
self . _timeout_multiplier . SetValue ( time_value )
2014-07-09 22:15:14 +00:00
2015-12-09 23:16:41 +00:00
self . _hashes = hashes
2017-12-06 22:06:56 +00:00
self . _service = HG . client_controller . services_manager . GetService ( CC . LOCAL_BOORU_SERVICE_KEY )
internal_port = self . _service . GetPort ( )
if internal_port is None :
self . _copy_internal_share_link . Disable ( )
self . _copy_external_share_link . Disable ( )
2015-12-09 23:16:41 +00:00
#
2016-08-31 19:55:14 +00:00
rows = [ ]
2015-12-09 23:16:41 +00:00
2016-08-31 19:55:14 +00:00
rows . append ( ( ' share name: ' , self . _name ) )
rows . append ( ( ' share text: ' , self . _text ) )
2015-12-09 23:16:41 +00:00
2016-08-31 19:55:14 +00:00
gridbox = ClientGUICommon . WrapInGrid ( self , rows )
2015-12-09 23:16:41 +00:00
timeout_box = wx . BoxSizer ( wx . HORIZONTAL )
2018-01-03 22:37:30 +00:00
timeout_box . Add ( self . _timeout_number , CC . FLAGS_EXPAND_BOTH_WAYS )
timeout_box . Add ( self . _timeout_multiplier , CC . FLAGS_EXPAND_BOTH_WAYS )
2015-12-09 23:16:41 +00:00
link_box = wx . BoxSizer ( wx . HORIZONTAL )
2018-01-03 22:37:30 +00:00
link_box . Add ( self . _copy_internal_share_link , CC . FLAGS_VCENTER )
link_box . Add ( self . _copy_external_share_link , CC . FLAGS_VCENTER )
2015-12-09 23:16:41 +00:00
b_box = wx . BoxSizer ( wx . HORIZONTAL )
2018-01-03 22:37:30 +00:00
b_box . Add ( self . _ok , CC . FLAGS_VCENTER )
b_box . Add ( self . _cancel , CC . FLAGS_VCENTER )
2015-12-09 23:16:41 +00:00
vbox = wx . BoxSizer ( wx . VERTICAL )
2018-07-04 20:48:28 +00:00
intro = ' Sharing ' + HydrusData . ToHumanInt ( len ( self . _hashes ) ) + ' files. '
2015-12-09 23:16:41 +00:00
intro + = os . linesep + ' Title and text are optional. '
if new_share : intro + = os . linesep + ' The link will not work until you ok this dialog. '
2018-01-03 22:37:30 +00:00
vbox . Add ( ClientGUICommon . BetterStaticText ( self , intro ) , CC . FLAGS_EXPAND_PERPENDICULAR )
vbox . Add ( gridbox , CC . FLAGS_EXPAND_SIZER_PERPENDICULAR )
vbox . Add ( timeout_box , CC . FLAGS_EXPAND_SIZER_PERPENDICULAR )
vbox . Add ( link_box , CC . FLAGS_BUTTON_SIZER )
vbox . Add ( b_box , CC . FLAGS_BUTTON_SIZER )
2015-12-09 23:16:41 +00:00
self . SetSizer ( vbox )
2014-07-09 22:15:14 +00:00
2015-12-09 23:16:41 +00:00
( x , y ) = self . GetEffectiveMinSize ( )
2014-07-09 22:15:14 +00:00
2015-12-09 23:16:41 +00:00
x = max ( x , 350 )
2014-07-09 22:15:14 +00:00
2015-12-09 23:16:41 +00:00
self . SetInitialSize ( ( x , y ) )
2014-07-09 22:15:14 +00:00
wx . CallAfter ( self . _ok . SetFocus )
def EventCopyExternalShareURL ( self , event ) :
2019-05-22 22:35:06 +00:00
internal_port = self . _service . GetPort ( )
2014-07-09 22:15:14 +00:00
2019-05-22 22:35:06 +00:00
if internal_port is None :
2017-03-02 02:14:56 +00:00
2019-05-22 22:35:06 +00:00
wx . MessageBox ( ' The local booru is not currently running! ' )
2017-03-02 02:14:56 +00:00
2014-07-09 22:15:14 +00:00
2019-05-22 22:35:06 +00:00
try :
url = self . _service . GetExternalShareURL ( self . _share_key )
except Exception as e :
HydrusData . ShowException ( e )
wx . MessageBox ( ' Unfortunately, could not generate an external URL: {} ' . format ( e ) )
return
2014-07-09 22:15:14 +00:00
2017-05-10 21:33:58 +00:00
HG . client_controller . pub ( ' clipboard ' , ' text ' , url )
2014-07-09 22:15:14 +00:00
def EventCopyInternalShareURL ( self , event ) :
2017-06-28 20:23:21 +00:00
self . _service = HG . client_controller . services_manager . GetService ( CC . LOCAL_BOORU_SERVICE_KEY )
2014-07-09 22:15:14 +00:00
internal_ip = ' 127.0.0.1 '
2017-03-02 02:14:56 +00:00
internal_port = self . _service . GetPort ( )
2014-07-09 22:15:14 +00:00
2019-01-09 22:59:03 +00:00
url = ' http:// ' + internal_ip + ' : ' + str ( internal_port ) + ' /gallery?share_key= ' + self . _share_key . hex ( )
2014-07-09 22:15:14 +00:00
2017-05-10 21:33:58 +00:00
HG . client_controller . pub ( ' clipboard ' , ' text ' , url )
2014-07-09 22:15:14 +00:00
def GetInfo ( self ) :
name = self . _name . GetValue ( )
text = self . _text . GetValue ( )
timeout = self . _timeout_number . GetValue ( )
2019-07-24 21:39:02 +00:00
if timeout is not None : timeout = timeout * self . _timeout_multiplier . GetValue ( ) + HydrusData . GetNow ( )
2014-07-09 22:15:14 +00:00
return ( self . _share_key , name , text , timeout , self . _hashes )
2013-07-31 21:26:38 +00:00
class DialogInputNamespaceRegex ( Dialog ) :
def __init__ ( self , parent , namespace = ' ' , regex = ' ' ) :
2015-10-14 21:02:25 +00:00
Dialog . __init__ ( self , parent , ' configure quick namespace ' )
2013-07-31 21:26:38 +00:00
2015-10-14 21:02:25 +00:00
self . _namespace = wx . TextCtrl ( self )
2013-07-31 21:26:38 +00:00
2015-10-14 21:02:25 +00:00
self . _regex = wx . TextCtrl ( self )
self . _shortcuts = ClientGUICommon . RegexButton ( self )
2018-08-29 20:20:41 +00:00
self . _regex_intro_link = ClientGUICommon . BetterHyperLink ( self , ' a good regex introduction ' , ' http://www.aivosto.com/vbtips/regex.html ' )
self . _regex_practise_link = ClientGUICommon . BetterHyperLink ( self , ' regex practise ' , ' http://regexr.com/3cvmf ' )
2015-10-14 21:02:25 +00:00
2017-06-07 22:05:15 +00:00
self . _ok = wx . Button ( self , id = wx . ID_OK , label = ' OK ' )
2015-10-14 21:02:25 +00:00
self . _ok . Bind ( wx . EVT_BUTTON , self . EventOK )
self . _ok . SetForegroundColour ( ( 0 , 128 , 0 ) )
self . _cancel = wx . Button ( self , id = wx . ID_CANCEL , label = ' Cancel ' )
self . _cancel . SetForegroundColour ( ( 128 , 0 , 0 ) )
#
self . _namespace . SetValue ( namespace )
self . _regex . SetValue ( regex )
#
control_box = wx . BoxSizer ( wx . HORIZONTAL )
2018-01-03 22:37:30 +00:00
control_box . Add ( self . _namespace , CC . FLAGS_EXPAND_BOTH_WAYS )
control_box . Add ( ClientGUICommon . BetterStaticText ( self , ' : ' ) , CC . FLAGS_VCENTER )
control_box . Add ( self . _regex , CC . FLAGS_EXPAND_BOTH_WAYS )
2015-10-14 21:02:25 +00:00
b_box = wx . BoxSizer ( wx . HORIZONTAL )
2018-01-03 22:37:30 +00:00
b_box . Add ( self . _ok , CC . FLAGS_VCENTER )
b_box . Add ( self . _cancel , CC . FLAGS_VCENTER )
2015-10-14 21:02:25 +00:00
vbox = wx . BoxSizer ( wx . VERTICAL )
2017-03-15 20:13:04 +00:00
intro = r ' Put the namespace (e.g. page) on the left. ' + os . linesep + r ' Put the regex (e.g. [1-9]+ \ d*(?=. {4} $)) on the right. ' + os . linesep + r ' All files will be tagged with " namespace:regex " . '
2015-10-14 21:02:25 +00:00
2018-01-03 22:37:30 +00:00
vbox . Add ( ClientGUICommon . BetterStaticText ( self , intro ) , CC . FLAGS_EXPAND_PERPENDICULAR )
vbox . Add ( control_box , CC . FLAGS_EXPAND_SIZER_PERPENDICULAR )
vbox . Add ( self . _shortcuts , CC . FLAGS_LONE_BUTTON )
vbox . Add ( self . _regex_intro_link , CC . FLAGS_LONE_BUTTON )
vbox . Add ( self . _regex_practise_link , CC . FLAGS_LONE_BUTTON )
vbox . Add ( b_box , CC . FLAGS_BUTTON_SIZER )
2015-10-14 21:02:25 +00:00
self . SetSizer ( vbox )
( x , y ) = self . GetEffectiveMinSize ( )
self . SetInitialSize ( ( x , y ) )
wx . CallAfter ( self . _ok . SetFocus )
def EventOK ( self , event ) :
( namespace , regex ) = self . GetInfo ( )
if namespace == ' ' :
2013-07-31 21:26:38 +00:00
2015-10-14 21:02:25 +00:00
wx . MessageBox ( ' Please enter something for the namespace. ' )
2013-07-31 21:26:38 +00:00
2015-10-14 21:02:25 +00:00
return
2013-07-31 21:26:38 +00:00
2015-10-14 21:02:25 +00:00
try :
2013-07-31 21:26:38 +00:00
2019-01-09 22:59:03 +00:00
re . compile ( regex )
2014-03-12 22:08:23 +00:00
2015-10-14 21:02:25 +00:00
except Exception as e :
2013-07-31 21:26:38 +00:00
2015-10-14 21:02:25 +00:00
text = ' That regex would not compile! '
text + = os . linesep * 2
2019-01-09 22:59:03 +00:00
text + = str ( e )
2013-07-31 21:26:38 +00:00
2015-10-14 21:02:25 +00:00
wx . MessageBox ( text )
2013-07-31 21:26:38 +00:00
2015-10-14 21:02:25 +00:00
return
2013-07-31 21:26:38 +00:00
2015-10-14 21:02:25 +00:00
self . EndModal ( wx . ID_OK )
2013-07-31 21:26:38 +00:00
def GetInfo ( self ) :
namespace = self . _namespace . GetValue ( )
regex = self . _regex . GetValue ( )
return ( namespace , regex )
2015-10-21 21:53:10 +00:00
class DialogInputTags ( Dialog ) :
2018-04-11 22:30:40 +00:00
def __init__ ( self , parent , service_key , tags , message = ' ' ) :
2015-10-21 21:53:10 +00:00
Dialog . __init__ ( self , parent , ' input tags ' )
2016-05-25 21:54:03 +00:00
self . _service_key = service_key
2017-02-01 21:11:17 +00:00
self . _tags = ClientGUIListBoxes . ListBoxTagsStringsAddRemove ( self , service_key = service_key )
2015-10-21 21:53:10 +00:00
2015-10-28 21:29:05 +00:00
expand_parents = True
2019-06-26 21:27:18 +00:00
self . _tag_box = ClientGUIACDropdown . AutoCompleteDropdownTagsWrite ( self , self . EnterTags , expand_parents , CC . LOCAL_FILE_SERVICE_KEY , service_key , null_entry_callable = self . OK , show_paste_button = True )
2015-10-21 21:53:10 +00:00
2019-05-22 22:35:06 +00:00
self . _ok = ClientGUICommon . BetterButton ( self , ' OK ' , self . EndModal , wx . ID_OK )
2015-10-21 21:53:10 +00:00
self . _ok . SetForegroundColour ( ( 0 , 128 , 0 ) )
self . _cancel = wx . Button ( self , id = wx . ID_CANCEL , label = ' Cancel ' )
self . _cancel . SetForegroundColour ( ( 128 , 0 , 0 ) )
#
self . _tags . SetTags ( tags )
#
b_box = wx . BoxSizer ( wx . HORIZONTAL )
2018-01-03 22:37:30 +00:00
b_box . Add ( self . _ok , CC . FLAGS_VCENTER )
b_box . Add ( self . _cancel , CC . FLAGS_VCENTER )
2015-10-21 21:53:10 +00:00
vbox = wx . BoxSizer ( wx . VERTICAL )
2018-04-11 22:30:40 +00:00
if message != ' ' :
vbox . Add ( ClientGUICommon . BetterStaticText ( self , message ) , CC . FLAGS_EXPAND_PERPENDICULAR )
2018-01-03 22:37:30 +00:00
vbox . Add ( self . _tags , CC . FLAGS_EXPAND_BOTH_WAYS )
vbox . Add ( self . _tag_box , CC . FLAGS_EXPAND_PERPENDICULAR )
vbox . Add ( b_box , CC . FLAGS_BUTTON_SIZER )
2015-10-21 21:53:10 +00:00
self . SetSizer ( vbox )
( x , y ) = self . GetEffectiveMinSize ( )
x = max ( x , 300 )
self . SetInitialSize ( ( x , y ) )
wx . CallAfter ( self . _tag_box . SetFocus )
2016-05-25 21:54:03 +00:00
def EnterTags ( self , tags ) :
2019-04-17 21:51:50 +00:00
tag_parents_manager = HG . client_controller . tag_parents_manager
2016-05-25 21:54:03 +00:00
parents = set ( )
2015-10-21 21:53:10 +00:00
2016-05-25 21:54:03 +00:00
for tag in tags :
2015-10-21 21:53:10 +00:00
2016-05-25 21:54:03 +00:00
some_parents = tag_parents_manager . GetParents ( self . _service_key , tag )
parents . update ( some_parents )
2015-10-21 21:53:10 +00:00
2015-10-28 21:29:05 +00:00
if len ( tags ) > 0 :
2015-10-21 21:53:10 +00:00
2015-10-28 21:29:05 +00:00
self . _tags . EnterTags ( tags )
self . _tags . AddTags ( parents )
2015-10-21 21:53:10 +00:00
def GetTags ( self ) :
return self . _tags . GetTags ( )
2017-06-07 22:05:15 +00:00
def OK ( self ) :
2015-10-28 21:29:05 +00:00
self . EndModal ( wx . ID_OK )
2013-09-25 20:20:10 +00:00
class DialogInputUPnPMapping ( Dialog ) :
2014-04-23 20:56:12 +00:00
def __init__ ( self , parent , external_port , protocol_type , internal_port , description , duration ) :
2013-09-25 20:20:10 +00:00
2016-06-01 20:04:15 +00:00
Dialog . __init__ ( self , parent , ' configure upnp mapping ' )
2013-09-25 20:20:10 +00:00
2016-06-01 20:04:15 +00:00
self . _external_port = wx . SpinCtrl ( self , min = 0 , max = 65535 )
2013-09-25 20:20:10 +00:00
2016-06-01 20:04:15 +00:00
self . _protocol_type = ClientGUICommon . BetterChoice ( self )
self . _protocol_type . Append ( ' TCP ' , ' TCP ' )
self . _protocol_type . Append ( ' UDP ' , ' UDP ' )
2013-09-25 20:20:10 +00:00
2016-06-01 20:04:15 +00:00
self . _internal_port = wx . SpinCtrl ( self , min = 0 , max = 65535 )
self . _description = wx . TextCtrl ( self )
self . _duration = wx . SpinCtrl ( self , min = 0 , max = 86400 )
2013-09-25 20:20:10 +00:00
2019-05-22 22:35:06 +00:00
self . _ok = ClientGUICommon . BetterButton ( self , ' OK ' , self . EndModal , wx . ID_OK )
2016-06-01 20:04:15 +00:00
self . _ok . SetForegroundColour ( ( 0 , 128 , 0 ) )
2013-09-25 20:20:10 +00:00
2016-06-01 20:04:15 +00:00
self . _cancel = wx . Button ( self , id = wx . ID_CANCEL , label = ' Cancel ' )
self . _cancel . SetForegroundColour ( ( 128 , 0 , 0 ) )
#
self . _external_port . SetValue ( external_port )
if protocol_type == ' TCP ' : self . _protocol_type . Select ( 0 )
elif protocol_type == ' UDP ' : self . _protocol_type . Select ( 1 )
self . _internal_port . SetValue ( internal_port )
self . _description . SetValue ( description )
self . _duration . SetValue ( duration )
#
2016-08-31 19:55:14 +00:00
rows = [ ]
2016-06-01 20:04:15 +00:00
2016-08-31 19:55:14 +00:00
rows . append ( ( ' external port: ' , self . _external_port ) )
rows . append ( ( ' protocol type: ' , self . _protocol_type ) )
rows . append ( ( ' internal port: ' , self . _internal_port ) )
rows . append ( ( ' description: ' , self . _description ) )
rows . append ( ( ' duration (0 = indefinite): ' , self . _duration ) )
2016-06-01 20:04:15 +00:00
2016-08-31 19:55:14 +00:00
gridbox = ClientGUICommon . WrapInGrid ( self , rows )
2016-06-01 20:04:15 +00:00
b_box = wx . BoxSizer ( wx . HORIZONTAL )
2018-01-03 22:37:30 +00:00
b_box . Add ( self . _ok , CC . FLAGS_VCENTER )
b_box . Add ( self . _cancel , CC . FLAGS_VCENTER )
2016-06-01 20:04:15 +00:00
vbox = wx . BoxSizer ( wx . VERTICAL )
2018-01-03 22:37:30 +00:00
vbox . Add ( gridbox , CC . FLAGS_EXPAND_SIZER_BOTH_WAYS )
vbox . Add ( b_box , CC . FLAGS_BUTTON_SIZER )
2016-06-01 20:04:15 +00:00
self . SetSizer ( vbox )
( x , y ) = self . GetEffectiveMinSize ( )
self . SetInitialSize ( ( x , y ) )
2013-09-25 20:20:10 +00:00
wx . CallAfter ( self . _ok . SetFocus )
def GetInfo ( self ) :
external_port = self . _external_port . GetValue ( )
2019-07-24 21:39:02 +00:00
protocol_type = self . _protocol_type . GetValue ( )
2013-09-25 20:20:10 +00:00
internal_port = self . _internal_port . GetValue ( )
description = self . _description . GetValue ( )
2014-04-23 20:56:12 +00:00
duration = self . _duration . GetValue ( )
2013-09-25 20:20:10 +00:00
2014-04-23 20:56:12 +00:00
return ( external_port , protocol_type , internal_port , description , duration )
2013-09-25 20:20:10 +00:00
2013-02-19 00:11:43 +00:00
class DialogModifyAccounts ( Dialog ) :
2014-08-27 22:15:22 +00:00
def __init__ ( self , parent , service_key , subject_identifiers ) :
2013-02-19 00:11:43 +00:00
2016-06-01 20:04:15 +00:00
Dialog . __init__ ( self , parent , ' modify account ' )
2013-02-19 00:11:43 +00:00
2017-06-28 20:23:21 +00:00
self . _service = HG . client_controller . services_manager . GetService ( service_key )
2016-06-01 20:04:15 +00:00
self . _subject_identifiers = list ( subject_identifiers )
#
self . _account_info_panel = ClientGUICommon . StaticBox ( self , ' account info ' )
self . _subject_text = wx . StaticText ( self . _account_info_panel )
#
self . _account_types_panel = ClientGUICommon . StaticBox ( self , ' account types ' )
self . _account_types = wx . Choice ( self . _account_types_panel )
2017-06-07 22:05:15 +00:00
self . _account_types_ok = wx . Button ( self . _account_types_panel , label = ' OK ' )
2016-06-01 20:04:15 +00:00
self . _account_types_ok . Bind ( wx . EVT_BUTTON , self . EventChangeAccountType )
#
self . _expiration_panel = ClientGUICommon . StaticBox ( self , ' change expiration ' )
self . _add_to_expires = wx . Choice ( self . _expiration_panel )
2017-06-07 22:05:15 +00:00
self . _add_to_expires_ok = wx . Button ( self . _expiration_panel , label = ' OK ' )
2016-06-01 20:04:15 +00:00
self . _add_to_expires_ok . Bind ( wx . EVT_BUTTON , self . EventAddToExpires )
self . _set_expires = wx . Choice ( self . _expiration_panel )
2017-06-07 22:05:15 +00:00
self . _set_expires_ok = wx . Button ( self . _expiration_panel , label = ' OK ' )
2016-06-01 20:04:15 +00:00
self . _set_expires_ok . Bind ( wx . EVT_BUTTON , self . EventSetExpires )
#
self . _ban_panel = ClientGUICommon . StaticBox ( self , ' bans ' )
self . _ban = wx . Button ( self . _ban_panel , label = ' ban user ' )
self . _ban . Bind ( wx . EVT_BUTTON , self . EventBan )
self . _ban . SetBackgroundColour ( ( 255 , 0 , 0 ) )
self . _ban . SetForegroundColour ( ( 255 , 255 , 0 ) )
self . _superban = wx . Button ( self . _ban_panel , label = ' ban user and delete every contribution they have ever made ' )
self . _superban . Bind ( wx . EVT_BUTTON , self . EventSuperban )
self . _superban . SetBackgroundColour ( ( 255 , 0 , 0 ) )
self . _superban . SetForegroundColour ( ( 255 , 255 , 0 ) )
self . _exit = wx . Button ( self , id = wx . ID_CANCEL , label = ' Exit ' )
#
if len ( self . _subject_identifiers ) == 1 :
2013-02-19 00:11:43 +00:00
2016-06-01 20:04:15 +00:00
( subject_identifier , ) = self . _subject_identifiers
2013-02-19 00:11:43 +00:00
2016-06-01 20:04:15 +00:00
response = self . _service . Request ( HC . GET , ' account_info ' , { ' subject_identifier ' : subject_identifier } )
2013-02-19 00:11:43 +00:00
2019-01-09 22:59:03 +00:00
subject_string = str ( response [ ' account_info ' ] )
else :
subject_string = ' modifying ' + HydrusData . ToHumanInt ( len ( self . _subject_identifiers ) ) + ' accounts '
2013-02-19 00:11:43 +00:00
2016-06-01 20:04:15 +00:00
self . _subject_text . SetLabelText ( subject_string )
#
response = self . _service . Request ( HC . GET , ' account_types ' )
account_types = response [ ' account_types ' ]
for account_type in account_types : self . _account_types . Append ( account_type . ConvertToString ( ) , account_type )
self . _account_types . SetSelection ( 0 )
#
for ( string , value ) in HC . lifetimes :
2013-02-19 00:11:43 +00:00
2017-03-02 02:14:56 +00:00
if value is not None :
self . _add_to_expires . Append ( string , value ) # don't want 'add no limit'
2013-02-19 00:11:43 +00:00
2016-06-01 20:04:15 +00:00
self . _add_to_expires . SetSelection ( 1 ) # three months
for ( string , value ) in HC . lifetimes : self . _set_expires . Append ( string , value )
self . _set_expires . SetSelection ( 1 ) # three months
#
2013-02-19 00:11:43 +00:00
2018-01-03 22:37:30 +00:00
self . _account_info_panel . Add ( self . _subject_text , CC . FLAGS_EXPAND_PERPENDICULAR )
2013-02-19 00:11:43 +00:00
2016-06-01 20:04:15 +00:00
account_types_hbox = wx . BoxSizer ( wx . HORIZONTAL )
2013-02-19 00:11:43 +00:00
2018-01-03 22:37:30 +00:00
account_types_hbox . Add ( self . _account_types , CC . FLAGS_VCENTER )
account_types_hbox . Add ( self . _account_types_ok , CC . FLAGS_VCENTER )
2013-07-31 21:26:38 +00:00
2018-01-03 22:37:30 +00:00
self . _account_types_panel . Add ( account_types_hbox , CC . FLAGS_EXPAND_PERPENDICULAR )
2016-06-01 20:04:15 +00:00
add_to_expires_box = wx . BoxSizer ( wx . HORIZONTAL )
2018-01-03 22:37:30 +00:00
add_to_expires_box . Add ( wx . StaticText ( self . _expiration_panel , label = ' add to expires: ' ) , CC . FLAGS_VCENTER )
add_to_expires_box . Add ( self . _add_to_expires , CC . FLAGS_EXPAND_BOTH_WAYS )
add_to_expires_box . Add ( self . _add_to_expires_ok , CC . FLAGS_VCENTER )
2016-06-01 20:04:15 +00:00
set_expires_box = wx . BoxSizer ( wx . HORIZONTAL )
2018-01-03 22:37:30 +00:00
set_expires_box . Add ( wx . StaticText ( self . _expiration_panel , label = ' set expires to: ' ) , CC . FLAGS_VCENTER )
set_expires_box . Add ( self . _set_expires , CC . FLAGS_EXPAND_BOTH_WAYS )
set_expires_box . Add ( self . _set_expires_ok , CC . FLAGS_VCENTER )
2016-06-01 20:04:15 +00:00
2018-01-03 22:37:30 +00:00
self . _expiration_panel . Add ( add_to_expires_box , CC . FLAGS_EXPAND_PERPENDICULAR )
self . _expiration_panel . Add ( set_expires_box , CC . FLAGS_EXPAND_PERPENDICULAR )
2016-06-01 20:04:15 +00:00
2018-01-03 22:37:30 +00:00
self . _ban_panel . Add ( self . _ban , CC . FLAGS_EXPAND_PERPENDICULAR )
self . _ban_panel . Add ( self . _superban , CC . FLAGS_EXPAND_PERPENDICULAR )
2016-06-01 20:04:15 +00:00
vbox = wx . BoxSizer ( wx . VERTICAL )
2018-01-03 22:37:30 +00:00
vbox . Add ( self . _account_info_panel , CC . FLAGS_EXPAND_PERPENDICULAR )
vbox . Add ( self . _account_types_panel , CC . FLAGS_EXPAND_PERPENDICULAR )
vbox . Add ( self . _expiration_panel , CC . FLAGS_EXPAND_PERPENDICULAR )
vbox . Add ( self . _ban_panel , CC . FLAGS_EXPAND_PERPENDICULAR )
vbox . Add ( self . _exit , CC . FLAGS_BUTTON_SIZER )
2016-06-01 20:04:15 +00:00
self . SetSizer ( vbox )
( x , y ) = self . GetEffectiveMinSize ( )
self . SetInitialSize ( ( x , y ) )
2013-07-31 21:26:38 +00:00
wx . CallAfter ( self . _exit . SetFocus )
2013-02-19 00:11:43 +00:00
2017-03-02 02:14:56 +00:00
def _DoModification ( self ) :
2015-10-14 21:02:25 +00:00
2017-03-02 02:14:56 +00:00
# change this to saveaccounts or whatever. the previous func changes the accounts, and then we push that change
2018-07-18 21:07:15 +00:00
# generate accounts, with the modification having occurred
2013-08-14 20:21:49 +00:00
2017-03-02 02:14:56 +00:00
self . _service . Request ( HC . POST , ' account ' , { ' accounts ' : self . _accounts } )
2013-08-14 20:21:49 +00:00
if len ( self . _subject_identifiers ) == 1 :
2013-02-19 00:11:43 +00:00
2013-08-14 20:21:49 +00:00
( subject_identifier , ) = self . _subject_identifiers
2013-02-19 00:11:43 +00:00
2014-01-29 21:59:42 +00:00
response = self . _service . Request ( HC . GET , ' account_info ' , { ' subject_identifier ' : subject_identifier } )
2013-10-02 22:06:06 +00:00
account_info = response [ ' account_info ' ]
2019-01-09 22:59:03 +00:00
self . _subject_text . SetLabelText ( str ( account_info ) )
2013-02-19 00:11:43 +00:00
if len ( self . _subject_identifiers ) > 1 : wx . MessageBox ( ' Done! ' )
2017-03-02 02:14:56 +00:00
def EventAddToExpires ( self , event ) :
2018-05-09 20:23:00 +00:00
raise NotImplementedError ( )
#self._DoModification( HC.ADD_TO_EXPIRES, timespan = self._add_to_expires.GetClientData( self._add_to_expires.GetSelection() ) )
2017-03-02 02:14:56 +00:00
2013-02-19 00:11:43 +00:00
def EventBan ( self , event ) :
2014-09-24 21:50:07 +00:00
with DialogTextEntry ( self , ' Enter reason for the ban. ' ) as dlg :
2013-02-19 00:11:43 +00:00
2018-05-09 20:23:00 +00:00
if dlg . ShowModal ( ) == wx . ID_OK :
raise NotImplementedError ( )
#self._DoModification( HC.BAN, reason = dlg.GetValue() )
2013-02-19 00:11:43 +00:00
2017-03-02 02:14:56 +00:00
def EventChangeAccountType ( self , event ) :
2018-05-09 20:23:00 +00:00
raise NotImplementedError ( )
2019-07-24 21:39:02 +00:00
#self._DoModification( HC.CHANGE_ACCOUNT_TYPE, account_type_key = self._account_types.GetValue() )
2017-03-02 02:14:56 +00:00
2013-02-19 00:11:43 +00:00
2014-10-01 22:58:32 +00:00
def EventSetExpires ( self , event ) :
2013-07-24 20:26:00 +00:00
2014-10-01 22:58:32 +00:00
expires = self . _set_expires . GetClientData ( self . _set_expires . GetSelection ( ) )
2013-07-24 20:26:00 +00:00
2018-05-09 20:23:00 +00:00
if expires is not None :
expires + = HydrusData . GetNow ( )
2013-07-24 20:26:00 +00:00
2018-05-09 20:23:00 +00:00
raise NotImplementedError ( )
#self._DoModification( HC.SET_EXPIRES, expires = expires )
2013-07-24 20:26:00 +00:00
2013-02-19 00:11:43 +00:00
def EventSuperban ( self , event ) :
2014-09-24 21:50:07 +00:00
with DialogTextEntry ( self , ' Enter reason for the superban. ' ) as dlg :
2013-02-19 00:11:43 +00:00
2018-05-09 20:23:00 +00:00
if dlg . ShowModal ( ) == wx . ID_OK :
raise NotImplementedError ( )
#self._DoModification( HC.SUPERBAN, reason = dlg.GetValue() )
2013-02-19 00:11:43 +00:00
2016-03-23 19:42:56 +00:00
class DialogSelectFromURLTree ( Dialog ) :
2013-02-19 00:11:43 +00:00
2016-03-23 19:42:56 +00:00
def __init__ ( self , parent , url_tree ) :
2013-02-19 00:11:43 +00:00
2016-03-23 19:42:56 +00:00
Dialog . __init__ ( self , parent , ' select items ' )
agwStyle = wx . lib . agw . customtreectrl . TR_DEFAULT_STYLE | wx . lib . agw . customtreectrl . TR_AUTO_CHECK_CHILD
self . _tree = wx . lib . agw . customtreectrl . CustomTreeCtrl ( self , agwStyle = agwStyle )
2019-05-22 22:35:06 +00:00
self . _ok = ClientGUICommon . BetterButton ( self , ' OK ' , self . EndModal , wx . ID_OK )
2016-03-23 19:42:56 +00:00
self . _ok . SetForegroundColour ( ( 0 , 128 , 0 ) )
2019-05-22 22:35:06 +00:00
self . _cancel = wx . Button ( self , id = wx . ID_CANCEL , label = ' Cancel ' )
2016-03-23 19:42:56 +00:00
self . _cancel . SetForegroundColour ( ( 128 , 0 , 0 ) )
#
( text_gumpf , name , size , children ) = url_tree
root_name = self . _RenderItemName ( name , size )
root_item = self . _tree . AddRoot ( root_name , ct_type = 1 )
self . _AddDirectory ( root_item , children )
self . _tree . CheckItem ( root_item )
self . _tree . Expand ( root_item )
#
button_hbox = wx . BoxSizer ( wx . HORIZONTAL )
2018-01-03 22:37:30 +00:00
button_hbox . Add ( self . _ok , CC . FLAGS_VCENTER )
button_hbox . Add ( self . _cancel , CC . FLAGS_VCENTER )
2016-03-23 19:42:56 +00:00
vbox = wx . BoxSizer ( wx . VERTICAL )
2018-01-03 22:37:30 +00:00
vbox . Add ( self . _tree , CC . FLAGS_EXPAND_BOTH_WAYS )
vbox . Add ( button_hbox , CC . FLAGS_BUTTON_SIZER )
2016-03-23 19:42:56 +00:00
self . SetSizer ( vbox )
( x , y ) = self . GetEffectiveMinSize ( )
2016-05-25 21:54:03 +00:00
x = max ( x , 640 )
2016-03-23 19:42:56 +00:00
y = max ( y , 640 )
self . SetInitialSize ( ( x , y ) )
def _AddDirectory ( self , root , children ) :
for ( child_type , name , size , data ) in children :
2013-02-19 00:11:43 +00:00
2016-03-23 19:42:56 +00:00
item_name = self . _RenderItemName ( name , size )
2014-02-19 22:37:23 +00:00
2016-03-23 19:42:56 +00:00
if child_type == ' file ' :
self . _tree . AppendItem ( root , item_name , ct_type = 1 , data = data )
else :
subroot = self . _tree . AppendItem ( root , item_name , ct_type = 1 )
self . _AddDirectory ( subroot , data )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
2016-03-23 19:42:56 +00:00
def _GetSelectedChildrenData ( self , parent_item ) :
result = [ ]
cookie = 0
( child_item , cookie ) = self . _tree . GetNextChild ( parent_item , cookie )
while child_item is not None :
2013-02-19 00:11:43 +00:00
2016-03-23 19:42:56 +00:00
data = self . _tree . GetItemPyData ( child_item )
2013-02-19 00:11:43 +00:00
2016-03-23 19:42:56 +00:00
if data is None :
2013-02-19 00:11:43 +00:00
2016-03-23 19:42:56 +00:00
result . extend ( self . _GetSelectedChildrenData ( child_item ) )
2013-02-19 00:11:43 +00:00
2016-03-23 19:42:56 +00:00
else :
if self . _tree . IsItemChecked ( child_item ) :
2013-02-19 00:11:43 +00:00
2016-03-23 19:42:56 +00:00
result . append ( data )
2013-02-19 00:11:43 +00:00
2016-03-23 19:42:56 +00:00
( child_item , cookie ) = self . _tree . GetNextChild ( parent_item , cookie )
2013-02-19 00:11:43 +00:00
2016-03-23 19:42:56 +00:00
return result
def _RenderItemName ( self , name , size ) :
2019-01-09 22:59:03 +00:00
return name + ' - ' + HydrusData . ToHumanBytes ( size )
2016-03-23 19:42:56 +00:00
def GetURLs ( self ) :
root_item = self . _tree . GetRootItem ( )
urls = self . _GetSelectedChildrenData ( root_item )
return urls
class DialogSelectImageboard ( Dialog ) :
def __init__ ( self , parent ) :
Dialog . __init__ ( self , parent , ' select imageboard ' )
self . _tree = wx . TreeCtrl ( self )
self . _tree . Bind ( wx . EVT_TREE_ITEM_ACTIVATED , self . EventActivate )
#
2017-05-10 21:33:58 +00:00
all_imageboards = HG . client_controller . Read ( ' imageboards ' )
2016-03-23 19:42:56 +00:00
root_item = self . _tree . AddRoot ( ' all sites ' )
2019-01-09 22:59:03 +00:00
for ( site , imageboards ) in list ( all_imageboards . items ( ) ) :
2013-02-19 00:11:43 +00:00
2016-03-23 19:42:56 +00:00
site_item = self . _tree . AppendItem ( root_item , site )
2013-02-19 00:11:43 +00:00
2016-03-23 19:42:56 +00:00
for imageboard in imageboards :
name = imageboard . GetName ( )
self . _tree . AppendItem ( site_item , name , data = wx . TreeItemData ( imageboard ) )
2013-02-19 00:11:43 +00:00
2016-03-23 19:42:56 +00:00
self . _tree . Expand ( root_item )
2013-02-19 00:11:43 +00:00
2016-03-23 19:42:56 +00:00
#
2013-02-19 00:11:43 +00:00
2016-03-23 19:42:56 +00:00
vbox = wx . BoxSizer ( wx . VERTICAL )
2013-07-31 21:26:38 +00:00
2018-01-03 22:37:30 +00:00
vbox . Add ( self . _tree , CC . FLAGS_EXPAND_BOTH_WAYS )
2016-03-23 19:42:56 +00:00
self . SetSizer ( vbox )
( x , y ) = self . GetEffectiveMinSize ( )
if x < 320 : x = 320
if y < 640 : y = 640
self . SetInitialSize ( ( x , y ) )
2013-02-19 00:11:43 +00:00
2014-02-19 22:37:23 +00:00
def EventActivate ( self , event ) :
2013-02-19 00:11:43 +00:00
item = self . _tree . GetSelection ( )
2013-03-15 02:38:12 +00:00
data_object = self . _tree . GetItemData ( item )
if data_object is None : self . _tree . Toggle ( item )
2013-02-19 00:11:43 +00:00
else : self . EndModal ( wx . ID_OK )
def GetImageboard ( self ) : return self . _tree . GetItemData ( self . _tree . GetSelection ( ) ) . GetData ( )
2014-08-06 20:29:17 +00:00
class DialogTextEntry ( Dialog ) :
2017-08-02 21:32:54 +00:00
def __init__ ( self , parent , message , default = ' ' , allow_blank = False , suggestions = None , max_chars = None ) :
2016-12-07 22:12:52 +00:00
if suggestions is None :
suggestions = [ ]
2014-08-06 20:29:17 +00:00
Dialog . __init__ ( self , parent , ' enter text ' , position = ' center ' )
2016-12-07 22:12:52 +00:00
self . _chosen_suggestion = None
2014-08-06 20:29:17 +00:00
self . _allow_blank = allow_blank
2017-08-02 21:32:54 +00:00
self . _max_chars = max_chars
2014-08-06 20:29:17 +00:00
2016-12-07 22:12:52 +00:00
button_choices = [ ]
for text in suggestions :
button_choices . append ( ClientGUICommon . BetterButton ( self , text , self . ButtonChoice , text ) )
2016-03-30 22:56:50 +00:00
self . _text = wx . TextCtrl ( self , style = wx . TE_PROCESS_ENTER )
self . _text . Bind ( wx . EVT_TEXT , self . EventText )
self . _text . Bind ( wx . EVT_TEXT_ENTER , self . EventEnter )
2014-08-06 20:29:17 +00:00
2017-08-02 21:32:54 +00:00
if self . _max_chars is not None :
self . _text . SetMaxLength ( self . _max_chars )
2019-05-22 22:35:06 +00:00
self . _ok = ClientGUICommon . BetterButton ( self , ' ok ' , self . EndModal , wx . ID_OK )
2016-03-30 22:56:50 +00:00
self . _ok . SetForegroundColour ( ( 0 , 128 , 0 ) )
2014-08-06 20:29:17 +00:00
2016-03-30 22:56:50 +00:00
self . _cancel = wx . Button ( self , id = wx . ID_CANCEL , label = ' cancel ' )
self . _cancel . SetForegroundColour ( ( 128 , 0 , 0 ) )
#
self . _text . SetValue ( default )
self . _CheckText ( )
#
hbox = wx . BoxSizer ( wx . HORIZONTAL )
2018-01-03 22:37:30 +00:00
hbox . Add ( self . _ok , CC . FLAGS_SMALL_INDENT )
hbox . Add ( self . _cancel , CC . FLAGS_SMALL_INDENT )
2016-03-30 22:56:50 +00:00
2017-04-19 20:58:30 +00:00
st_message = ClientGUICommon . BetterStaticText ( self , message )
2018-07-04 20:48:28 +00:00
st_message . SetWrapWidth ( 480 )
2016-03-30 22:56:50 +00:00
vbox = wx . BoxSizer ( wx . VERTICAL )
2018-01-03 22:37:30 +00:00
vbox . Add ( st_message , CC . FLAGS_BIG_INDENT )
2016-12-07 22:12:52 +00:00
for button in button_choices :
2018-01-03 22:37:30 +00:00
vbox . Add ( button , CC . FLAGS_EXPAND_PERPENDICULAR )
2016-12-07 22:12:52 +00:00
2018-01-03 22:37:30 +00:00
vbox . Add ( self . _text , CC . FLAGS_EXPAND_BOTH_WAYS )
vbox . Add ( hbox , CC . FLAGS_BUTTON_SIZER )
2016-03-30 22:56:50 +00:00
self . SetSizer ( vbox )
( x , y ) = self . GetEffectiveMinSize ( )
x = max ( x , 250 )
self . SetInitialSize ( ( x , y ) )
2014-08-06 20:29:17 +00:00
def _CheckText ( self ) :
if not self . _allow_blank :
2017-08-02 21:32:54 +00:00
if self . _text . GetValue ( ) == ' ' :
self . _ok . Disable ( )
else :
self . _ok . Enable ( )
2014-08-06 20:29:17 +00:00
2016-12-07 22:12:52 +00:00
def ButtonChoice ( self , text ) :
self . _chosen_suggestion = text
self . EndModal ( wx . ID_OK )
2015-07-29 19:11:35 +00:00
def EventText ( self , event ) :
2014-08-06 20:29:17 +00:00
wx . CallAfter ( self . _CheckText )
event . Skip ( )
def EventEnter ( self , event ) :
2016-12-07 22:12:52 +00:00
if self . _text . GetValue ( ) != ' ' :
self . EndModal ( wx . ID_OK )
2014-08-06 20:29:17 +00:00
2016-12-07 22:12:52 +00:00
def GetValue ( self ) :
if self . _chosen_suggestion is None :
return self . _text . GetValue ( )
else :
return self . _chosen_suggestion
2014-08-06 20:29:17 +00:00
2017-06-07 22:05:15 +00:00
class DialogYesYesNo ( Dialog ) :
def __init__ ( self , parent , message , title = ' Are you sure? ' , yes_tuples = None , no_label = ' no ' ) :
if yes_tuples is None :
yes_tuples = [ ( ' yes ' , ' yes ' ) ]
Dialog . __init__ ( self , parent , title , position = ' center ' )
self . _value = None
yes_buttons = [ ]
for ( label , data ) in yes_tuples :
yes_button = ClientGUICommon . BetterButton ( self , label , self . _DoYes , data )
yes_button . SetForegroundColour ( ( 0 , 128 , 0 ) )
yes_buttons . append ( yes_button )
2019-05-22 22:35:06 +00:00
self . _no = ClientGUICommon . BetterButton ( self , no_label , self . EndModal , wx . ID_NO )
2017-06-07 22:05:15 +00:00
self . _no . SetForegroundColour ( ( 128 , 0 , 0 ) )
#
hbox = wx . BoxSizer ( wx . HORIZONTAL )
for yes_button in yes_buttons :
2018-01-03 22:37:30 +00:00
hbox . Add ( yes_button , CC . FLAGS_SMALL_INDENT )
2017-06-07 22:05:15 +00:00
2018-01-03 22:37:30 +00:00
hbox . Add ( self . _no , CC . FLAGS_SMALL_INDENT )
2017-06-07 22:05:15 +00:00
vbox = wx . BoxSizer ( wx . VERTICAL )
text = ClientGUICommon . BetterStaticText ( self , message )
2018-07-04 20:48:28 +00:00
text . SetWrapWidth ( 480 )
2017-06-07 22:05:15 +00:00
2018-01-03 22:37:30 +00:00
vbox . Add ( text , CC . FLAGS_BIG_INDENT )
vbox . Add ( hbox , CC . FLAGS_BUTTON_SIZER )
2017-06-07 22:05:15 +00:00
self . SetSizer ( vbox )
( x , y ) = self . GetEffectiveMinSize ( )
x = max ( x , 250 )
self . SetInitialSize ( ( x , y ) )
wx . CallAfter ( yes_buttons [ 0 ] . SetFocus )
def _DoYes ( self , value ) :
self . _value = value
self . EndModal ( wx . ID_YES )
def GetValue ( self ) :
return self . _value