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
from . import ClientGUIImport
from . import ClientGUIListBoxes
from . import ClientGUIListCtrl
from . import ClientGUIPredicates
from . import ClientGUIShortcuts
from . import ClientGUITime
from . import ClientGUITopLevelWindows
from . import ClientImporting
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 HydrusTagArchive
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
2013-07-24 20:26:00 +00:00
self . Bind ( wx . EVT_BUTTON , self . EventDialogButton )
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
2018-02-07 23:40:33 +00:00
def EventDialogButton ( self , event ) :
if self . IsModal ( ) :
self . EndModal ( event . GetId ( ) )
2013-07-24 20:26:00 +00:00
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
self . _hidden_cancel = wx . Button ( self , id = wx . ID_CANCEL , size = ( 0 , 0 ) )
2013-03-15 02:38:12 +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 )
2013-07-24 20:26:00 +00:00
def GetRegister ( self ) : return self . _should_register
2013-03-15 02:38:12 +00:00
2017-04-19 20:58:30 +00:00
class DialogCommitInterstitialFiltering ( Dialog ) :
def __init__ ( self , parent , label ) :
Dialog . __init__ ( self , parent , ' commit and continue? ' , position = ' center ' )
self . _commit = wx . Button ( self , id = wx . ID_YES , label = ' commit and continue ' )
self . _commit . SetForegroundColour ( ( 0 , 128 , 0 ) )
self . _back = wx . Button ( self , id = wx . ID_CANCEL , label = ' go back ' )
vbox = wx . BoxSizer ( wx . VERTICAL )
2018-01-03 22:37:30 +00:00
vbox . Add ( wx . StaticText ( self , label = label , style = wx . ALIGN_CENTER ) , CC . FLAGS_EXPAND_PERPENDICULAR )
vbox . Add ( self . _commit , CC . FLAGS_EXPAND_SIZER_PERPENDICULAR )
vbox . Add ( wx . StaticText ( self , label = ' -or- ' , style = wx . ALIGN_CENTER ) , CC . FLAGS_EXPAND_PERPENDICULAR )
vbox . Add ( self . _back , CC . FLAGS_EXPAND_PERPENDICULAR )
2017-04-19 20:58:30 +00:00
self . SetSizer ( vbox )
( x , y ) = self . GetEffectiveMinSize ( )
self . SetInitialSize ( ( x , y ) )
wx . CallAfter ( self . _commit . SetFocus )
2013-02-19 00:11:43 +00:00
class DialogFinishFiltering ( Dialog ) :
2017-04-19 20:58:30 +00:00
def __init__ ( self , parent , label ) :
2013-02-19 00:11:43 +00:00
2015-05-20 21:31:40 +00:00
Dialog . __init__ ( self , parent , ' are you sure? ' , position = ' center ' )
2013-02-19 00:11:43 +00:00
2018-04-05 01:22:26 +00:00
self . _commit = ClientGUICommon . BetterButton ( self , ' commit ' , self . EndModal , wx . ID_YES )
2015-05-20 21:31:40 +00:00
self . _commit . SetForegroundColour ( ( 0 , 128 , 0 ) )
2013-07-31 21:26:38 +00:00
2018-04-05 01:22:26 +00:00
self . _forget = ClientGUICommon . BetterButton ( self , ' forget ' , self . EndModal , wx . ID_NO )
2015-05-20 21:31:40 +00:00
self . _forget . SetForegroundColour ( ( 128 , 0 , 0 ) )
2013-02-19 00:11:43 +00:00
2018-04-05 01:22:26 +00:00
self . _back = ClientGUICommon . BetterButton ( self , ' back to filtering ' , self . EndModal , wx . ID_CANCEL )
self . _back . SetId ( wx . ID_CANCEL )
2013-02-19 00:11:43 +00:00
2015-05-20 21:31:40 +00:00
hbox = wx . BoxSizer ( wx . HORIZONTAL )
2013-02-19 00:11:43 +00:00
2018-01-03 22:37:30 +00:00
hbox . Add ( self . _commit , CC . FLAGS_EXPAND_BOTH_WAYS )
hbox . Add ( self . _forget , CC . FLAGS_EXPAND_BOTH_WAYS )
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 ( wx . StaticText ( self , label = label , style = wx . ALIGN_CENTER ) , CC . FLAGS_EXPAND_PERPENDICULAR )
vbox . Add ( hbox , CC . FLAGS_EXPAND_SIZER_PERPENDICULAR )
vbox . Add ( wx . StaticText ( self , label = ' -or- ' , style = wx . ALIGN_CENTER ) , CC . FLAGS_EXPAND_PERPENDICULAR )
vbox . Add ( self . _back , CC . FLAGS_EXPAND_PERPENDICULAR )
2015-05-20 21:31:40 +00:00
self . SetSizer ( vbox )
( x , y ) = self . GetEffectiveMinSize ( )
self . SetInitialSize ( ( x , y ) )
2013-07-31 21:26:38 +00:00
wx . CallAfter ( self . _commit . SetFocus )
2013-02-19 00:11:43 +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
2017-06-07 22:05:15 +00:00
self . _ok = wx . Button ( self , 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 ( )
2017-03-02 02:14:56 +00:00
account_type = self . _account_types . GetChoice ( )
account_type_key = account_type . GetAccountTypeKey ( )
2013-11-27 18:27:11 +00:00
2017-03-02 02:14:56 +00:00
lifetime = self . _lifetime . GetChoice ( )
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
2015-12-09 23:16:41 +00:00
self . _timeout_multiplier . SelectClientData ( 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
2015-12-09 23:16:41 +00:00
self . _timeout_multiplier . SelectClientData ( 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 ) :
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
external_ip = HydrusNATPunch . GetExternalIP ( ) # eventually check for optional host replacement here
2017-03-02 02:14:56 +00:00
external_port = self . _service . GetUPnPPort ( )
2014-07-09 22:15:14 +00:00
2017-03-02 02:14:56 +00:00
if external_port is None :
external_port = self . _service . GetPort ( )
2014-07-09 22:15:14 +00:00
2019-01-09 22:59:03 +00:00
url = ' http:// ' + external_ip + ' : ' + str ( external_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 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 ( )
2015-03-25 22:04:19 +00:00
if timeout is not None : timeout = timeout * self . _timeout_multiplier . GetChoice ( ) + HydrusData . GetNow ( )
2014-07-09 22:15:14 +00:00
return ( self . _share_key , name , text , timeout , self . _hashes )
2017-11-08 22:07:12 +00:00
class FrameInputLocalFiles ( wx . Frame ) :
2014-01-01 20:01:00 +00:00
2015-03-25 22:04:19 +00:00
def __init__ ( self , parent , paths = None ) :
2018-01-03 22:37:30 +00:00
( pos_x , pos_y ) = parent . GetPosition ( )
2014-01-01 20:01:00 +00:00
2017-11-08 22:07:12 +00:00
pos = ( pos_x + 50 , pos_y + 50 )
style = wx . DEFAULT_FRAME_STYLE | wx . FRAME_FLOAT_ON_PARENT
wx . Frame . __init__ ( self , parent , title = ' importing files ' , style = style , pos = pos )
self . SetBackgroundColour ( wx . SystemSettings . GetColour ( wx . SYS_COLOUR_FRAMEBK ) )
2017-11-15 22:35:49 +00:00
self . SetIcon ( HG . client_controller . frame_icon )
2017-11-08 22:07:12 +00:00
if paths is None :
paths = [ ]
2014-01-01 20:01:00 +00:00
2017-11-22 21:03:07 +00:00
self . SetDropTarget ( ClientDragDrop . FileDropTarget ( self , filenames_callable = self . _AddPathsToList ) )
2014-01-01 20:01:00 +00:00
2017-08-02 21:32:54 +00:00
listctrl_panel = ClientGUIListCtrl . SaneListCtrlPanel ( self )
2017-07-27 00:47:13 +00:00
2017-08-02 21:32:54 +00:00
self . _paths_list = ClientGUIListCtrl . SaneListCtrl ( listctrl_panel , 120 , [ ( ' path ' , - 1 ) , ( ' guessed mime ' , 110 ) , ( ' size ' , 60 ) ] , delete_key_callback = self . RemovePaths )
2017-07-27 00:47:13 +00:00
listctrl_panel . SetListCtrl ( self . _paths_list )
listctrl_panel . AddButton ( ' add files ' , self . AddPaths )
listctrl_panel . AddButton ( ' add folder ' , self . AddFolder )
listctrl_panel . AddButton ( ' remove files ' , self . RemovePaths , enabled_only_on_selection = True )
2014-01-01 20:01:00 +00:00
2017-02-01 21:11:17 +00:00
self . _progress = ClientGUICommon . TextAndGauge ( self )
2014-01-01 20:01:00 +00:00
2017-02-01 21:11:17 +00:00
self . _progress_pause = ClientGUICommon . BetterBitmapButton ( self , CC . GlobalBMPs . pause , self . PauseProgress )
self . _progress_pause . Disable ( )
2015-07-22 19:40:39 +00:00
2017-02-01 21:11:17 +00:00
self . _progress_cancel = ClientGUICommon . BetterBitmapButton ( self , CC . GlobalBMPs . stop , self . StopProgress )
self . _progress_cancel . Disable ( )
2015-07-22 19:40:39 +00:00
2018-01-10 22:41:51 +00:00
file_import_options = HG . client_controller . new_options . GetDefaultFileImportOptions ( ' loud ' )
2018-10-03 21:00:15 +00:00
show_downloader_options = False
2017-09-13 20:50:41 +00:00
2018-10-03 21:00:15 +00:00
self . _file_import_options = ClientGUIImport . FileImportOptionsButton ( self , file_import_options , show_downloader_options )
2015-07-22 19:40:39 +00:00
2018-08-08 20:29:54 +00:00
menu_items = [ ]
check_manager = ClientGUICommon . CheckboxManagerOptions ( ' do_human_sort_on_hdd_file_import_paths ' )
menu_items . append ( ( ' check ' , ' sort paths as they are added ' , ' If checked, paths will be sorted in a numerically human-friendly (e.g. " page 9.jpg " comes before " page 10.jpg " ) way. ' , check_manager ) )
self . _cog_button = ClientGUICommon . MenuBitmapButton ( self , CC . GlobalBMPs . cog , menu_items )
2017-08-09 21:33:51 +00:00
self . _delete_after_success_st = ClientGUICommon . BetterStaticText ( self , style = wx . ALIGN_RIGHT | wx . ST_NO_AUTORESIZE )
self . _delete_after_success_st . SetForegroundColour ( ( 127 , 0 , 0 ) )
2016-06-29 19:55:46 +00:00
self . _delete_after_success = wx . CheckBox ( self , label = ' delete original files after successful import ' )
2017-08-09 21:33:51 +00:00
self . _delete_after_success . Bind ( wx . EVT_CHECKBOX , self . EventDeleteAfterSuccessCheck )
2015-07-22 19:40:39 +00:00
2016-08-03 22:15:54 +00:00
self . _add_button = wx . Button ( self , label = ' import now ' )
2015-07-22 19:40:39 +00:00
self . _add_button . Bind ( wx . EVT_BUTTON , self . EventOK )
self . _add_button . SetForegroundColour ( ( 0 , 128 , 0 ) )
2016-08-03 22:15:54 +00:00
self . _tag_button = wx . Button ( self , label = ' add tags based on filename ' )
2015-07-22 19:40:39 +00:00
self . _tag_button . Bind ( wx . EVT_BUTTON , self . EventTags )
self . _tag_button . SetForegroundColour ( ( 0 , 128 , 0 ) )
2016-08-03 22:15:54 +00:00
self . _cancel = wx . Button ( self , id = wx . ID_CANCEL , label = ' cancel ' )
2015-07-22 19:40:39 +00:00
self . _cancel . Bind ( wx . EVT_BUTTON , self . EventCancel )
self . _cancel . SetForegroundColour ( ( 128 , 0 , 0 ) )
gauge_sizer = wx . BoxSizer ( wx . HORIZONTAL )
2018-01-03 22:37:30 +00:00
gauge_sizer . Add ( self . _progress , CC . FLAGS_EXPAND_SIZER_BOTH_WAYS )
gauge_sizer . Add ( self . _progress_pause , CC . FLAGS_VCENTER )
gauge_sizer . Add ( self . _progress_cancel , CC . FLAGS_VCENTER )
2015-07-22 19:40:39 +00:00
2017-08-09 21:33:51 +00:00
delete_hbox = wx . BoxSizer ( wx . HORIZONTAL )
2018-01-03 22:37:30 +00:00
delete_hbox . Add ( self . _delete_after_success_st , CC . FLAGS_EXPAND_BOTH_WAYS )
delete_hbox . Add ( self . _delete_after_success , CC . FLAGS_VCENTER )
2017-08-09 21:33:51 +00:00
2018-08-08 20:29:54 +00:00
import_options_buttons = wx . BoxSizer ( wx . HORIZONTAL )
import_options_buttons . Add ( self . _file_import_options , CC . FLAGS_SIZER_VCENTER )
import_options_buttons . Add ( self . _cog_button , CC . FLAGS_SIZER_VCENTER )
2015-07-22 19:40:39 +00:00
buttons = wx . BoxSizer ( wx . HORIZONTAL )
2018-01-03 22:37:30 +00:00
buttons . Add ( self . _add_button , CC . FLAGS_VCENTER )
buttons . Add ( self . _tag_button , CC . FLAGS_VCENTER )
buttons . Add ( self . _cancel , CC . FLAGS_VCENTER )
2015-07-22 19:40:39 +00:00
vbox = wx . BoxSizer ( wx . VERTICAL )
2018-01-03 22:37:30 +00:00
vbox . Add ( listctrl_panel , CC . FLAGS_EXPAND_BOTH_WAYS )
vbox . Add ( gauge_sizer , CC . FLAGS_EXPAND_SIZER_PERPENDICULAR )
vbox . Add ( delete_hbox , CC . FLAGS_EXPAND_SIZER_PERPENDICULAR )
2018-08-08 20:29:54 +00:00
vbox . Add ( import_options_buttons , CC . FLAGS_LONE_BUTTON )
2018-01-03 22:37:30 +00:00
vbox . Add ( buttons , CC . FLAGS_BUTTON_SIZER )
2015-07-22 19:40:39 +00:00
self . SetSizer ( vbox )
( x , y ) = self . GetEffectiveMinSize ( )
if x < 780 : x = 780
if y < 480 : y = 480
self . SetInitialSize ( ( x , y ) )
2014-01-01 20:01:00 +00:00
2017-02-01 21:11:17 +00:00
self . _lock = threading . Lock ( )
2015-08-12 20:35:24 +00:00
self . _current_paths = [ ]
self . _current_paths_set = set ( )
2014-03-12 22:08:23 +00:00
2016-02-17 22:06:47 +00:00
self . _job_key = ClientThreading . JobKey ( )
2014-01-01 20:01:00 +00:00
2019-01-09 22:59:03 +00:00
self . _unparsed_paths_queue = queue . Queue ( )
2018-01-24 23:09:42 +00:00
self . _currently_parsing = threading . Event ( )
self . _work_to_do = threading . Event ( )
2019-01-09 22:59:03 +00:00
self . _parsed_path_queue = queue . Queue ( )
2018-01-24 23:09:42 +00:00
self . _pause_event = threading . Event ( )
self . _cancel_event = threading . Event ( )
2016-11-30 20:24:17 +00:00
2017-02-01 21:11:17 +00:00
self . _progress_updater = ClientGUICommon . ThreadToGUIUpdater ( self . _progress , self . _progress . SetValue )
2016-11-30 20:24:17 +00:00
2017-02-01 21:11:17 +00:00
if len ( paths ) > 0 :
self . _AddPathsToList ( paths )
2014-01-01 20:01:00 +00:00
2017-11-08 22:07:12 +00:00
self . Show ( )
2014-01-01 20:01:00 +00:00
2018-01-24 23:09:42 +00:00
HG . client_controller . gui . RegisterUIUpdateWindow ( self )
2014-01-01 20:01:00 +00:00
2018-01-24 23:09:42 +00:00
HG . client_controller . CallToThreadLongRunning ( self . THREADParseImportablePaths , self . _unparsed_paths_queue , self . _currently_parsing , self . _work_to_do , self . _parsed_path_queue , self . _progress_updater , self . _pause_event , self . _cancel_event )
2014-01-01 20:01:00 +00:00
2018-01-24 23:09:42 +00:00
def _AddPathsToList ( self , paths ) :
2014-01-01 20:01:00 +00:00
2018-01-24 23:09:42 +00:00
if self . _cancel_event . is_set ( ) :
2014-01-01 20:01:00 +00:00
2018-01-24 23:09:42 +00:00
message = ' Please wait for the cancel to clear. '
wx . MessageBox ( message )
return
2014-01-01 20:01:00 +00:00
2018-01-24 23:09:42 +00:00
self . _unparsed_paths_queue . put ( paths )
2014-01-01 20:01:00 +00:00
2016-01-20 23:57:33 +00:00
def _TidyUp ( self ) :
2018-01-24 23:09:42 +00:00
self . _pause_event . set ( )
2016-01-20 23:57:33 +00:00
2014-01-01 20:01:00 +00:00
2016-12-07 22:12:52 +00:00
def AddFolder ( self ) :
2014-01-01 20:01:00 +00:00
2016-11-30 20:24:17 +00:00
with wx . DirDialog ( self , ' Select a folder to add. ' , style = wx . DD_DIR_MUST_EXIST ) as dlg :
2014-03-12 22:08:23 +00:00
2016-11-30 20:24:17 +00:00
if dlg . ShowModal ( ) == wx . ID_OK :
2019-01-09 22:59:03 +00:00
path = dlg . GetPath ( )
2016-11-30 20:24:17 +00:00
self . _AddPathsToList ( ( path , ) )
2014-03-12 22:08:23 +00:00
2014-01-01 20:01:00 +00:00
2016-12-07 22:12:52 +00:00
def AddPaths ( self ) :
2014-01-01 20:01:00 +00:00
2014-02-19 22:37:23 +00:00
with wx . FileDialog ( self , ' Select the files to add. ' , style = wx . FD_MULTIPLE ) as dlg :
2014-01-01 20:01:00 +00:00
if dlg . ShowModal ( ) == wx . ID_OK :
2019-01-09 22:59:03 +00:00
paths = dlg . GetPaths ( )
2014-01-01 20:01:00 +00:00
self . _AddPathsToList ( paths )
def EventCancel ( self , event ) :
self . _TidyUp ( )
2017-11-08 22:07:12 +00:00
self . Close ( )
2014-01-01 20:01:00 +00:00
2017-08-09 21:33:51 +00:00
def EventDeleteAfterSuccessCheck ( self , event ) :
if self . _delete_after_success . GetValue ( ) :
self . _delete_after_success_st . SetLabelText ( ' YOUR ORIGINAL FILES WILL BE DELETED ' )
else :
self . _delete_after_success_st . SetLabelText ( ' ' )
2014-01-01 20:01:00 +00:00
def EventOK ( self , event ) :
self . _TidyUp ( )
2015-07-22 19:40:39 +00:00
if len ( self . _current_paths ) > 0 :
2014-01-01 20:01:00 +00:00
2017-09-13 20:50:41 +00:00
file_import_options = self . _file_import_options . GetValue ( )
2014-01-01 20:01:00 +00:00
2015-06-24 22:10:14 +00:00
paths_to_tags = { }
2014-01-01 20:01:00 +00:00
delete_after_success = self . _delete_after_success . GetValue ( )
2017-09-13 20:50:41 +00:00
HG . client_controller . pub ( ' new_hdd_import ' , self . _current_paths , file_import_options , paths_to_tags , delete_after_success )
2014-01-01 20:01:00 +00:00
2017-11-08 22:07:12 +00:00
self . Close ( )
2015-07-22 19:40:39 +00:00
2014-01-01 20:01:00 +00:00
def EventTags ( self , event ) :
2015-07-22 19:40:39 +00:00
if len ( self . _current_paths ) > 0 :
2014-01-01 20:01:00 +00:00
2017-09-13 20:50:41 +00:00
file_import_options = self . _file_import_options . GetValue ( )
2014-01-01 20:01:00 +00:00
2017-11-22 21:03:07 +00:00
with ClientGUITopLevelWindows . DialogEdit ( self , ' filename tagging ' , frame_key = ' local_import_filename_tagging ' ) as dlg :
panel = ClientGUIImport . EditLocalImportFilenameTaggingPanel ( dlg , self . _current_paths )
dlg . SetPanel ( panel )
2014-01-01 20:01:00 +00:00
2015-07-22 19:40:39 +00:00
if dlg . ShowModal ( ) == wx . ID_OK :
2014-01-01 20:01:00 +00:00
2017-11-22 21:03:07 +00:00
paths_to_tags = panel . GetValue ( )
2014-01-01 20:01:00 +00:00
2015-07-22 19:40:39 +00:00
delete_after_success = self . _delete_after_success . GetValue ( )
2014-01-01 20:01:00 +00:00
2017-09-13 20:50:41 +00:00
HG . client_controller . pub ( ' new_hdd_import ' , self . _current_paths , file_import_options , paths_to_tags , delete_after_success )
2014-01-01 20:01:00 +00:00
2017-11-08 22:07:12 +00:00
self . Close ( )
2014-01-01 20:01:00 +00:00
2017-02-01 21:11:17 +00:00
def PauseProgress ( self ) :
2018-01-24 23:09:42 +00:00
if self . _pause_event . is_set ( ) :
2017-02-01 21:11:17 +00:00
2018-01-24 23:09:42 +00:00
self . _pause_event . clear ( )
2017-02-01 21:11:17 +00:00
else :
2018-01-24 23:09:42 +00:00
self . _pause_event . set ( )
2017-02-01 21:11:17 +00:00
2018-01-24 23:09:42 +00:00
def StopProgress ( self ) :
self . _cancel_event . set ( )
2015-03-04 22:44:32 +00:00
def RemovePaths ( self ) :
2017-03-22 22:38:15 +00:00
with DialogYesNo ( self , ' Remove all selected? ' ) as dlg :
if dlg . ShowModal ( ) == wx . ID_YES :
self . _paths_list . RemoveAllSelected ( )
self . _current_paths = [ row [ 0 ] for row in self . _paths_list . GetClientData ( ) ]
self . _current_paths_set = set ( self . _current_paths )
2015-03-04 22:44:32 +00:00
2018-01-24 23:09:42 +00:00
def THREADParseImportablePaths ( self , unparsed_paths_queue , currently_parsing , work_to_do , parsed_path_queue , progress_updater , pause_event , cancel_event ) :
2014-01-01 20:01:00 +00:00
2018-06-20 20:20:22 +00:00
unparsed_paths = collections . deque ( )
2016-08-24 18:36:56 +00:00
2018-01-24 23:09:42 +00:00
num_files_done = 0
2014-01-01 20:01:00 +00:00
num_good_files = 0
2018-01-24 23:09:42 +00:00
2016-01-20 23:57:33 +00:00
num_empty_files = 0
2018-04-25 22:07:52 +00:00
num_unimportable_mime_files = 0
2018-01-24 23:09:42 +00:00
num_occupied_files = 0
2014-01-01 20:01:00 +00:00
2018-01-24 23:09:42 +00:00
while not HG . view_shutdown :
2014-01-01 20:01:00 +00:00
2018-01-24 23:09:42 +00:00
if not self :
2015-11-04 22:30:28 +00:00
2018-01-24 23:09:42 +00:00
return
2015-11-04 22:30:28 +00:00
2015-01-14 22:27:55 +00:00
2018-01-24 23:09:42 +00:00
if len ( unparsed_paths ) > 0 :
work_to_do . set ( )
else :
work_to_do . clear ( )
2014-01-01 20:01:00 +00:00
2018-01-24 23:09:42 +00:00
currently_parsing . clear ( )
2017-02-01 21:11:17 +00:00
2018-01-24 23:09:42 +00:00
# ready to start, let's update ui on status
2014-01-01 20:01:00 +00:00
2018-01-24 23:09:42 +00:00
total_paths = num_files_done + len ( unparsed_paths )
2014-01-01 20:01:00 +00:00
2018-01-24 23:09:42 +00:00
if num_good_files == 0 :
2015-07-01 22:02:07 +00:00
2018-01-24 23:09:42 +00:00
if num_files_done == 0 :
message = ' waiting for paths to parse '
else :
2018-07-04 20:48:28 +00:00
message = ' none of the ' + HydrusData . ToHumanInt ( total_paths ) + ' files parsed successfully '
2018-01-24 23:09:42 +00:00
else :
message = HydrusData . ConvertValueRangeToPrettyString ( num_good_files , total_paths ) + ' files parsed successfully '
2015-07-01 22:02:07 +00:00
2014-01-01 20:01:00 +00:00
2018-04-25 22:07:52 +00:00
if num_empty_files > 0 or num_unimportable_mime_files > 0 or num_occupied_files > 0 :
2014-01-01 20:01:00 +00:00
2018-01-24 23:09:42 +00:00
if num_good_files == 0 :
message + = ' : '
else :
message + = ' , but '
2016-11-09 23:13:22 +00:00
2018-01-24 23:09:42 +00:00
bad_comments = [ ]
2014-01-01 20:01:00 +00:00
2018-01-24 23:09:42 +00:00
if num_empty_files > 0 :
2018-07-04 20:48:28 +00:00
bad_comments . append ( HydrusData . ToHumanInt ( num_empty_files ) + ' were empty ' )
2018-01-24 23:09:42 +00:00
2018-04-25 22:07:52 +00:00
if num_unimportable_mime_files > 0 :
2018-01-24 23:09:42 +00:00
2018-07-04 20:48:28 +00:00
bad_comments . append ( HydrusData . ToHumanInt ( num_unimportable_mime_files ) + ' had unsupported file types ' )
2018-01-24 23:09:42 +00:00
if num_occupied_files > 0 :
2018-09-26 19:05:12 +00:00
bad_comments . append ( HydrusData . ToHumanInt ( num_occupied_files ) + ' were inaccessible (maybe in use by another process) ' )
2018-01-24 23:09:42 +00:00
message + = ' and ' . join ( bad_comments )
2014-01-01 20:01:00 +00:00
2018-01-24 23:09:42 +00:00
message + = ' . '
2014-01-01 20:01:00 +00:00
2018-01-24 23:09:42 +00:00
progress_updater . Update ( message , num_files_done , total_paths )
# status updated, lets see what work there is to do
if cancel_event . is_set ( ) :
2014-01-01 20:01:00 +00:00
2018-01-24 23:09:42 +00:00
while not unparsed_paths_queue . empty ( ) :
try :
unparsed_paths_queue . get ( block = False )
2019-01-09 22:59:03 +00:00
except queue . Empty :
2018-01-24 23:09:42 +00:00
pass
2014-01-01 20:01:00 +00:00
2018-07-18 21:07:15 +00:00
unparsed_paths = collections . deque ( )
2017-02-01 21:11:17 +00:00
2018-01-24 23:09:42 +00:00
cancel_event . clear ( )
pause_event . clear ( )
2014-01-01 20:01:00 +00:00
2018-01-24 23:09:42 +00:00
continue
2014-01-01 20:01:00 +00:00
2018-01-24 23:09:42 +00:00
if pause_event . is_set ( ) :
2016-11-09 23:13:22 +00:00
2018-01-24 23:09:42 +00:00
time . sleep ( 1 )
2014-01-01 20:01:00 +00:00
continue
2018-01-24 23:09:42 +00:00
# let's see if there is anything to parse
2014-01-01 20:01:00 +00:00
2018-01-24 23:09:42 +00:00
# first we'll flesh out unparsed_paths with anything new to look at
2014-01-01 20:01:00 +00:00
2018-08-08 20:29:54 +00:00
do_human_sort = HG . client_controller . new_options . GetBoolean ( ' do_human_sort_on_hdd_file_import_paths ' )
2018-01-24 23:09:42 +00:00
while not unparsed_paths_queue . empty ( ) :
try :
raw_paths = unparsed_paths_queue . get ( block = False )
2018-08-08 20:29:54 +00:00
paths = ClientFiles . GetAllPaths ( raw_paths , do_human_sort = do_human_sort ) # convert any dirs to subpaths
2018-01-24 23:09:42 +00:00
unparsed_paths . extend ( paths )
2019-01-09 22:59:03 +00:00
except queue . Empty :
2018-01-24 23:09:42 +00:00
pass
2016-01-20 23:57:33 +00:00
2018-01-24 23:09:42 +00:00
# if unparsed_paths still has nothing, we'll nonetheless sleep on new paths
2014-01-01 20:01:00 +00:00
2018-01-24 23:09:42 +00:00
if len ( unparsed_paths ) == 0 :
try :
raw_paths = unparsed_paths_queue . get ( timeout = 5 )
2018-08-08 20:29:54 +00:00
paths = ClientFiles . GetAllPaths ( raw_paths , do_human_sort = do_human_sort ) # convert any dirs to subpaths
2018-01-24 23:09:42 +00:00
unparsed_paths . extend ( paths )
2019-01-09 22:59:03 +00:00
except queue . Empty :
2018-01-24 23:09:42 +00:00
pass
continue # either we added some or didn't--in any case, restart the cycle
2014-01-01 20:01:00 +00:00
2018-06-20 20:20:22 +00:00
path = unparsed_paths . popleft ( )
2014-01-01 20:01:00 +00:00
2018-01-24 23:09:42 +00:00
currently_parsing . set ( )
2016-01-20 23:57:33 +00:00
2018-01-24 23:09:42 +00:00
# we are now dealing with a file. let's clear out quick no-gos
num_files_done + = 1
if path . endswith ( os . path . sep + ' Thumbs.db ' ) or path . endswith ( os . path . sep + ' thumbs.db ' ) :
2018-04-25 22:07:52 +00:00
num_unimportable_mime_files + = 1
2016-01-20 23:57:33 +00:00
2018-01-24 23:09:42 +00:00
continue
2016-01-20 23:57:33 +00:00
2018-01-24 23:09:42 +00:00
if not HydrusPaths . PathIsFree ( path ) :
2016-01-20 23:57:33 +00:00
2018-01-24 23:09:42 +00:00
num_occupied_files + = 1
continue
2016-01-20 23:57:33 +00:00
2018-01-24 23:09:42 +00:00
size = os . path . getsize ( path )
2016-01-20 23:57:33 +00:00
2018-01-24 23:09:42 +00:00
if size == 0 :
2016-01-20 23:57:33 +00:00
2018-01-24 23:09:42 +00:00
HydrusData . Print ( ' Empty file: ' + path )
2016-01-20 23:57:33 +00:00
2018-01-24 23:09:42 +00:00
num_empty_files + = 1
2016-01-20 23:57:33 +00:00
2018-01-24 23:09:42 +00:00
continue
2016-01-20 23:57:33 +00:00
2018-01-24 23:09:42 +00:00
# looks good, let's burn some CPU
mime = HydrusFileHandling . GetMime ( path )
if mime in HC . ALLOWED_MIMES :
2016-08-24 18:36:56 +00:00
2018-01-24 23:09:42 +00:00
num_good_files + = 1
parsed_path_queue . put ( ( path , mime , size ) )
else :
2016-08-24 18:36:56 +00:00
2018-01-24 23:09:42 +00:00
HydrusData . Print ( ' Unparsable file: ' + path )
2018-04-25 22:07:52 +00:00
num_unimportable_mime_files + = 1
2018-01-24 23:09:42 +00:00
def TIMERUIUpdate ( self ) :
while not self . _parsed_path_queue . empty ( ) :
2016-08-24 18:36:56 +00:00
2018-01-24 23:09:42 +00:00
( path , mime , size ) = self . _parsed_path_queue . get ( )
pretty_mime = HC . mime_string_lookup [ mime ]
2019-01-09 22:59:03 +00:00
pretty_size = HydrusData . ToHumanBytes ( size )
2018-01-24 23:09:42 +00:00
if path not in self . _current_paths_set :
self . _current_paths_set . add ( path )
self . _current_paths . append ( path )
self . _paths_list . Append ( ( path , pretty_mime , pretty_size ) , ( path , mime , size ) )
2016-01-20 23:57:33 +00:00
2018-01-24 23:09:42 +00:00
#
paused = self . _pause_event . is_set ( )
no_work_in_queue = not self . _work_to_do . is_set ( )
working_on_a_file_now = self . _currently_parsing . is_set ( )
2014-01-01 20:01:00 +00:00
2018-01-24 23:09:42 +00:00
can_import = ( no_work_in_queue or paused ) and not working_on_a_file_now
2016-01-20 23:57:33 +00:00
2018-01-24 23:09:42 +00:00
if no_work_in_queue :
self . _progress_pause . Disable ( )
self . _progress_cancel . Disable ( )
else :
self . _progress_pause . Enable ( )
self . _progress_cancel . Enable ( )
if can_import :
self . _add_button . Enable ( )
self . _tag_button . Enable ( )
else :
self . _add_button . Disable ( )
self . _tag_button . Disable ( )
2017-02-01 21:11:17 +00:00
2018-01-24 23:09:42 +00:00
if paused :
ClientGUICommon . SetBitmapButtonBitmap ( self . _progress_pause , CC . GlobalBMPs . play )
else :
ClientGUICommon . SetBitmapButtonBitmap ( self . _progress_pause , CC . GlobalBMPs . pause )
2014-01-01 20:01:00 +00:00
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 )
class DialogInputNewFormField ( Dialog ) :
def __init__ ( self , parent , form_field = None ) :
Dialog . __init__ ( self , parent , ' configure form field ' )
2013-07-24 20:26:00 +00:00
2014-09-10 22:37:38 +00:00
if form_field is None : ( name , field_type , default , editable ) = ( ' ' , CC . FIELD_TEXT , ' ' , True )
else : ( name , field_type , default , editable ) = form_field
2013-07-31 21:26:38 +00:00
2015-12-09 23:16:41 +00:00
self . _name = wx . TextCtrl ( self )
self . _type = wx . Choice ( self )
self . _default = wx . TextCtrl ( self )
self . _editable = wx . CheckBox ( self )
2013-07-31 21:26:38 +00:00
2017-06-07 22:05:15 +00:00
self . _ok = wx . Button ( self , id = wx . ID_OK , label = ' OK ' )
2015-12-09 23:16:41 +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 . _name . SetValue ( name )
for temp_type in CC . FIELDS : self . _type . Append ( CC . field_string_lookup [ temp_type ] , temp_type )
self . _type . Select ( field_type )
self . _default . SetValue ( default )
self . _editable . SetValue ( editable )
#
2017-04-19 20:58:30 +00:00
rows = [ ]
2016-02-24 21:42:54 +00:00
2017-04-19 20:58:30 +00:00
rows . append ( ( ' name: ' , self . _name ) )
rows . append ( ( ' type: ' , self . _type ) )
rows . append ( ( ' default: ' , self . _default ) )
rows . append ( ( ' editable: ' , self . _editable ) )
2016-02-24 21:42:54 +00:00
2017-04-19 20:58:30 +00:00
gridbox = ClientGUICommon . WrapInGrid ( self , rows )
2016-02-24 21:42:54 +00:00
b_box = wx . BoxSizer ( wx . HORIZONTAL )
2017-04-19 20:58:30 +00:00
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-02-24 21:42:54 +00:00
vbox = wx . BoxSizer ( wx . VERTICAL )
2018-01-03 22:37:30 +00:00
vbox . Add ( gridbox , CC . FLAGS_EXPAND_SIZER_PERPENDICULAR )
vbox . Add ( b_box , CC . FLAGS_BUTTON_SIZER )
2016-02-24 21:42:54 +00:00
self . SetSizer ( vbox )
( x , y ) = self . GetEffectiveMinSize ( )
self . SetInitialSize ( ( x , y ) )
2013-07-31 21:26:38 +00:00
wx . CallAfter ( self . _ok . SetFocus )
2013-07-24 20:26:00 +00:00
2017-04-19 20:58:30 +00:00
def GetFormField ( self ) :
2013-07-24 20:26:00 +00:00
2017-04-19 20:58:30 +00:00
name = self . _name . GetValue ( )
2017-04-12 21:46:46 +00:00
2017-04-19 20:58:30 +00:00
field_type = self . _type . GetClientData ( self . _type . GetSelection ( ) )
2017-04-12 21:46:46 +00:00
2017-04-19 20:58:30 +00:00
default = self . _default . GetValue ( )
2017-04-12 21:46:46 +00:00
2017-04-19 20:58:30 +00:00
editable = self . _editable . GetValue ( )
2013-07-24 20:26:00 +00:00
2017-04-19 20:58:30 +00:00
return ( name , field_type , default , editable )
2013-07-24 20:26:00 +00:00
2013-02-19 00:11:43 +00:00
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
2017-06-07 22:05:15 +00:00
self . _tag_box = ClientGUIACDropdown . AutoCompleteDropdownTagsWrite ( self , self . EnterTags , expand_parents , CC . LOCAL_FILE_SERVICE_KEY , service_key , null_entry_callable = self . OK )
2015-10-21 21:53:10 +00:00
2017-06-07 22:05:15 +00:00
self . _ok = wx . Button ( self , id = wx . ID_OK , label = ' 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 ) :
2017-05-10 21:33:58 +00:00
tag_parents_manager = HG . client_controller . GetManager ( ' tag_parents ' )
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
2017-06-07 22:05:15 +00:00
self . _ok = wx . Button ( self , id = wx . ID_OK , label = ' 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 ( )
protocol_type = self . _protocol_type . GetChoice ( )
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 ( )
#self._DoModification( HC.CHANGE_ACCOUNT_TYPE, account_type_key = self._account_types.GetChoice() )
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 )
self . _ok = wx . Button ( self , id = wx . ID_OK )
self . _ok . SetForegroundColour ( ( 0 , 128 , 0 ) )
self . _cancel = wx . Button ( self , id = wx . ID_CANCEL )
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 . _hidden_cancel = wx . Button ( self , id = wx . ID_CANCEL , size = ( 0 , 0 ) )
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 )
2016-03-30 22:56:50 +00:00
self . _ok = wx . Button ( self , id = wx . ID_OK , label = ' ok ' )
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
2013-02-19 00:11:43 +00:00
class DialogYesNo ( Dialog ) :
2014-11-20 01:48:04 +00:00
def __init__ ( self , parent , message , title = ' Are you sure? ' , yes_label = ' yes ' , no_label = ' no ' ) :
2013-02-19 00:11:43 +00:00
2016-03-30 22:56:50 +00:00
Dialog . __init__ ( self , parent , title , position = ' center ' )
2013-02-19 00:11:43 +00:00
2017-04-19 20:58:30 +00:00
self . _yes = wx . Button ( self , id = wx . ID_YES )
2016-03-30 22:56:50 +00:00
self . _yes . SetForegroundColour ( ( 0 , 128 , 0 ) )
2017-04-19 20:58:30 +00:00
self . _yes . SetLabelText ( yes_label )
2013-02-19 00:11:43 +00:00
2017-04-19 20:58:30 +00:00
self . _no = wx . Button ( self , id = wx . ID_NO )
2016-03-30 22:56:50 +00:00
self . _no . SetForegroundColour ( ( 128 , 0 , 0 ) )
2017-04-19 20:58:30 +00:00
self . _no . SetLabelText ( no_label )
2013-02-19 00:11:43 +00:00
2016-03-30 22:56:50 +00:00
self . _hidden_cancel = wx . Button ( self , id = wx . ID_CANCEL , size = ( 0 , 0 ) )
2013-02-19 00:11:43 +00:00
2016-03-30 22:56:50 +00:00
#
2013-07-31 21:26:38 +00:00
2016-03-30 22:56:50 +00:00
hbox = wx . BoxSizer ( wx . HORIZONTAL )
2013-02-19 00:11:43 +00:00
2018-01-03 22:37:30 +00:00
hbox . Add ( self . _yes , CC . FLAGS_SMALL_INDENT )
hbox . Add ( self . _no , CC . FLAGS_SMALL_INDENT )
2013-02-19 00:11:43 +00:00
2016-03-30 22:56:50 +00:00
vbox = wx . BoxSizer ( wx . VERTICAL )
2013-07-31 21:26:38 +00:00
2017-04-19 20:58:30 +00:00
text = ClientGUICommon . BetterStaticText ( self , message )
2013-02-19 00:11:43 +00:00
2018-07-04 20:48:28 +00:00
text . SetWrapWidth ( 480 )
2016-03-30 22:56:50 +00:00
2018-01-03 22:37:30 +00:00
vbox . Add ( 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 ) )
wx . CallAfter ( self . _yes . SetFocus )
2013-02-19 00:11:43 +00:00
2016-12-07 22:12:52 +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 )
self . _no = wx . Button ( self , id = wx . ID_NO )
self . _no . SetForegroundColour ( ( 128 , 0 , 0 ) )
self . _no . SetLabelText ( no_label )
self . _hidden_cancel = wx . Button ( self , id = wx . ID_CANCEL , size = ( 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