hydrus/include/ClientGUIDialogs.py

4696 lines
168 KiB
Python
Raw Normal View History

2013-02-19 00:11:43 +00:00
import Crypto.PublicKey.RSA
import HydrusConstants as HC
2013-05-01 17:21:53 +00:00
import HydrusEncryption
2013-07-17 20:56:13 +00:00
import HydrusTags
2013-02-19 00:11:43 +00:00
import ClientConstants as CC
import ClientGUICommon
import collections
2013-06-12 22:53:31 +00:00
import itertools
2013-02-19 00:11:43 +00:00
import os
import random
import re
2013-07-17 20:56:13 +00:00
import string
2013-04-03 20:56:07 +00:00
import subprocess
2013-02-19 00:11:43 +00:00
import time
import traceback
2013-03-15 02:38:12 +00:00
import urllib
2013-02-19 00:11:43 +00:00
import wx
import yaml
2013-05-01 17:21:53 +00:00
import zipfile
2013-02-19 00:11:43 +00:00
# Option Enums
ID_NULL = wx.NewId()
ID_TIMER_UPDATE = wx.NewId()
# Hue is generally 200, Sat and Lum changes based on need
COLOUR_SELECTED = wx.Colour( 217, 242, 255 )
COLOUR_SELECTED_DARK = wx.Colour( 1, 17, 26 )
COLOUR_UNSELECTED = wx.Colour( 223, 227, 230 )
# Sizer Flags
FLAGS_NONE = wx.SizerFlags( 0 )
FLAGS_SMALL_INDENT = wx.SizerFlags( 0 ).Border( wx.ALL, 2 )
FLAGS_BIG_INDENT = wx.SizerFlags( 0 ).Border( wx.ALL, 8 )
FLAGS_EXPAND_PERPENDICULAR = wx.SizerFlags( 0 ).Border( wx.ALL, 2 ).Expand()
FLAGS_EXPAND_BOTH_WAYS = wx.SizerFlags( 2 ).Border( wx.ALL, 2 ).Expand()
FLAGS_EXPAND_DEPTH_ONLY = wx.SizerFlags( 2 ).Border( wx.ALL, 2 ).Align( wx.ALIGN_CENTER_VERTICAL )
2013-03-15 02:38:12 +00:00
FLAGS_EXPAND_SIZER_PERPENDICULAR = wx.SizerFlags( 0 ).Expand()
FLAGS_EXPAND_SIZER_BOTH_WAYS = wx.SizerFlags( 2 ).Expand()
FLAGS_EXPAND_SIZER_DEPTH_ONLY = wx.SizerFlags( 2 ).Align( wx.ALIGN_CENTER_VERTICAL )
2013-02-19 00:11:43 +00:00
FLAGS_BUTTON_SIZERS = wx.SizerFlags( 0 ).Align( wx.ALIGN_RIGHT )
FLAGS_LONE_BUTTON = wx.SizerFlags( 0 ).Border( wx.ALL, 2 ).Align( wx.ALIGN_RIGHT )
FLAGS_MIXED = wx.SizerFlags( 0 ).Border( wx.ALL, 2 ).Align( wx.ALIGN_CENTER_VERTICAL )
def SelectServiceIdentifier( permission = None, service_types = HC.ALL_SERVICES, service_identifiers = None, unallowed = None ):
if service_identifiers is None:
2013-07-10 20:25:57 +00:00
services = HC.app.Read( 'services', service_types )
2013-02-19 00:11:43 +00:00
if permission is not None: services = [ service for service in services if service.GetAccount().HasPermission( permission ) ]
service_identifiers = [ service.GetServiceIdentifier() for service in services ]
if unallowed is not None: service_identifiers.difference_update( unallowed )
if len( service_identifiers ) == 0: return None
elif len( service_identifiers ) == 1:
( service_identifier, ) = service_identifiers
return service_identifier
else:
names_to_service_identifiers = { service_identifier.GetName() : service_identifier for service_identifier in service_identifiers }
2013-07-10 20:25:57 +00:00
with DialogSelectFromListOfStrings( HC.app.GetGUI(), 'select service', [ service_identifier.GetName() for service_identifier in service_identifiers ] ) as dlg:
2013-02-19 00:11:43 +00:00
if dlg.ShowModal() == wx.ID_OK: return names_to_service_identifiers[ dlg.GetString() ]
else: return None
def ShowMessage( parent, message ):
with DialogMessage( parent, message ) as dlg: dlg.ShowModal()
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
2013-07-10 20:25:57 +00:00
( pos_x, pos_y ) = HC.app.GetGUI().GetPositionTuple()
2013-02-19 00:11:43 +00:00
pos = ( pos_x + 50, pos_y + 100 )
else: pos = ( -1, -1 )
wx.Dialog.__init__( self, parent, title = title, style = style, pos = pos )
2013-07-31 21:26:38 +00:00
self._options = HC.app.Read( 'options' )
2013-02-19 00:11:43 +00:00
self.SetDoubleBuffered( True )
self.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_BTNFACE ) )
self.SetIcon( wx.Icon( HC.STATIC_DIR + os.path.sep + 'hydrus.ico', wx.BITMAP_TYPE_ICO ) )
2013-07-31 21:26:38 +00:00
self._dialog_cancel_button = wx.Button( self, id = wx.ID_CANCEL, size = ( 0, 0 ) )
2013-02-19 00:11:43 +00:00
if position == 'center': wx.CallAfter( self.Center )
2013-07-24 20:26:00 +00:00
self.Bind( wx.EVT_BUTTON, self.EventDialogButton )
def EventDialogButton( self, event ): self.EndModal( event.GetId() )
2013-03-15 02:38:12 +00:00
class DialogChooseNewServiceMethod( Dialog ):
def __init__( self, parent ):
def InitialiseControls():
register_message = 'I want to set up a new account. I have a registration key (a key starting with \'r\').'
self._register = wx.Button( self, id = wx.ID_OK, label = register_message )
self._register.Bind( wx.EVT_BUTTON, self.EventRegister )
setup_message = 'The account is already set up; I just want to add it to this client. I have a normal access key.'
self._setup = wx.Button( self, id = wx.ID_OK, label = setup_message )
2013-07-31 21:26:38 +00:00
def PopulateControls():
pass
2013-03-15 02:38:12 +00:00
2013-07-31 21:26:38 +00:00
def ArrangeControls():
2013-03-15 02:38:12 +00:00
vbox = wx.BoxSizer( wx.VERTICAL )
vbox.AddF( self._register, FLAGS_EXPAND_PERPENDICULAR )
vbox.AddF( wx.StaticText( self, label = '-or-', style = wx.ALIGN_CENTER ), FLAGS_EXPAND_PERPENDICULAR )
vbox.AddF( self._setup, FLAGS_EXPAND_PERPENDICULAR )
self.SetSizer( vbox )
( x, y ) = self.GetEffectiveMinSize()
self.SetInitialSize( ( x, y ) )
Dialog.__init__( self, parent, 'how to set up the account?', position = 'center' )
InitialiseControls()
2013-07-31 21:26:38 +00:00
PopulateControls()
ArrangeControls()
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
2013-02-19 00:11:43 +00:00
class DialogFinishFiltering( Dialog ):
2013-07-24 20:26:00 +00:00
def __init__( self, parent, num_kept, num_deleted, keep = 'keep', delete = 'delete' ):
2013-02-19 00:11:43 +00:00
def InitialiseControls():
2013-07-24 20:26:00 +00:00
self._commit = wx.Button( self, id = wx.ID_YES, label = 'commit' )
2013-02-19 00:11:43 +00:00
self._commit.SetForegroundColour( ( 0, 128, 0 ) )
2013-07-24 20:26:00 +00:00
self._forget = wx.Button( self, id = wx.ID_NO, label = 'forget' )
2013-02-19 00:11:43 +00:00
self._forget.SetForegroundColour( ( 128, 0, 0 ) )
self._back = wx.Button( self, id = wx.ID_CANCEL, label = 'back to filtering' )
2013-07-31 21:26:38 +00:00
def PopulateControls():
pass
def ArrangeControls():
2013-02-19 00:11:43 +00:00
hbox = wx.BoxSizer( wx.HORIZONTAL )
hbox.AddF( self._commit, FLAGS_EXPAND_BOTH_WAYS )
hbox.AddF( self._forget, FLAGS_EXPAND_BOTH_WAYS )
vbox = wx.BoxSizer( wx.VERTICAL )
2013-04-03 20:56:07 +00:00
label = keep + ' ' + HC.ConvertIntToPrettyString( num_kept ) + ' and ' + delete + ' ' + HC.ConvertIntToPrettyString( num_deleted ) + ' files?'
2013-02-19 00:11:43 +00:00
vbox.AddF( wx.StaticText( self, label = label, style = wx.ALIGN_CENTER ), FLAGS_EXPAND_PERPENDICULAR )
2013-03-15 02:38:12 +00:00
vbox.AddF( hbox, FLAGS_EXPAND_SIZER_PERPENDICULAR )
2013-02-19 00:11:43 +00:00
vbox.AddF( wx.StaticText( self, label = '-or-', style = wx.ALIGN_CENTER ), FLAGS_EXPAND_PERPENDICULAR )
vbox.AddF( self._back, FLAGS_EXPAND_PERPENDICULAR )
self.SetSizer( vbox )
( x, y ) = self.GetEffectiveMinSize()
self.SetInitialSize( ( x, y ) )
Dialog.__init__( self, parent, 'are you sure?', position = 'center' )
InitialiseControls()
2013-07-31 21:26:38 +00:00
PopulateControls()
ArrangeControls()
wx.CallAfter( self._commit.SetFocus )
2013-02-19 00:11:43 +00:00
class DialogFinishRatingFiltering( Dialog ):
def __init__( self, parent, num_certain_ratings, num_uncertain_ratings ):
def InitialiseControls():
2013-07-24 20:26:00 +00:00
self._commit = wx.Button( self, id = wx.ID_YES, label = 'commit' )
2013-02-19 00:11:43 +00:00
self._commit.SetForegroundColour( ( 0, 128, 0 ) )
2013-07-24 20:26:00 +00:00
self._forget = wx.Button( self, id = wx.ID_NO, label = 'forget' )
2013-02-19 00:11:43 +00:00
self._forget.SetForegroundColour( ( 128, 0, 0 ) )
self._back = wx.Button( self, id = wx.ID_CANCEL, label = 'back to filtering' )
2013-07-31 21:26:38 +00:00
def PopulateControls():
pass
def ArrangeControls():
2013-02-19 00:11:43 +00:00
hbox = wx.BoxSizer( wx.HORIZONTAL )
hbox.AddF( self._commit, FLAGS_EXPAND_BOTH_WAYS )
hbox.AddF( self._forget, FLAGS_EXPAND_BOTH_WAYS )
vbox = wx.BoxSizer( wx.VERTICAL )
info_strings = []
if num_certain_ratings > 0: info_strings.append( HC.ConvertIntToPrettyString( num_certain_ratings ) + ' ratings' )
if num_uncertain_ratings > 0: info_strings.append( HC.ConvertIntToPrettyString( num_uncertain_ratings ) + ' uncertain changes' )
label = 'Apply ' + ' and '.join( info_strings ) + '?'
vbox.AddF( wx.StaticText( self, label = label, style = wx.ALIGN_CENTER ), FLAGS_EXPAND_PERPENDICULAR )
2013-03-15 02:38:12 +00:00
vbox.AddF( hbox, FLAGS_EXPAND_SIZER_PERPENDICULAR )
2013-02-19 00:11:43 +00:00
vbox.AddF( wx.StaticText( self, label = '-or-', style = wx.ALIGN_CENTER ), FLAGS_EXPAND_PERPENDICULAR )
vbox.AddF( self._back, FLAGS_EXPAND_PERPENDICULAR )
self.SetSizer( vbox )
( x, y ) = self.GetEffectiveMinSize()
self.SetInitialSize( ( x, y ) )
Dialog.__init__( self, parent, 'are you sure?', position = 'center' )
InitialiseControls()
2013-07-31 21:26:38 +00:00
PopulateControls()
ArrangeControls()
wx.CallAfter( self._commit.SetFocus )
2013-02-19 00:11:43 +00:00
2013-04-03 20:56:07 +00:00
class DialogFirstStart( Dialog ):
def __init__( self, parent ):
def InitialiseControls():
self._ok = wx.Button( self, id = wx.ID_OK, label = 'ok!' )
self._ok.SetForegroundColour( ( 0, 128, 0 ) )
2013-07-31 21:26:38 +00:00
def PopulateControls():
pass
2013-04-03 20:56:07 +00:00
2013-07-31 21:26:38 +00:00
def ArrangeControls():
2013-04-03 20:56:07 +00:00
message1 = 'Hi, this looks like the first time you have started the hydrus client. Don\'t forget to check out the'
link = wx.HyperlinkCtrl( self, id = -1, label = 'help', url = 'file://' + HC.BASE_DIR + '/help/index.html' )
message2 = 'if you haven\'t already.'
message3 = 'When you close this dialog, the client will start its local http server. You will probably get a firewall warning.'
message4 = 'You can block it if you like, or you can allow it. It doesn\'t phone home, or expose your files to your network; it just provides another way to locally export your files.'
hbox = wx.BoxSizer( wx.HORIZONTAL )
hbox.AddF( wx.StaticText( self, label = message1 ), FLAGS_MIXED )
hbox.AddF( link, FLAGS_MIXED )
hbox.AddF( wx.StaticText( self, label = message2 ), FLAGS_MIXED )
vbox = wx.BoxSizer( wx.VERTICAL )
vbox.AddF( hbox, FLAGS_EXPAND_SIZER_PERPENDICULAR )
vbox.AddF( wx.StaticText( self, label = message3 ), FLAGS_EXPAND_PERPENDICULAR )
vbox.AddF( wx.StaticText( self, label = message4 ), FLAGS_EXPAND_PERPENDICULAR )
vbox.AddF( self._ok, FLAGS_LONE_BUTTON )
self.SetSizer( vbox )
( x, y ) = self.GetEffectiveMinSize()
self.SetInitialSize( ( x, y ) )
Dialog.__init__( self, parent, 'First start', position = 'center' )
InitialiseControls()
2013-07-31 21:26:38 +00:00
PopulateControls()
ArrangeControls()
wx.CallAfter( self._ok.SetFocus )
2013-04-03 20:56:07 +00:00
2013-02-19 00:11:43 +00:00
class DialogInputCustomFilterAction( Dialog ):
def __init__( self, parent, modifier = wx.ACCEL_NORMAL, key = wx.WXK_F7, service_identifier = None, action = 'archive' ):
def InitialiseControls():
2013-07-10 20:25:57 +00:00
service_identifiers = HC.app.Read( 'service_identifiers', ( HC.LOCAL_TAG, HC.TAG_REPOSITORY, HC.LOCAL_RATING_LIKE, HC.LOCAL_RATING_NUMERICAL ) )
2013-02-19 00:11:43 +00:00
2013-03-15 02:38:12 +00:00
self._shortcut_panel = ClientGUICommon.StaticBox( self, 'shortcut' )
2013-02-19 00:11:43 +00:00
2013-03-15 02:38:12 +00:00
self._shortcut = ClientGUICommon.Shortcut( self._shortcut_panel, modifier, key )
2013-02-19 00:11:43 +00:00
2013-03-15 02:38:12 +00:00
self._none_panel = ClientGUICommon.StaticBox( self, 'non-service actions' )
self._none_actions = wx.Choice( self._none_panel, choices = [ 'manage_tags', 'manage_ratings', 'archive', 'inbox', 'delete', 'fullscreen_switch', 'frame_back', 'frame_next', 'previous', 'next', 'first', 'last' ] )
self._ok_none = wx.Button( self._none_panel, label = 'ok' )
2013-02-19 00:11:43 +00:00
self._ok_none.Bind( wx.EVT_BUTTON, self.EventOKNone )
self._ok_none.SetForegroundColour( ( 0, 128, 0 ) )
2013-03-15 02:38:12 +00:00
self._tag_panel = ClientGUICommon.StaticBox( self, 'tag service actions' )
2013-02-19 00:11:43 +00:00
2013-03-15 02:38:12 +00:00
self._tag_service_identifiers = wx.Choice( self._tag_panel )
self._tag_value = wx.TextCtrl( self._tag_panel, style = wx.TE_READONLY )
2013-05-29 20:19:54 +00:00
self._tag_input = ClientGUICommon.AutoCompleteDropdownTagsWrite( self._tag_panel, self.SetTag, HC.LOCAL_FILE_SERVICE_IDENTIFIER, HC.COMBINED_TAG_SERVICE_IDENTIFIER )
2013-03-15 02:38:12 +00:00
self._ok_tag = wx.Button( self._tag_panel, label = 'ok' )
2013-02-19 00:11:43 +00:00
self._ok_tag.Bind( wx.EVT_BUTTON, self.EventOKTag )
self._ok_tag.SetForegroundColour( ( 0, 128, 0 ) )
2013-03-15 02:38:12 +00:00
self._ratings_like_panel = ClientGUICommon.StaticBox( self, 'ratings like service actions' )
self._ratings_like_service_identifiers = wx.Choice( self._ratings_like_panel )
2013-02-19 00:11:43 +00:00
self._ratings_like_service_identifiers.Bind( wx.EVT_CHOICE, self.EventRecalcActions )
2013-03-15 02:38:12 +00:00
self._ratings_like_like = wx.RadioButton( self._ratings_like_panel, style = wx.RB_GROUP, label = 'like' )
self._ratings_like_dislike = wx.RadioButton( self._ratings_like_panel, label = 'dislike' )
self._ratings_like_remove = wx.RadioButton( self._ratings_like_panel, label = 'remove rating' )
2013-02-19 00:11:43 +00:00
2013-03-15 02:38:12 +00:00
self._ok_ratings_like = wx.Button( self._ratings_like_panel, label = 'ok' )
2013-02-19 00:11:43 +00:00
self._ok_ratings_like.Bind( wx.EVT_BUTTON, self.EventOKRatingsLike )
self._ok_ratings_like.SetForegroundColour( ( 0, 128, 0 ) )
2013-03-15 02:38:12 +00:00
self._ratings_numerical_panel = ClientGUICommon.StaticBox( self, 'ratings numerical service actions' )
self._ratings_numerical_service_identifiers = wx.Choice( self._ratings_numerical_panel )
2013-02-19 00:11:43 +00:00
self._ratings_numerical_service_identifiers.Bind( wx.EVT_CHOICE, self.EventRecalcActions )
2013-03-15 02:38:12 +00:00
self._ratings_numerical_slider = wx.Slider( self._ratings_numerical_panel, style = wx.SL_AUTOTICKS | wx.SL_LABELS )
self._ratings_numerical_remove = wx.CheckBox( self._ratings_numerical_panel, label = 'remove rating' )
2013-02-19 00:11:43 +00:00
2013-03-15 02:38:12 +00:00
self._ok_ratings_numerical = wx.Button( self._ratings_numerical_panel, label = 'ok' )
2013-02-19 00:11:43 +00:00
self._ok_ratings_numerical.Bind( wx.EVT_BUTTON, self.EventOKRatingsNumerical )
self._ok_ratings_numerical.SetForegroundColour( ( 0, 128, 0 ) )
for service_identifier in service_identifiers:
service_type = service_identifier.GetType()
if service_type in ( HC.LOCAL_TAG, HC.TAG_REPOSITORY ): choice = self._tag_service_identifiers
elif service_type == HC.LOCAL_RATING_LIKE: choice = self._ratings_like_service_identifiers
elif service_type == HC.LOCAL_RATING_NUMERICAL: choice = self._ratings_numerical_service_identifiers
choice.Append( service_identifier.GetName(), service_identifier )
self._SetActions()
if self._service_identifier is None:
self._none_actions.SetStringSelection( self._action )
else:
service_name = self._service_identifier.GetName()
service_type = self._service_identifier.GetType()
if service_type in ( HC.LOCAL_TAG, HC.TAG_REPOSITORY ):
self._tag_service_identifiers.SetStringSelection( service_name )
self._tag_value.SetValue( self._action )
elif service_type == HC.LOCAL_RATING_LIKE:
self._ratings_like_service_identifiers.SetStringSelection( service_name )
self._SetActions()
if self._action is None: self._ratings_like_remove.SetValue( True )
elif self._action == True: self._ratings_like_like.SetValue( True )
elif self._action == False: self._ratings_like_dislike.SetValue( True )
elif service_type == HC.LOCAL_RATING_NUMERICAL:
self._ratings_numerical_service_identifiers.SetStringSelection( service_name )
self._SetActions()
if self._action is None: self._ratings_numerical_remove.SetValue( True )
else:
( lower, upper ) = self._current_ratings_numerical_service.GetExtraInfo()
slider_value = int( self._action * ( upper - lower ) ) + lower
self._ratings_numerical_slider.SetValue( slider_value )
2013-07-31 21:26:38 +00:00
def PopulateControls():
pass
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
def ArrangeControls():
2013-02-19 00:11:43 +00:00
2013-03-15 02:38:12 +00:00
self._shortcut_panel.AddF( self._shortcut, FLAGS_EXPAND_PERPENDICULAR )
2013-02-19 00:11:43 +00:00
none_hbox = wx.BoxSizer( wx.HORIZONTAL )
none_hbox.AddF( self._none_actions, FLAGS_EXPAND_DEPTH_ONLY )
none_hbox.AddF( self._ok_none, FLAGS_MIXED )
2013-03-15 02:38:12 +00:00
self._none_panel.AddF( none_hbox, FLAGS_EXPAND_SIZER_PERPENDICULAR )
2013-02-19 00:11:43 +00:00
tag_sub_vbox = wx.BoxSizer( wx.VERTICAL )
tag_sub_vbox.AddF( self._tag_value, FLAGS_EXPAND_BOTH_WAYS )
tag_sub_vbox.AddF( self._tag_input, FLAGS_EXPAND_BOTH_WAYS )
tag_hbox = wx.BoxSizer( wx.HORIZONTAL )
tag_hbox.AddF( self._tag_service_identifiers, FLAGS_EXPAND_DEPTH_ONLY )
2013-03-15 02:38:12 +00:00
tag_hbox.AddF( tag_sub_vbox, FLAGS_EXPAND_SIZER_BOTH_WAYS )
2013-02-19 00:11:43 +00:00
tag_hbox.AddF( self._ok_tag, FLAGS_MIXED )
2013-03-15 02:38:12 +00:00
self._tag_panel.AddF( tag_hbox, FLAGS_EXPAND_SIZER_PERPENDICULAR )
2013-02-19 00:11:43 +00:00
ratings_like_hbox = wx.BoxSizer( wx.HORIZONTAL )
ratings_like_hbox.AddF( self._ratings_like_service_identifiers, FLAGS_EXPAND_DEPTH_ONLY )
ratings_like_hbox.AddF( self._ratings_like_like, FLAGS_MIXED )
ratings_like_hbox.AddF( self._ratings_like_dislike, FLAGS_MIXED )
ratings_like_hbox.AddF( self._ratings_like_remove, FLAGS_MIXED )
ratings_like_hbox.AddF( self._ok_ratings_like, FLAGS_MIXED )
2013-03-15 02:38:12 +00:00
self._ratings_like_panel.AddF( ratings_like_hbox, FLAGS_EXPAND_SIZER_PERPENDICULAR )
2013-02-19 00:11:43 +00:00
ratings_numerical_hbox = wx.BoxSizer( wx.HORIZONTAL )
ratings_numerical_hbox.AddF( self._ratings_numerical_service_identifiers, FLAGS_EXPAND_DEPTH_ONLY )
ratings_numerical_hbox.AddF( self._ratings_numerical_slider, FLAGS_MIXED )
ratings_numerical_hbox.AddF( self._ratings_numerical_remove, FLAGS_MIXED )
ratings_numerical_hbox.AddF( self._ok_ratings_numerical, FLAGS_MIXED )
2013-03-15 02:38:12 +00:00
self._ratings_numerical_panel.AddF( ratings_numerical_hbox, FLAGS_EXPAND_SIZER_PERPENDICULAR )
2013-02-19 00:11:43 +00:00
vbox = wx.BoxSizer( wx.VERTICAL )
2013-03-15 02:38:12 +00:00
vbox.AddF( self._none_panel, FLAGS_EXPAND_PERPENDICULAR )
vbox.AddF( self._tag_panel, FLAGS_EXPAND_PERPENDICULAR )
vbox.AddF( self._ratings_like_panel, FLAGS_EXPAND_PERPENDICULAR )
vbox.AddF( self._ratings_numerical_panel, FLAGS_EXPAND_PERPENDICULAR )
2013-02-19 00:11:43 +00:00
hbox = wx.BoxSizer( wx.HORIZONTAL )
2013-03-15 02:38:12 +00:00
hbox.AddF( self._shortcut_panel, FLAGS_MIXED )
hbox.AddF( wx.StaticText( self, label = u'\u2192' ), FLAGS_MIXED )
hbox.AddF( vbox, FLAGS_EXPAND_SIZER_BOTH_WAYS )
2013-02-19 00:11:43 +00:00
self.SetSizer( hbox )
( x, y ) = self.GetEffectiveMinSize()
self.SetInitialSize( ( 680, y ) )
Dialog.__init__( self, parent, 'input custom filter action' )
2013-07-31 21:26:38 +00:00
self._service_identifier = service_identifier
self._action = action
self._current_ratings_like_service = None
self._current_ratings_numerical_service = None
2013-02-19 00:11:43 +00:00
InitialiseControls()
2013-07-31 21:26:38 +00:00
PopulateControls()
ArrangeControls()
wx.CallAfter( self._ok_none.SetFocus )
2013-02-19 00:11:43 +00:00
def _SetActions( self ):
if self._ratings_like_service_identifiers.GetCount() > 0:
selection = self._ratings_like_service_identifiers.GetSelection()
if selection != wx.NOT_FOUND:
service_identifier = self._ratings_like_service_identifiers.GetClientData( selection )
2013-07-10 20:25:57 +00:00
service = HC.app.Read( 'service', service_identifier )
2013-02-19 00:11:43 +00:00
self._current_ratings_like_service = service
( like, dislike ) = service.GetExtraInfo()
self._ratings_like_like.SetLabel( like )
self._ratings_like_dislike.SetLabel( dislike )
else:
self._ratings_like_like.SetLabel( 'like' )
self._ratings_like_dislike.SetLabel( 'dislike' )
if self._ratings_numerical_service_identifiers.GetCount() > 0:
selection = self._ratings_numerical_service_identifiers.GetSelection()
if selection != wx.NOT_FOUND:
service_identifier = self._ratings_numerical_service_identifiers.GetClientData( selection )
2013-07-10 20:25:57 +00:00
service = HC.app.Read( 'service', service_identifier )
2013-02-19 00:11:43 +00:00
self._current_ratings_numerical_service = service
( lower, upper ) = service.GetExtraInfo()
self._ratings_numerical_slider.SetRange( lower, upper )
else: self._ratings_numerical_slider.SetRange( 0, 5 )
def EventOKNone( self, event ):
self._service_identifier = None
self._action = self._none_actions.GetStringSelection()
self._pretty_action = self._action
self.EndModal( wx.ID_OK )
def EventOKRatingsLike( self, event ):
selection = self._ratings_like_service_identifiers.GetSelection()
if selection != wx.NOT_FOUND:
self._service_identifier = self._ratings_like_service_identifiers.GetClientData( selection )
( like, dislike ) = self._current_ratings_like_service.GetExtraInfo()
if self._ratings_like_like.GetValue():
self._action = 1.0
self._pretty_action = like
elif self._ratings_like_dislike.GetValue():
self._action = 0.0
self._pretty_action = dislike
else:
self._action = None
self._pretty_action = 'remove'
self.EndModal( wx.ID_OK )
else: self.EndModal( wx.ID_CANCEL )
def EventOKRatingsNumerical( self, event ):
selection = self._ratings_numerical_service_identifiers.GetSelection()
if selection != wx.NOT_FOUND:
self._service_identifier = self._ratings_numerical_service_identifiers.GetClientData( selection )
if self._ratings_numerical_remove.GetValue():
self._action = None
self._pretty_action = 'remove'
else:
2013-07-31 21:26:38 +00:00
self._pretty_action = HC.u( self._ratings_numerical_slider.GetValue() )
2013-02-19 00:11:43 +00:00
( lower, upper ) = self._current_ratings_numerical_service.GetExtraInfo()
self._action = ( float( self._pretty_action ) - float( lower ) ) / ( upper - lower )
self.EndModal( wx.ID_OK )
else: self.EndModal( wx.ID_CANCEL )
def EventOKTag( self, event ):
selection = self._tag_service_identifiers.GetSelection()
if selection != wx.NOT_FOUND:
self._service_identifier = self._tag_service_identifiers.GetClientData( selection )
self._action = self._tag_value.GetValue()
self._pretty_action = self._action
self.EndModal( wx.ID_OK )
else: self.EndModal( wx.ID_CANCEL )
def EventRecalcActions( self, event ):
self._SetActions()
event.Skip()
def GetInfo( self ):
( modifier, key ) = self._shortcut.GetValue()
if self._service_identifier is None: pretty_service_identifier = ''
else: pretty_service_identifier = self._service_identifier.GetName()
# ignore this pretty_action
( pretty_modifier, pretty_key, pretty_action ) = HC.ConvertShortcutToPrettyShortcut( modifier, key, self._action )
return ( ( pretty_modifier, pretty_key, pretty_service_identifier, self._pretty_action ), ( modifier, key, self._service_identifier, self._action ) )
2013-05-15 18:58:14 +00:00
def SetTag( self, tag, parents = [] ): self._tag_value.SetValue( tag )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
class DialogInputFileSystemPredicate( Dialog ):
2013-04-24 21:23:53 +00:00
2013-07-31 21:26:38 +00:00
def __init__( self, parent, type ):
2013-04-24 21:23:53 +00:00
2013-07-31 21:26:38 +00:00
def Age():
2013-04-24 21:23:53 +00:00
2013-07-31 21:26:38 +00:00
def InitialiseControls():
self._sign = wx.Choice( self, choices=[ '<', u'\u2248', '>' ] )
self._years = wx.SpinCtrl( self, max = 30 )
self._months = wx.SpinCtrl( self, max = 60 )
self._days = wx.SpinCtrl( self, max = 90 )
self._hours = wx.SpinCtrl( self, max = 24 )
self._ok = wx.Button( self, id = wx.ID_OK, label='Ok' )
self._ok.SetDefault()
self._ok.Bind( wx.EVT_BUTTON, self.EventOK )
self._ok.SetForegroundColour( ( 0, 128, 0 ) )
2013-04-24 21:23:53 +00:00
2013-07-31 21:26:38 +00:00
def PopulateControls():
( sign, years, months, days ) = system_predicates[ 'age' ]
self._sign.SetSelection( sign )
self._years.SetValue( years )
self._months.SetValue( months )
self._days.SetValue( days )
self._hours.SetValue( 0 )
2013-04-24 21:23:53 +00:00
2013-07-31 21:26:38 +00:00
def ArrangeControls():
hbox = wx.BoxSizer( wx.HORIZONTAL )
hbox.AddF( wx.StaticText( self, label='system:age' ), FLAGS_MIXED )
hbox.AddF( self._sign, FLAGS_MIXED )
hbox.AddF( self._years, FLAGS_MIXED )
hbox.AddF( wx.StaticText( self, label='years' ), FLAGS_MIXED )
hbox.AddF( self._months, FLAGS_MIXED )
hbox.AddF( wx.StaticText( self, label='months' ), FLAGS_MIXED )
hbox.AddF( self._days, FLAGS_MIXED )
hbox.AddF( wx.StaticText( self, label='days' ), FLAGS_MIXED )
hbox.AddF( self._hours, FLAGS_MIXED )
hbox.AddF( wx.StaticText( self, label='hours' ), FLAGS_MIXED )
hbox.AddF( self._ok, FLAGS_MIXED )
self.SetSizer( hbox )
2013-04-24 21:23:53 +00:00
2013-07-31 21:26:38 +00:00
Dialog.__init__( self, parent, 'enter age predicate' )
2013-04-24 21:23:53 +00:00
2013-07-31 21:26:38 +00:00
InitialiseControls()
PopulateControls()
2013-04-24 21:23:53 +00:00
2013-07-31 21:26:38 +00:00
ArrangeControls()
2013-04-24 21:23:53 +00:00
2013-07-31 21:26:38 +00:00
( x, y ) = self.GetEffectiveMinSize()
2013-04-24 21:23:53 +00:00
2013-07-31 21:26:38 +00:00
self.SetInitialSize( ( x, y ) )
2013-04-24 21:23:53 +00:00
2013-07-31 21:26:38 +00:00
wx.CallAfter( self._ok.SetFocus )
2013-04-24 21:23:53 +00:00
2013-07-31 21:26:38 +00:00
def Duration():
2013-04-24 21:23:53 +00:00
2013-07-31 21:26:38 +00:00
def InitialiseControls():
self._sign = wx.Choice( self, choices=[ '<', u'\u2248', '=', '>' ] )
self._duration_s = wx.SpinCtrl( self, max = 3599 )
self._duration_ms = wx.SpinCtrl( self, max = 999 )
self._ok = wx.Button( self, id = wx.ID_OK, label='Ok' )
self._ok.SetDefault()
self._ok.Bind( wx.EVT_BUTTON, self.EventOK )
self._ok.SetForegroundColour( ( 0, 128, 0 ) )
2013-04-24 21:23:53 +00:00
2013-07-31 21:26:38 +00:00
def PopulateControls():
( sign, s, ms ) = system_predicates[ 'duration' ]
self._sign.SetSelection( sign )
self._duration_s.SetValue( s )
self._duration_ms.SetValue( ms )
2013-04-24 21:23:53 +00:00
2013-07-31 21:26:38 +00:00
def ArrangeControls():
hbox = wx.BoxSizer( wx.HORIZONTAL )
hbox.AddF( wx.StaticText( self, label='system:duration' ), FLAGS_MIXED )
hbox.AddF( self._sign, FLAGS_MIXED )
hbox.AddF( self._duration_s, FLAGS_MIXED )
hbox.AddF( wx.StaticText( self, label='s' ), FLAGS_MIXED )
hbox.AddF( self._duration_ms, FLAGS_MIXED )
hbox.AddF( wx.StaticText( self, label='ms' ), FLAGS_MIXED )
hbox.AddF( self._ok, FLAGS_MIXED )
self.SetSizer( hbox )
2013-04-24 21:23:53 +00:00
2013-07-31 21:26:38 +00:00
Dialog.__init__( self, parent, 'enter duration predicate' )
2013-04-24 21:23:53 +00:00
2013-07-31 21:26:38 +00:00
InitialiseControls()
2013-04-24 21:23:53 +00:00
2013-07-31 21:26:38 +00:00
PopulateControls()
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
ArrangeControls()
( x, y ) = self.GetEffectiveMinSize()
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
self.SetInitialSize( ( x, y ) )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
wx.CallAfter( self._ok.SetFocus )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
def FileService():
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
def InitialiseControls():
self._sign = wx.Choice( self )
self._sign.Append( 'is', True )
self._sign.Append( 'is not', False )
self._current_pending = wx.Choice( self )
self._current_pending.Append( 'currently in', HC.CURRENT )
self._current_pending.Append( 'pending to', HC.PENDING )
self._file_service_identifier = wx.Choice( self )
self._ok = wx.Button( self, id = wx.ID_OK, label='Ok' )
self._ok.SetDefault()
self._ok.Bind( wx.EVT_BUTTON, self.EventOK )
self._ok.SetForegroundColour( ( 0, 128, 0 ) )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
def PopulateControls():
self._sign.SetSelection( 0 )
self._current_pending.SetSelection( 0 )
service_identifiers = HC.app.Read( 'service_identifiers', ( HC.FILE_REPOSITORY, HC.LOCAL_FILE ) )
for service_identifier in service_identifiers: self._file_service_identifier.Append( service_identifier.GetName(), service_identifier )
self._file_service_identifier.SetSelection( 0 )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
def ArrangeControls():
hbox = wx.BoxSizer( wx.HORIZONTAL )
hbox.AddF( wx.StaticText( self, label='system:file service:' ), FLAGS_MIXED )
hbox.AddF( self._sign, FLAGS_MIXED )
hbox.AddF( self._current_pending, FLAGS_MIXED )
hbox.AddF( self._file_service_identifier, FLAGS_MIXED )
hbox.AddF( self._ok, FLAGS_MIXED )
self.SetSizer( hbox )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
Dialog.__init__( self, parent, 'enter file service predicate' )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
InitialiseControls()
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
PopulateControls()
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
ArrangeControls()
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
( x, y ) = self.GetEffectiveMinSize()
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
self.SetInitialSize( ( x, y ) )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
wx.CallAfter( self._ok.SetFocus )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
def Hash():
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
def InitialiseControls():
self._hash = wx.TextCtrl( self )
self._ok = wx.Button( self, id = wx.ID_OK, label='Ok' )
self._ok.SetDefault()
self._ok.Bind( wx.EVT_BUTTON, self.EventOK )
self._ok.SetForegroundColour( ( 0, 128, 0 ) )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
def PopulateControls():
pass
def ArrangeControls():
hbox = wx.BoxSizer( wx.HORIZONTAL )
hbox.AddF( wx.StaticText( self, label='system:hash=' ), FLAGS_MIXED )
hbox.AddF( self._hash, FLAGS_MIXED )
hbox.AddF( self._ok, FLAGS_MIXED )
self.SetSizer( hbox )
Dialog.__init__( self, parent, 'enter hash predicate' )
InitialiseControls()
PopulateControls()
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
ArrangeControls()
2013-02-19 00:11:43 +00:00
( x, y ) = self.GetEffectiveMinSize()
self.SetInitialSize( ( x, y ) )
2013-07-31 21:26:38 +00:00
wx.CallAfter( self._ok.SetFocus )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
def Height():
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
def InitialiseControls():
self._sign = wx.Choice( self, choices=[ '<', u'\u2248', '=', '>' ] )
self._height = wx.SpinCtrl( self, max = 200000 )
self._ok = wx.Button( self, id = wx.ID_OK, label='Ok' )
self._ok.SetDefault()
self._ok.Bind( wx.EVT_BUTTON, self.EventOK )
self._ok.SetForegroundColour( ( 0, 128, 0 ) )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
def PopulateControls():
( sign, height ) = system_predicates[ 'height' ]
self._sign.SetSelection( sign )
self._height.SetValue( height )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
def ArrangeControls():
hbox = wx.BoxSizer( wx.HORIZONTAL )
hbox.AddF( wx.StaticText( self, label='system:height' ), FLAGS_MIXED )
hbox.AddF( self._sign, FLAGS_MIXED )
hbox.AddF( self._height, FLAGS_MIXED )
hbox.AddF( self._ok, FLAGS_MIXED )
self.SetSizer( hbox )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
Dialog.__init__( self, parent, 'enter height predicate' )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
InitialiseControls()
2013-03-15 02:38:12 +00:00
2013-07-31 21:26:38 +00:00
PopulateControls()
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
ArrangeControls()
( x, y ) = self.GetEffectiveMinSize()
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
self.SetInitialSize( ( x, y ) )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
wx.CallAfter( self._ok.SetFocus )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
def Limit():
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
def InitialiseControls():
self._limit = wx.SpinCtrl( self, max = 1000000 )
self._ok = wx.Button( self, id = wx.ID_OK, label='Ok' )
self._ok.SetDefault()
self._ok.Bind( wx.EVT_BUTTON, self.EventOK )
self._ok.SetForegroundColour( ( 0, 128, 0 ) )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
def PopulateControls():
limit = system_predicates[ 'limit' ]
self._limit.SetValue( limit )
def ArrangeControls():
hbox = wx.BoxSizer( wx.HORIZONTAL )
hbox.AddF( wx.StaticText( self, label='system:limit=' ), FLAGS_MIXED )
hbox.AddF( self._limit, FLAGS_MIXED )
hbox.AddF( self._ok, FLAGS_MIXED )
self.SetSizer( hbox )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
Dialog.__init__( self, parent, 'enter limit predicate' )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
InitialiseControls()
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
PopulateControls()
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
ArrangeControls()
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
( x, y ) = self.GetEffectiveMinSize()
2013-03-15 02:38:12 +00:00
2013-07-31 21:26:38 +00:00
self.SetInitialSize( ( x, y ) )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
wx.CallAfter( self._ok.SetFocus )
2013-03-15 02:38:12 +00:00
2013-07-31 21:26:38 +00:00
def Mime():
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
def InitialiseControls():
self._mime_media = wx.Choice( self, choices = [ 'image', 'application', 'audio', 'video' ] )
self._mime_media.Bind( wx.EVT_CHOICE, self.EventMime )
self._mime_type = wx.Choice( self, choices = [], size = ( 120, -1 ) )
self._ok = wx.Button( self, id = wx.ID_OK, label='Ok' )
self._ok.SetDefault()
self._ok.Bind( wx.EVT_BUTTON, self.EventOK )
self._ok.SetForegroundColour( ( 0, 128, 0 ) )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
def PopulateControls():
( media, type ) = system_predicates[ 'mime' ]
self._mime_media.SetSelection( media )
self.EventMime( None )
self._mime_type.SetSelection( type )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
def ArrangeControls():
hbox = wx.BoxSizer( wx.HORIZONTAL )
hbox.AddF( wx.StaticText( self, label='system:mime' ), FLAGS_MIXED )
hbox.AddF( self._mime_media, FLAGS_MIXED )
hbox.AddF( wx.StaticText( self, label='/' ), FLAGS_MIXED )
hbox.AddF( self._mime_type, FLAGS_MIXED )
hbox.AddF( self._ok, FLAGS_MIXED )
self.SetSizer( hbox )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
Dialog.__init__( self, parent, 'enter mime predicate' )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
InitialiseControls()
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
PopulateControls()
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
ArrangeControls()
2013-02-19 00:11:43 +00:00
( x, y ) = self.GetEffectiveMinSize()
2013-07-31 21:26:38 +00:00
self.SetInitialSize( ( x, y ) )
wx.CallAfter( self._ok.SetFocus )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
def NumTags():
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
def InitialiseControls():
self._sign = wx.Choice( self, choices=[ '<', u'\u2248', '=', '>' ] )
self._num_tags = wx.SpinCtrl( self, max = 2000 )
self._ok = wx.Button( self, id = wx.ID_OK, label='Ok' )
self._ok.SetDefault()
self._ok.Bind( wx.EVT_BUTTON, self.EventOK )
self._ok.SetForegroundColour( ( 0, 128, 0 ) )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
def PopulateControls():
( sign, num_tags ) = system_predicates[ 'num_tags' ]
self._sign.SetSelection( sign )
self._num_tags.SetValue( num_tags )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
def ArrangeControls():
hbox = wx.BoxSizer( wx.HORIZONTAL )
hbox.AddF( wx.StaticText( self, label='system:num_tags' ), FLAGS_MIXED )
hbox.AddF( self._sign, FLAGS_MIXED )
hbox.AddF( self._num_tags, FLAGS_MIXED )
hbox.AddF( self._ok, FLAGS_MIXED )
self.SetSizer( hbox )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
Dialog.__init__( self, parent, 'enter number of tags predicate' )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
InitialiseControls()
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
PopulateControls()
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
ArrangeControls()
( x, y ) = self.GetEffectiveMinSize()
self.SetInitialSize( ( x, y ) )
wx.CallAfter( self._ok.SetFocus )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
def NumWords():
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
def InitialiseControls():
self._sign = wx.Choice( self, choices=[ '<', u'\u2248', '=', '>' ] )
self._num_words = wx.SpinCtrl( self, max = 1000000 )
self._ok = wx.Button( self, id = wx.ID_OK, label='Ok' )
self._ok.SetDefault()
self._ok.Bind( wx.EVT_BUTTON, self.EventOK )
self._ok.SetForegroundColour( ( 0, 128, 0 ) )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
def PopulateControls():
( sign, num_words ) = system_predicates[ 'num_words' ]
self._sign.SetSelection( sign )
self._num_words.SetValue( num_words )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
def ArrangeControls():
hbox = wx.BoxSizer( wx.HORIZONTAL )
hbox.AddF( wx.StaticText( self, label='system:num_words' ), FLAGS_MIXED )
hbox.AddF( self._sign, FLAGS_MIXED )
hbox.AddF( self._num_words, FLAGS_MIXED )
hbox.AddF( self._ok, FLAGS_MIXED )
self.SetSizer( hbox )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
Dialog.__init__( self, parent, 'enter number of words predicate' )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
InitialiseControls()
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
PopulateControls()
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
ArrangeControls()
( x, y ) = self.GetEffectiveMinSize()
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
self.SetInitialSize( ( x, y ) )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
wx.CallAfter( self._ok.SetFocus )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
def Rating():
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
def InitialiseControls():
self._service_numerical = wx.Choice( self )
self._service_numerical.Bind( wx.EVT_CHOICE, self.EventRatingsService )
self._sign_numerical = wx.Choice( self, choices=[ '>', '<', '=', u'\u2248', '=rated', '=not rated', '=uncertain' ] )
self._value_numerical = wx.SpinCtrl( self, min = 0, max = 50000 ) # set bounds based on current service
self._first_ok = wx.Button( self, label='Ok', id = HC.LOCAL_RATING_NUMERICAL )
self._first_ok.Bind( wx.EVT_BUTTON, self.EventOK )
self._first_ok.SetForegroundColour( ( 0, 128, 0 ) )
self._service_like = wx.Choice( self )
self._service_like.Bind( wx.EVT_CHOICE, self.EventRatingsService )
self._value_like = wx.Choice( self, choices=[ 'like', 'dislike', 'rated', 'not rated' ] ) # set words based on current service
self._second_ok = wx.Button( self, label='Ok', id = HC.LOCAL_RATING_LIKE )
self._second_ok.Bind( wx.EVT_BUTTON, self.EventOK )
self._second_ok.SetForegroundColour( ( 0, 128, 0 ) )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
def PopulateControls():
self._local_numericals = HC.app.Read( 'services', ( HC.LOCAL_RATING_NUMERICAL, ) )
self._local_likes = HC.app.Read( 'services', ( HC.LOCAL_RATING_LIKE, ) )
for service in self._local_numericals: self._service_numerical.Append( service.GetServiceIdentifier().GetName(), service )
( sign, value ) = system_predicates[ 'local_rating_numerical' ]
self._sign_numerical.SetSelection( sign )
self._value_numerical.SetValue( value )
for service in self._local_likes: self._service_like.Append( service.GetServiceIdentifier().GetName(), service )
value = system_predicates[ 'local_rating_like' ]
self._value_like.SetSelection( value )
if len( self._local_numericals ) > 0: self._service_numerical.SetSelection( 0 )
if len( self._local_likes ) > 0: self._service_like.SetSelection( 0 )
self.EventRatingsService( None )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
def ArrangeControls():
vbox = wx.BoxSizer( wx.VERTICAL )
hbox = wx.BoxSizer( wx.HORIZONTAL )
hbox.AddF( wx.StaticText( self, label='system:rating:' ), FLAGS_MIXED )
hbox.AddF( self._service_numerical, FLAGS_MIXED )
hbox.AddF( self._sign_numerical, FLAGS_MIXED )
hbox.AddF( self._value_numerical, FLAGS_MIXED )
hbox.AddF( self._first_ok, FLAGS_MIXED )
vbox.AddF( hbox, FLAGS_EXPAND_SIZER_PERPENDICULAR )
hbox = wx.BoxSizer( wx.HORIZONTAL )
hbox.AddF( wx.StaticText( self, label='system:rating:' ), FLAGS_MIXED )
hbox.AddF( self._service_like, FLAGS_MIXED )
hbox.AddF( wx.StaticText( self, label='=' ), FLAGS_MIXED )
hbox.AddF( self._value_like, FLAGS_MIXED )
hbox.AddF( self._second_ok, FLAGS_MIXED )
vbox.AddF( hbox, FLAGS_EXPAND_SIZER_PERPENDICULAR )
self.SetSizer( vbox )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
Dialog.__init__( self, parent, 'enter rating predicate' )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
InitialiseControls()
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
PopulateControls()
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
ArrangeControls()
2013-02-19 00:11:43 +00:00
( x, y ) = self.GetEffectiveMinSize()
self.SetInitialSize( ( x, y ) )
2013-07-31 21:26:38 +00:00
wx.CallAfter( self._first_ok.SetFocus )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
def Ratio():
2013-02-19 00:11:43 +00:00
def InitialiseControls():
2013-07-31 21:26:38 +00:00
self._sign = wx.Choice( self, choices = [ '=', u'\u2248' ] )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
self._width = wx.SpinCtrl( self, max = 50000 )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
self._height = wx.SpinCtrl( self, max = 50000 )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
self._ok = wx.Button( self, id = wx.ID_OK, label='Ok' )
self._ok.SetDefault()
2013-07-17 20:56:13 +00:00
self._ok.Bind( wx.EVT_BUTTON, self.EventOK )
2013-02-19 00:11:43 +00:00
self._ok.SetForegroundColour( ( 0, 128, 0 ) )
2013-07-31 21:26:38 +00:00
def PopulateControls():
( sign, width, height ) = system_predicates[ 'ratio' ]
self._sign.SetSelection( sign )
self._width.SetValue( width )
self._height.SetValue( height )
def ArrangeControls():
2013-02-19 00:11:43 +00:00
hbox = wx.BoxSizer( wx.HORIZONTAL )
2013-07-31 21:26:38 +00:00
hbox.AddF( wx.StaticText( self, label = 'system:ratio' ), FLAGS_MIXED )
2013-02-19 00:11:43 +00:00
hbox.AddF( self._sign, FLAGS_MIXED )
2013-07-31 21:26:38 +00:00
hbox.AddF( self._width, FLAGS_MIXED )
hbox.AddF( wx.StaticText( self, label = ':' ), FLAGS_MIXED )
hbox.AddF( self._height, FLAGS_MIXED )
2013-02-19 00:11:43 +00:00
hbox.AddF( self._ok, FLAGS_MIXED )
self.SetSizer( hbox )
2013-07-31 21:26:38 +00:00
Dialog.__init__( self, parent, 'enter ratio predicate' )
2013-02-19 00:11:43 +00:00
InitialiseControls()
2013-07-31 21:26:38 +00:00
PopulateControls()
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
ArrangeControls()
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
( x, y ) = self.GetEffectiveMinSize()
self.SetInitialSize( ( x, y ) )
wx.CallAfter( self._ok.SetFocus )
def Size():
2013-02-19 00:11:43 +00:00
def InitialiseControls():
2013-07-31 21:26:38 +00:00
self._sign = wx.Choice( self, choices = [ '<', u'\u2248', '=', '>' ] )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
self._size = wx.SpinCtrl( self, max = 1048576 )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
self._unit = wx.Choice( self, choices = [ 'B', 'KB', 'MB', 'GB' ] )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
self._ok = wx.Button( self, id = wx.ID_OK, label='Ok' )
self._ok.SetDefault()
2013-07-17 20:56:13 +00:00
self._ok.Bind( wx.EVT_BUTTON, self.EventOK )
2013-02-19 00:11:43 +00:00
self._ok.SetForegroundColour( ( 0, 128, 0 ) )
2013-07-31 21:26:38 +00:00
def PopulateControls():
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
( sign, size, unit ) = system_predicates[ 'size' ]
2013-04-03 20:56:07 +00:00
2013-07-31 21:26:38 +00:00
self._sign.SetSelection( sign )
2013-04-03 20:56:07 +00:00
2013-07-31 21:26:38 +00:00
self._size.SetValue( size )
2013-04-03 20:56:07 +00:00
2013-07-31 21:26:38 +00:00
self._unit.SetSelection( unit )
2013-04-03 20:56:07 +00:00
2013-07-31 21:26:38 +00:00
def ArrangeControls():
2013-04-03 20:56:07 +00:00
hbox = wx.BoxSizer( wx.HORIZONTAL )
2013-07-31 21:26:38 +00:00
hbox.AddF( wx.StaticText( self, label='system:size' ), FLAGS_MIXED )
2013-04-03 20:56:07 +00:00
hbox.AddF( self._sign, FLAGS_MIXED )
2013-07-31 21:26:38 +00:00
hbox.AddF( self._size, FLAGS_MIXED )
hbox.AddF( self._unit, FLAGS_MIXED )
2013-04-03 20:56:07 +00:00
hbox.AddF( self._ok, FLAGS_MIXED )
self.SetSizer( hbox )
2013-07-31 21:26:38 +00:00
Dialog.__init__( self, parent, 'enter size predicate' )
2013-04-03 20:56:07 +00:00
InitialiseControls()
2013-07-31 21:26:38 +00:00
PopulateControls()
2013-04-03 20:56:07 +00:00
2013-07-31 21:26:38 +00:00
ArrangeControls()
2013-04-03 20:56:07 +00:00
2013-07-31 21:26:38 +00:00
( x, y ) = self.GetEffectiveMinSize()
self.SetInitialSize( ( x, y ) )
wx.CallAfter( self._ok.SetFocus )
def Width():
2013-02-19 00:11:43 +00:00
def InitialiseControls():
2013-07-31 21:26:38 +00:00
self._sign = wx.Choice( self, choices = [ '<', u'\u2248', '=', '>' ] )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
self._width = wx.SpinCtrl( self, max = 200000 )
self._ok = wx.Button( self, id = wx.ID_OK, label='Ok' )
self._ok.SetDefault()
2013-07-17 20:56:13 +00:00
self._ok.Bind( wx.EVT_BUTTON, self.EventOK )
2013-02-19 00:11:43 +00:00
self._ok.SetForegroundColour( ( 0, 128, 0 ) )
2013-07-31 21:26:38 +00:00
def PopulateControls():
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
( sign, width ) = system_predicates[ 'width' ]
2013-02-19 00:11:43 +00:00
self._sign.SetSelection( sign )
2013-07-31 21:26:38 +00:00
self._width.SetValue( width )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
def ArrangeControls():
2013-02-19 00:11:43 +00:00
hbox = wx.BoxSizer( wx.HORIZONTAL )
2013-07-31 21:26:38 +00:00
hbox.AddF( wx.StaticText( self, label='system:width' ), FLAGS_MIXED )
2013-02-19 00:11:43 +00:00
hbox.AddF( self._sign, FLAGS_MIXED )
2013-07-31 21:26:38 +00:00
hbox.AddF( self._width, FLAGS_MIXED )
2013-02-19 00:11:43 +00:00
hbox.AddF( self._ok, FLAGS_MIXED )
self.SetSizer( hbox )
2013-07-31 21:26:38 +00:00
Dialog.__init__( self, parent, 'enter width predicate' )
2013-02-19 00:11:43 +00:00
InitialiseControls()
2013-07-31 21:26:38 +00:00
PopulateControls()
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
ArrangeControls()
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
( x, y ) = self.GetEffectiveMinSize()
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
self.SetInitialSize( ( x, y ) )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
wx.CallAfter( self._ok.SetFocus )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
def SimilarTo():
2013-02-19 00:11:43 +00:00
def InitialiseControls():
2013-07-31 21:26:38 +00:00
self._hash = wx.TextCtrl( self )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
self._max_hamming = wx.SpinCtrl( self, max = 256 )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
self._ok = wx.Button( self, id = wx.ID_OK, label='Ok' )
self._ok.SetDefault()
2013-07-17 20:56:13 +00:00
self._ok.Bind( wx.EVT_BUTTON, self.EventOK )
2013-02-19 00:11:43 +00:00
self._ok.SetForegroundColour( ( 0, 128, 0 ) )
2013-07-31 21:26:38 +00:00
def PopulateControls():
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
self._hash.SetValue( 'enter hash' )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
self._max_hamming.SetValue( 5 )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
def ArrangeControls():
2013-02-19 00:11:43 +00:00
hbox = wx.BoxSizer( wx.HORIZONTAL )
2013-07-31 21:26:38 +00:00
hbox.AddF( wx.StaticText( self, label='system:similar_to' ), FLAGS_MIXED )
hbox.AddF( self._hash, FLAGS_MIXED )
hbox.AddF( wx.StaticText( self, label=u'\u2248' ), FLAGS_MIXED )
hbox.AddF( self._max_hamming, FLAGS_MIXED )
2013-02-19 00:11:43 +00:00
hbox.AddF( self._ok, FLAGS_MIXED )
self.SetSizer( hbox )
2013-07-31 21:26:38 +00:00
Dialog.__init__( self, parent, 'enter similar to predicate' )
2013-02-19 00:11:43 +00:00
InitialiseControls()
2013-07-31 21:26:38 +00:00
PopulateControls()
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
ArrangeControls()
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
( x, y ) = self.GetEffectiveMinSize()
2013-03-27 20:02:51 +00:00
2013-07-31 21:26:38 +00:00
self.SetInitialSize( ( x, y ) )
2013-03-27 20:02:51 +00:00
2013-07-31 21:26:38 +00:00
wx.CallAfter( self._ok.SetFocus )
2013-03-27 20:02:51 +00:00
2013-07-31 21:26:38 +00:00
options = HC.app.Read( 'options' ) # have to do this, since dialog.__init__ hasn't fired yet
system_predicates = options[ 'file_system_predicates' ]
self._type = type
if self._type == HC.SYSTEM_PREDICATE_TYPE_AGE: Age()
elif self._type == HC.SYSTEM_PREDICATE_TYPE_DURATION: Duration()
elif self._type == HC.SYSTEM_PREDICATE_TYPE_HASH: Hash()
elif self._type == HC.SYSTEM_PREDICATE_TYPE_HEIGHT: Height()
elif self._type == HC.SYSTEM_PREDICATE_TYPE_LIMIT: Limit()
elif self._type == HC.SYSTEM_PREDICATE_TYPE_MIME: Mime()
elif self._type == HC.SYSTEM_PREDICATE_TYPE_NUM_TAGS: NumTags()
elif self._type == HC.SYSTEM_PREDICATE_TYPE_RATING: Rating()
elif self._type == HC.SYSTEM_PREDICATE_TYPE_RATIO: Ratio()
elif self._type == HC.SYSTEM_PREDICATE_TYPE_SIZE: Size()
elif self._type == HC.SYSTEM_PREDICATE_TYPE_WIDTH: Width()
elif self._type == HC.SYSTEM_PREDICATE_TYPE_SIMILAR_TO: SimilarTo()
elif self._type == HC.SYSTEM_PREDICATE_TYPE_NUM_WORDS: NumWords()
elif self._type == HC.SYSTEM_PREDICATE_TYPE_FILE_SERVICE: FileService()
def EventMime( self, event ):
media = self._mime_media.GetStringSelection()
self._mime_type.Clear()
if media == 'image':
2013-02-19 00:11:43 +00:00
self._mime_type.Append( 'any', HC.IMAGES )
self._mime_type.Append( 'jpeg', HC.IMAGE_JPEG )
self._mime_type.Append( 'png', HC.IMAGE_PNG )
self._mime_type.Append( 'gif', HC.IMAGE_GIF )
elif media == 'application':
2013-03-15 02:38:12 +00:00
self._mime_type.Append( 'any', HC.APPLICATIONS )
self._mime_type.Append( 'pdf', HC.APPLICATION_PDF )
2013-02-19 00:11:43 +00:00
self._mime_type.Append( 'x-shockwave-flash', HC.APPLICATION_FLASH )
2013-07-10 20:25:57 +00:00
elif media == 'audio':
2013-07-17 20:56:13 +00:00
self._mime_type.Append( 'any', HC.AUDIO )
2013-07-10 20:25:57 +00:00
self._mime_type.Append( 'mp3', HC.AUDIO_MP3 )
2013-07-17 20:56:13 +00:00
self._mime_type.Append( 'ogg', HC.AUDIO_OGG )
self._mime_type.Append( 'flac', HC.AUDIO_FLAC )
2013-07-10 20:25:57 +00:00
2013-02-19 00:11:43 +00:00
elif media == 'video':
self._mime_type.Append( 'x-flv', HC.VIDEO_FLV )
self._mime_type.SetSelection( 0 )
2013-07-17 20:56:13 +00:00
def EventOK( self, event ):
2013-02-19 00:11:43 +00:00
2013-06-19 20:25:06 +00:00
if self._type == HC.SYSTEM_PREDICATE_TYPE_AGE: info = ( self._sign.GetStringSelection(), self._years.GetValue(), self._months.GetValue(), self._days.GetValue(), self._hours.GetValue() )
2013-03-27 20:02:51 +00:00
elif self._type == HC.SYSTEM_PREDICATE_TYPE_DURATION: info = ( self._sign.GetStringSelection(), self._duration_s.GetValue() * 1000 + self._duration_ms.GetValue() )
elif self._type == HC.SYSTEM_PREDICATE_TYPE_HASH:
2013-07-17 20:56:13 +00:00
hex_filter = lambda c: c in string.hexdigits
2013-03-27 20:02:51 +00:00
2013-08-07 22:25:18 +00:00
hash = filter( hex_filter, self._hash.GetValue().lower() )
2013-03-27 20:02:51 +00:00
if len( hash ) == 0: hash == '00'
elif len( hash ) % 2 == 1: hash += '0' # since we are later decoding to byte
info = hash.decode( 'hex' )
elif self._type == HC.SYSTEM_PREDICATE_TYPE_HEIGHT: info = ( self._sign.GetStringSelection(), self._height.GetValue() )
elif self._type == HC.SYSTEM_PREDICATE_TYPE_LIMIT: info = self._limit.GetValue()
elif self._type == HC.SYSTEM_PREDICATE_TYPE_MIME: info = self._mime_type.GetClientData( self._mime_type.GetSelection() )
elif self._type == HC.SYSTEM_PREDICATE_TYPE_NUM_TAGS: info = ( self._sign.GetStringSelection(), self._num_tags.GetValue() )
elif self._type == HC.SYSTEM_PREDICATE_TYPE_NUM_WORDS: info = ( self._sign.GetStringSelection(), self._num_words.GetValue() )
elif self._type == HC.SYSTEM_PREDICATE_TYPE_RATING:
2013-02-19 00:11:43 +00:00
id = event.GetId()
2013-03-27 20:02:51 +00:00
if id == HC.LOCAL_RATING_LIKE:
service_identifier = self._service_like.GetClientData( self._service_like.GetSelection() ).GetServiceIdentifier()
operator = '='
selection = self._value_like.GetSelection()
if selection == 0: value = '1'
elif selection == 1: value = '0'
elif selection == 2: value = 'rated'
elif selection == 3: value = 'not rated'
info = ( service_identifier, operator, value )
elif id == HC.LOCAL_RATING_NUMERICAL:
service = self._service_numerical.GetClientData( self._service_numerical.GetSelection() )
service_identifier = service.GetServiceIdentifier()
operator = self._sign_numerical.GetStringSelection()
if operator in ( '=rated', '=not rated', '=uncertain' ):
value = operator[1:]
operator = '='
else:
( lower, upper ) = service.GetExtraInfo()
value_raw = self._value_numerical.GetValue()
value = float( value_raw - lower ) / float( upper - lower )
info = ( service_identifier, operator, value )
elif self._type == HC.SYSTEM_PREDICATE_TYPE_RATIO: info = ( self._sign.GetStringSelection(), float( ( self._width.GetValue() ) / float( self._height.GetValue() ) ) )
elif self._type == HC.SYSTEM_PREDICATE_TYPE_SIZE: info = ( self._sign.GetStringSelection(), self._size.GetValue(), HC.ConvertUnitToInteger( self._unit.GetStringSelection() ) )
elif self._type == HC.SYSTEM_PREDICATE_TYPE_WIDTH: info = ( self._sign.GetStringSelection(), self._width.GetValue() )
elif self._type == HC.SYSTEM_PREDICATE_TYPE_SIMILAR_TO:
2013-07-17 20:56:13 +00:00
hex_filter = lambda c: c in string.hexdigits
2013-03-27 20:02:51 +00:00
2013-07-17 20:56:13 +00:00
hash = filter( hex_filter, lower( self._hash.GetValue() ) )
2013-03-27 20:02:51 +00:00
if len( hash ) == 0: hash == '00'
elif len( hash ) % 2 == 1: hash += '0' # since we are later decoding to byte
info = ( hash.decode( 'hex' ), self._max_hamming.GetValue() )
2013-02-19 00:11:43 +00:00
2013-04-03 20:56:07 +00:00
elif self._type == HC.SYSTEM_PREDICATE_TYPE_FILE_SERVICE: info = ( self._sign.GetClientData( self._sign.GetSelection() ), self._current_pending.GetClientData( self._current_pending.GetSelection() ), self._file_service_identifier.GetClientData( self._file_service_identifier.GetSelection() ) )
2013-02-19 00:11:43 +00:00
2013-03-27 20:02:51 +00:00
self._predicate = HC.Predicate( HC.PREDICATE_TYPE_SYSTEM, ( self._type, info ), None )
2013-02-19 00:11:43 +00:00
self.EndModal( wx.ID_OK )
def EventRatingsService( self, event ):
try:
service = self._service_numerical.GetClientData( self._service_numerical.GetSelection() )
( min, max ) = service.GetExtraInfo()
self._value_numerical.SetRange( min, max )
service = self._service_like.GetClientData( self._service_like.GetSelection() )
except: pass
try:
( like, dislike ) = service.GetExtraInfo()
selection = self._value_like.GetSelection()
self._value_like.SetString( 0, like )
self._value_like.SetString( 1, dislike )
self._value_like.SetSelection( selection )
except: pass
2013-03-27 20:02:51 +00:00
def GetPredicate( self ): return self._predicate
2013-02-19 00:11:43 +00:00
class DialogInputMessageSystemPredicate( Dialog ):
def __init__( self, parent, type ):
def Age():
def InitialiseControls():
self._sign = wx.Choice( self, choices=[ '<', u'\u2248', '>' ] )
2013-07-31 21:26:38 +00:00
self._years = wx.SpinCtrl( self, max = 30 )
self._months = wx.SpinCtrl( self, max = 60 )
self._days = wx.SpinCtrl( self, max = 90 )
2013-02-19 00:11:43 +00:00
self._ok = wx.Button( self, label='Ok' )
2013-07-17 20:56:13 +00:00
self._ok.Bind( wx.EVT_BUTTON, self.EventOK )
2013-02-19 00:11:43 +00:00
self._ok.SetForegroundColour( ( 0, 128, 0 ) )
2013-07-31 21:26:38 +00:00
def PopulateControls():
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
self._sign.SetSelection( 0 )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
self._years.SetValue( 0 )
self._months.SetValue( 0 )
self._days.SetValue( 7 )
def ArrangeControls():
hbox = wx.BoxSizer( wx.HORIZONTAL )
hbox.AddF( wx.StaticText( self, label='system:age' ), FLAGS_MIXED )
2013-02-19 00:11:43 +00:00
hbox.AddF( self._sign, FLAGS_MIXED )
hbox.AddF( self._years, FLAGS_MIXED )
hbox.AddF( wx.StaticText( self, label='years' ), FLAGS_MIXED )
hbox.AddF( self._months, FLAGS_MIXED )
hbox.AddF( wx.StaticText( self, label='months' ), FLAGS_MIXED )
hbox.AddF( self._days, FLAGS_MIXED )
hbox.AddF( wx.StaticText( self, label='days' ), FLAGS_MIXED )
hbox.AddF( self._ok, FLAGS_MIXED )
self.SetSizer( hbox )
Dialog.__init__( self, parent, 'enter age predicate' )
InitialiseControls()
2013-07-31 21:26:38 +00:00
ArrangeControls()
( x, y ) = self.GetEffectiveMinSize()
self.SetInitialSize( ( x, y ) )
wx.CallAfter( self._ok.SetFocus )
2013-02-19 00:11:43 +00:00
def From():
2013-07-24 20:26:00 +00:00
def InitialiseControls():
2013-03-23 17:57:29 +00:00
2013-07-24 20:26:00 +00:00
contact_names = HC.app.Read( 'contact_names' )
2013-03-23 17:57:29 +00:00
2013-07-24 20:26:00 +00:00
self._contact = wx.Choice( self, choices=contact_names )
2013-03-23 17:57:29 +00:00
2013-07-24 20:26:00 +00:00
self._ok = wx.Button( self, label='Ok' )
self._ok.Bind( wx.EVT_BUTTON, self.EventOK )
self._ok.SetForegroundColour( ( 0, 128, 0 ) )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
def PopulateControls():
self._contact.SetSelection( 0 )
def ArrangeControls():
2013-03-23 17:57:29 +00:00
2013-07-24 20:26:00 +00:00
hbox = wx.BoxSizer( wx.HORIZONTAL )
2013-03-23 17:57:29 +00:00
2013-07-24 20:26:00 +00:00
hbox.AddF( wx.StaticText( self, label='system:from' ), FLAGS_MIXED )
hbox.AddF( self._contact, FLAGS_MIXED )
hbox.AddF( self._ok, FLAGS_MIXED )
2013-03-23 17:57:29 +00:00
2013-07-24 20:26:00 +00:00
self.SetSizer( hbox )
2013-03-23 17:57:29 +00:00
2013-02-19 00:11:43 +00:00
2013-07-24 20:26:00 +00:00
Dialog.__init__( self, parent, 'enter from predicate' )
2013-02-19 00:11:43 +00:00
2013-07-24 20:26:00 +00:00
InitialiseControls()
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
ArrangeControls()
( x, y ) = self.GetEffectiveMinSize()
self.SetInitialSize( ( x, y ) )
wx.CallAfter( self._ok.SetFocus )
2013-06-12 22:53:31 +00:00
2013-07-24 20:26:00 +00:00
def StartedBy():
2013-02-19 00:11:43 +00:00
2013-07-24 20:26:00 +00:00
def InitialiseControls():
2013-03-23 17:57:29 +00:00
2013-07-24 20:26:00 +00:00
contact_names = HC.app.Read( 'contact_names' )
2013-03-23 17:57:29 +00:00
2013-07-31 21:26:38 +00:00
self._contact = wx.Choice( self, choices = contact_names )
2013-07-24 20:26:00 +00:00
self._ok = wx.Button( self, label='Ok' )
self._ok.Bind( wx.EVT_BUTTON, self.EventOK )
self._ok.SetForegroundColour( ( 0, 128, 0 ) )
2013-03-23 17:57:29 +00:00
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
def PopulateControls():
self._contact.SetSelection( 0 )
def ArrangeControls():
2013-02-19 00:11:43 +00:00
2013-07-24 20:26:00 +00:00
hbox = wx.BoxSizer( wx.HORIZONTAL )
2013-05-15 18:58:14 +00:00
2013-07-24 20:26:00 +00:00
hbox.AddF( wx.StaticText( self, label='system:started_by' ), FLAGS_MIXED )
hbox.AddF( self._contact, FLAGS_MIXED )
hbox.AddF( self._ok, FLAGS_MIXED )
2013-05-15 18:58:14 +00:00
2013-07-24 20:26:00 +00:00
self.SetSizer( hbox )
2013-05-15 18:58:14 +00:00
2013-07-24 20:26:00 +00:00
Dialog.__init__( self, parent, 'enter started by predicate' )
InitialiseControls()
2013-07-31 21:26:38 +00:00
ArrangeControls()
( x, y ) = self.GetEffectiveMinSize()
self.SetInitialSize( ( x, y ) )
wx.CallAfter( self._ok.SetFocus )
2013-07-24 20:26:00 +00:00
2013-05-15 18:58:14 +00:00
2013-07-24 20:26:00 +00:00
def To():
2013-05-15 18:58:14 +00:00
2013-07-24 20:26:00 +00:00
def InitialiseControls():
contact_names = [ name for name in HC.app.Read( 'contact_names' ) if name != 'Anonymous' ]
2013-05-15 18:58:14 +00:00
2013-07-31 21:26:38 +00:00
self._contact = wx.Choice( self, choices = contact_names )
2013-05-15 18:58:14 +00:00
2013-07-24 20:26:00 +00:00
self._ok = wx.Button( self, label='Ok' )
self._ok.Bind( wx.EVT_BUTTON, self.EventOK )
self._ok.SetForegroundColour( ( 0, 128, 0 ) )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
def PopulateControls():
self._contact.SetSelection( 0 )
def ArrangeControls():
2013-02-19 00:11:43 +00:00
2013-07-24 20:26:00 +00:00
hbox = wx.BoxSizer( wx.HORIZONTAL )
2013-02-19 00:11:43 +00:00
2013-07-24 20:26:00 +00:00
hbox.AddF( wx.StaticText( self, label='system:to' ), FLAGS_MIXED )
hbox.AddF( self._contact, FLAGS_MIXED )
hbox.AddF( self._ok, FLAGS_MIXED )
2013-03-23 17:57:29 +00:00
2013-07-24 20:26:00 +00:00
self.SetSizer( hbox )
2013-03-23 17:57:29 +00:00
2013-02-19 00:11:43 +00:00
2013-07-24 20:26:00 +00:00
Dialog.__init__( self, parent, 'enter to predicate' )
InitialiseControls()
2013-07-31 21:26:38 +00:00
ArrangeControls()
( x, y ) = self.GetEffectiveMinSize()
self.SetInitialSize( ( x, y ) )
wx.CallAfter( self._ok.SetFocus )
2013-02-19 00:11:43 +00:00
2013-07-24 20:26:00 +00:00
def NumAttachments():
2013-02-19 00:11:43 +00:00
2013-07-24 20:26:00 +00:00
def InitialiseControls():
2013-03-23 17:57:29 +00:00
2013-07-24 20:26:00 +00:00
self._sign = wx.Choice( self, choices=[ '<', '=', '>' ] )
2013-03-23 17:57:29 +00:00
2013-07-31 21:26:38 +00:00
self._num_attachments = wx.SpinCtrl( self, max = 2000 )
2013-07-24 20:26:00 +00:00
self._ok = wx.Button( self, label='Ok' )
self._ok.Bind( wx.EVT_BUTTON, self.EventOK )
self._ok.SetForegroundColour( ( 0, 128, 0 ) )
2013-03-23 17:57:29 +00:00
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
def PopulateControls():
self._sign.SetSelection( 0 )
self._num_attachments.SetValue( 4 )
def ArrangeControls():
2013-03-23 17:57:29 +00:00
2013-07-24 20:26:00 +00:00
hbox = wx.BoxSizer( wx.HORIZONTAL )
2013-02-19 00:11:43 +00:00
2013-07-24 20:26:00 +00:00
hbox.AddF( wx.StaticText( self, label='system:numattachments' ), FLAGS_MIXED )
hbox.AddF( self._sign, FLAGS_MIXED )
hbox.AddF( self._num_attachments, FLAGS_MIXED )
hbox.AddF( self._ok, FLAGS_MIXED )
2013-03-23 17:57:29 +00:00
2013-07-24 20:26:00 +00:00
self.SetSizer( hbox )
2013-02-19 00:11:43 +00:00
2013-07-24 20:26:00 +00:00
Dialog.__init__( self, parent, 'enter number of attachments predicate' )
2013-03-23 17:57:29 +00:00
2013-07-24 20:26:00 +00:00
InitialiseControls()
2013-03-23 17:57:29 +00:00
2013-07-31 21:26:38 +00:00
PopulateControls()
ArrangeControls()
( x, y ) = self.GetEffectiveMinSize()
self.SetInitialSize( ( x, y ) )
wx.CallAfter( self._ok.SetFocus )
self._type = type
if self._type == 'system:age': Age()
elif self._type == 'system:started_by': StartedBy()
elif self._type == 'system:from': From()
elif self._type == 'system:to': To()
elif self._type == 'system:numattachments': NumAttachments()
def EventOK( self, event ): self.EndModal( wx.ID_OK )
def GetString( self ):
if self._type == 'system:age': return 'system:age' + self._sign.GetStringSelection() + HC.u( self._years.GetValue() ) + 'y' + HC.u( self._months.GetValue() ) + 'm' + HC.u( self._days.GetValue() ) + 'd'
elif self._type == 'system:started_by': return 'system:started_by=' + self._contact.GetStringSelection()
elif self._type == 'system:from': return 'system:from=' + self._contact.GetStringSelection()
elif self._type == 'system:to': return 'system:to=' + self._contact.GetStringSelection()
elif self._type == 'system:numattachments': return 'system:numattachments' + self._sign.GetStringSelection() + HC.u( self._num_attachments.GetValue() )
class DialogInputNamespaceRegex( Dialog ):
def __init__( self, parent, namespace = '', regex = '' ):
def InitialiseControls():
self._namespace = wx.TextCtrl( self )
self._regex = wx.TextCtrl( self )
self._shortcuts = ClientGUICommon.RegexButton( self )
self._ok = wx.Button( self, label='Ok' )
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.Bind( wx.EVT_BUTTON, self.EventCancel )
self._cancel.SetForegroundColour( ( 128, 0, 0 ) )
def PopulateControls():
self._namespace.SetValue( namespace )
self._regex.SetValue( regex )
def ArrangeControls():
control_box = wx.BoxSizer( wx.HORIZONTAL )
control_box.AddF( self._namespace, FLAGS_EXPAND_BOTH_WAYS )
control_box.AddF( wx.StaticText( self, label = ':' ), FLAGS_MIXED )
control_box.AddF( self._regex, FLAGS_EXPAND_BOTH_WAYS )
b_box = wx.BoxSizer( wx.HORIZONTAL )
b_box.AddF( self._ok, FLAGS_MIXED )
b_box.AddF( self._cancel, FLAGS_MIXED )
vbox = wx.BoxSizer( wx.VERTICAL )
vbox.AddF( control_box, FLAGS_EXPAND_SIZER_PERPENDICULAR )
vbox.AddF( self._shortcuts, FLAGS_LONE_BUTTON )
vbox.AddF( b_box, FLAGS_BUTTON_SIZERS )
self.SetSizer( vbox )
( x, y ) = self.GetEffectiveMinSize()
self.SetInitialSize( ( x, y ) )
Dialog.__init__( self, parent, 'configure quick namespace' )
InitialiseControls()
PopulateControls()
ArrangeControls()
wx.CallAfter( self._ok.SetFocus )
def EventCancel( self, event ): self.EndModal( wx.ID_CANCEL )
def EventOK( self, event ): self.EndModal( wx.ID_OK )
def GetInfo( self ):
namespace = self._namespace.GetValue()
regex = self._regex.GetValue()
return ( namespace, regex )
class DialogInputNewAccounts( Dialog ):
def __init__( self, parent, service_identifier ):
def InitialiseControls():
self._num = wx.SpinCtrl( self, min=1, max=10000 )
self._account_types = wx.Choice( self, size = ( 400, -1 ) )
self._expiration = wx.Choice( self )
self._ok = wx.Button( self, label='Ok' )
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.Bind( wx.EVT_BUTTON, self.EventCancel )
self._cancel.SetForegroundColour( ( 128, 0, 0 ) )
def PopulateControls():
self._num.SetValue( 1 )
service = HC.app.Read( 'service', service_identifier )
connection = service.GetConnection()
account_types = connection.Get( 'account_types' )
for account_type in account_types: self._account_types.Append( account_type.ConvertToString(), account_type )
self._account_types.SetSelection( 0 ) # admin
for ( str, value ) in HC.expirations: self._expiration.Append( str, value )
self._expiration.SetSelection( 3 ) # one year
def ArrangeControls():
ctrl_box = wx.BoxSizer( wx.HORIZONTAL )
ctrl_box.AddF( self._num, FLAGS_SMALL_INDENT )
ctrl_box.AddF( self._account_types, FLAGS_SMALL_INDENT )
ctrl_box.AddF( self._expiration, FLAGS_SMALL_INDENT )
b_box = wx.BoxSizer( wx.HORIZONTAL )
b_box.AddF( self._ok, FLAGS_MIXED )
b_box.AddF( self._cancel, FLAGS_MIXED )
vbox = wx.BoxSizer( wx.VERTICAL )
vbox.AddF( ctrl_box, FLAGS_EXPAND_SIZER_PERPENDICULAR )
vbox.AddF( b_box, FLAGS_BUTTON_SIZERS )
self.SetSizer( vbox )
( x, y ) = self.GetEffectiveMinSize()
self.SetInitialSize( ( x, y ) )
Dialog.__init__( self, parent, 'configure new accounts' )
self._service_identifier = service_identifier
InitialiseControls()
PopulateControls()
ArrangeControls()
wx.CallAfter( self._ok.SetFocus )
def EventCancel( self, event ): self.EndModal( wx.ID_CANCEL )
def EventOK( self, event ):
num = self._num.GetValue()
account_type = self._account_types.GetClientData( self._account_types.GetSelection() )
title = account_type.GetTitle()
expiration = self._expiration.GetClientData( self._expiration.GetSelection() )
service = HC.app.Read( 'service', self._service_identifier )
try:
connection = service.GetConnection()
if expiration is None: access_keys = connection.Get( 'registration_keys', num = num, title = title )
else: access_keys = connection.Get( 'registration_keys', num = num, title = title, expiration = expiration )
except Exception as e: wx.MessageBox( HC.u( e ) )
self.EndModal( wx.ID_OK )
class DialogInputNewAccountType( Dialog ):
def __init__( self, parent, account_type = None ):
def InitialiseControls():
self._title = wx.TextCtrl( self )
self._permissions_panel = ClientGUICommon.StaticBox( self, 'permissions' )
self._permissions = wx.ListBox( self._permissions_panel )
self._permission_choice = wx.Choice( self._permissions_panel )
self._add_permission = wx.Button( self._permissions_panel, label = 'add' )
self._add_permission.Bind( wx.EVT_BUTTON, self.EventAddPermission )
self._remove_permission = wx.Button( self._permissions_panel, label = 'remove' )
self._remove_permission.Bind( wx.EVT_BUTTON, self.EventRemovePermission )
self._max_num_mb = ClientGUICommon.NoneableSpinCtrl( self, 'max monthly data (MB)', multiplier = 1048576 )
self._max_num_mb.SetValue( max_num_bytes )
self._max_num_requests = ClientGUICommon.NoneableSpinCtrl( self, 'max monthly requests' )
self._max_num_requests.SetValue( max_num_requests )
self._apply = wx.Button( self, label='apply' )
self._apply.Bind( wx.EVT_BUTTON, self.EventOK )
self._apply.SetForegroundColour( ( 0, 128, 0 ) )
self._cancel = wx.Button( self, id = wx.ID_CANCEL, label='cancel' )
self._cancel.Bind( wx.EVT_BUTTON, self.EventCancel )
self._cancel.SetForegroundColour( ( 128, 0, 0 ) )
def PopulateControls():
self._title.SetValue( title )
for permission in permissions: self._permissions.Append( HC.permissions_string_lookup[ permission ], permission )
for permission in HC.CREATABLE_PERMISSIONS: self._permission_choice.Append( HC.permissions_string_lookup[ permission ], permission )
self._permission_choice.SetSelection( 0 )
def ArrangeControls():
t_box = wx.BoxSizer( wx.HORIZONTAL )
t_box.AddF( wx.StaticText( self, label = 'title: ' ), FLAGS_SMALL_INDENT )
t_box.AddF( self._title, FLAGS_EXPAND_BOTH_WAYS )
perm_buttons_box = wx.BoxSizer( wx.HORIZONTAL )
perm_buttons_box.AddF( self._permission_choice, FLAGS_MIXED )
perm_buttons_box.AddF( self._add_permission, FLAGS_MIXED )
perm_buttons_box.AddF( self._remove_permission, FLAGS_MIXED )
self._permissions_panel.AddF( self._permissions, FLAGS_EXPAND_BOTH_WAYS )
self._permissions_panel.AddF( perm_buttons_box, FLAGS_EXPAND_SIZER_PERPENDICULAR )
b_box = wx.BoxSizer( wx.HORIZONTAL )
b_box.AddF( self._apply, FLAGS_MIXED )
b_box.AddF( self._cancel, FLAGS_MIXED )
vbox = wx.BoxSizer( wx.VERTICAL )
vbox.AddF( t_box, FLAGS_EXPAND_SIZER_PERPENDICULAR )
vbox.AddF( self._permissions_panel, FLAGS_EXPAND_PERPENDICULAR )
vbox.AddF( self._max_num_mb, FLAGS_EXPAND_PERPENDICULAR )
vbox.AddF( self._max_num_requests, FLAGS_EXPAND_PERPENDICULAR )
vbox.AddF( b_box, FLAGS_BUTTON_SIZERS )
self.SetSizer( vbox )
( x, y ) = self.GetEffectiveMinSize()
self.SetInitialSize( ( 800, y ) )
if account_type is None:
title = ''
permissions = [ HC.GET_DATA ]
max_num_bytes = 104857600
max_num_requests = 1000
else:
title = account_type.GetTitle()
permissions = account_type.GetPermissions()
( max_num_bytes, max_num_requests ) = account_type.GetMaxMonthlyData()
Dialog.__init__( self, parent, 'edit account type' )
InitialiseControls()
PopulateControls()
ArrangeControls()
wx.CallAfter( self._apply.SetFocus )
def EventAddPermission( self, event ):
selection = self._permission_choice.GetSelection()
if selection != wx.NOT_FOUND:
permission = self._permission_choice.GetClientData( selection )
existing_permissions = [ self._permissions.GetClientData( i ) for i in range( self._permissions.GetCount() ) ]
if permission not in existing_permissions: self._permissions.Append( HC.permissions_string_lookup[ permission ], permission )
def EventCancel( self, event ): self.EndModal( wx.ID_CANCEL )
def EventCheckBox( self, event ):
if self._max_num_requests_checkbox.GetValue(): self._max_num_requests.Disable()
else: self._max_num_requests.Enable()
def EventOK( self, event ): self.EndModal( wx.ID_OK )
def EventRemovePermission( self, event ):
selection = self._permissions.GetSelection()
if selection != wx.NOT_FOUND: self._permissions.Delete( selection )
def GetAccountType( self ):
title = self._title.GetValue()
permissions = [ self._permissions.GetClientData( i ) for i in range( self._permissions.GetCount() ) ]
max_num_bytes = self._max_num_mb.GetValue()
max_num_requests = self._max_num_requests.GetValue()
return HC.AccountType( title, permissions, ( max_num_bytes, max_num_requests ) )
class DialogInputNewFormField( Dialog ):
def __init__( self, parent, form_field = None ):
def InitialiseControls():
self._name = wx.TextCtrl( self )
self._type = wx.Choice( self )
self._default = wx.TextCtrl( self )
self._editable = wx.CheckBox( self )
self._ok = wx.Button( self, label='Ok' )
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.Bind( wx.EVT_BUTTON, self.EventCancel )
self._cancel.SetForegroundColour( ( 128, 0, 0 ) )
def PopulateControls():
self._name.SetValue( name )
for temp_type in CC.FIELDS: self._type.Append( CC.field_string_lookup[ temp_type ], temp_type )
self._type.Select( type )
self._default.SetValue( default )
self._editable.SetValue( editable )
def ArrangeControls():
gridbox = wx.FlexGridSizer( 0, 2 )
gridbox.AddGrowableCol( 1, 1 )
gridbox.AddF( wx.StaticText( self, label='name' ), FLAGS_MIXED )
gridbox.AddF( self._name, FLAGS_EXPAND_BOTH_WAYS )
gridbox.AddF( wx.StaticText( self, label='type' ), FLAGS_MIXED )
gridbox.AddF( self._type, FLAGS_EXPAND_BOTH_WAYS )
gridbox.AddF( wx.StaticText( self, label='default' ), FLAGS_MIXED )
gridbox.AddF( self._default, FLAGS_EXPAND_BOTH_WAYS )
gridbox.AddF( wx.StaticText( self, label='editable' ), FLAGS_MIXED )
gridbox.AddF( self._editable, FLAGS_EXPAND_BOTH_WAYS )
b_box = wx.BoxSizer( wx.HORIZONTAL )
b_box.AddF( self._ok, FLAGS_MIXED )
b_box.AddF( self._cancel, FLAGS_MIXED )
vbox = wx.BoxSizer( wx.VERTICAL )
vbox.AddF( gridbox, FLAGS_EXPAND_SIZER_PERPENDICULAR )
vbox.AddF( b_box, FLAGS_BUTTON_SIZERS )
self.SetSizer( vbox )
( x, y ) = self.GetEffectiveMinSize()
self.SetInitialSize( ( x, y ) )
2013-03-23 17:57:29 +00:00
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
Dialog.__init__( self, parent, 'configure form field' )
2013-07-24 20:26:00 +00:00
2013-07-31 21:26:38 +00:00
if form_field is None: ( name, type, default, editable ) = ( '', CC.FIELD_TEXT, '', True )
else: ( name, type, default, editable ) = form_field
InitialiseControls()
PopulateControls()
2013-07-24 20:26:00 +00:00
2013-07-31 21:26:38 +00:00
ArrangeControls()
wx.CallAfter( self._ok.SetFocus )
2013-07-24 20:26:00 +00:00
def EventCancel( self, event ): self.EndModal( wx.ID_CANCEL )
def EventOK( self, event ): self.EndModal( wx.ID_OK )
2013-07-31 21:26:38 +00:00
def GetFormField( self ):
2013-07-24 20:26:00 +00:00
2013-07-31 21:26:38 +00:00
name = self._name.GetValue()
type = self._type.GetClientData( self._type.GetSelection() )
default = self._default.GetValue()
editable = self._editable.GetValue()
return ( name, type, default, editable )
2013-07-24 20:26:00 +00:00
class DialogInputShortcut( Dialog ):
def __init__( self, parent, modifier = wx.ACCEL_NORMAL, key = wx.WXK_F7, action = 'new_page' ):
2013-02-19 00:11:43 +00:00
2013-07-24 20:26:00 +00:00
self._action = action
2013-03-23 17:57:29 +00:00
2013-07-24 20:26:00 +00:00
def InitialiseControls():
self._shortcut = ClientGUICommon.Shortcut( self, modifier, key )
self._actions = wx.Choice( self, choices = [ 'archive', 'inbox', 'close_page', 'filter', 'fullscreen_switch', 'ratings_filter', 'frame_back', 'frame_next', 'manage_ratings', 'manage_tags', 'new_page', 'refresh', 'set_search_focus', 'show_hide_splitters', 'synchronised_wait_switch', 'previous', 'next', 'first', 'last' ] )
self._ok = wx.Button( self, label='Ok' )
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.Bind( wx.EVT_BUTTON, self.EventCancel )
self._cancel.SetForegroundColour( ( 128, 0, 0 ) )
2013-07-31 21:26:38 +00:00
def PopulateControls():
self._actions.SetSelection( self._actions.FindString( action ) )
2013-03-15 02:38:12 +00:00
2013-07-31 21:26:38 +00:00
def ArrangeControls():
2013-07-24 20:26:00 +00:00
hbox = wx.BoxSizer( wx.HORIZONTAL )
hbox.AddF( self._shortcut, FLAGS_MIXED )
hbox.AddF( self._actions, FLAGS_EXPAND_PERPENDICULAR )
b_box = wx.BoxSizer( wx.HORIZONTAL )
b_box.AddF( self._ok, FLAGS_MIXED )
b_box.AddF( self._cancel, FLAGS_MIXED )
vbox = wx.BoxSizer( wx.VERTICAL )
vbox.AddF( hbox, FLAGS_EXPAND_SIZER_PERPENDICULAR )
vbox.AddF( b_box, FLAGS_BUTTON_SIZERS )
self.SetSizer( vbox )
2013-03-23 17:57:29 +00:00
2013-07-24 20:26:00 +00:00
( x, y ) = self.GetEffectiveMinSize()
self.SetInitialSize( ( x, y ) )
2013-03-23 17:57:29 +00:00
2013-03-15 02:38:12 +00:00
2013-07-24 20:26:00 +00:00
Dialog.__init__( self, parent, 'configure shortcut' )
InitialiseControls()
2013-07-31 21:26:38 +00:00
PopulateControls()
ArrangeControls()
wx.CallAfter( self._ok.SetFocus )
2013-07-24 20:26:00 +00:00
def EventCancel( self, event ): self.EndModal( wx.ID_CANCEL )
def EventOK( self, event ): self.EndModal( wx.ID_OK )
def GetInfo( self ):
( modifier, key ) = self._shortcut.GetValue()
return ( modifier, key, self._actions.GetStringSelection() )
2013-02-19 00:11:43 +00:00
class DialogMessage( Dialog ):
def __init__( self, parent, message, ok_label = 'ok' ):
def InitialiseControls():
self._ok = wx.Button( self, id = wx.ID_CANCEL, label = ok_label )
self._ok.SetForegroundColour( ( 0, 128, 0 ) )
2013-07-31 21:26:38 +00:00
def PopulateControls():
pass
def ArrangeControls():
2013-02-19 00:11:43 +00:00
vbox = wx.BoxSizer( wx.VERTICAL )
2013-07-31 21:26:38 +00:00
text = wx.StaticText( self, label = HC.u( message ) )
2013-02-19 00:11:43 +00:00
text.Wrap( 480 )
vbox.AddF( text, FLAGS_BIG_INDENT )
vbox.AddF( self._ok, FLAGS_BUTTON_SIZERS )
self.SetSizer( vbox )
( x, y ) = self.GetEffectiveMinSize()
self.SetInitialSize( ( x, y ) )
Dialog.__init__( self, parent, 'message', position = 'center' )
InitialiseControls()
2013-07-31 21:26:38 +00:00
PopulateControls()
ArrangeControls()
wx.CallAfter( self._ok.SetFocus )
2013-02-19 00:11:43 +00:00
class DialogModifyAccounts( Dialog ):
def __init__( self, parent, service_identifier, subject_identifiers ):
def InitialiseControls():
2013-03-15 02:38:12 +00:00
self._account_info_panel = ClientGUICommon.StaticBox( self, 'account info' )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
self._subject_text = wx.StaticText( self._account_info_panel )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
#
2013-03-15 02:38:12 +00:00
self._account_types_panel = ClientGUICommon.StaticBox( self, 'account types' )
self._account_types = wx.Choice( self._account_types_panel )
2013-02-19 00:11:43 +00:00
2013-03-15 02:38:12 +00:00
self._account_types_ok = wx.Button( self._account_types_panel, label = 'Ok' )
2013-02-19 00:11:43 +00:00
self._account_types_ok.Bind( wx.EVT_BUTTON, self.EventChangeAccountType )
2013-07-31 21:26:38 +00:00
#
2013-03-15 02:38:12 +00:00
self._expiration_panel = ClientGUICommon.StaticBox( self, 'change expiration' )
self._add_to_expires = wx.Choice( self._expiration_panel )
2013-02-19 00:11:43 +00:00
2013-03-15 02:38:12 +00:00
self._add_to_expires_ok = wx.Button( self._expiration_panel, label = 'Ok' )
2013-02-19 00:11:43 +00:00
self._add_to_expires_ok.Bind( wx.EVT_BUTTON, self.EventAddToExpires )
2013-03-15 02:38:12 +00:00
self._set_expires = wx.Choice( self._expiration_panel )
2013-02-19 00:11:43 +00:00
2013-03-15 02:38:12 +00:00
self._set_expires_ok = wx.Button( self._expiration_panel, label = 'Ok' )
2013-02-19 00:11:43 +00:00
self._set_expires_ok.Bind( wx.EVT_BUTTON, self.EventSetExpires )
2013-07-31 21:26:38 +00:00
#
2013-03-15 02:38:12 +00:00
self._ban_panel = ClientGUICommon.StaticBox( self, 'bans' )
self._ban = wx.Button( self._ban_panel, label = 'ban user' )
2013-02-19 00:11:43 +00:00
self._ban.Bind( wx.EVT_BUTTON, self.EventBan )
self._ban.SetBackgroundColour( ( 255, 0, 0 ) )
self._ban.SetForegroundColour( ( 255, 255, 0 ) )
2013-03-15 02:38:12 +00:00
self._superban = wx.Button( self._ban_panel, label = 'ban user and delete every contribution they have ever made' )
2013-02-19 00:11:43 +00:00
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' )
self._exit.Bind( wx.EVT_BUTTON, lambda event: self.EndModal( wx.ID_OK ) )
2013-07-31 21:26:38 +00:00
def PopulateControls():
connection = self._service.GetConnection()
if len( self._subject_identifiers ) == 1:
( subject_identifier, ) = self._subject_identifiers
subject_string = connection.Get( 'account_info', subject_identifier = subject_identifier )
else: subject_string = 'modifying ' + HC.ConvertIntToPrettyString( len( self._subject_identifiers ) ) + ' accounts'
self._subject_text.SetLabel( subject_string )
#
account_types = connection.Get( '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.expirations:
if value is not None: self._add_to_expires.Append( string, value ) # don't want 'add no limit'
self._add_to_expires.SetSelection( 1 ) # three months
for ( string, value ) in HC.expirations: self._set_expires.Append( string, value )
self._set_expires.SetSelection( 1 ) # three months
#
2013-02-19 00:11:43 +00:00
if not self._service.GetAccount().HasPermission( HC.GENERAL_ADMIN ):
self._account_types_ok.Disable()
self._add_to_expires_ok.Disable()
self._set_expires_ok.Disable()
2013-07-31 21:26:38 +00:00
def ArrangeControls():
2013-02-19 00:11:43 +00:00
2013-03-15 02:38:12 +00:00
self._account_info_panel.AddF( self._subject_text, FLAGS_EXPAND_PERPENDICULAR )
2013-02-19 00:11:43 +00:00
2013-03-15 02:38:12 +00:00
account_types_hbox = wx.BoxSizer( wx.HORIZONTAL )
2013-02-19 00:11:43 +00:00
2013-03-15 02:38:12 +00:00
account_types_hbox.AddF( self._account_types, FLAGS_MIXED )
account_types_hbox.AddF( self._account_types_ok, FLAGS_MIXED )
2013-02-19 00:11:43 +00:00
2013-03-15 02:38:12 +00:00
self._account_types_panel.AddF( account_types_hbox, FLAGS_EXPAND_PERPENDICULAR )
2013-02-19 00:11:43 +00:00
add_to_expires_box = wx.BoxSizer( wx.HORIZONTAL )
2013-03-15 02:38:12 +00:00
add_to_expires_box.AddF( wx.StaticText( self._expiration_panel, label = 'add to expires: ' ), FLAGS_MIXED )
2013-02-19 00:11:43 +00:00
add_to_expires_box.AddF( self._add_to_expires, FLAGS_EXPAND_BOTH_WAYS )
add_to_expires_box.AddF( self._add_to_expires_ok, FLAGS_MIXED )
set_expires_box = wx.BoxSizer( wx.HORIZONTAL )
2013-03-15 02:38:12 +00:00
set_expires_box.AddF( wx.StaticText( self._expiration_panel, label = 'set expires to: ' ), FLAGS_MIXED )
2013-02-19 00:11:43 +00:00
set_expires_box.AddF( self._set_expires, FLAGS_EXPAND_BOTH_WAYS )
set_expires_box.AddF( self._set_expires_ok, FLAGS_MIXED )
2013-03-15 02:38:12 +00:00
self._expiration_panel.AddF( add_to_expires_box, FLAGS_EXPAND_PERPENDICULAR )
self._expiration_panel.AddF( set_expires_box, FLAGS_EXPAND_PERPENDICULAR )
2013-02-19 00:11:43 +00:00
2013-03-15 02:38:12 +00:00
self._ban_panel.AddF( self._ban, FLAGS_EXPAND_PERPENDICULAR )
self._ban_panel.AddF( self._superban, FLAGS_EXPAND_PERPENDICULAR )
2013-02-19 00:11:43 +00:00
vbox = wx.BoxSizer( wx.VERTICAL )
2013-03-15 02:38:12 +00:00
vbox.AddF( self._account_info_panel, FLAGS_EXPAND_PERPENDICULAR )
vbox.AddF( self._account_types_panel, FLAGS_EXPAND_PERPENDICULAR )
vbox.AddF( self._expiration_panel, FLAGS_EXPAND_PERPENDICULAR )
vbox.AddF( self._ban_panel, FLAGS_EXPAND_PERPENDICULAR )
2013-02-19 00:11:43 +00:00
vbox.AddF( self._exit, FLAGS_BUTTON_SIZERS )
self.SetSizer( vbox )
( x, y ) = self.GetEffectiveMinSize()
self.SetInitialSize( ( x, y ) )
Dialog.__init__( self, parent, 'modify account' )
2013-07-10 20:25:57 +00:00
self._service = HC.app.Read( 'service', service_identifier )
2013-02-19 00:11:43 +00:00
self._subject_identifiers = set( subject_identifiers )
InitialiseControls()
2013-07-31 21:26:38 +00:00
PopulateControls()
ArrangeControls()
wx.CallAfter( self._exit.SetFocus )
2013-02-19 00:11:43 +00:00
def _DoModification( self, action, **kwargs ):
try:
connection = self._service.GetConnection()
kwargs[ 'subject_identifiers' ] = list( self._subject_identifiers )
kwargs[ 'action' ] = action
2013-03-15 02:38:12 +00:00
connection.Post( 'account_modification', **kwargs )
2013-02-19 00:11:43 +00:00
if len( self._subject_identifiers ) == 1:
( subject_identifier, ) = self._subject_identifiers
2013-07-31 21:26:38 +00:00
self._subject_text.SetLabel( HC.u( connection.Get( 'account_info', subject_identifier = subject_identifier ) ) )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
except Exception as e: wx.MessageBox( HC.u( e ) )
2013-02-19 00:11:43 +00:00
if len( self._subject_identifiers ) > 1: wx.MessageBox( 'Done!' )
def EventAddToExpires( self, event ): self._DoModification( HC.ADD_TO_EXPIRES, expiration = self._add_to_expires.GetClientData( self._add_to_expires.GetSelection() ) )
def EventBan( self, event ):
with wx.TextEntryDialog( self, 'Enter reason for the ban' ) as dlg:
if dlg.ShowModal() == wx.ID_OK: self._DoModification( HC.BAN, reason = dlg.GetValue() )
def EventChangeAccountType( self, event ): self._DoModification( HC.CHANGE_ACCOUNT_TYPE, title = self._account_types.GetClientData( self._account_types.GetSelection() ).GetTitle() )
2013-07-24 20:26:00 +00:00
def EventSetExpires( self, event ):
expires = self._set_expires.GetClientData( self._set_expires.GetSelection() )
2013-07-31 21:26:38 +00:00
if expires is not None: expires += HC.GetNow()
2013-07-24 20:26:00 +00:00
self._DoModification( HC.SET_EXPIRES, expiry = expires )
2013-02-19 00:11:43 +00:00
def EventSuperban( self, event ):
with wx.TextEntryDialog( self, 'Enter reason for the superban' ) as dlg:
if dlg.ShowModal() == wx.ID_OK: self._DoModification( HC.SUPERBAN, reason = dlg.GetValue() )
class DialogNews( Dialog ):
def __init__( self, parent, service_identifier ):
def InitialiseControls():
2013-07-31 21:26:38 +00:00
self._news = wx.TextCtrl( self, style = wx.TE_READONLY | wx.TE_MULTILINE )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
self._previous = wx.Button( self, label = '<' )
2013-02-19 00:11:43 +00:00
self._previous.Bind( wx.EVT_BUTTON, self.EventPrevious )
self._news_position = wx.TextCtrl( self )
2013-07-31 21:26:38 +00:00
self._next = wx.Button( self, label = '>' )
2013-02-19 00:11:43 +00:00
self._next.Bind( wx.EVT_BUTTON, self.EventNext )
2013-07-31 21:26:38 +00:00
self._done = wx.Button( self, id = wx.ID_CANCEL, label = 'Done' )
2013-07-17 20:56:13 +00:00
self._done.Bind( wx.EVT_BUTTON, self.EventOK )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
def PopulateControls():
2013-02-19 00:11:43 +00:00
2013-07-10 20:25:57 +00:00
self._newslist = HC.app.Read( 'news', service_identifier )
2013-02-19 00:11:43 +00:00
self._current_news_position = len( self._newslist )
self._ShowNews()
2013-07-31 21:26:38 +00:00
def ArrangeControls():
2013-02-19 00:11:43 +00:00
buttonbox = wx.BoxSizer( wx.HORIZONTAL )
buttonbox.AddF( self._previous, FLAGS_MIXED )
buttonbox.AddF( self._news_position, FLAGS_MIXED )
buttonbox.AddF( self._next, FLAGS_MIXED )
donebox = wx.BoxSizer( wx.HORIZONTAL )
donebox.AddF( self._done, FLAGS_MIXED )
vbox = wx.BoxSizer( wx.VERTICAL )
vbox.AddF( self._news, FLAGS_EXPAND_BOTH_WAYS )
vbox.AddF( buttonbox, FLAGS_BUTTON_SIZERS )
vbox.AddF( donebox, FLAGS_BUTTON_SIZERS )
self.SetSizer( vbox )
( x, y ) = self.GetEffectiveMinSize()
self.SetInitialSize( ( x + 200, 580 ) )
Dialog.__init__( self, parent, 'news' )
InitialiseControls()
2013-07-31 21:26:38 +00:00
PopulateControls()
ArrangeControls()
wx.CallAfter( self._done.SetFocus )
2013-02-19 00:11:43 +00:00
def _ShowNews( self ):
if self._current_news_position == 0:
self._news.SetValue( '' )
self._news_position.SetValue( 'No News' )
else:
( news, timestamp ) = self._newslist[ self._current_news_position - 1 ]
self._news.SetValue( time.ctime( timestamp ) + ':' + os.linesep + os.linesep + news )
self._news_position.SetValue( HC.ConvertIntToPrettyString( self._current_news_position ) + ' / ' + HC.ConvertIntToPrettyString( len( self._newslist ) ) )
def EventNext( self, event ):
if self._current_news_position < len( self._newslist ): self._current_news_position += 1
self._ShowNews()
2013-07-17 20:56:13 +00:00
def EventOK( self, event ): self.EndModal( wx.ID_OK )
2013-02-19 00:11:43 +00:00
def EventPrevious( self, event ):
if self._current_news_position > 1: self._current_news_position -= 1
self._ShowNews()
class DialogPathsToTagsRegex( Dialog ):
def __init__( self, parent, paths ):
def InitialiseControls():
self._tag_repositories = ClientGUICommon.ListBook( self )
self._tag_repositories.Bind( wx.EVT_NOTEBOOK_PAGE_CHANGED, self.EventServiceChanged )
2013-07-31 21:26:38 +00:00
self._add_button = wx.Button( self, label='Import Files' )
self._add_button.Bind( wx.EVT_BUTTON, self.EventOK )
self._add_button.SetForegroundColour( ( 0, 128, 0 ) )
self._cancel = wx.Button( self, id = wx.ID_CANCEL, label='Back to File Selection' )
self._cancel.Bind( wx.EVT_BUTTON, self.EventCancel )
self._cancel.SetForegroundColour( ( 128, 0, 0 ) )
def PopulateControls():
2013-07-10 20:25:57 +00:00
services = HC.app.Read( 'services', ( HC.TAG_REPOSITORY, ) )
2013-02-19 00:11:43 +00:00
for service in services:
account = service.GetAccount()
if account.HasPermission( HC.POST_DATA ):
service_identifier = service.GetServiceIdentifier()
2013-03-23 17:57:29 +00:00
page_info = ( self._Panel, ( self._tag_repositories, service_identifier, paths ), {} )
2013-02-19 00:11:43 +00:00
name = service_identifier.GetName()
self._tag_repositories.AddPage( page_info, name )
2013-04-10 18:10:37 +00:00
page = self._Panel( self._tag_repositories, HC.LOCAL_TAG_SERVICE_IDENTIFIER, paths )
2013-02-19 00:11:43 +00:00
2013-04-10 18:10:37 +00:00
name = HC.LOCAL_TAG_SERVICE_IDENTIFIER.GetName()
2013-02-19 00:11:43 +00:00
self._tag_repositories.AddPage( page, name )
default_tag_repository = self._options[ 'default_tag_repository' ]
self._tag_repositories.Select( default_tag_repository.GetName() )
2013-07-31 21:26:38 +00:00
def ArrangeControls():
2013-02-19 00:11:43 +00:00
buttons = wx.BoxSizer( wx.HORIZONTAL )
buttons.AddF( self._add_button, FLAGS_SMALL_INDENT )
2013-07-31 21:26:38 +00:00
buttons.AddF( self._cancel, FLAGS_SMALL_INDENT )
2013-02-19 00:11:43 +00:00
vbox = wx.BoxSizer( wx.VERTICAL )
vbox.AddF( self._tag_repositories, FLAGS_EXPAND_BOTH_WAYS )
vbox.AddF( buttons, FLAGS_BUTTON_SIZERS )
self.SetSizer( vbox )
self.SetInitialSize( ( 980, 680 ) )
Dialog.__init__( self, parent, 'path tagging' )
self._paths = paths
InitialiseControls()
2013-07-31 21:26:38 +00:00
PopulateControls()
ArrangeControls()
2013-02-19 00:11:43 +00:00
2013-03-15 02:38:12 +00:00
interested_actions = [ 'set_search_focus' ]
entries = []
for ( modifier, key_dict ) in self._options[ 'shortcuts' ].items(): entries.extend( [ ( modifier, key, CC.MENU_EVENT_ID_TO_ACTION_CACHE.GetId( action ) ) for ( key, action ) in key_dict.items() if action in interested_actions ] )
self.SetAcceleratorTable( wx.AcceleratorTable( entries ) )
self.Bind( wx.EVT_MENU, self.EventMenu )
2013-07-31 21:26:38 +00:00
wx.CallAfter( self._add_button.SetFocus )
2013-03-15 02:38:12 +00:00
def _SetSearchFocus( self ):
page = self._tag_repositories.GetCurrentPage()
page.SetTagBoxFocus()
2013-02-19 00:11:43 +00:00
def EventCancel( self, event ): self.EndModal( wx.ID_CANCEL )
2013-03-15 02:38:12 +00:00
def EventMenu( self, event ):
action = CC.MENU_EVENT_ID_TO_ACTION_CACHE.GetAction( event.GetId() )
if action is not None:
try:
( command, data ) = action
if command == 'set_search_focus': self._SetSearchFocus()
else: event.Skip()
except Exception as e:
2013-07-31 21:26:38 +00:00
wx.MessageBox( HC.u( e ) )
2013-03-15 02:38:12 +00:00
wx.MessageBox( traceback.format_exc() )
2013-02-19 00:11:43 +00:00
def EventOK( self, event ): self.EndModal( wx.ID_OK )
def EventServiceChanged( self, event ):
page = self._tag_repositories.GetCurrentPage()
wx.CallAfter( page.SetTagBoxFocus )
def GetInfo( self ):
2013-05-01 17:21:53 +00:00
paths_to_tags = collections.defaultdict( dict )
2013-02-19 00:11:43 +00:00
try:
2013-05-01 17:21:53 +00:00
for page in self._tag_repositories.GetNameToPageDict().values():
2013-02-19 00:11:43 +00:00
2013-05-01 17:21:53 +00:00
page_of_paths_to_tags = page.GetInfo()
2013-02-19 00:11:43 +00:00
2013-05-01 17:21:53 +00:00
service_identifier = page.GetServiceIdentifier()
2013-02-19 00:11:43 +00:00
2013-05-01 17:21:53 +00:00
for ( path, tags ) in page_of_paths_to_tags.items(): paths_to_tags[ path ][ service_identifier ] = tags
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
except Exception as e: wx.MessageBox( 'Saving regex tags to DB raised this error: ' + HC.u( e ) )
2013-02-19 00:11:43 +00:00
return paths_to_tags
2013-03-23 17:57:29 +00:00
class _Panel( wx.Panel ):
def __init__( self, parent, service_identifier, paths ):
2013-02-19 00:11:43 +00:00
2013-03-23 17:57:29 +00:00
def InitialiseControls():
2013-05-01 17:21:53 +00:00
self._paths_list = ClientGUICommon.SaneListCtrl( self, 250, [ ( '#', 50 ), ( 'path', 400 ), ( 'tags', -1 ) ] )
2013-03-23 17:57:29 +00:00
self._paths_list.Bind( wx.EVT_LIST_ITEM_SELECTED, self.EventItemSelected )
self._paths_list.Bind( wx.EVT_LIST_ITEM_DESELECTED, self.EventItemSelected )
#
self._quick_namespaces_panel = ClientGUICommon.StaticBox( self, 'quick namespaces' )
2013-04-24 21:23:53 +00:00
self._quick_namespaces_list = ClientGUICommon.SaneListCtrl( self._quick_namespaces_panel, 200, [ ( 'namespace', 80 ), ( 'regex', -1 ) ] )
self._add_quick_namespace_button = wx.Button( self._quick_namespaces_panel, label = 'add' )
self._add_quick_namespace_button.Bind( wx.EVT_BUTTON, self.EventAddQuickNamespace )
2013-03-23 17:57:29 +00:00
2013-04-24 21:23:53 +00:00
self._edit_quick_namespace_button = wx.Button( self._quick_namespaces_panel, label = 'edit' )
self._edit_quick_namespace_button.Bind( wx.EVT_BUTTON, self.EventEditQuickNamespace )
2013-03-23 17:57:29 +00:00
2013-04-24 21:23:53 +00:00
self._delete_quick_namespace_button = wx.Button( self._quick_namespaces_panel, label = 'delete' )
self._delete_quick_namespace_button.Bind( wx.EVT_BUTTON, self.EventDeleteQuickNamespace )
self._regex_shortcuts = ClientGUICommon.RegexButton( self._quick_namespaces_panel )
2013-03-23 17:57:29 +00:00
self._regex_link = wx.HyperlinkCtrl( self._quick_namespaces_panel, id = -1, label = 'a good regex introduction', url = 'http://www.aivosto.com/vbtips/regex.html' )
#
self._regexes_panel = ClientGUICommon.StaticBox( self, 'regexes' )
self._regexes = wx.ListBox( self._regexes_panel )
self._regexes.Bind( wx.EVT_LISTBOX_DCLICK, self.EventRemoveRegex )
self._regex_box = wx.TextCtrl( self._regexes_panel, style=wx.TE_PROCESS_ENTER )
self._regex_box.Bind( wx.EVT_TEXT_ENTER, self.EventAddRegex )
#
2013-05-01 17:21:53 +00:00
self._num_panel = ClientGUICommon.StaticBox( self, '#' )
self._num_namespace = wx.TextCtrl( self._num_panel )
self._num_namespace.Bind( wx.EVT_TEXT, self.EventNumNamespaceChanged )
#
2013-03-23 17:57:29 +00:00
self._tags_panel = ClientGUICommon.StaticBox( self, 'tags for all' )
self._tags = ClientGUICommon.TagsBoxFlat( self._tags_panel, self.TagRemoved )
2013-04-10 18:10:37 +00:00
self._tag_box = ClientGUICommon.AutoCompleteDropdownTagsWrite( self._tags_panel, self.AddTag, HC.LOCAL_FILE_SERVICE_IDENTIFIER, service_identifier )
2013-03-23 17:57:29 +00:00
#
self._single_tags_panel = ClientGUICommon.StaticBox( self, 'tags just for this file' )
self._paths_to_single_tags = collections.defaultdict( list )
self._single_tags = ClientGUICommon.TagsBoxFlat( self._single_tags_panel, self.SingleTagRemoved )
2013-04-10 18:10:37 +00:00
self._single_tag_box = ClientGUICommon.AutoCompleteDropdownTagsWrite( self._single_tags_panel, self.AddTagSingle, HC.LOCAL_FILE_SERVICE_IDENTIFIER, service_identifier )
2013-07-31 21:26:38 +00:00
def PopulateControls():
2013-03-23 17:57:29 +00:00
2013-05-01 17:21:53 +00:00
for ( num, path ) in enumerate( self._paths, 1 ):
pretty_num = HC.ConvertIntToPrettyString( num )
2013-03-23 17:57:29 +00:00
2013-05-01 17:21:53 +00:00
tags = self._GetTags( num, path )
2013-03-23 17:57:29 +00:00
tags_string = ', '.join( tags )
2013-05-01 17:21:53 +00:00
self._paths_list.Append( ( pretty_num, path, tags_string ), ( num, path, tags ) )
2013-03-23 17:57:29 +00:00
2013-07-31 21:26:38 +00:00
self._single_tag_box.Disable()
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
def ArrangeControls():
2013-03-23 17:57:29 +00:00
2013-04-24 21:23:53 +00:00
button_box = wx.BoxSizer( wx.HORIZONTAL )
2013-03-23 17:57:29 +00:00
2013-04-24 21:23:53 +00:00
button_box.AddF( self._add_quick_namespace_button, FLAGS_MIXED )
button_box.AddF( self._edit_quick_namespace_button, FLAGS_MIXED )
button_box.AddF( self._delete_quick_namespace_button, FLAGS_MIXED )
2013-03-23 17:57:29 +00:00
2013-04-24 21:23:53 +00:00
self._quick_namespaces_panel.AddF( self._quick_namespaces_list, FLAGS_EXPAND_PERPENDICULAR )
self._quick_namespaces_panel.AddF( button_box, FLAGS_BUTTON_SIZERS )
2013-03-23 17:57:29 +00:00
self._quick_namespaces_panel.AddF( self._regex_shortcuts, FLAGS_LONE_BUTTON )
self._quick_namespaces_panel.AddF( self._regex_link, FLAGS_LONE_BUTTON )
2013-05-01 17:21:53 +00:00
#
2013-03-23 17:57:29 +00:00
self._regexes_panel.AddF( self._regexes, FLAGS_EXPAND_BOTH_WAYS )
self._regexes_panel.AddF( self._regex_box, FLAGS_EXPAND_PERPENDICULAR )
2013-05-01 17:21:53 +00:00
hbox = wx.BoxSizer( wx.HORIZONTAL )
hbox.AddF( wx.StaticText( self._num_panel, label = '# namespace: ' ), FLAGS_MIXED )
hbox.AddF( self._num_namespace, FLAGS_EXPAND_BOTH_WAYS )
self._num_panel.AddF( hbox, FLAGS_EXPAND_SIZER_PERPENDICULAR )
second_vbox = wx.BoxSizer( wx.VERTICAL )
second_vbox.AddF( self._regexes_panel, FLAGS_EXPAND_BOTH_WAYS )
second_vbox.AddF( self._num_panel, FLAGS_EXPAND_PERPENDICULAR )
#
2013-03-23 17:57:29 +00:00
self._tags_panel.AddF( self._tags, FLAGS_EXPAND_BOTH_WAYS )
self._tags_panel.AddF( self._tag_box, FLAGS_EXPAND_PERPENDICULAR )
self._single_tags_panel.AddF( self._single_tags, FLAGS_EXPAND_BOTH_WAYS )
self._single_tags_panel.AddF( self._single_tag_box, FLAGS_EXPAND_PERPENDICULAR )
hbox = wx.BoxSizer( wx.HORIZONTAL )
hbox.AddF( self._quick_namespaces_panel, FLAGS_EXPAND_BOTH_WAYS )
2013-05-01 17:21:53 +00:00
hbox.AddF( second_vbox, FLAGS_EXPAND_SIZER_BOTH_WAYS )
2013-03-23 17:57:29 +00:00
hbox.AddF( self._tags_panel, FLAGS_EXPAND_BOTH_WAYS )
hbox.AddF( self._single_tags_panel, FLAGS_EXPAND_BOTH_WAYS )
vbox = wx.BoxSizer( wx.VERTICAL )
vbox.AddF( self._paths_list, FLAGS_EXPAND_BOTH_WAYS )
vbox.AddF( hbox, FLAGS_EXPAND_SIZER_BOTH_WAYS )
self.SetSizer( vbox )
2013-02-19 00:11:43 +00:00
2013-03-23 17:57:29 +00:00
wx.Panel.__init__( self, parent )
2013-02-19 00:11:43 +00:00
2013-03-23 17:57:29 +00:00
self._service_identifier = service_identifier
self._paths = paths
2013-02-19 00:11:43 +00:00
2013-03-23 17:57:29 +00:00
InitialiseControls()
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
PopulateControls()
ArrangeControls()
2013-03-15 02:38:12 +00:00
2013-03-23 17:57:29 +00:00
2013-05-01 17:21:53 +00:00
def _GetTags( self, num, path ):
2013-02-19 00:11:43 +00:00
2013-03-23 17:57:29 +00:00
tags = []
2013-02-19 00:11:43 +00:00
2013-03-23 17:57:29 +00:00
tags.extend( self._tags.GetTags() )
2013-02-19 00:11:43 +00:00
2013-03-23 17:57:29 +00:00
for regex in self._regexes.GetStrings():
try:
m = re.search( regex, path )
if m is not None:
match = m.group()
if len( match ) > 0: tags.append( match )
except: pass
2013-03-15 02:38:12 +00:00
2013-04-24 21:23:53 +00:00
for ( namespace, regex ) in self._quick_namespaces_list.GetClientData():
2013-03-23 17:57:29 +00:00
try:
2013-04-24 21:23:53 +00:00
m = re.search( regex, path )
2013-03-23 17:57:29 +00:00
if m is not None:
match = m.group()
2013-04-24 21:23:53 +00:00
if len( match ) > 0: tags.append( namespace + ':' + match )
2013-03-23 17:57:29 +00:00
except: pass
2013-03-15 02:38:12 +00:00
2013-03-23 17:57:29 +00:00
if path in self._paths_to_single_tags: tags.extend( self._paths_to_single_tags[ path ] )
2013-02-19 00:11:43 +00:00
2013-05-01 17:21:53 +00:00
num_namespace = self._num_namespace.GetValue()
if num_namespace != '':
2013-07-31 21:26:38 +00:00
tags.append( num_namespace + ':' + HC.u( num ) )
2013-05-01 17:21:53 +00:00
2013-03-23 17:57:29 +00:00
tags = [ HC.CleanTag( tag ) for tag in tags ]
2013-02-19 00:11:43 +00:00
2013-03-23 17:57:29 +00:00
return tags
2013-02-19 00:11:43 +00:00
2013-03-23 17:57:29 +00:00
def _RefreshFileList( self ):
2013-02-19 00:11:43 +00:00
2013-05-01 17:21:53 +00:00
for ( index, ( num, path, old_tags ) ) in enumerate( self._paths_list.GetClientData() ):
2013-02-19 00:11:43 +00:00
2013-03-23 17:57:29 +00:00
# when doing regexes, make sure not to include '' results, same for system: and - started tags.
2013-02-19 00:11:43 +00:00
2013-05-01 17:21:53 +00:00
tags = self._GetTags( num, path )
2013-02-19 00:11:43 +00:00
2013-03-23 17:57:29 +00:00
if tags != old_tags:
2013-05-01 17:21:53 +00:00
pretty_num = HC.ConvertIntToPrettyString( num )
2013-03-23 17:57:29 +00:00
tags_string = ', '.join( tags )
2013-05-01 17:21:53 +00:00
self._paths_list.UpdateRow( index, ( pretty_num, path, tags_string ), ( num, path, tags ) )
2013-03-23 17:57:29 +00:00
2013-02-19 00:11:43 +00:00
2013-05-29 20:19:54 +00:00
def AddTag( self, tag, parents = [] ):
2013-02-19 00:11:43 +00:00
2013-03-23 17:57:29 +00:00
if tag is not None:
2013-05-29 20:19:54 +00:00
self._tags.AddTag( tag, parents )
2013-03-23 17:57:29 +00:00
self._tag_box.Clear()
self._RefreshFileList()
2013-02-19 00:11:43 +00:00
2013-05-29 20:19:54 +00:00
def AddTagSingle( self, tag, parents = [] ):
2013-02-19 00:11:43 +00:00
2013-03-23 17:57:29 +00:00
if tag is not None:
2013-05-29 20:19:54 +00:00
self._single_tags.AddTag( tag, parents )
2013-03-23 17:57:29 +00:00
self._single_tag_box.Clear()
2013-02-19 00:11:43 +00:00
2013-03-23 17:57:29 +00:00
indices = self._paths_list.GetAllSelected()
2013-02-19 00:11:43 +00:00
2013-03-23 17:57:29 +00:00
for index in indices:
2013-02-19 00:11:43 +00:00
2013-05-01 17:21:53 +00:00
( num, path, old_tags ) = self._paths_list.GetClientData( index )
2013-02-19 00:11:43 +00:00
2013-03-23 17:57:29 +00:00
if tag not in self._paths_to_single_tags[ path ]: self._paths_to_single_tags[ path ].append( tag )
2013-02-19 00:11:43 +00:00
2013-05-29 20:19:54 +00:00
for parent in parents:
if parent not in self._paths_to_single_tags[ path ]: self._paths_to_single_tags[ path ].append( parent )
2013-02-19 00:11:43 +00:00
2013-03-23 17:57:29 +00:00
self._RefreshFileList() # make this more clever
2013-02-19 00:11:43 +00:00
2013-03-23 17:57:29 +00:00
def EventAddRegex( self, event ):
2013-02-19 00:11:43 +00:00
2013-03-23 17:57:29 +00:00
regex = self._regex_box.GetValue()
if regex != '':
2013-02-19 00:11:43 +00:00
2013-03-23 17:57:29 +00:00
self._regexes.Append( regex )
2013-02-19 00:11:43 +00:00
2013-03-23 17:57:29 +00:00
self._regex_box.Clear()
self._RefreshFileList()
2013-02-19 00:11:43 +00:00
2013-04-24 21:23:53 +00:00
def EventAddQuickNamespace( self, event ):
2013-02-19 00:11:43 +00:00
2013-04-24 21:23:53 +00:00
with DialogInputNamespaceRegex( self ) as dlg:
2013-02-19 00:11:43 +00:00
2013-04-24 21:23:53 +00:00
if dlg.ShowModal() == wx.ID_OK:
2013-03-23 17:57:29 +00:00
2013-04-24 21:23:53 +00:00
( namespace, regex ) = dlg.GetInfo()
2013-03-23 17:57:29 +00:00
2013-04-24 21:23:53 +00:00
self._quick_namespaces_list.Append( ( namespace, regex ), ( namespace, regex ) )
self._RefreshFileList()
2013-03-23 17:57:29 +00:00
2013-02-19 00:11:43 +00:00
2013-04-24 21:23:53 +00:00
def EventDeleteQuickNamespace( self, event ):
2013-02-19 00:11:43 +00:00
2013-04-24 21:23:53 +00:00
self._quick_namespaces_list.RemoveAllSelected()
2013-02-19 00:11:43 +00:00
2013-04-24 21:23:53 +00:00
self._RefreshFileList()
2013-02-19 00:11:43 +00:00
2013-04-24 21:23:53 +00:00
def EventEditQuickNamespace( self, event ):
2013-02-19 00:11:43 +00:00
2013-04-24 21:23:53 +00:00
for index in self._quick_namespaces_list.GetAllSelected():
2013-02-19 00:11:43 +00:00
2013-04-24 21:23:53 +00:00
( namespace, regex ) = self._quick_namespaces_list.GetClientData( index = index )
with DialogInputNamespaceRegex( self, namespace = namespace, regex = regex ) as dlg:
2013-03-23 17:57:29 +00:00
2013-04-24 21:23:53 +00:00
if dlg.ShowModal() == wx.ID_OK:
( namespace, regex ) = dlg.GetInfo()
self._quick_namespaces_list.UpdateRow( index, ( namespace, regex ), ( namespace, regex ) )
2013-03-23 17:57:29 +00:00
2013-02-19 00:11:43 +00:00
2013-04-24 21:23:53 +00:00
self._RefreshFileList()
2013-02-19 00:11:43 +00:00
2013-04-24 21:23:53 +00:00
def EventItemSelected( self, event ):
2013-03-23 17:57:29 +00:00
2013-04-24 21:23:53 +00:00
single_tags = set()
2013-03-23 17:57:29 +00:00
2013-04-24 21:23:53 +00:00
indices = self._paths_list.GetAllSelected()
2013-03-23 17:57:29 +00:00
2013-04-24 21:23:53 +00:00
if len( indices ) > 0:
for index in indices:
2013-05-01 17:21:53 +00:00
path = self._paths_list.GetClientData( index )[1]
2013-04-24 21:23:53 +00:00
if path in self._paths_to_single_tags: single_tags.update( self._paths_to_single_tags[ path ] )
self._single_tag_box.Enable()
else: self._single_tag_box.Disable()
2013-03-23 17:57:29 +00:00
2013-04-24 21:23:53 +00:00
self._single_tags.SetTags( single_tags )
2013-04-03 20:56:07 +00:00
2013-02-19 00:11:43 +00:00
2013-05-01 17:21:53 +00:00
def EventNumNamespaceChanged( self, event ): self._RefreshFileList()
2013-03-23 17:57:29 +00:00
def EventRemoveRegex( self, event ):
2013-02-19 00:11:43 +00:00
2013-03-23 17:57:29 +00:00
selection = self._regexes.GetSelection()
if selection != wx.NOT_FOUND:
2013-02-19 00:11:43 +00:00
2013-03-23 17:57:29 +00:00
if len( self._regex_box.GetValue() ) == 0: self._regex_box.SetValue( self._regexes.GetString( selection ) )
2013-02-19 00:11:43 +00:00
2013-03-23 17:57:29 +00:00
self._regexes.Delete( selection )
2013-02-19 00:11:43 +00:00
2013-03-23 17:57:29 +00:00
self._RefreshFileList()
2013-02-19 00:11:43 +00:00
2013-05-01 17:21:53 +00:00
def GetInfo( self ): return { path : tags for ( num, path, tags ) in self._paths_list.GetClientData() }
2013-02-19 00:11:43 +00:00
2013-05-01 17:21:53 +00:00
def GetServiceIdentifier( self ): return self._service_identifier
2013-02-19 00:11:43 +00:00
2013-03-23 17:57:29 +00:00
def SetTagBoxFocus( self ): self._tag_box.SetFocus()
2013-02-19 00:11:43 +00:00
2013-03-23 17:57:29 +00:00
def SingleTagRemoved( self, tag ):
2013-02-19 00:11:43 +00:00
2013-03-23 17:57:29 +00:00
indices = self._paths_list.GetAllSelected()
2013-02-19 00:11:43 +00:00
2013-03-23 17:57:29 +00:00
for index in indices:
2013-05-01 17:21:53 +00:00
( num, path, old_tags ) = self._paths_list.GetClientData( index )
2013-03-23 17:57:29 +00:00
if tag in self._paths_to_single_tags[ path ]: self._paths_to_single_tags[ path ].remove( tag )
2013-02-19 00:11:43 +00:00
self._RefreshFileList()
2013-03-23 17:57:29 +00:00
def TagRemoved( self, tag ): self._RefreshFileList()
2013-02-19 00:11:43 +00:00
class DialogProgress( Dialog ):
def __init__( self, parent, job_key, cancel_event = None ):
def InitialiseControls():
self._status = wx.StaticText( self, label = 'initialising', style = wx.ALIGN_CENTER | wx.ST_NO_AUTORESIZE )
self._gauge = ClientGUICommon.Gauge( self, range = 100 )
self._time_taken_so_far = wx.StaticText( self, label = 'initialising', style = wx.ALIGN_CENTER | wx.ST_NO_AUTORESIZE )
self._time_left = wx.StaticText( self, label = 'initialising', style = wx.ALIGN_CENTER | wx.ST_NO_AUTORESIZE )
if cancel_event is not None:
self._cancel = wx.Button( self, id = wx.ID_CANCEL, label = 'cancel' )
self._cancel.Bind( wx.EVT_BUTTON, self.EventCancel )
self._time_started = None
2013-07-31 21:26:38 +00:00
def PopulateControls():
pass
def ArrangeControls():
2013-02-19 00:11:43 +00:00
vbox = wx.BoxSizer( wx.VERTICAL )
vbox.AddF( self._status, FLAGS_EXPAND_PERPENDICULAR )
vbox.AddF( self._gauge, FLAGS_EXPAND_PERPENDICULAR )
vbox.AddF( self._time_taken_so_far, FLAGS_EXPAND_PERPENDICULAR )
vbox.AddF( self._time_left, FLAGS_EXPAND_PERPENDICULAR )
if cancel_event is not None: vbox.AddF( self._cancel, FLAGS_LONE_BUTTON )
self.SetSizer( vbox )
( x, y ) = self.GetEffectiveMinSize()
if x < 640: x = 640
self.SetInitialSize( ( x, y ) )
Dialog.__init__( self, parent, 'progress', style = wx.SYSTEM_MENU | wx.CAPTION | wx.RESIZE_BORDER, position = 'center' )
self._job_key = job_key
self._cancel_event = cancel_event
InitialiseControls()
2013-07-31 21:26:38 +00:00
PopulateControls()
ArrangeControls()
2013-02-19 00:11:43 +00:00
self.Bind( wx.EVT_TIMER, self.EventTimer, id = ID_TIMER_UPDATE )
self._timer = wx.Timer( self, id = ID_TIMER_UPDATE )
self._timer.Start( 1000, wx.TIMER_CONTINUOUS )
HC.pubsub.sub( self, 'Update', 'progress_update' )
def _DisplayTimes( self ):
value = self._gauge.GetValue()
range = self._gauge.GetRange()
if self._time_started is not None:
time_taken_so_far = time.clock() - self._time_started
if value > 1: time_left = HC.ConvertTimeToPrettyTime( time_taken_so_far * ( float( range - value ) / float( value ) ) )
else: time_left = 'unknown'
self._time_taken_so_far.SetLabel( 'elapsed: ' + HC.ConvertTimeToPrettyTime( time_taken_so_far ) )
self._time_left.SetLabel( 'remaining: ' + time_left )
def EventCancel( self, event ):
self._cancel.Disable()
self._cancel_event.set()
def EventTimer( self, event ):
value = self._gauge.GetValue()
range = self._gauge.GetRange()
if value == range: self.EndModal( wx.OK )
else: self._DisplayTimes()
def Update( self, job_key, index, range, status ):
if job_key == self._job_key:
if self._time_started is None: self._time_started = time.clock()
if range != self._gauge.GetRange(): self._gauge.SetRange( range )
self._gauge.SetValue( index )
self._status.SetLabel( status )
self._DisplayTimes()
2013-03-15 02:38:12 +00:00
class DialogRegisterService( Dialog ):
def __init__( self, parent ):
def InitialiseControls():
2013-07-31 21:26:38 +00:00
self._address = wx.TextCtrl( self )
self._registration_key = wx.TextCtrl( self )
2013-03-15 02:38:12 +00:00
self._register = wx.Button( self, label = 'register' )
self._register.Bind( wx.EVT_BUTTON, self.EventRegister )
self._cancel = wx.Button( self, id = wx.ID_CANCEL, label = 'cancel' )
2013-07-31 21:26:38 +00:00
def PopulateControls():
self._address.SetValue( 'hostname:port' )
self._registration_key.SetValue( 'r0000000000000000000000000000000000000000000000000000000000000000' )
def ArrangeControls():
2013-03-15 02:38:12 +00:00
vbox = wx.BoxSizer( wx.VERTICAL )
vbox.AddF( wx.StaticText( self, label = 'Please fill out the forms with the appropriate information for your service.' ), FLAGS_EXPAND_PERPENDICULAR )
gridbox = wx.FlexGridSizer( 0, 2 )
gridbox.AddGrowableCol( 1, 1 )
gridbox.AddF( wx.StaticText( self, label='address' ), FLAGS_MIXED )
gridbox.AddF( self._address, FLAGS_EXPAND_BOTH_WAYS )
gridbox.AddF( wx.StaticText( self, label='registration key' ), FLAGS_MIXED )
gridbox.AddF( self._registration_key, FLAGS_EXPAND_BOTH_WAYS )
vbox.AddF( gridbox, FLAGS_EXPAND_SIZER_BOTH_WAYS )
buttonbox = wx.BoxSizer( wx.HORIZONTAL )
buttonbox.AddF( self._register, FLAGS_MIXED )
buttonbox.AddF( self._cancel, FLAGS_MIXED )
vbox.AddF( buttonbox, FLAGS_BUTTON_SIZERS )
self.SetSizer( vbox )
( x, y ) = self.GetEffectiveMinSize()
self.SetInitialSize( ( x, y ) )
Dialog.__init__( self, parent, 'register account', position = 'center' )
InitialiseControls()
2013-07-31 21:26:38 +00:00
PopulateControls()
ArrangeControls()
2013-03-15 02:38:12 +00:00
self._register = False
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 ):
address = self._address.GetValue()
try:
( host, port ) = address.split( ':' )
port = int( port )
except:
wx.MessageBox( 'Could not parse that address!' )
return
registration_key_encoded = self._registration_key.GetValue()
if registration_key_encoded[0] == 'r': registration_key_encoded = registration_key_encoded[1:]
try: registration_key = registration_key_encoded.decode( 'hex' )
except:
wx.MessageBox( 'Could not parse that registration key!' )
return
2013-07-31 21:26:38 +00:00
connection = HC.get_connection( host = host, port = port )
2013-03-15 02:38:12 +00:00
headers = {}
headers[ 'Authorization' ] = 'hydrus_network ' + registration_key.encode( 'hex' )
try: access_key = connection.request( 'GET', '/access_key', headers = headers )
except Exception as e:
2013-07-31 21:26:38 +00:00
wx.MessageBox( HC.u( e ) )
2013-03-15 02:38:12 +00:00
return
self._credentials = CC.Credentials( host, port, access_key )
self.EndModal( wx.ID_OK )
def GetCredentials( self ): return self._credentials
2013-02-19 00:11:43 +00:00
class DialogSelectBooru( Dialog ):
def __init__( self, parent ):
def InitialiseControls():
self._boorus = wx.ListBox( self, style = wx.LB_SORT )
2013-07-31 21:26:38 +00:00
self._boorus.Bind( wx.EVT_LISTBOX_DCLICK, self.EventDoubleClick )
self._ok = wx.Button( self, id = wx.ID_OK, size = ( 0, 0 ) )
self._ok.Bind( wx.EVT_BUTTON, self.EventOK )
self._ok.SetDefault()
def PopulateControls():
boorus = HC.app.Read( 'boorus' )
2013-02-19 00:11:43 +00:00
for booru in boorus: self._boorus.Append( booru.GetName(), booru )
2013-07-31 21:26:38 +00:00
def ArrangeControls():
2013-02-19 00:11:43 +00:00
vbox = wx.BoxSizer( wx.VERTICAL )
vbox.AddF( self._boorus, FLAGS_EXPAND_PERPENDICULAR )
self.SetSizer( vbox )
( x, y ) = self.GetEffectiveMinSize()
if x < 320: x = 320
self.SetInitialSize( ( x, y ) )
Dialog.__init__( self, parent, 'select booru' )
InitialiseControls()
2013-07-31 21:26:38 +00:00
PopulateControls()
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
ArrangeControls()
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
wx.CallAfter( self._ok.SetFocus )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
def EventDoubleClick( self, event ): self.EndModal( wx.ID_OK )
def EventOK( self, event ):
selection = self._boorus.GetSelection()
if selection != wx.NOT_FOUND: self.EndModal( wx.ID_OK )
2013-02-19 00:11:43 +00:00
def GetBooru( self ): return self._boorus.GetClientData( self._boorus.GetSelection() )
class DialogSelectImageboard( Dialog ):
def __init__( self, parent ):
def InitialiseControls():
self._tree = wx.TreeCtrl( self )
self._tree.Bind( wx.EVT_TREE_ITEM_ACTIVATED, self.EventSelect )
2013-07-31 21:26:38 +00:00
def PopulateControls():
2013-07-10 20:25:57 +00:00
all_imageboards = HC.app.Read( 'imageboards' )
2013-02-19 00:11:43 +00:00
root_item = self._tree.AddRoot( 'all sites' )
for ( site, imageboards ) in all_imageboards:
site_item = self._tree.AppendItem( root_item, site )
for imageboard in imageboards:
name = imageboard.GetName()
self._tree.AppendItem( site_item, name, data = wx.TreeItemData( imageboard ) )
self._tree.Expand( root_item )
2013-07-31 21:26:38 +00:00
def ArrangeControls():
2013-02-19 00:11:43 +00:00
vbox = wx.BoxSizer( wx.VERTICAL )
vbox.AddF( self._tree, FLAGS_EXPAND_BOTH_WAYS )
self.SetSizer( vbox )
( x, y ) = self.GetEffectiveMinSize()
if x < 320: x = 320
2013-03-15 02:38:12 +00:00
if y < 640: y = 640
2013-02-19 00:11:43 +00:00
self.SetInitialSize( ( x, y ) )
Dialog.__init__( self, parent, 'select imageboard' )
InitialiseControls()
2013-07-31 21:26:38 +00:00
PopulateControls()
ArrangeControls()
2013-02-19 00:11:43 +00:00
def EventSelect( self, event ):
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()
class DialogSelectFromListOfStrings( Dialog ):
def __init__( self, parent, title, list_of_strings ):
def InitialiseControls():
self._strings = wx.ListBox( self, choices = list_of_strings )
self._strings.Bind( wx.EVT_KEY_DOWN, self.EventKeyDown )
self._strings.Bind( wx.EVT_LISTBOX_DCLICK, self.EventSelect )
2013-07-31 21:26:38 +00:00
self._ok = wx.Button( self, id = wx.ID_OK, size = ( 0, 0 ) )
self._ok.Bind( wx.EVT_BUTTON, self.EventOK )
self._ok.SetDefault()
def PopulateControls():
pass
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
def ArrangeControls():
2013-02-19 00:11:43 +00:00
vbox = wx.BoxSizer( wx.VERTICAL )
vbox.AddF( self._strings, FLAGS_EXPAND_PERPENDICULAR )
self.SetSizer( vbox )
( x, y ) = self.GetEffectiveMinSize()
if x < 320: x = 320
self.SetInitialSize( ( x, y ) )
Dialog.__init__( self, parent, title )
InitialiseControls()
2013-07-31 21:26:38 +00:00
PopulateControls()
ArrangeControls()
2013-02-19 00:11:43 +00:00
def EventKeyDown( self, event ):
if event.KeyCode == wx.WXK_SPACE:
selection = self._strings.GetSelection()
if selection != wx.NOT_FOUND: self.EndModal( wx.ID_OK )
else: event.Skip()
2013-07-31 21:26:38 +00:00
def EventOK( self, event ):
selection = self._strings.GetSelection()
if selection != wx.NOT_FOUND: self.EndModal( wx.ID_OK )
2013-02-19 00:11:43 +00:00
def EventSelect( self, event ): self.EndModal( wx.ID_OK )
def GetString( self ): return self._strings.GetStringSelection()
class DialogSelectLocalFiles( Dialog ):
def __init__( self, parent, paths = [] ):
def InitialiseControls():
self._paths_list = ClientGUICommon.SaneListCtrl( self, 480, [ ( 'path', -1 ), ( 'guessed mime', 110 ), ( 'size', 60 ) ] )
self._paths_list.SetMinSize( ( 780, 360 ) )
self._add_button = wx.Button( self, label='Import now' )
self._add_button.Bind( wx.EVT_BUTTON, self.EventOK )
self._add_button.SetForegroundColour( ( 0, 128, 0 ) )
self._tag_button = wx.Button( self, label = 'Add tags before importing' )
self._tag_button.Bind( wx.EVT_BUTTON, self.EventTags )
self._tag_button.SetForegroundColour( ( 0, 128, 0 ) )
2013-07-31 21:26:38 +00:00
self._cancel = wx.Button( self, id = wx.ID_CANCEL, label='Cancel' )
self._cancel.Bind( wx.EVT_BUTTON, self.EventCancel )
self._cancel.SetForegroundColour( ( 128, 0, 0 ) )
2013-02-19 00:11:43 +00:00
2013-05-01 17:21:53 +00:00
self._delete_after_success = wx.CheckBox( self, label = 'delete files after successful import' )
2013-02-19 00:11:43 +00:00
self._advanced_import_options = ClientGUICommon.AdvancedImportOptions( self )
self._add_files_button = wx.Button( self, label='Add Files' )
self._add_files_button.Bind( wx.EVT_BUTTON, self.EventAddPaths )
self._add_folder_button = wx.Button( self, label='Add Folder' )
self._add_folder_button.Bind( wx.EVT_BUTTON, self.EventAddFolder )
self._remove_files_button = wx.Button( self, label='Remove Files' )
self._remove_files_button.Bind( wx.EVT_BUTTON, self.EventRemovePaths )
2013-07-31 21:26:38 +00:00
def PopulateControls():
pass
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
def ArrangeControls():
2013-02-19 00:11:43 +00:00
file_buttons = wx.BoxSizer( wx.HORIZONTAL )
file_buttons.AddF( ( 20, 0 ), FLAGS_NONE )
file_buttons.AddF( self._add_files_button, FLAGS_MIXED )
file_buttons.AddF( self._add_folder_button, FLAGS_MIXED )
file_buttons.AddF( self._remove_files_button, FLAGS_MIXED )
buttons = wx.BoxSizer( wx.HORIZONTAL )
buttons.AddF( self._add_button, FLAGS_MIXED )
buttons.AddF( self._tag_button, FLAGS_MIXED )
2013-07-31 21:26:38 +00:00
buttons.AddF( self._cancel, FLAGS_MIXED )
2013-02-19 00:11:43 +00:00
vbox = wx.BoxSizer( wx.VERTICAL )
vbox.AddF( self._paths_list, FLAGS_EXPAND_PERPENDICULAR )
vbox.AddF( file_buttons, FLAGS_BUTTON_SIZERS )
2013-03-15 02:38:12 +00:00
vbox.AddF( self._advanced_import_options, FLAGS_EXPAND_PERPENDICULAR )
2013-05-01 17:21:53 +00:00
vbox.AddF( self._delete_after_success, FLAGS_LONE_BUTTON )
2013-02-19 00:11:43 +00:00
vbox.AddF( ( 0, 5 ), FLAGS_NONE )
vbox.AddF( buttons, FLAGS_BUTTON_SIZERS )
self.SetSizer( vbox )
( x, y ) = self.GetEffectiveMinSize()
self.SetInitialSize( ( x, y ) )
Dialog.__init__( self, parent, 'importing files' )
self.SetDropTarget( ClientGUICommon.FileDropTarget( self._AddPathsToList ) )
InitialiseControls()
2013-07-31 21:26:38 +00:00
PopulateControls()
ArrangeControls()
2013-02-19 00:11:43 +00:00
self._AddPathsToList( paths )
2013-07-31 21:26:38 +00:00
wx.CallAfter( self._add_button.SetFocus )
2013-02-19 00:11:43 +00:00
def _AddPathsToList( self, paths ):
2013-05-01 17:21:53 +00:00
good_paths_info = CC.ParseImportablePaths( paths )
2013-02-19 00:11:43 +00:00
odd_paths = False
2013-05-01 17:21:53 +00:00
for ( path_type, mime, size, path_info ) in good_paths_info:
2013-02-19 00:11:43 +00:00
2013-05-01 17:21:53 +00:00
pretty_size = HC.ConvertIntToBytes( size )
2013-02-19 00:11:43 +00:00
2013-05-01 17:21:53 +00:00
if path_type == 'path': pretty_path = path_info
elif path_type == 'zip':
2013-02-19 00:11:43 +00:00
2013-05-01 17:21:53 +00:00
( zip_path, name ) = path_info
2013-02-19 00:11:43 +00:00
2013-05-01 17:21:53 +00:00
pretty_path = zip_path + os.path.sep + name
2013-02-19 00:11:43 +00:00
2013-05-01 17:21:53 +00:00
self._paths_list.Append( ( pretty_path, HC.mime_string_lookup[ mime ], pretty_size ), ( ( path_type, path_info ), mime, size ) )
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
if odd_paths: wx.MessageBox( HC.u( len( odd_paths ) ) + ' files could not be added.' )
2013-02-19 00:11:43 +00:00
2013-05-01 17:21:53 +00:00
def _GetPathsInfo( self ): return [ row[0] for row in self._paths_list.GetClientData() ]
2013-02-19 00:11:43 +00:00
def EventAddPaths( self, event ):
with wx.FileDialog( self, 'Select the files to add.', style=wx.FD_MULTIPLE ) as dlg:
if dlg.ShowModal() == wx.ID_OK:
paths = dlg.GetPaths()
self._AddPathsToList( paths )
def EventAddFolder( self, event ):
with wx.DirDialog( self, 'Select a folder to add.', style=wx.DD_DIR_MUST_EXIST ) as dlg:
if dlg.ShowModal() == wx.ID_OK:
path = dlg.GetPath()
self._AddPathsToList( ( path, ) )
def EventCancel( self, event ): self.EndModal( wx.ID_CANCEL )
def EventOK( self, event ):
2013-05-01 17:21:53 +00:00
paths_info = self._GetPathsInfo()
2013-02-19 00:11:43 +00:00
2013-05-01 17:21:53 +00:00
if len( paths_info ) > 0:
2013-02-19 00:11:43 +00:00
advanced_import_options = self._advanced_import_options.GetInfo()
2013-05-01 17:21:53 +00:00
delete_after_success = self._delete_after_success.GetValue()
HC.pubsub.pub( 'new_hdd_import', paths_info, advanced_import_options = advanced_import_options, delete_after_success = delete_after_success )
2013-02-19 00:11:43 +00:00
self.EndModal( wx.ID_OK )
def EventRemovePaths( self, event ): self._paths_list.RemoveAllSelected()
def EventTags( self, event ):
try:
2013-05-01 17:21:53 +00:00
paths_info = self._GetPathsInfo()
2013-02-19 00:11:43 +00:00
2013-05-01 17:21:53 +00:00
if len( paths_info ) > 0:
2013-02-19 00:11:43 +00:00
advanced_import_options = self._advanced_import_options.GetInfo()
2013-05-01 17:21:53 +00:00
paths_to_send_to_dialog = []
for ( path_type, path_info ) in paths_info:
if path_type == 'path': pretty_path = path_info
elif path_type == 'zip':
( zip_path, name ) = path_info
pretty_path = zip_path + os.path.sep + name
paths_to_send_to_dialog.append( pretty_path )
with DialogPathsToTagsRegex( self, paths_to_send_to_dialog ) as dlg:
2013-02-19 00:11:43 +00:00
if dlg.ShowModal() == wx.ID_OK:
2013-05-01 17:21:53 +00:00
delete_after_success = self._delete_after_success.GetValue()
2013-02-19 00:11:43 +00:00
paths_to_tags = dlg.GetInfo()
2013-05-01 17:21:53 +00:00
HC.pubsub.pub( 'new_hdd_import', paths_info, advanced_import_options = advanced_import_options, paths_to_tags = paths_to_tags, delete_after_success = delete_after_success )
2013-02-19 00:11:43 +00:00
self.EndModal( wx.ID_OK )
except: wx.MessageBox( traceback.format_exc() )
class DialogSetupCustomFilterActions( Dialog ):
def __init__( self, parent ):
def InitialiseControls():
self._actions = ClientGUICommon.SaneListCtrl( self, 480, [ ( 'modifier', 150 ), ( 'key', 150 ), ( 'service', -1 ), ( 'action', 250 ) ] )
self._actions.SetMinSize( ( 780, 360 ) )
2013-03-15 02:38:12 +00:00
self._favourites = wx.ListBox( self )
self._favourites.Bind( wx.EVT_LISTBOX, self.EventSelectFavourite )
2013-02-19 00:11:43 +00:00
2013-03-15 02:38:12 +00:00
self._save_favourite = wx.Button( self, label = 'save' )
self._save_favourite.Bind( wx.EVT_BUTTON, self.EventSaveFavourite )
2013-02-19 00:11:43 +00:00
2013-03-15 02:38:12 +00:00
self._save_new_favourite = wx.Button( self, label = 'save as' )
self._save_new_favourite.Bind( wx.EVT_BUTTON, self.EventSaveNewFavourite )
2013-02-19 00:11:43 +00:00
2013-03-15 02:38:12 +00:00
self._delete_favourite = wx.Button( self, label = 'delete' )
self._delete_favourite.Bind( wx.EVT_BUTTON, self.EventDeleteFavourite )
2013-02-19 00:11:43 +00:00
2013-03-15 02:38:12 +00:00
self._current_actions_selection = wx.NOT_FOUND
2013-02-19 00:11:43 +00:00
self._add = wx.Button( self, label='add' )
self._add.Bind( wx.EVT_BUTTON, self.EventAdd )
self._add.SetForegroundColour( ( 0, 128, 0 ) )
self._edit = wx.Button( self, label='edit' )
self._edit.Bind( wx.EVT_BUTTON, self.EventEdit )
self._remove = wx.Button( self, label='remove' )
self._remove.Bind( wx.EVT_BUTTON, self.EventRemove )
self._remove.SetForegroundColour( ( 128, 0, 0 ) )
self._ok = wx.Button( self, label = 'ok' )
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.Bind( wx.EVT_BUTTON, self.EventCancel )
self._cancel.SetForegroundColour( ( 128, 0, 0 ) )
2013-07-31 21:26:38 +00:00
def PopulateControls():
default_actions = self._GetDefaultActions()
self._favourites.Append( 'default', default_actions )
favourites = HC.app.Read( 'favourite_custom_filter_actions' )
if 'previous' in favourites: self._favourites.Append( 'previous', favourites[ 'previous' ] )
else: self._favourites.Append( 'previous', default_actions )
for ( name, actions ) in favourites.items():
if name != 'previous': self._favourites.Append( name, actions )
self._favourites.Select( 1 ) # previous
def ArrangeControls():
2013-02-19 00:11:43 +00:00
action_buttons = wx.BoxSizer( wx.HORIZONTAL )
action_buttons.AddF( self._add, FLAGS_MIXED )
action_buttons.AddF( self._edit, FLAGS_MIXED )
action_buttons.AddF( self._remove, FLAGS_MIXED )
buttons = wx.BoxSizer( wx.HORIZONTAL )
buttons.AddF( self._ok, FLAGS_MIXED )
buttons.AddF( self._cancel, FLAGS_MIXED )
vbox = wx.BoxSizer( wx.VERTICAL )
vbox.AddF( self._actions, FLAGS_EXPAND_PERPENDICULAR )
vbox.AddF( action_buttons, FLAGS_BUTTON_SIZERS )
vbox.AddF( buttons, FLAGS_BUTTON_SIZERS )
2013-03-15 02:38:12 +00:00
button_hbox = wx.BoxSizer( wx.HORIZONTAL )
button_hbox.AddF( self._save_favourite, FLAGS_MIXED )
button_hbox.AddF( self._save_new_favourite, FLAGS_MIXED )
button_hbox.AddF( self._delete_favourite, FLAGS_MIXED )
f_vbox = wx.BoxSizer( wx.VERTICAL )
f_vbox.AddF( self._favourites, FLAGS_EXPAND_BOTH_WAYS )
f_vbox.AddF( button_hbox, FLAGS_BUTTON_SIZERS )
hbox = wx.BoxSizer( wx.HORIZONTAL )
hbox.AddF( f_vbox, FLAGS_EXPAND_PERPENDICULAR )
hbox.AddF( vbox, FLAGS_EXPAND_BOTH_WAYS )
self.SetSizer( hbox )
2013-02-19 00:11:43 +00:00
( x, y ) = self.GetEffectiveMinSize()
self.SetInitialSize( ( x, y ) )
Dialog.__init__( self, parent, 'setup custom filter' )
InitialiseControls()
2013-07-31 21:26:38 +00:00
PopulateControls()
ArrangeControls()
2013-02-19 00:11:43 +00:00
2013-03-15 02:38:12 +00:00
wx.CallAfter( self.EventSelectFavourite, None )
2013-07-31 21:26:38 +00:00
wx.CallAfter( self._ok.SetFocus )
2013-03-15 02:38:12 +00:00
def _GetDefaultActions( self ):
default_actions = []
for ( modifier, key_dict ) in self._options[ 'shortcuts' ].items():
for ( key, action ) in key_dict.items():
2013-04-03 20:56:07 +00:00
if action in ( 'manage_tags', 'manage_ratings', 'archive', 'inbox', 'fullscreen_switch', 'frame_back', 'frame_next', 'previous', 'next', 'first', 'last', 'pan_up', 'pan_down', 'pan_left', 'pan_right' ):
2013-03-15 02:38:12 +00:00
service_identifier = None
default_actions.append( ( modifier, key, service_identifier, action ) )
( modifier, key, service_identifier, action ) = ( wx.ACCEL_NORMAL, wx.WXK_DELETE, None, 'delete' )
default_actions.append( ( modifier, key, service_identifier, action ) )
return default_actions
def _IsUntouchableFavouriteSelection( self, selection ):
name = self._favourites.GetString( selection )
if name in ( 'previous', 'default' ): return True
else: return False
2013-02-19 00:11:43 +00:00
def _SortListCtrl( self ): self._actions.SortListItems( 3 )
def EventAdd( self, event ):
with DialogInputCustomFilterAction( self ) as dlg:
if dlg.ShowModal() == wx.ID_OK:
( pretty_tuple, data_tuple ) = dlg.GetInfo()
self._actions.Append( pretty_tuple, data_tuple )
self._SortListCtrl()
def EventCancel( self, event ): self.EndModal( wx.ID_CANCEL )
2013-03-15 02:38:12 +00:00
def EventDeleteFavourite( self, event ):
selection = self._favourites.GetSelection()
if selection != wx.NOT_FOUND:
if not self._IsUntouchableFavouriteSelection( selection ):
self._favourites.Delete( selection )
2013-02-19 00:11:43 +00:00
def EventEdit( self, event ):
for index in self._actions.GetAllSelected():
( modifier, key, service_identifier, action ) = self._actions.GetClientData( index )
with DialogInputCustomFilterAction( self, modifier = modifier, key = key, service_identifier = service_identifier, action = action ) as dlg:
if dlg.ShowModal() == wx.ID_OK:
( pretty_tuple, data_tuple ) = dlg.GetInfo()
self._actions.UpdateRow( index, pretty_tuple, data_tuple )
self._SortListCtrl()
2013-03-15 02:38:12 +00:00
def EventOK( self, event ):
favourites = {}
for i in range( self._favourites.GetCount() ):
name = self._favourites.GetString( i )
if name == 'default': continue
actions = self._favourites.GetClientData( i )
favourites[ name ] = actions
favourites[ 'previous' ] = self._actions.GetClientData() # overwrite
2013-07-10 20:25:57 +00:00
HC.app.Write( 'favourite_custom_filter_actions', favourites )
2013-03-15 02:38:12 +00:00
self.EndModal( wx.ID_OK )
2013-02-19 00:11:43 +00:00
def EventRemove( self, event ): self._actions.RemoveAllSelected()
2013-03-15 02:38:12 +00:00
def EventSaveFavourite( self, event ):
selection = self._favourites.GetSelection()
if selection != wx.NOT_FOUND:
if not self._IsUntouchableFavouriteSelection( selection ):
actions = self._actions.GetClientData()
self._favourites.SetClientData( selection, actions )
def EventSaveNewFavourite( self, event ):
existing_names = { self._favourites.GetString( i ) for i in range( self._favourites.GetCount() ) }
with wx.TextEntryDialog( self, 'Enter name for these favourite actions' ) as dlg:
if dlg.ShowModal() == wx.ID_OK:
name = dlg.GetValue()
if name == '': return
2013-07-31 21:26:38 +00:00
while name in existing_names: name += HC.u( random.randint( 0, 9 ) )
2013-03-15 02:38:12 +00:00
actions = self._actions.GetClientData()
self._favourites.Append( name, actions )
def EventSelectFavourite( self, event ):
selection = self._favourites.GetSelection()
if selection != wx.NOT_FOUND:
if selection != self._current_actions_selection:
self._actions.DeleteAllItems()
2013-03-23 17:57:29 +00:00
name = self._favourites.GetString( selection )
if name in ( 'default', 'previous' ):
self._save_favourite.Disable()
self._delete_favourite.Disable()
else:
self._save_favourite.Enable()
self._delete_favourite.Enable()
2013-03-15 02:38:12 +00:00
actions = self._favourites.GetClientData( selection )
for ( modifier, key, service_identifier, action ) in actions:
( pretty_modifier, pretty_key, pretty_action ) = HC.ConvertShortcutToPrettyShortcut( modifier, key, action )
if service_identifier is None: pretty_service_identifier = ''
else: pretty_service_identifier = service_identifier.GetName()
self._actions.Append( ( pretty_modifier, pretty_key, pretty_service_identifier, pretty_action ), ( modifier, key, service_identifier, action ) )
self._SortListCtrl()
2013-02-19 00:11:43 +00:00
def GetActions( self ):
raw_data = self._actions.GetClientData()
actions = collections.defaultdict( dict )
for ( modifier, key, service_identifier, action ) in raw_data: actions[ modifier ][ key ] = ( service_identifier, action )
return actions
2013-04-03 20:56:07 +00:00
class DialogSetupExport( Dialog ):
ID_HASH = 0
ID_TAGS = 1
ID_NN_TAGS = 2
ID_NAMESPACE = 3
ID_TAG = 4
def __init__( self, parent, flat_media ):
def InitialiseControls():
self._tags_box = ClientGUICommon.TagsBoxCPPWithSorter( self, self._page_key )
self._tags_box.SetMinSize( ( 220, 300 ) )
self._paths = ClientGUICommon.SaneListCtrl( self, 480, [ ( 'number', 60 ), ( 'mime', 70 ), ( 'path', -1 ) ] )
self._paths.Bind( wx.EVT_LIST_ITEM_SELECTED, self.EventSelectPath )
self._paths.Bind( wx.EVT_LIST_ITEM_DESELECTED, self.EventSelectPath )
self._paths.SetMinSize( ( 740, 360 ) )
self._directory_picker = wx.DirPickerCtrl( self )
self._directory_picker.Bind( wx.EVT_DIRPICKER_CHANGED, self.EventRecalcPaths )
self._open_location = wx.Button( self, label = 'open this location' )
self._open_location.Bind( wx.EVT_BUTTON, self.EventOpenLocation )
2013-05-01 17:21:53 +00:00
self._zip_name = wx.TextCtrl( self )
self._export_to_zip = wx.CheckBox( self, label = 'export to zip' )
self._export_encrypted = wx.CheckBox( self, label = 'encrypt zip' )
2013-04-03 20:56:07 +00:00
self._pattern = wx.TextCtrl( self )
self._update = wx.Button( self, label = 'update' )
self._update.Bind( wx.EVT_BUTTON, self.EventRecalcPaths )
self._examples = wx.Button( self, label = 'pattern shortcuts' )
self._examples.Bind( wx.EVT_BUTTON, self.EventPatternShortcuts )
self._export = wx.Button( self, label = 'export' )
self._export.Bind( wx.EVT_BUTTON, self.EventExport )
self._cancel = wx.Button( self, id = wx.ID_CANCEL, label='close' )
2013-07-31 21:26:38 +00:00
def PopulateControls():
for ( i, media ) in enumerate( flat_media ):
mime = media.GetMime()
pretty_tuple = ( HC.u( i + 1 ), HC.mime_string_lookup[ mime ], '' )
data_tuple = ( ( i, media ), mime, '' )
self._paths.Append( pretty_tuple, data_tuple )
if self._options[ 'export_path' ] is not None: self._directory_picker.SetPath( HC.ConvertPortablePathToAbsPath( self._options[ 'export_path' ] ) )
self._zip_name.SetValue( 'archive name.zip' )
self._pattern.SetValue( '{hash}' )
2013-04-03 20:56:07 +00:00
2013-07-31 21:26:38 +00:00
def ArrangeControls():
2013-04-03 20:56:07 +00:00
top_hbox = wx.BoxSizer( wx.HORIZONTAL )
top_hbox.AddF( self._tags_box, FLAGS_EXPAND_PERPENDICULAR )
top_hbox.AddF( self._paths, FLAGS_EXPAND_BOTH_WAYS )
destination_hbox = wx.BoxSizer( wx.HORIZONTAL )
destination_hbox.AddF( self._directory_picker, FLAGS_EXPAND_BOTH_WAYS )
destination_hbox.AddF( self._open_location, FLAGS_MIXED )
2013-05-01 17:21:53 +00:00
zip_hbox = wx.BoxSizer( wx.HORIZONTAL )
zip_hbox.AddF( self._zip_name, FLAGS_EXPAND_BOTH_WAYS )
zip_hbox.AddF( self._export_to_zip, FLAGS_MIXED )
zip_hbox.AddF( self._export_encrypted, FLAGS_MIXED )
2013-04-03 20:56:07 +00:00
pattern_hbox = wx.BoxSizer( wx.HORIZONTAL )
pattern_hbox.AddF( self._pattern, FLAGS_EXPAND_BOTH_WAYS )
pattern_hbox.AddF( self._update, FLAGS_MIXED )
pattern_hbox.AddF( self._examples, FLAGS_MIXED )
pattern_hbox.AddF( self._export, FLAGS_MIXED )
button_hbox = wx.BoxSizer( wx.HORIZONTAL )
vbox = wx.BoxSizer( wx.VERTICAL )
vbox.AddF( top_hbox, FLAGS_EXPAND_SIZER_BOTH_WAYS )
vbox.AddF( destination_hbox, FLAGS_EXPAND_SIZER_PERPENDICULAR )
2013-05-01 17:21:53 +00:00
vbox.AddF( zip_hbox, FLAGS_EXPAND_SIZER_PERPENDICULAR )
2013-04-03 20:56:07 +00:00
vbox.AddF( pattern_hbox, FLAGS_EXPAND_SIZER_PERPENDICULAR )
vbox.AddF( self._cancel, FLAGS_LONE_BUTTON )
self.SetSizer( vbox )
( x, y ) = self.GetEffectiveMinSize()
self.SetInitialSize( ( x, y ) )
Dialog.__init__( self, parent, 'setup export' )
self._page_key = os.urandom( 32 )
InitialiseControls()
2013-07-31 21:26:38 +00:00
PopulateControls()
ArrangeControls()
2013-04-03 20:56:07 +00:00
wx.CallAfter( self.EventSelectPath, None )
wx.CallAfter( self.EventRecalcPaths, None )
self.Bind( wx.EVT_MENU, self.EventMenu )
2013-07-31 21:26:38 +00:00
wx.CallAfter( self._export.SetFocus )
2013-04-03 20:56:07 +00:00
def _GetPath( self, media, terms ):
directory = self._directory_picker.GetPath()
filename = ''
for ( term_type, term ) in terms:
2013-05-29 20:19:54 +00:00
tags_manager = media.GetTagsManager()
2013-04-03 20:56:07 +00:00
if term_type == 'string': filename += term
elif term_type == 'namespace':
2013-05-29 20:19:54 +00:00
tags = tags_manager.GetNamespaceSlice( ( term, ) )
2013-04-03 20:56:07 +00:00
filename += ', '.join( [ tag.split( ':' )[1] for tag in tags ] )
elif term_type == 'predicate':
if term in ( 'tags', 'nn tags' ):
2013-05-29 20:19:54 +00:00
current = tags_manager.GetCurrent()
pending = tags_manager.GetPending()
2013-04-03 20:56:07 +00:00
tags = list( current.union( pending ) )
if term == 'nn tags': tags = [ tag for tag in tags if ':' not in tag ]
else: tags = [ tag if ':' not in tag else tag.split( ':' )[1] for tag in tags ]
tags.sort()
filename += ', '.join( tags )
elif term == 'hash':
hash = media.GetHash()
filename += hash.encode( 'hex' )
elif term_type == 'tag':
if ':' in term: term = term.split( ':' )[1]
2013-05-29 20:19:54 +00:00
if tags_manager.HasTag( term ): filename += term
2013-04-03 20:56:07 +00:00
2013-05-01 17:21:53 +00:00
if self._export_to_zip.GetValue() == True: zip_path = self._zip_name.GetValue() + os.path.sep
else: zip_path = ''
2013-04-03 20:56:07 +00:00
mime = media.GetMime()
ext = HC.mime_ext_lookup[ mime ]
2013-05-01 17:21:53 +00:00
return directory + os.path.sep + zip_path + filename + ext
2013-04-03 20:56:07 +00:00
def _RecalcPaths( self ):
pattern = self._pattern.GetValue()
try:
terms = [ ( 'string', pattern ) ]
new_terms = []
for ( term_type, term ) in terms:
if term_type == 'string':
while '[' in term:
( pre, term ) = term.split( '[', 1 )
( namespace, term ) = term.split( ']', 1 )
new_terms.append( ( 'string', pre ) )
new_terms.append( ( 'namespace', namespace ) )
new_terms.append( ( term_type, term ) )
terms = new_terms
new_terms = []
for ( term_type, term ) in terms:
if term_type == 'string':
while '{' in term:
( pre, term ) = term.split( '{', 1 )
( predicate, term ) = term.split( '}', 1 )
new_terms.append( ( 'string', pre ) )
new_terms.append( ( 'predicate', predicate ) )
new_terms.append( ( term_type, term ) )
terms = new_terms
new_terms = []
for ( term_type, term ) in terms:
if term_type == 'string':
while '(' in term:
( pre, term ) = term.split( '(', 1 )
( tag, term ) = term.split( ')', 1 )
new_terms.append( ( 'string', pre ) )
new_terms.append( ( 'tag', tag ) )
new_terms.append( ( term_type, term ) )
terms = new_terms
except: raise Exception( 'Could not parse that pattern!' )
all_paths = set()
for ( index, ( ( ordering_index, media ), mime, old_path ) ) in enumerate( self._paths.GetClientData() ):
path = self._GetPath( media, terms )
if path in all_paths:
i = 1
2013-07-31 21:26:38 +00:00
while self._GetPath( media, terms + [ ( 'string', HC.u( i ) ) ] ) in all_paths: i += 1
2013-04-03 20:56:07 +00:00
2013-07-31 21:26:38 +00:00
path = self._GetPath( media, terms + [ ( 'string', HC.u( i ) ) ] )
2013-04-03 20:56:07 +00:00
all_paths.add( path )
if path != old_path:
mime = media.GetMime()
2013-07-31 21:26:38 +00:00
self._paths.UpdateRow( index, ( HC.u( ordering_index + 1 ), HC.mime_string_lookup[ mime ], path ), ( ( ordering_index, media ), mime, path ) )
2013-04-03 20:56:07 +00:00
def EventExport( self, event ):
try: self._RecalcPaths()
except Exception as e:
2013-07-31 21:26:38 +00:00
wx.MessageBox( HC.u( e ) )
2013-04-03 20:56:07 +00:00
return
2013-05-01 17:21:53 +00:00
if self._export_to_zip.GetValue() == True:
2013-04-03 20:56:07 +00:00
2013-05-01 17:21:53 +00:00
directory = self._directory_picker.GetPath()
zip_path = directory + os.path.sep + self._zip_name.GetValue()
with zipfile.ZipFile( zip_path, mode = 'w', compression = zipfile.ZIP_DEFLATED ) as z:
2013-04-03 20:56:07 +00:00
2013-05-01 17:21:53 +00:00
for ( ( ordering_index, media ), mime, path ) in self._paths.GetClientData():
try:
hash = media.GetHash()
2013-07-10 20:25:57 +00:00
file = HC.app.Read( 'file', hash )
2013-05-01 17:21:53 +00:00
( gumpf, filename ) = os.path.split( path )
z.writestr( filename, file )
except:
2013-07-31 21:26:38 +00:00
wx.MessageBox( 'Encountered a problem while attempting to export file with index ' + HC.u( ordering_index + 1 ) + '.' + os.linesep + os.linesep + traceback.format_exc() )
2013-05-01 17:21:53 +00:00
break
2013-04-03 20:56:07 +00:00
2013-05-01 17:21:53 +00:00
if self._export_encrypted.GetValue() == True: HydrusEncryption.EncryptAESFile( zip_path, preface = 'hydrus encrypted zip' )
else:
for ( ( ordering_index, media ), mime, path ) in self._paths.GetClientData():
2013-04-03 20:56:07 +00:00
2013-05-01 17:21:53 +00:00
try:
hash = media.GetHash()
2013-07-10 20:25:57 +00:00
file = HC.app.Read( 'file', hash )
2013-05-01 17:21:53 +00:00
2013-07-31 21:26:38 +00:00
with HC.o( path, 'wb' ) as f: f.write( file )
2013-05-01 17:21:53 +00:00
except:
2013-07-31 21:26:38 +00:00
wx.MessageBox( 'Encountered a problem while attempting to export file with index ' + HC.u( ordering_index + 1 ) + '.' + os.linesep + os.linesep + traceback.format_exc() )
2013-05-01 17:21:53 +00:00
break
2013-04-03 20:56:07 +00:00
def EventMenu( self, event ):
id = event.GetId()
phrase = None
if id == self.ID_HASH: phrase = r'{hash}'
if id == self.ID_TAGS: phrase = r'{tags}'
if id == self.ID_NN_TAGS: phrase = r'{nn tags}'
if id == self.ID_NAMESPACE: phrase = r'[...]'
if id == self.ID_TAG: phrase = r'(...)'
else: event.Skip()
if phrase is not None:
if wx.TheClipboard.Open():
data = wx.TextDataObject( phrase )
wx.TheClipboard.SetData( data )
wx.TheClipboard.Close()
else: wx.MessageBox( 'I could not get permission to access the clipboard.' )
def EventPatternShortcuts( self, event ):
menu = wx.Menu()
menu.Append( -1, 'click on a phrase to copy to clipboard' )
menu.AppendSeparator()
menu.Append( self.ID_HASH, r'the file\'s hash - {hash}' )
menu.Append( self.ID_TAGS, r'all the file\'s tags - {tags}' )
menu.Append( self.ID_NN_TAGS, r'all the file\'s non-namespaced tags - {nn tags}' )
menu.AppendSeparator()
menu.Append( self.ID_NAMESPACE, r'all instances of a particular namespace - [...]' )
menu.AppendSeparator()
menu.Append( self.ID_TAG, r'a particular tag, if the file has it - (...)' )
self.PopupMenu( menu )
menu.Destroy()
def EventOpenLocation( self, event ):
directory = self._directory_picker.GetPath()
if directory is not None and directory != '':
try:
if 'Windows' in os.environ.get( 'os' ): subprocess.Popen( [ 'explorer', directory ] )
else: subprocess.Popen( [ 'explorer', directory ] )
except: wx.MessageBox( 'Could not open that location!' )
def EventRecalcPaths( self, event ):
try: self._RecalcPaths()
2013-07-31 21:26:38 +00:00
except Exception as e: wx.MessageBox( HC.u( e ) )
2013-04-03 20:56:07 +00:00
def EventSelectPath( self, event ):
indices = self._paths.GetAllSelected()
if len( indices ) == 0:
all_media = [ media for ( ( ordering_index, media ), mime, old_path ) in self._paths.GetClientData() ]
else:
all_media = [ media for ( ( ordering_index, media ), mime, old_path ) in [ self._paths.GetClientData( index ) for index in indices ] ]
HC.pubsub.pub( 'new_tags_selection', self._page_key, all_media )
2013-02-19 00:11:43 +00:00
class DialogYesNo( Dialog ):
def __init__( self, parent, message, yes_label = 'yes', no_label = 'no' ):
def InitialiseControls():
self._yes = wx.Button( self, label = yes_label )
self._yes.Bind( wx.EVT_BUTTON, self.EventYes )
self._yes.SetForegroundColour( ( 0, 128, 0 ) )
self._no = wx.Button( self, id = wx.ID_CANCEL, label = no_label )
self._no.Bind( wx.EVT_BUTTON, self.EventNo )
self._no.SetForegroundColour( ( 128, 0, 0 ) )
2013-07-31 21:26:38 +00:00
def PopulateControls():
pass
2013-02-19 00:11:43 +00:00
2013-07-31 21:26:38 +00:00
def ArrangeControls():
2013-02-19 00:11:43 +00:00
hbox = wx.BoxSizer( wx.HORIZONTAL )
hbox.AddF( self._yes, FLAGS_SMALL_INDENT )
hbox.AddF( self._no, FLAGS_SMALL_INDENT )
vbox = wx.BoxSizer( wx.VERTICAL )
text = wx.StaticText( self, label = message )
text.Wrap( 480 )
vbox.AddF( text, FLAGS_BIG_INDENT )
vbox.AddF( hbox, FLAGS_BUTTON_SIZERS )
self.SetSizer( vbox )
( x, y ) = self.GetEffectiveMinSize()
self.SetInitialSize( ( x, y ) )
Dialog.__init__( self, parent, 'are you sure?', position = 'center' )
InitialiseControls()
2013-07-31 21:26:38 +00:00
PopulateControls()
ArrangeControls()
2013-02-19 00:11:43 +00:00
self.Bind( wx.EVT_CHAR_HOOK, self.EventCharHook )
2013-07-31 21:26:38 +00:00
wx.CallAfter( self._yes.SetFocus )
2013-02-19 00:11:43 +00:00
def EventCharHook( self, event ):
if event.KeyCode == wx.WXK_ESCAPE: self.EndModal( wx.ID_NO )
else: event.Skip()
def EventNo( self, event ): self.EndModal( wx.ID_NO )
def EventYes( self, event ): self.EndModal( wx.ID_YES )
2013-07-31 21:26:38 +00:00