2017-02-01 21:11:17 +00:00
import ClientCaches
import ClientConstants as CC
import ClientData
2017-04-05 21:16:40 +00:00
import ClientGUICommon
2017-03-15 20:13:04 +00:00
import ClientGUIMenus
2018-05-16 20:09:50 +00:00
import ClientGUIShortcuts
2018-10-24 21:34:02 +00:00
import ClientGUITopLevelWindows
2017-02-01 21:11:17 +00:00
import ClientSearch
2018-04-11 22:30:40 +00:00
import ClientSerialisable
2017-03-22 22:38:15 +00:00
import ClientTags
2017-02-01 21:11:17 +00:00
import collections
import HydrusConstants as HC
import HydrusData
2017-03-22 22:38:15 +00:00
import HydrusExceptions
2017-05-10 21:33:58 +00:00
import HydrusGlobals as HG
2018-04-11 22:30:40 +00:00
import HydrusSerialisable
2017-02-01 21:11:17 +00:00
import HydrusTags
import os
import wx
2017-11-29 21:48:23 +00:00
( ListBoxEvent , EVT_LIST_BOX ) = wx . lib . newevent . NewCommandEvent ( )
2018-01-24 23:09:42 +00:00
class AddEditDeleteListBox ( wx . Panel ) :
def __init__ ( self , parent , height_num_chars , data_to_pretty_callable , add_callable , edit_callable ) :
self . _data_to_pretty_callable = data_to_pretty_callable
self . _add_callable = add_callable
self . _edit_callable = edit_callable
wx . Panel . __init__ ( self , parent )
self . _listbox = wx . ListBox ( self , style = wx . LB_EXTENDED )
self . _add_button = ClientGUICommon . BetterButton ( self , ' add ' , self . _Add )
self . _edit_button = ClientGUICommon . BetterButton ( self , ' edit ' , self . _Edit )
self . _delete_button = ClientGUICommon . BetterButton ( self , ' delete ' , self . _Delete )
2018-04-11 22:30:40 +00:00
self . _enabled_only_on_selection_buttons = [ ]
self . _permitted_object_types = [ ]
2018-01-24 23:09:42 +00:00
#
vbox = wx . BoxSizer ( wx . VERTICAL )
2018-04-11 22:30:40 +00:00
self . _buttons_hbox = wx . BoxSizer ( wx . HORIZONTAL )
2018-01-24 23:09:42 +00:00
2018-04-11 22:30:40 +00:00
self . _buttons_hbox . Add ( self . _add_button , CC . FLAGS_EXPAND_BOTH_WAYS )
self . _buttons_hbox . Add ( self . _edit_button , CC . FLAGS_EXPAND_BOTH_WAYS )
self . _buttons_hbox . Add ( self . _delete_button , CC . FLAGS_EXPAND_BOTH_WAYS )
2018-01-24 23:09:42 +00:00
vbox . Add ( self . _listbox , CC . FLAGS_EXPAND_BOTH_WAYS )
2018-04-11 22:30:40 +00:00
vbox . Add ( self . _buttons_hbox , CC . FLAGS_EXPAND_PERPENDICULAR )
2018-01-24 23:09:42 +00:00
self . SetSizer ( vbox )
#
2018-05-16 20:09:50 +00:00
( width , height ) = ClientGUICommon . ConvertTextToPixels ( self . _listbox , ( 20 , height_num_chars ) )
2018-01-24 23:09:42 +00:00
self . _listbox . SetInitialSize ( ( width , height ) )
#
2018-04-11 22:30:40 +00:00
self . _ShowHideButtons ( )
2018-01-24 23:09:42 +00:00
self . _listbox . Bind ( wx . EVT_LISTBOX , self . EventSelection )
self . _listbox . Bind ( wx . EVT_LISTBOX_DCLICK , self . EventEdit )
def _Add ( self ) :
2018-10-17 21:00:09 +00:00
try :
2018-01-24 23:09:42 +00:00
2018-10-17 21:00:09 +00:00
data = self . _add_callable ( )
except HydrusExceptions . VetoException :
2018-01-24 23:09:42 +00:00
2018-10-17 21:00:09 +00:00
return
self . _AddData ( data )
2018-01-24 23:09:42 +00:00
2018-04-11 22:30:40 +00:00
def _AddAllDefaults ( self , defaults_callable ) :
defaults = defaults_callable ( )
for default in defaults :
self . _AddData ( default )
2018-01-24 23:09:42 +00:00
def _AddData ( self , data ) :
2018-04-11 22:30:40 +00:00
self . _SetNoneDupeName ( data )
2018-01-24 23:09:42 +00:00
pretty_data = self . _data_to_pretty_callable ( data )
self . _listbox . Append ( pretty_data , data )
2018-04-11 22:30:40 +00:00
def _AddSomeDefaults ( self , defaults_callable ) :
defaults = defaults_callable ( )
selected = False
choice_tuples = [ ( self . _data_to_pretty_callable ( default ) , default , selected ) for default in defaults ]
2018-08-08 20:29:54 +00:00
import ClientGUITopLevelWindows
import ClientGUIScrolledPanelsEdit
2018-04-11 22:30:40 +00:00
2018-08-08 20:29:54 +00:00
with ClientGUITopLevelWindows . DialogEdit ( self , ' select the defaults to add ' ) as dlg :
panel = ClientGUIScrolledPanelsEdit . EditChooseMultiple ( dlg , choice_tuples )
dlg . SetPanel ( panel )
2018-04-11 22:30:40 +00:00
if dlg . ShowModal ( ) == wx . ID_OK :
2018-08-08 20:29:54 +00:00
defaults_to_add = panel . GetValue ( )
2018-04-11 22:30:40 +00:00
for default in defaults_to_add :
self . _AddData ( default )
2018-01-24 23:09:42 +00:00
def _Delete ( self ) :
indices = list ( self . _listbox . GetSelections ( ) )
if len ( indices ) == 0 :
return
indices . sort ( reverse = True )
import ClientGUIDialogs
with ClientGUIDialogs . DialogYesNo ( self , ' Remove all selected? ' ) as dlg_yn :
if dlg_yn . ShowModal ( ) == wx . ID_YES :
for i in indices :
self . _listbox . Delete ( i )
2018-02-21 21:59:37 +00:00
wx . QueueEvent ( self . GetEventHandler ( ) , ListBoxEvent ( - 1 ) )
2018-01-24 23:09:42 +00:00
def _Edit ( self ) :
for i in range ( self . _listbox . GetCount ( ) ) :
if not self . _listbox . IsSelected ( i ) :
continue
data = self . _listbox . GetClientData ( i )
2018-10-17 21:00:09 +00:00
try :
2018-01-24 23:09:42 +00:00
2018-10-17 21:00:09 +00:00
new_data = self . _edit_callable ( data )
2018-04-11 22:30:40 +00:00
2018-10-17 21:00:09 +00:00
except HydrusExceptions . VetoException :
2018-01-24 23:09:42 +00:00
break
2018-10-17 21:00:09 +00:00
self . _listbox . Delete ( i )
self . _SetNoneDupeName ( new_data )
pretty_new_data = self . _data_to_pretty_callable ( new_data )
self . _listbox . Insert ( pretty_new_data , i , new_data )
2018-01-24 23:09:42 +00:00
2018-02-21 21:59:37 +00:00
wx . QueueEvent ( self . GetEventHandler ( ) , ListBoxEvent ( - 1 ) )
2018-01-24 23:09:42 +00:00
2018-04-11 22:30:40 +00:00
def _Duplicate ( self ) :
2018-01-24 23:09:42 +00:00
2018-04-11 22:30:40 +00:00
dupe_data = self . _GetExportObject ( )
if dupe_data is not None :
2018-01-24 23:09:42 +00:00
2018-04-11 22:30:40 +00:00
dupe_data = dupe_data . Duplicate ( )
self . _ImportObject ( dupe_data )
2018-01-24 23:09:42 +00:00
2018-04-11 22:30:40 +00:00
def _ExportToClipboard ( self ) :
export_object = self . _GetExportObject ( )
if export_object is not None :
json = export_object . DumpToString ( )
HG . client_controller . pub ( ' clipboard ' , ' text ' , json )
2018-01-24 23:09:42 +00:00
2018-04-11 22:30:40 +00:00
def _ExportToPng ( self ) :
2018-01-24 23:09:42 +00:00
2018-04-11 22:30:40 +00:00
export_object = self . _GetExportObject ( )
if export_object is not None :
import ClientGUITopLevelWindows
import ClientGUISerialisable
with ClientGUITopLevelWindows . DialogNullipotent ( self , ' export to png ' ) as dlg :
panel = ClientGUISerialisable . PngExportPanel ( dlg , export_object )
dlg . SetPanel ( panel )
dlg . ShowModal ( )
2018-01-24 23:09:42 +00:00
2018-04-11 22:30:40 +00:00
def _ExportToPngs ( self ) :
export_object = self . _GetExportObject ( )
if export_object is None :
return
if not isinstance ( export_object , HydrusSerialisable . SerialisableList ) :
self . _ExportToPng ( )
return
import ClientGUITopLevelWindows
import ClientGUISerialisable
2018-06-20 20:20:22 +00:00
with ClientGUITopLevelWindows . DialogNullipotent ( self , ' export to pngs ' ) as dlg :
2018-04-11 22:30:40 +00:00
panel = ClientGUISerialisable . PngsExportPanel ( dlg , export_object )
dlg . SetPanel ( panel )
dlg . ShowModal ( )
2018-01-24 23:09:42 +00:00
2018-04-11 22:30:40 +00:00
def _GetExportObject ( self ) :
to_export = HydrusSerialisable . SerialisableList ( )
for obj in self . GetData ( only_selected = True ) :
to_export . append ( obj )
if len ( to_export ) == 0 :
return None
elif len ( to_export ) == 1 :
return to_export [ 0 ]
else :
return to_export
def _ImportFromClipboard ( self ) :
raw_text = HG . client_controller . GetClipboardText ( )
try :
obj = HydrusSerialisable . CreateFromString ( raw_text )
self . _ImportObject ( obj )
except Exception as e :
wx . MessageBox ( ' I could not understand what was in the clipboard ' )
def _ImportFromPng ( self ) :
with wx . FileDialog ( self , ' select the png or pngs with the encoded data ' , style = wx . FD_OPEN | wx . FD_MULTIPLE , wildcard = ' PNG (*.png)|*.png ' ) as dlg :
if dlg . ShowModal ( ) == wx . ID_OK :
for path in dlg . GetPaths ( ) :
path = HydrusData . ToUnicode ( path )
try :
payload = ClientSerialisable . LoadFromPng ( path )
except Exception as e :
wx . MessageBox ( HydrusData . ToUnicode ( e ) )
return
try :
obj = HydrusSerialisable . CreateFromNetworkString ( payload )
self . _ImportObject ( obj )
except :
wx . MessageBox ( ' I could not understand what was encoded in the png! ' )
return
def _ImportObject ( self , obj ) :
2018-06-20 20:20:22 +00:00
bad_object_type_names = set ( )
2018-04-11 22:30:40 +00:00
if isinstance ( obj , HydrusSerialisable . SerialisableList ) :
for sub_obj in obj :
self . _ImportObject ( sub_obj )
else :
if isinstance ( obj , self . _permitted_object_types ) :
self . _AddData ( obj )
else :
2018-06-20 20:20:22 +00:00
bad_object_type_names . add ( HydrusData . GetTypeName ( type ( obj ) ) )
2018-04-11 22:30:40 +00:00
2018-06-20 20:20:22 +00:00
if len ( bad_object_type_names ) > 0 :
2018-04-11 22:30:40 +00:00
message = ' The imported objects included these types: '
message + = os . linesep * 2
2018-06-20 20:20:22 +00:00
message + = os . linesep . join ( bad_object_type_names )
2018-04-11 22:30:40 +00:00
message + = os . linesep * 2
message + = ' Whereas this control only allows: '
message + = os . linesep * 2
2018-06-20 20:20:22 +00:00
message + = os . linesep . join ( ( HydrusData . GetTypeName ( o ) for o in self . _permitted_object_types ) )
2018-04-11 22:30:40 +00:00
wx . MessageBox ( message )
def _SetNoneDupeName ( self , obj ) :
pass
def _ShowHideButtons ( self ) :
2018-01-24 23:09:42 +00:00
if len ( self . _listbox . GetSelections ( ) ) == 0 :
self . _edit_button . Disable ( )
self . _delete_button . Disable ( )
2018-04-11 22:30:40 +00:00
for button in self . _enabled_only_on_selection_buttons :
button . Disable ( )
2018-01-24 23:09:42 +00:00
else :
self . _edit_button . Enable ( )
self . _delete_button . Enable ( )
2018-04-11 22:30:40 +00:00
for button in self . _enabled_only_on_selection_buttons :
button . Enable ( )
def AddDatas ( self , datas ) :
for data in datas :
self . _AddData ( data )
wx . QueueEvent ( self . GetEventHandler ( ) , ListBoxEvent ( - 1 ) )
def AddDefaultsButton ( self , defaults_callable ) :
import_menu_items = [ ]
all_call = HydrusData . Call ( self . _AddAllDefaults , defaults_callable )
some_call = HydrusData . Call ( self . _AddSomeDefaults , defaults_callable )
import_menu_items . append ( ( ' normal ' , ' add them all ' , ' Load all the defaults. ' , all_call ) )
import_menu_items . append ( ( ' normal ' , ' select from a list ' , ' Load some of the defaults. ' , some_call ) )
button = ClientGUICommon . MenuButton ( self , ' add defaults ' , import_menu_items )
self . _buttons_hbox . Add ( button , CC . FLAGS_VCENTER )
def AddImportExportButtons ( self , permitted_object_types ) :
self . _permitted_object_types = permitted_object_types
export_menu_items = [ ]
export_menu_items . append ( ( ' normal ' , ' to clipboard ' , ' Serialise the selected data and put it on your clipboard. ' , self . _ExportToClipboard ) )
export_menu_items . append ( ( ' normal ' , ' to png ' , ' Serialise the selected data and encode it to an image file you can easily share with other hydrus users. ' , self . _ExportToPng ) )
all_objs_are_named = False not in ( issubclass ( o , HydrusSerialisable . SerialisableBaseNamed ) for o in self . _permitted_object_types )
if all_objs_are_named :
export_menu_items . append ( ( ' normal ' , ' to pngs ' , ' Serialise the selected data and encode it to multiple image files you can easily share with other hydrus users. ' , self . _ExportToPngs ) )
import_menu_items = [ ]
import_menu_items . append ( ( ' normal ' , ' from clipboard ' , ' Load a data from text in your clipboard. ' , self . _ImportFromClipboard ) )
import_menu_items . append ( ( ' normal ' , ' from pngs ' , ' Load a data from an encoded png. ' , self . _ImportFromPng ) )
button = ClientGUICommon . MenuButton ( self , ' export ' , export_menu_items )
self . _buttons_hbox . Add ( button , CC . FLAGS_VCENTER )
self . _enabled_only_on_selection_buttons . append ( button )
button = ClientGUICommon . MenuButton ( self , ' import ' , import_menu_items )
self . _buttons_hbox . Add ( button , CC . FLAGS_VCENTER )
button = ClientGUICommon . BetterButton ( self , ' duplicate ' , self . _Duplicate )
self . _buttons_hbox . Add ( button , CC . FLAGS_VCENTER )
self . _enabled_only_on_selection_buttons . append ( button )
self . _ShowHideButtons ( )
def AddSeparator ( self ) :
self . _buttons_hbox . Add ( ( 20 , 20 ) , CC . FLAGS_EXPAND_PERPENDICULAR )
def Bind ( self , event , handler ) :
self . _listbox . Bind ( event , handler )
def EventEdit ( self , event ) :
self . _Edit ( )
def EventSelection ( self , event ) :
self . _ShowHideButtons ( )
2018-01-24 23:09:42 +00:00
event . Skip ( )
def GetCount ( self ) :
return self . _listbox . GetCount ( )
def GetData ( self , only_selected = False ) :
datas = [ ]
for i in range ( self . _listbox . GetCount ( ) ) :
2018-04-11 22:30:40 +00:00
if only_selected and not self . _listbox . IsSelected ( i ) :
continue
2018-01-24 23:09:42 +00:00
data = self . _listbox . GetClientData ( i )
datas . append ( data )
return datas
2018-04-05 01:22:26 +00:00
def GetValue ( self ) :
return self . GetData ( )
2018-04-11 22:30:40 +00:00
class AddEditDeleteListBoxUniqueNamedObjects ( AddEditDeleteListBox ) :
def _SetNoneDupeName ( self , obj ) :
disallowed_names = { o . GetName ( ) for o in self . GetData ( ) }
HydrusSerialisable . SetNonDupeName ( obj , disallowed_names )
2017-09-27 21:52:54 +00:00
class QueueListBox ( wx . Panel ) :
2018-02-28 22:30:36 +00:00
def __init__ ( self , parent , height_num_chars , data_to_pretty_callable , add_callable = None , edit_callable = None ) :
2017-09-27 21:52:54 +00:00
self . _data_to_pretty_callable = data_to_pretty_callable
self . _add_callable = add_callable
self . _edit_callable = edit_callable
wx . Panel . __init__ ( self , parent )
2017-11-29 21:48:23 +00:00
self . _listbox = wx . ListBox ( self , style = wx . LB_EXTENDED )
2017-09-27 21:52:54 +00:00
self . _up_button = ClientGUICommon . BetterButton ( self , u ' \u2191 ' , self . _Up )
self . _delete_button = ClientGUICommon . BetterButton ( self , ' X ' , self . _Delete )
self . _down_button = ClientGUICommon . BetterButton ( self , u ' \u2193 ' , self . _Down )
self . _add_button = ClientGUICommon . BetterButton ( self , ' add ' , self . _Add )
self . _edit_button = ClientGUICommon . BetterButton ( self , ' edit ' , self . _Edit )
2017-12-13 22:33:07 +00:00
if self . _add_callable is None :
self . _add_button . Hide ( )
if self . _edit_callable is None :
self . _edit_button . Hide ( )
2017-09-27 21:52:54 +00:00
#
vbox = wx . BoxSizer ( wx . VERTICAL )
buttons_vbox = wx . BoxSizer ( wx . VERTICAL )
2018-01-03 22:37:30 +00:00
buttons_vbox . Add ( self . _up_button , CC . FLAGS_VCENTER )
buttons_vbox . Add ( self . _delete_button , CC . FLAGS_VCENTER )
buttons_vbox . Add ( self . _down_button , CC . FLAGS_VCENTER )
2017-09-27 21:52:54 +00:00
hbox = wx . BoxSizer ( wx . HORIZONTAL )
2018-01-03 22:37:30 +00:00
hbox . Add ( self . _listbox , CC . FLAGS_EXPAND_BOTH_WAYS )
hbox . Add ( buttons_vbox , CC . FLAGS_VCENTER )
2017-09-27 21:52:54 +00:00
buttons_hbox = wx . BoxSizer ( wx . HORIZONTAL )
2018-01-03 22:37:30 +00:00
buttons_hbox . Add ( self . _add_button , CC . FLAGS_EXPAND_BOTH_WAYS )
buttons_hbox . Add ( self . _edit_button , CC . FLAGS_EXPAND_BOTH_WAYS )
2017-09-27 21:52:54 +00:00
2018-01-03 22:37:30 +00:00
vbox . Add ( hbox , CC . FLAGS_EXPAND_BOTH_WAYS )
vbox . Add ( buttons_hbox , CC . FLAGS_EXPAND_PERPENDICULAR )
2017-09-27 21:52:54 +00:00
self . SetSizer ( vbox )
#
2018-05-16 20:09:50 +00:00
( width , height ) = ClientGUICommon . ConvertTextToPixels ( self . _listbox , ( 20 , height_num_chars ) )
2018-02-28 22:30:36 +00:00
self . _listbox . SetInitialSize ( ( width , height ) )
#
2017-09-27 21:52:54 +00:00
self . _listbox . Bind ( wx . EVT_LISTBOX , self . EventSelection )
2017-11-29 21:48:23 +00:00
self . _listbox . Bind ( wx . EVT_LISTBOX_DCLICK , self . EventEdit )
2017-09-27 21:52:54 +00:00
def _Add ( self ) :
2018-10-17 21:00:09 +00:00
try :
2017-09-27 21:52:54 +00:00
2018-10-17 21:00:09 +00:00
data = self . _add_callable ( )
except HydrusExceptions . VetoException :
return
2017-09-27 21:52:54 +00:00
2018-10-17 21:00:09 +00:00
self . _AddData ( data )
2017-09-27 21:52:54 +00:00
def _AddData ( self , data ) :
pretty_data = self . _data_to_pretty_callable ( data )
self . _listbox . Append ( pretty_data , data )
def _Delete ( self ) :
2017-11-29 21:48:23 +00:00
indices = list ( self . _listbox . GetSelections ( ) )
2017-09-27 21:52:54 +00:00
if len ( indices ) == 0 :
return
2017-11-29 21:48:23 +00:00
indices . sort ( reverse = True )
2017-09-27 21:52:54 +00:00
import ClientGUIDialogs
with ClientGUIDialogs . DialogYesNo ( self , ' Remove all selected? ' ) as dlg_yn :
if dlg_yn . ShowModal ( ) == wx . ID_YES :
for i in indices :
self . _listbox . Delete ( i )
2018-02-21 21:59:37 +00:00
wx . QueueEvent ( self . GetEventHandler ( ) , ListBoxEvent ( - 1 ) )
2017-11-29 21:48:23 +00:00
2017-09-27 21:52:54 +00:00
def _Down ( self ) :
2017-11-29 21:48:23 +00:00
indices = list ( self . _listbox . GetSelections ( ) )
2017-09-27 21:52:54 +00:00
indices . sort ( reverse = True )
for i in indices :
2017-11-29 21:48:23 +00:00
if i < self . _listbox . GetCount ( ) - 1 :
2017-09-27 21:52:54 +00:00
if not self . _listbox . IsSelected ( i + 1 ) : # is the one below not selected?
self . _SwapRows ( i , i + 1 )
2018-02-21 21:59:37 +00:00
wx . QueueEvent ( self . GetEventHandler ( ) , ListBoxEvent ( - 1 ) )
2017-11-29 21:48:23 +00:00
2017-09-27 21:52:54 +00:00
def _Edit ( self ) :
for i in range ( self . _listbox . GetCount ( ) ) :
if not self . _listbox . IsSelected ( i ) :
continue
data = self . _listbox . GetClientData ( i )
2018-10-17 21:00:09 +00:00
try :
2017-09-27 21:52:54 +00:00
2018-10-17 21:00:09 +00:00
new_data = self . _edit_callable ( data )
2017-09-27 21:52:54 +00:00
2018-10-17 21:00:09 +00:00
except HydrusExceptions . VetoException :
2017-09-27 21:52:54 +00:00
break
2018-10-17 21:00:09 +00:00
self . _listbox . Delete ( i )
pretty_new_data = self . _data_to_pretty_callable ( new_data )
self . _listbox . Insert ( pretty_new_data , i , new_data )
2017-09-27 21:52:54 +00:00
2018-02-21 21:59:37 +00:00
wx . QueueEvent ( self . GetEventHandler ( ) , ListBoxEvent ( - 1 ) )
2017-11-29 21:48:23 +00:00
2017-09-27 21:52:54 +00:00
def _SwapRows ( self , index_a , index_b ) :
2017-11-29 21:48:23 +00:00
a_was_selected = self . _listbox . IsSelected ( index_a )
b_was_selected = self . _listbox . IsSelected ( index_b )
2017-09-27 21:52:54 +00:00
data_a = self . _listbox . GetClientData ( index_a )
data_b = self . _listbox . GetClientData ( index_b )
pretty_data_a = self . _data_to_pretty_callable ( data_a )
pretty_data_b = self . _data_to_pretty_callable ( data_b )
self . _listbox . Delete ( index_a )
self . _listbox . Insert ( pretty_data_b , index_a , data_b )
self . _listbox . Delete ( index_b )
self . _listbox . Insert ( pretty_data_a , index_b , data_a )
2017-11-29 21:48:23 +00:00
if b_was_selected :
self . _listbox . Select ( index_a )
if a_was_selected :
self . _listbox . Select ( index_b )
2017-09-27 21:52:54 +00:00
def _Up ( self ) :
indices = self . _listbox . GetSelections ( )
for i in indices :
if i > 0 :
if not self . _listbox . IsSelected ( i - 1 ) : # is the one above not selected?
self . _SwapRows ( i , i - 1 )
2018-02-21 21:59:37 +00:00
wx . QueueEvent ( self . GetEventHandler ( ) , ListBoxEvent ( - 1 ) )
2017-11-29 21:48:23 +00:00
2017-09-27 21:52:54 +00:00
def AddDatas ( self , datas ) :
for data in datas :
self . _AddData ( data )
2018-02-21 21:59:37 +00:00
wx . QueueEvent ( self . GetEventHandler ( ) , ListBoxEvent ( - 1 ) )
2017-11-29 21:48:23 +00:00
2017-09-27 21:52:54 +00:00
def Bind ( self , event , handler ) :
self . _listbox . Bind ( event , handler )
2017-11-29 21:48:23 +00:00
def EventEdit ( self , event ) :
self . _Edit ( )
2017-09-27 21:52:54 +00:00
def EventSelection ( self , event ) :
2017-11-29 21:48:23 +00:00
if len ( self . _listbox . GetSelections ( ) ) == 0 :
2017-09-27 21:52:54 +00:00
self . _up_button . Disable ( )
self . _delete_button . Disable ( )
self . _down_button . Disable ( )
self . _edit_button . Disable ( )
else :
self . _up_button . Enable ( )
self . _delete_button . Enable ( )
self . _down_button . Enable ( )
self . _edit_button . Enable ( )
event . Skip ( )
2017-12-13 22:33:07 +00:00
def GetCount ( self ) :
return self . _listbox . GetCount ( )
2017-09-27 21:52:54 +00:00
def GetData ( self , only_selected = False ) :
datas = [ ]
for i in range ( self . _listbox . GetCount ( ) ) :
data = self . _listbox . GetClientData ( i )
datas . append ( data )
return datas
2017-12-13 22:33:07 +00:00
def Pop ( self ) :
if self . _listbox . GetCount ( ) == 0 :
return None
data = self . _listbox . GetClientData ( 0 )
self . _listbox . Delete ( 0 )
return data
2017-02-01 21:11:17 +00:00
class ListBox ( wx . ScrolledWindow ) :
TEXT_X_PADDING = 3
2018-05-23 21:05:06 +00:00
def __init__ ( self , parent , height_num_chars = 10 ) :
2017-02-01 21:11:17 +00:00
wx . ScrolledWindow . __init__ ( self , parent , style = wx . VSCROLL | wx . BORDER_DOUBLE )
self . _background_colour = wx . Colour ( 255 , 255 , 255 )
2017-03-22 22:38:15 +00:00
self . _terms = set ( )
self . _ordered_terms = [ ]
2017-02-01 21:11:17 +00:00
self . _selected_terms = set ( )
2017-03-22 22:38:15 +00:00
self . _terms_to_texts = { }
2017-02-01 21:11:17 +00:00
self . _last_hit_index = None
self . _last_view_start = None
self . _dirty = True
2018-01-03 22:37:30 +00:00
self . _client_bmp = wx . Bitmap ( 20 , 20 , 24 )
2017-03-22 22:38:15 +00:00
2017-02-01 21:11:17 +00:00
dc = wx . MemoryDC ( self . _client_bmp )
dc . SetFont ( wx . SystemSettings . GetFont ( wx . SYS_DEFAULT_GUI_FONT ) )
( text_x , self . _text_y ) = dc . GetTextExtent ( ' abcdefghijklmnopqrstuvwxyz ' )
self . _num_rows_per_page = 0
self . SetScrollRate ( 0 , self . _text_y )
2018-05-23 21:05:06 +00:00
( min_width , min_height ) = ClientGUICommon . ConvertTextToPixels ( self , ( 16 , height_num_chars ) )
self . SetMinClientSize ( ( min_width , min_height ) )
2017-02-01 21:11:17 +00:00
self . Bind ( wx . EVT_PAINT , self . EventPaint )
self . Bind ( wx . EVT_SIZE , self . EventResize )
self . Bind ( wx . EVT_ERASE_BACKGROUND , self . EventEraseBackground )
self . Bind ( wx . EVT_LEFT_DOWN , self . EventMouseSelect )
self . Bind ( wx . EVT_LEFT_DCLICK , self . EventDClick )
2017-04-19 20:58:30 +00:00
self . Bind ( wx . EVT_CHAR_HOOK , self . EventCharHook )
2017-02-01 21:11:17 +00:00
def __len__ ( self ) :
2017-03-22 22:38:15 +00:00
return len ( self . _ordered_terms )
2017-02-01 21:11:17 +00:00
def _Activate ( self ) :
2017-03-29 19:39:34 +00:00
pass
def _DeleteActivate ( self ) :
pass
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
def _AppendTerm ( self , term ) :
2017-03-29 19:39:34 +00:00
was_selected_before = term in self . _selected_terms
2017-03-22 22:38:15 +00:00
if term in self . _terms :
self . _RemoveTerm ( term )
self . _terms . add ( term )
self . _ordered_terms . append ( term )
self . _terms_to_texts [ term ] = self . _GetTextFromTerm ( term )
2017-03-29 19:39:34 +00:00
if was_selected_before :
self . _selected_terms . add ( term )
2017-03-22 22:38:15 +00:00
def _Clear ( self ) :
self . _terms = set ( )
self . _ordered_terms = [ ]
self . _selected_terms = set ( )
self . _terms_to_texts = { }
self . _last_hit_index = None
self . _last_view_start = None
self . _dirty = True
def _DataHasChanged ( self ) :
2018-01-10 22:41:51 +00:00
self . _SetVirtualSize ( )
2018-01-03 22:37:30 +00:00
self . _SetDirty ( )
2017-03-22 22:38:15 +00:00
2018-02-21 21:59:37 +00:00
wx . QueueEvent ( self . GetEventHandler ( ) , ListBoxEvent ( - 1 ) )
2017-11-22 21:03:07 +00:00
2017-03-22 22:38:15 +00:00
2017-02-01 21:11:17 +00:00
def _Deselect ( self , index ) :
2017-03-22 22:38:15 +00:00
term = self . _GetTerm ( index )
2017-02-01 21:11:17 +00:00
self . _selected_terms . discard ( term )
2017-03-22 22:38:15 +00:00
def _DeselectAll ( self ) :
self . _selected_terms = set ( )
2017-02-01 21:11:17 +00:00
def _GetIndexUnderMouse ( self , mouse_event ) :
( xUnit , yUnit ) = self . GetScrollPixelsPerUnit ( )
( x_scroll , y_scroll ) = self . GetViewStart ( )
y_offset = y_scroll * yUnit
y = mouse_event . GetY ( ) + y_offset
row_index = ( y / self . _text_y )
2017-03-22 22:38:15 +00:00
if row_index > = len ( self . _ordered_terms ) :
2017-02-01 21:11:17 +00:00
return None
return row_index
def _GetSelectedIncludeExcludePredicates ( self ) :
include_predicates = [ ]
exclude_predicates = [ ]
for term in self . _selected_terms :
if isinstance ( term , ClientSearch . Predicate ) :
predicate_type = term . GetType ( )
if predicate_type in ( HC . PREDICATE_TYPE_TAG , HC . PREDICATE_TYPE_NAMESPACE , HC . PREDICATE_TYPE_WILDCARD ) :
value = term . GetValue ( )
include_predicates . append ( ClientSearch . Predicate ( predicate_type , value ) )
exclude_predicates . append ( ClientSearch . Predicate ( predicate_type , value , False ) )
else :
include_predicates . append ( term )
else :
s = term
include_predicates . append ( ClientSearch . Predicate ( HC . PREDICATE_TYPE_TAG , term ) )
exclude_predicates . append ( ClientSearch . Predicate ( HC . PREDICATE_TYPE_TAG , term , False ) )
return ( include_predicates , exclude_predicates )
2017-03-22 22:38:15 +00:00
def _GetTerm ( self , index ) :
if index < 0 or index > len ( self . _ordered_terms ) - 1 :
raise HydrusExceptions . DataMissing ( ' No term for index ' + str ( index ) )
return self . _ordered_terms [ index ]
def _GetTextColour ( self , term ) :
return ( 0 , 111 , 250 )
2018-01-31 22:58:15 +00:00
def _GetSafeHitIndex ( self , hit_index , direction = None ) :
if hit_index is not None :
if hit_index == - 1 or hit_index > len ( self . _ordered_terms ) :
hit_index = len ( self . _ordered_terms ) - 1
elif hit_index == len ( self . _ordered_terms ) or hit_index < - 1 :
hit_index = 0
return hit_index
2017-03-22 22:38:15 +00:00
def _GetSimplifiedTextFromTerm ( self , term ) :
return self . _GetTextFromTerm ( term )
def _GetTextFromTerm ( self , term ) :
raise NotImplementedError ( )
2017-02-01 21:11:17 +00:00
def _HandleClick ( self , event ) :
hit_index = self . _GetIndexUnderMouse ( event )
shift = event . ShiftDown ( )
ctrl = event . CmdDown ( )
self . _Hit ( shift , ctrl , hit_index )
def _Hit ( self , shift , ctrl , hit_index ) :
2018-01-31 22:58:15 +00:00
hit_index = self . _GetSafeHitIndex ( hit_index )
2017-02-01 21:11:17 +00:00
to_select = set ( )
to_deselect = set ( )
2017-03-22 22:38:15 +00:00
deselect_all = False
2017-02-01 21:11:17 +00:00
if shift :
if hit_index is not None :
if self . _last_hit_index is not None :
lower = min ( hit_index , self . _last_hit_index )
upper = max ( hit_index , self . _last_hit_index )
to_select = range ( lower , upper + 1 )
else :
to_select . add ( hit_index )
elif ctrl :
if hit_index is not None :
2017-03-22 22:38:15 +00:00
if self . _IsSelected ( hit_index ) :
2017-02-01 21:11:17 +00:00
to_deselect . add ( hit_index )
else :
to_select . add ( hit_index )
else :
if hit_index is None :
2017-03-22 22:38:15 +00:00
deselect_all = True
2017-02-01 21:11:17 +00:00
else :
2017-03-22 22:38:15 +00:00
if not self . _IsSelected ( hit_index ) :
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
deselect_all = True
2017-02-01 21:11:17 +00:00
to_select . add ( hit_index )
2017-03-22 22:38:15 +00:00
if deselect_all :
self . _DeselectAll ( )
2017-02-01 21:11:17 +00:00
for index in to_select :
self . _Select ( index )
for index in to_deselect :
self . _Deselect ( index )
self . _last_hit_index = hit_index
if self . _last_hit_index is not None :
y = self . _text_y * self . _last_hit_index
( start_x , start_y ) = self . GetViewStart ( )
( x_unit , y_unit ) = self . GetScrollPixelsPerUnit ( )
( width , height ) = self . GetClientSize ( )
if y < start_y * y_unit :
y_to_scroll_to = y / y_unit
2018-01-31 22:58:15 +00:00
#self.Scroll( -1, y_to_scroll_to )
2017-02-01 21:11:17 +00:00
2018-02-21 21:59:37 +00:00
wx . QueueEvent ( self . GetEventHandler ( ) , wx . ScrollWinEvent ( wx . wxEVT_SCROLLWIN_THUMBRELEASE , pos = y_to_scroll_to ) )
2017-02-01 21:11:17 +00:00
elif y > ( start_y * y_unit ) + height - self . _text_y :
y_to_scroll_to = ( y - height ) / y_unit
2018-01-31 22:58:15 +00:00
#self.Scroll( -1, y_to_scroll_to + 2 )
2017-02-01 21:11:17 +00:00
2018-02-21 21:59:37 +00:00
wx . QueueEvent ( self . GetEventHandler ( ) , wx . ScrollWinEvent ( wx . wxEVT_SCROLLWIN_THUMBRELEASE , pos = y_to_scroll_to + 2 ) )
2017-02-01 21:11:17 +00:00
self . _SetDirty ( )
2017-03-22 22:38:15 +00:00
def _IsSelected ( self , index ) :
try :
term = self . _GetTerm ( index )
except HydrusExceptions . DataMissing :
return False
return term in self . _selected_terms
2017-02-01 21:11:17 +00:00
def _Redraw ( self , dc ) :
( xUnit , yUnit ) = self . GetScrollPixelsPerUnit ( )
( x_scroll , y_scroll ) = self . GetViewStart ( )
self . _last_view_start = self . GetViewStart ( )
y_offset = y_scroll * yUnit
( my_width , my_height ) = self . GetClientSize ( )
first_visible_index = y_offset / self . _text_y
last_visible_index = ( y_offset + my_height ) / self . _text_y
if ( y_offset + my_height ) % self . _text_y != 0 :
last_visible_index + = 1
2017-03-22 22:38:15 +00:00
last_visible_index = min ( last_visible_index , len ( self . _ordered_terms ) - 1 )
2017-02-01 21:11:17 +00:00
dc . SetFont ( wx . SystemSettings . GetFont ( wx . SYS_DEFAULT_GUI_FONT ) )
dc . SetBackground ( wx . Brush ( self . _background_colour ) )
dc . Clear ( )
for ( i , current_index ) in enumerate ( range ( first_visible_index , last_visible_index + 1 ) ) :
2017-03-22 22:38:15 +00:00
term = self . _GetTerm ( current_index )
text = self . _terms_to_texts [ term ]
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
( r , g , b ) = self . _GetTextColour ( term )
2017-02-01 21:11:17 +00:00
text_colour = wx . Colour ( r , g , b )
2017-03-22 22:38:15 +00:00
if term in self . _selected_terms :
2017-02-01 21:11:17 +00:00
dc . SetBrush ( wx . Brush ( text_colour ) )
dc . SetPen ( wx . TRANSPARENT_PEN )
dc . DrawRectangle ( 0 , i * self . _text_y , my_width , self . _text_y )
text_colour = self . _background_colour
dc . SetTextForeground ( text_colour )
( x , y ) = ( self . TEXT_X_PADDING , i * self . _text_y )
dc . DrawText ( text , x , y )
self . _dirty = False
2017-03-22 22:38:15 +00:00
def _RefreshTexts ( self ) :
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
self . _terms_to_texts = { term : self . _GetTextFromTerm ( term ) for term in self . _terms }
self . _SetDirty ( )
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
def _RemoveSelectedTerms ( self ) :
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
for term in list ( self . _selected_terms ) :
self . _RemoveTerm ( term )
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
def _RemoveTerm ( self , term ) :
if term in self . _terms :
self . _terms . discard ( term )
self . _ordered_terms . remove ( term )
self . _selected_terms . discard ( term )
del self . _terms_to_texts [ term ]
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
def _Select ( self , index ) :
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
term = self . _GetTerm ( index )
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
self . _selected_terms . add ( term )
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
def _SelectAll ( self ) :
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
self . _selected_terms = set ( self . _terms )
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
def _SetDirty ( self ) :
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
self . _dirty = True
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
self . Refresh ( )
2018-01-10 22:41:51 +00:00
def _SetVirtualSize ( self ) :
( my_x , my_y ) = self . GetClientSize ( )
ideal_virtual_size = ( my_x , max ( self . _text_y * len ( self . _ordered_terms ) , my_y ) )
if ideal_virtual_size != self . GetVirtualSize ( ) :
self . SetVirtualSize ( ideal_virtual_size )
2017-03-22 22:38:15 +00:00
def _SortByText ( self ) :
def lexicographic_key ( term ) :
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
return self . _terms_to_texts [ term ]
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
self . _ordered_terms . sort ( key = lexicographic_key )
2017-02-01 21:11:17 +00:00
2017-04-19 20:58:30 +00:00
def EventCharHook ( self , event ) :
2017-02-01 21:11:17 +00:00
shift = event . ShiftDown ( )
ctrl = event . CmdDown ( )
key_code = event . GetKeyCode ( )
2017-04-05 21:16:40 +00:00
if ClientGUICommon . WindowHasFocus ( self ) and key_code in CC . DELETE_KEYS :
2017-03-29 19:39:34 +00:00
self . _DeleteActivate ( )
elif key_code in ( wx . WXK_RETURN , wx . WXK_NUMPAD_ENTER ) :
2017-02-01 21:11:17 +00:00
self . _Activate ( )
else :
if ctrl and key_code in ( ord ( ' A ' ) , ord ( ' a ' ) ) :
2017-03-22 22:38:15 +00:00
self . _SelectAll ( )
self . _SetDirty ( )
2017-02-01 21:11:17 +00:00
else :
hit_index = None
2017-04-05 21:16:40 +00:00
if len ( self . _ordered_terms ) > 1 :
2017-02-01 21:11:17 +00:00
2018-01-31 22:58:15 +00:00
roll_up = False
roll_down = False
2017-02-01 21:11:17 +00:00
if key_code in ( wx . WXK_HOME , wx . WXK_NUMPAD_HOME ) :
hit_index = 0
elif key_code in ( wx . WXK_END , wx . WXK_NUMPAD_END ) :
2017-03-22 22:38:15 +00:00
hit_index = len ( self . _ordered_terms ) - 1
2017-02-01 21:11:17 +00:00
2018-01-31 22:58:15 +00:00
roll_up = True
2017-02-01 21:11:17 +00:00
elif self . _last_hit_index is not None :
if key_code in ( wx . WXK_UP , wx . WXK_NUMPAD_UP ) :
hit_index = self . _last_hit_index - 1
2018-01-31 22:58:15 +00:00
roll_up = True
2017-02-01 21:11:17 +00:00
elif key_code in ( wx . WXK_DOWN , wx . WXK_NUMPAD_DOWN ) :
hit_index = self . _last_hit_index + 1
2018-01-31 22:58:15 +00:00
roll_down = True
2017-02-01 21:11:17 +00:00
elif key_code in ( wx . WXK_PAGEUP , wx . WXK_NUMPAD_PAGEUP ) :
hit_index = max ( 0 , self . _last_hit_index - self . _num_rows_per_page )
2018-01-31 22:58:15 +00:00
roll_up = True
2017-02-01 21:11:17 +00:00
elif key_code in ( wx . WXK_PAGEDOWN , wx . WXK_NUMPAD_PAGEDOWN ) :
2017-03-22 22:38:15 +00:00
hit_index = min ( len ( self . _ordered_terms ) - 1 , self . _last_hit_index + self . _num_rows_per_page )
2017-02-01 21:11:17 +00:00
2018-01-31 22:58:15 +00:00
roll_down = True
2017-02-01 21:11:17 +00:00
if hit_index is None :
event . Skip ( )
else :
2018-01-31 22:58:15 +00:00
if roll_up :
hit_index = self . _GetSafeHitIndex ( hit_index , - 1 )
if roll_down :
hit_index = self . _GetSafeHitIndex ( hit_index , 1 )
2017-02-01 21:11:17 +00:00
self . _Hit ( shift , ctrl , hit_index )
2017-04-19 20:58:30 +00:00
def EventDClick ( self , event ) :
self . _Activate ( )
def EventEraseBackground ( self , event ) : pass
2017-02-01 21:11:17 +00:00
def EventMouseSelect ( self , event ) :
self . _HandleClick ( event )
event . Skip ( )
def EventPaint ( self , event ) :
( my_x , my_y ) = self . GetClientSize ( )
if ( my_x , my_y ) != self . _client_bmp . GetSize ( ) :
2018-01-03 22:37:30 +00:00
self . _client_bmp = wx . Bitmap ( my_x , my_y , 24 )
2017-02-01 21:11:17 +00:00
self . _dirty = True
dc = wx . BufferedPaintDC ( self , self . _client_bmp )
if self . _dirty or self . _last_view_start != self . GetViewStart ( ) :
self . _Redraw ( dc )
def EventResize ( self , event ) :
( my_x , my_y ) = self . GetClientSize ( )
self . _num_rows_per_page = my_y / self . _text_y
2018-01-10 22:41:51 +00:00
self . _SetVirtualSize ( )
2017-02-01 21:11:17 +00:00
self . _SetDirty ( )
2017-03-22 22:38:15 +00:00
def GetClientData ( self , index = None ) :
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
if index is None :
return set ( self . _terms )
else :
return self . _GetTerm ( index )
2017-02-01 21:11:17 +00:00
def GetIdealHeight ( self ) :
2017-03-22 22:38:15 +00:00
return self . _text_y * len ( self . _ordered_terms ) + 20
2017-02-01 21:11:17 +00:00
2018-01-31 22:58:15 +00:00
def MoveSelectionDown ( self ) :
if len ( self . _ordered_terms ) > 1 and self . _last_hit_index is not None :
self . _Hit ( False , False , self . _last_hit_index + 1 )
def MoveSelectionUp ( self ) :
if len ( self . _ordered_terms ) > 1 and self . _last_hit_index is not None :
self . _Hit ( False , False , self . _last_hit_index - 1 )
2017-02-01 21:11:17 +00:00
class ListBoxTags ( ListBox ) :
has_counts = False
can_spawn_new_windows = True
def __init__ ( self , * args , * * kwargs ) :
ListBox . __init__ ( self , * args , * * kwargs )
2017-03-22 22:38:15 +00:00
self . _get_current_predicates_callable = None
2017-02-01 21:11:17 +00:00
2017-09-20 19:47:31 +00:00
self . _UpdateBackgroundColour ( )
2017-02-01 21:11:17 +00:00
self . Bind ( wx . EVT_RIGHT_DOWN , self . EventMouseRightClick )
self . Bind ( wx . EVT_MIDDLE_DOWN , self . EventMouseMiddleClick )
2017-05-10 21:33:58 +00:00
HG . client_controller . sub ( self , ' SiblingsHaveChanged ' , ' notify_new_siblings_gui ' )
2017-09-20 19:47:31 +00:00
HG . client_controller . sub ( self , ' _UpdateBackgroundColour ' , ' notify_new_colourset ' )
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
def _GetNamespaceColours ( self ) :
return HC . options [ ' namespace_colours ' ]
2017-02-01 21:11:17 +00:00
def _GetAllTagsForClipboard ( self , with_counts = False ) :
2017-03-29 19:39:34 +00:00
texts = list ( self . _terms_to_texts . values ( ) )
texts . sort ( )
return texts
2017-03-22 22:38:15 +00:00
def _GetNamespaceFromTerm ( self , term ) :
raise NotImplementedError ( )
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
def _GetTextColour ( self , term ) :
2017-02-01 21:11:17 +00:00
namespace_colours = self . _GetNamespaceColours ( )
2017-03-22 22:38:15 +00:00
namespace = self . _GetNamespaceFromTerm ( term )
2017-02-08 22:27:00 +00:00
2017-03-22 22:38:15 +00:00
if namespace in namespace_colours :
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
( r , g , b ) = namespace_colours [ namespace ]
2017-02-08 22:27:00 +00:00
else :
2017-03-22 22:38:15 +00:00
( r , g , b ) = namespace_colours [ None ]
2017-02-01 21:11:17 +00:00
return ( r , g , b )
def _NewSearchPage ( self ) :
predicates = [ ]
for term in self . _selected_terms :
if isinstance ( term , ClientSearch . Predicate ) :
predicates . append ( term )
else :
predicates . append ( ClientSearch . Predicate ( HC . PREDICATE_TYPE_TAG , term ) )
2018-10-17 21:00:09 +00:00
predicates = HG . client_controller . GetGUI ( ) . FleshOutPredicates ( predicates )
2017-02-01 21:11:17 +00:00
if len ( predicates ) > 0 :
2018-03-22 00:03:33 +00:00
s = [ predicate . GetUnicode ( ) for predicate in predicates ]
s . sort ( )
page_name = ' , ' . join ( s )
HG . client_controller . pub ( ' new_page_query ' , CC . LOCAL_FILE_SERVICE_KEY , initial_predicates = predicates , page_name = page_name )
2017-02-01 21:11:17 +00:00
2018-10-17 21:00:09 +00:00
def _NewSearchPageForEach ( self ) :
predicates = [ ]
for term in self . _selected_terms :
if isinstance ( term , ClientSearch . Predicate ) :
predicates . append ( term )
else :
predicates . append ( ClientSearch . Predicate ( HC . PREDICATE_TYPE_TAG , term ) )
predicates = HG . client_controller . GetGUI ( ) . FleshOutPredicates ( predicates )
for predicate in predicates :
page_name = predicate . GetUnicode ( )
HG . client_controller . pub ( ' new_page_query ' , CC . LOCAL_FILE_SERVICE_KEY , initial_predicates = ( predicate , ) , page_name = page_name )
2017-09-20 19:47:31 +00:00
def _ProcessMenuCopyEvent ( self , command ) :
2017-02-01 21:11:17 +00:00
2017-09-20 19:47:31 +00:00
if command in ( ' copy_terms ' , ' copy_sub_terms ' ) :
2017-02-01 21:11:17 +00:00
2017-09-20 19:47:31 +00:00
texts = [ ]
2017-02-01 21:11:17 +00:00
2017-09-20 19:47:31 +00:00
for term in self . _selected_terms :
2017-02-01 21:11:17 +00:00
2017-09-20 19:47:31 +00:00
if isinstance ( term , ClientSearch . Predicate ) :
2017-02-01 21:11:17 +00:00
2017-09-20 19:47:31 +00:00
text = term . GetUnicode ( with_count = False )
2017-02-01 21:11:17 +00:00
2017-09-20 19:47:31 +00:00
else :
2017-02-01 21:11:17 +00:00
2017-09-20 19:47:31 +00:00
text = HydrusData . ToUnicode ( term )
2017-02-01 21:11:17 +00:00
2017-09-20 19:47:31 +00:00
if command == ' copy_sub_terms ' :
2017-02-01 21:11:17 +00:00
2017-09-20 19:47:31 +00:00
( namespace_gumpf , text ) = HydrusTags . SplitTag ( text )
2017-02-01 21:11:17 +00:00
2017-09-20 19:47:31 +00:00
texts . append ( text )
2017-02-01 21:11:17 +00:00
2017-09-20 19:47:31 +00:00
texts . sort ( )
text = os . linesep . join ( texts )
elif command == ' copy_all_tags ' :
text = os . linesep . join ( self . _GetAllTagsForClipboard ( with_counts = False ) )
elif command == ' copy_all_tags_with_counts ' :
text = os . linesep . join ( self . _GetAllTagsForClipboard ( with_counts = True ) )
HG . client_controller . pub ( ' clipboard ' , ' text ' , text )
def _ProcessMenuPredicateEvent ( self , command ) :
pass
def _ProcessMenuTagEvent ( self , command ) :
2018-10-24 21:34:02 +00:00
import ClientGUITags
2017-09-20 19:47:31 +00:00
2018-10-31 21:41:14 +00:00
if command == ' censorship ' :
title = ' manage tag censorship '
elif command == ' parent ' :
title = ' manage tag parents '
elif command == ' sibling ' :
title = ' manage tag siblings '
with ClientGUITopLevelWindows . DialogManage ( self , title ) as dlg :
2017-09-20 19:47:31 +00:00
2018-10-24 21:34:02 +00:00
if command == ' censorship ' :
2017-02-01 21:11:17 +00:00
2018-10-24 21:34:02 +00:00
( tag , ) = self . _selected_terms
2017-02-01 21:11:17 +00:00
2018-10-24 21:34:02 +00:00
panel = ClientGUITags . ManageTagCensorshipPanel ( dlg , tag )
2017-02-01 21:11:17 +00:00
2018-10-24 21:34:02 +00:00
elif command == ' parent ' :
2017-02-01 21:11:17 +00:00
2018-10-24 21:34:02 +00:00
panel = ClientGUITags . ManageTagParents ( dlg , self . _selected_terms )
2017-02-01 21:11:17 +00:00
2018-10-24 21:34:02 +00:00
elif command == ' sibling ' :
panel = ClientGUITags . ManageTagSiblings ( dlg , self . _selected_terms )
2017-02-01 21:11:17 +00:00
2018-10-24 21:34:02 +00:00
dlg . SetPanel ( panel )
dlg . ShowModal ( )
2017-02-01 21:11:17 +00:00
2017-09-20 19:47:31 +00:00
def _UpdateBackgroundColour ( self ) :
2017-12-06 22:06:56 +00:00
new_options = HG . client_controller . new_options
2017-09-20 19:47:31 +00:00
self . _background_colour = new_options . GetColour ( CC . COLOUR_TAGS_BOX )
self . Refresh ( )
2017-02-01 21:11:17 +00:00
def EventMouseMiddleClick ( self , event ) :
self . _HandleClick ( event )
if self . can_spawn_new_windows :
self . _NewSearchPage ( )
def EventMouseRightClick ( self , event ) :
self . _HandleClick ( event )
2017-03-22 22:38:15 +00:00
if len ( self . _ordered_terms ) > 0 :
2017-02-01 21:11:17 +00:00
menu = wx . Menu ( )
if len ( self . _selected_terms ) > 0 :
if len ( self . _selected_terms ) == 1 :
( term , ) = self . _selected_terms
if isinstance ( term , ClientSearch . Predicate ) :
if term . GetType ( ) == HC . PREDICATE_TYPE_TAG :
selection_string = ' " ' + term . GetValue ( ) + ' " '
else :
selection_string = ' " ' + term . GetUnicode ( with_count = False ) + ' " '
else :
selection_string = ' " ' + HydrusData . ToUnicode ( term ) + ' " '
else :
selection_string = ' selected '
2017-03-22 22:38:15 +00:00
if self . _get_current_predicates_callable is not None :
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
current_predicates = self . _get_current_predicates_callable ( )
2017-02-01 21:11:17 +00:00
( include_predicates , exclude_predicates ) = self . _GetSelectedIncludeExcludePredicates ( )
if current_predicates is not None :
if True in ( include_predicate in current_predicates for include_predicate in include_predicates ) :
2017-09-20 19:47:31 +00:00
ClientGUIMenus . AppendMenuItem ( self , menu , ' discard ' + selection_string + ' from current search ' , ' Remove the selected predicates from the current search. ' , self . _ProcessMenuPredicateEvent , ' remove_include_predicates ' )
2017-02-01 21:11:17 +00:00
if True in ( include_predicate not in current_predicates for include_predicate in include_predicates ) :
2017-09-20 19:47:31 +00:00
ClientGUIMenus . AppendMenuItem ( self , menu , ' require ' + selection_string + ' for current search ' , ' Add the selected predicates from the current search. ' , self . _ProcessMenuPredicateEvent , ' add_include_predicates ' )
2017-02-01 21:11:17 +00:00
if True in ( exclude_predicate in current_predicates for exclude_predicate in exclude_predicates ) :
2017-09-20 19:47:31 +00:00
ClientGUIMenus . AppendMenuItem ( self , menu , ' permit ' + selection_string + ' for current search ' , ' Stop disallowing the selected predicates from the current search. ' , self . _ProcessMenuPredicateEvent , ' remove_exclude_predicates ' )
2017-02-01 21:11:17 +00:00
if True in ( exclude_predicate not in current_predicates for exclude_predicate in exclude_predicates ) :
2017-09-20 19:47:31 +00:00
ClientGUIMenus . AppendMenuItem ( self , menu , ' exclude ' + selection_string + ' from current search ' , ' Disallow the selected predicates for the current search. ' , self . _ProcessMenuPredicateEvent , ' add_exclude_predicates ' )
2017-02-01 21:11:17 +00:00
2017-03-15 20:13:04 +00:00
ClientGUIMenus . AppendSeparator ( menu )
2017-02-01 21:11:17 +00:00
if self . can_spawn_new_windows :
2017-09-20 19:47:31 +00:00
ClientGUIMenus . AppendMenuItem ( self , menu , ' open a new search page for ' + selection_string , ' Open a new search page starting with the selected predicates. ' , self . _NewSearchPage )
2017-02-01 21:11:17 +00:00
2018-10-17 21:00:09 +00:00
if len ( self . _selected_terms ) > 1 :
ClientGUIMenus . AppendMenuItem ( self , menu , ' open new search pages for each in selection ' , ' Open one new search page for each selected predicate. ' , self . _NewSearchPageForEach )
2017-02-01 21:11:17 +00:00
2017-03-15 20:13:04 +00:00
ClientGUIMenus . AppendSeparator ( menu )
2017-02-01 21:11:17 +00:00
2017-09-20 19:47:31 +00:00
ClientGUIMenus . AppendMenuItem ( self , menu , ' copy ' + selection_string , ' Copy the selected predicates to your clipboard. ' , self . _ProcessMenuCopyEvent , ' copy_terms ' )
2017-02-01 21:11:17 +00:00
if len ( self . _selected_terms ) == 1 :
2017-02-08 22:27:00 +00:00
( namespace , subtag ) = HydrusTags . SplitTag ( selection_string )
if namespace != ' ' :
2017-02-01 21:11:17 +00:00
2017-02-08 22:27:00 +00:00
sub_selection_string = ' " ' + subtag
2017-02-01 21:11:17 +00:00
2017-09-20 19:47:31 +00:00
ClientGUIMenus . AppendMenuItem ( self , menu , ' copy ' + sub_selection_string , ' Copy the selected sub-predicates to your clipboard. ' , self . _ProcessMenuCopyEvent , ' copy_sub_terms ' )
2017-02-01 21:11:17 +00:00
else :
2017-09-20 19:47:31 +00:00
ClientGUIMenus . AppendMenuItem ( self , menu , ' copy selected subtags ' , ' Copy the selected sub-predicates to your clipboard. ' , self . _ProcessMenuCopyEvent , ' copy_sub_terms ' )
2017-02-01 21:11:17 +00:00
2017-03-15 20:13:04 +00:00
ClientGUIMenus . AppendSeparator ( menu )
2017-03-22 22:38:15 +00:00
if len ( self . _ordered_terms ) > len ( self . _selected_terms ) :
2017-02-01 21:11:17 +00:00
2017-09-20 19:47:31 +00:00
ClientGUIMenus . AppendMenuItem ( self , menu , ' copy all tags ' , ' Copy all the predicates in this list to your clipboard. ' , self . _ProcessMenuCopyEvent , ' copy_all_tags ' )
if self . has_counts :
ClientGUIMenus . AppendMenuItem ( self , menu , ' copy all tags with counts ' , ' Copy all the predicates in this list, with their counts, to your clipboard. ' , self . _ProcessMenuCopyEvent , ' copy_all_tags_with_counts ' )
2017-02-01 21:11:17 +00:00
if self . can_spawn_new_windows and len ( self . _selected_terms ) > 0 :
term_types = [ type ( term ) for term in self . _selected_terms ]
if str in term_types or unicode in term_types :
2017-03-15 20:13:04 +00:00
ClientGUIMenus . AppendSeparator ( menu )
2017-02-01 21:11:17 +00:00
if len ( self . _selected_terms ) == 1 :
( tag , ) = self . _selected_terms
text = tag
else :
text = ' selection '
if len ( self . _selected_terms ) == 1 :
2017-09-20 19:47:31 +00:00
ClientGUIMenus . AppendMenuItem ( self , menu , ' censor ' + text , ' Hide this tag from view in future. ' , self . _ProcessMenuTagEvent , ' censorship ' )
2017-02-01 21:11:17 +00:00
2017-09-20 19:47:31 +00:00
ClientGUIMenus . AppendMenuItem ( self , menu , ' add parents to ' + text , ' Add a parent to this tag. ' , self . _ProcessMenuTagEvent , ' parent ' )
2017-09-27 21:52:54 +00:00
ClientGUIMenus . AppendMenuItem ( self , menu , ' add siblings to ' + text , ' Add a sibling to this tag. ' , self . _ProcessMenuTagEvent , ' sibling ' )
2017-02-01 21:11:17 +00:00
2017-05-10 21:33:58 +00:00
HG . client_controller . PopupMenu ( self , menu )
2017-02-01 21:11:17 +00:00
event . Skip ( )
def GetSelectedTags ( self ) :
2017-05-24 20:28:24 +00:00
return set ( self . _selected_terms )
2017-02-01 21:11:17 +00:00
def SiblingsHaveChanged ( self ) :
pass
2017-03-22 22:38:15 +00:00
class ListBoxTagsPredicates ( ListBoxTags ) :
2017-02-01 21:11:17 +00:00
has_counts = True
def _GetWithParentIndices ( self , index ) :
indices = [ index ]
index + = 1
2017-03-22 22:38:15 +00:00
while index < len ( self . _ordered_terms ) :
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
term = self . _GetTerm ( index )
2017-02-01 21:11:17 +00:00
if term . GetType ( ) == HC . PREDICATE_TYPE_PARENT :
indices . append ( index )
else :
break
index + = 1
return indices
def _Deselect ( self , index ) :
to_deselect = self . _GetWithParentIndices ( index )
for index in to_deselect :
ListBoxTags . _Deselect ( self , index )
def _GetAllTagsForClipboard ( self , with_counts = False ) :
2017-03-22 22:38:15 +00:00
return [ term . GetUnicode ( with_counts ) for term in self . _terms ]
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
def _GetNamespaceFromTerm ( self , term ) :
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
predicate = term
namespace = predicate . GetNamespace ( )
return namespace
2018-01-31 22:58:15 +00:00
def _GetSafeHitIndex ( self , hit_index , direction = None ) :
hit_index = ListBox . _GetSafeHitIndex ( self , hit_index )
if direction is not None and hit_index is not None :
hit_term = self . _GetTerm ( hit_index )
while hit_term . GetType ( ) == HC . PREDICATE_TYPE_PARENT :
hit_index + = direction
if hit_index > = len ( self . _ordered_terms ) :
hit_index = 0
hit_term = self . _GetTerm ( hit_index )
return hit_index
2017-03-22 22:38:15 +00:00
def _GetSimplifiedTextFromTerm ( self , term ) :
predicate = term
return predicate . GetUnicode ( with_counts = False )
def _GetTextFromTerm ( self , term ) :
predicate = term
return predicate . GetUnicode ( )
def _HasPredicate ( self , predicate ) :
return predicate in self . _terms
2017-02-01 21:11:17 +00:00
def _Hit ( self , shift , ctrl , hit_index ) :
2018-01-31 22:58:15 +00:00
hit_index = self . _GetSafeHitIndex ( hit_index )
if hit_index is not None and hit_index > 0 :
2017-02-01 21:11:17 +00:00
2018-01-31 22:58:15 +00:00
# this realigns the hit index in the up direction, so if user clicks on parent, they get the upper child
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
while self . _GetTerm ( hit_index ) . GetType ( ) == HC . PREDICATE_TYPE_PARENT :
2017-02-01 21:11:17 +00:00
hit_index - = 1
ListBoxTags . _Hit ( self , shift , ctrl , hit_index )
def _Select ( self , index ) :
to_select = self . _GetWithParentIndices ( index )
for index in to_select :
ListBoxTags . _Select ( self , index )
2017-03-22 22:38:15 +00:00
def GetPredicates ( self ) :
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
return set ( self . _terms )
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
class ListBoxTagsActiveSearchPredicates ( ListBoxTagsPredicates ) :
has_counts = False
def __init__ ( self , parent , page_key , initial_predicates = None ) :
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
if initial_predicates is None :
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
initial_predicates = [ ]
2017-02-01 21:11:17 +00:00
2018-05-23 21:05:06 +00:00
ListBoxTagsPredicates . __init__ ( self , parent , height_num_chars = 6 )
2017-03-22 22:38:15 +00:00
self . _page_key = page_key
self . _get_current_predicates_callable = self . GetPredicates
if len ( initial_predicates ) > 0 :
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
for predicate in initial_predicates :
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
self . _AppendTerm ( predicate )
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
self . _DataHasChanged ( )
2017-02-01 21:11:17 +00:00
2017-05-10 21:33:58 +00:00
HG . client_controller . sub ( self , ' EnterPredicates ' , ' enter_predicates ' )
2017-02-01 21:11:17 +00:00
def _Activate ( self ) :
if len ( self . _selected_terms ) > 0 :
2017-03-22 22:38:15 +00:00
self . _EnterPredicates ( set ( self . _selected_terms ) )
2017-02-01 21:11:17 +00:00
2017-03-29 19:39:34 +00:00
def _DeleteActivate ( self ) :
self . _Activate ( )
2017-03-22 22:38:15 +00:00
def _EnterPredicates ( self , predicates , permit_add = True , permit_remove = True ) :
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
if len ( predicates ) == 0 :
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
return
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
predicates_to_be_added = set ( )
predicates_to_be_removed = set ( )
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
for predicate in predicates :
predicate = predicate . GetCountlessCopy ( )
if self . _HasPredicate ( predicate ) :
if permit_remove :
predicates_to_be_removed . add ( predicate )
else :
if permit_add :
predicates_to_be_added . add ( predicate )
inverse_predicate = predicate . GetInverseCopy ( )
if self . _HasPredicate ( inverse_predicate ) :
predicates_to_be_removed . add ( inverse_predicate )
for predicate in predicates_to_be_added :
self . _AppendTerm ( predicate )
for predicate in predicates_to_be_removed :
self . _RemoveTerm ( predicate )
self . _SortByText ( )
self . _DataHasChanged ( )
2017-05-10 21:33:58 +00:00
HG . client_controller . pub ( ' refresh_query ' , self . _page_key )
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
def _GetTextFromTerm ( self , term ) :
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
predicate = term
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
return predicate . GetUnicode ( render_for_user = True )
def _ProcessMenuPredicateEvent ( self , command ) :
( include_predicates , exclude_predicates ) = self . _GetSelectedIncludeExcludePredicates ( )
if command == ' add_include_predicates ' :
self . _EnterPredicates ( include_predicates , permit_remove = False )
elif command == ' remove_include_predicates ' :
self . _EnterPredicates ( include_predicates , permit_add = False )
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
elif command == ' add_exclude_predicates ' :
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
self . _EnterPredicates ( exclude_predicates , permit_remove = False )
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
elif command == ' remove_exclude_predicates ' :
self . _EnterPredicates ( exclude_predicates , permit_add = False )
def EnterPredicates ( self , page_key , predicates , permit_add = True , permit_remove = True ) :
if page_key == self . _page_key :
self . _EnterPredicates ( predicates , permit_add = permit_add , permit_remove = permit_remove )
class ListBoxTagsAC ( ListBoxTagsPredicates ) :
def __init__ ( self , parent , callable , service_key , * * kwargs ) :
ListBoxTagsPredicates . __init__ ( self , parent , * * kwargs )
self . _callable = callable
self . _service_key = service_key
self . _predicates = { }
def _Activate ( self ) :
predicates = [ term for term in self . _selected_terms if term . GetType ( ) != HC . PREDICATE_TYPE_PARENT ]
2018-10-17 21:00:09 +00:00
predicates = HG . client_controller . GetGUI ( ) . FleshOutPredicates ( predicates )
2017-03-22 22:38:15 +00:00
if len ( predicates ) > 0 :
self . _callable ( predicates )
def SetPredicates ( self , predicates ) :
# need to do a clever compare, since normal predicate compare doesn't take count into account
they_are_the_same = True
if len ( predicates ) == len ( self . _predicates ) :
for index in range ( len ( predicates ) ) :
p_1 = predicates [ index ]
p_2 = self . _predicates [ index ]
if p_1 != p_2 or p_1 . GetCount ( ) != p_2 . GetCount ( ) :
they_are_the_same = False
break
else :
they_are_the_same = False
if not they_are_the_same :
# important to make own copy, as same object originals can be altered (e.g. set non-inclusive) in cache, and we need to notice that change just above
self . _predicates = [ predicate . GetCopy ( ) for predicate in predicates ]
self . _Clear ( )
for predicate in predicates :
self . _AppendTerm ( predicate )
self . _DataHasChanged ( )
if len ( predicates ) > 0 :
2018-02-07 23:40:33 +00:00
hit_index = 0
if len ( predicates ) > 1 :
if HG . client_controller . new_options . GetBoolean ( ' ac_select_first_with_count ' ) :
for ( index , predicate ) in enumerate ( predicates ) :
if predicate . GetCount ( ) != 0 :
hit_index = index
break
self . _Hit ( False , False , hit_index )
2017-03-22 22:38:15 +00:00
def SetTagService ( self , service_key ) :
self . _service_key = service_key
class ListBoxTagsACRead ( ListBoxTagsAC ) :
def _GetTextFromTerm ( self , term ) :
predicate = term
return predicate . GetUnicode ( render_for_user = True )
class ListBoxTagsACWrite ( ListBoxTagsAC ) :
def _GetTextFromTerm ( self , term ) :
predicate = term
return predicate . GetUnicode ( sibling_service_key = self . _service_key )
class ListBoxTagsCensorship ( ListBoxTags ) :
2018-08-08 20:29:54 +00:00
def __init__ ( self , parent , removed_callable = None ) :
ListBoxTags . __init__ ( self , parent )
self . _removed_callable = removed_callable
2017-03-22 22:38:15 +00:00
def _Activate ( self ) :
if len ( self . _selected_terms ) > 0 :
tags = set ( self . _selected_terms )
for tag in tags :
self . _RemoveTerm ( tag )
2018-08-08 20:29:54 +00:00
if self . _removed_callable is not None :
self . _removed_callable ( tags )
2017-06-07 22:05:15 +00:00
self . _ordered_terms . sort ( )
2017-03-22 22:38:15 +00:00
self . _DataHasChanged ( )
def _GetNamespaceFromTerm ( self , term ) :
tag = term
if tag == ' : ' :
return None
else :
( namespace , subtag ) = HydrusTags . SplitTag ( tag )
return namespace
def _GetTextFromTerm ( self , term ) :
2017-05-24 20:28:24 +00:00
tag_slice = term
2017-03-22 22:38:15 +00:00
2018-04-25 22:07:52 +00:00
return ClientTags . ConvertTagSliceToString ( tag_slice )
2017-02-01 21:11:17 +00:00
def AddTags ( self , tags ) :
for tag in tags :
2017-03-22 22:38:15 +00:00
self . _AppendTerm ( tag )
2017-02-01 21:11:17 +00:00
2017-06-07 22:05:15 +00:00
self . _ordered_terms . sort ( )
2017-03-22 22:38:15 +00:00
self . _DataHasChanged ( )
2017-02-01 21:11:17 +00:00
def EnterTags ( self , tags ) :
for tag in tags :
2017-03-22 22:38:15 +00:00
if tag in self . _terms :
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
self . _RemoveTerm ( tag )
2017-02-01 21:11:17 +00:00
else :
2017-03-22 22:38:15 +00:00
self . _AppendTerm ( tag )
2017-02-01 21:11:17 +00:00
2017-06-07 22:05:15 +00:00
self . _ordered_terms . sort ( )
2017-03-22 22:38:15 +00:00
self . _DataHasChanged ( )
2017-02-01 21:11:17 +00:00
2018-08-22 21:10:59 +00:00
def GetTags ( self ) :
return list ( self . _ordered_terms )
2017-05-24 20:28:24 +00:00
def RemoveTags ( self , tags ) :
2017-02-01 21:11:17 +00:00
for tag in tags :
2017-03-22 22:38:15 +00:00
self . _RemoveTerm ( tag )
2017-02-01 21:11:17 +00:00
2017-06-07 22:05:15 +00:00
self . _ordered_terms . sort ( )
2017-03-22 22:38:15 +00:00
self . _DataHasChanged ( )
2017-02-01 21:11:17 +00:00
2018-08-08 20:29:54 +00:00
def SetTags ( self , tags ) :
self . _Clear ( )
self . AddTags ( tags )
2017-02-01 21:11:17 +00:00
class ListBoxTagsColourOptions ( ListBoxTags ) :
2017-03-29 19:39:34 +00:00
PROTECTED_TERMS = ( None , ' ' )
2017-02-01 21:11:17 +00:00
can_spawn_new_windows = False
def __init__ ( self , parent , initial_namespace_colours ) :
ListBoxTags . __init__ ( self , parent )
2017-03-22 22:38:15 +00:00
for ( namespace , colour ) in initial_namespace_colours . items ( ) :
2017-02-01 21:11:17 +00:00
2017-03-23 01:00:00 +00:00
colour = tuple ( colour ) # tuple to convert from list, for oooold users who have list colours
2017-03-22 22:38:15 +00:00
self . _AppendTerm ( ( namespace , colour ) )
2017-02-01 21:11:17 +00:00
2017-03-29 19:39:34 +00:00
self . _SortByText ( )
2017-03-22 22:38:15 +00:00
self . _DataHasChanged ( )
2017-02-01 21:11:17 +00:00
def _Activate ( self ) :
2017-03-29 19:39:34 +00:00
namespaces = [ namespace for ( namespace , colour ) in self . _selected_terms ]
2018-01-17 22:52:10 +00:00
if len ( namespaces ) > 0 :
import ClientGUIDialogs
with ClientGUIDialogs . DialogYesNo ( self , ' Delete all selected colours? ' ) as dlg :
if dlg . ShowModal ( ) == wx . ID_YES :
self . _RemoveNamespaces ( namespaces )
2017-03-29 19:39:34 +00:00
def _DeleteActivate ( self ) :
self . _Activate ( )
2017-03-22 22:38:15 +00:00
def _GetTextFromTerm ( self , term ) :
( namespace , colour ) = term
if namespace is None :
namespace_string = ' default namespace:tag '
elif namespace == ' ' :
namespace_string = ' unnamespaced tag '
else :
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
namespace_string = namespace + ' :tag '
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
return namespace_string
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
def _GetNamespaceColours ( self ) :
2017-03-29 19:39:34 +00:00
return dict ( self . _terms )
2017-03-22 22:38:15 +00:00
def _GetNamespaceFromTerm ( self , term ) :
( namespace , colour ) = term
return namespace
2017-02-01 21:11:17 +00:00
def _RemoveNamespaces ( self , namespaces ) :
2017-03-29 19:39:34 +00:00
namespaces = [ namespace for namespace in namespaces if namespace not in self . PROTECTED_TERMS ]
2017-03-22 22:38:15 +00:00
removees = [ ( existing_namespace , existing_colour ) for ( existing_namespace , existing_colour ) in self . _terms if existing_namespace in namespaces ]
for removee in removees :
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
self . _RemoveTerm ( removee )
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
self . _DataHasChanged ( )
2017-02-01 21:11:17 +00:00
def SetNamespaceColour ( self , namespace , colour ) :
2018-01-10 22:41:51 +00:00
( r , g , b , a ) = colour . Get ( )
colour_tuple = ( r , g , b )
2017-03-23 01:00:00 +00:00
2017-03-22 22:38:15 +00:00
for ( existing_namespace , existing_colour ) in self . _terms :
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
if existing_namespace == namespace :
self . _RemoveTerm ( ( existing_namespace , existing_colour ) )
break
2017-02-01 21:11:17 +00:00
2018-01-10 22:41:51 +00:00
self . _AppendTerm ( ( namespace , colour_tuple ) )
2017-02-01 21:11:17 +00:00
2017-03-29 19:39:34 +00:00
self . _SortByText ( )
2017-03-22 22:38:15 +00:00
self . _DataHasChanged ( )
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
def GetNamespaceColours ( self ) :
2017-03-29 19:39:34 +00:00
return self . _GetNamespaceColours ( )
2017-03-22 22:38:15 +00:00
2017-02-01 21:11:17 +00:00
def GetSelectedNamespaceColours ( self ) :
2017-03-22 22:38:15 +00:00
namespace_colours = dict ( self . _selected_terms )
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
return namespace_colours
2017-02-01 21:11:17 +00:00
class ListBoxTagsStrings ( ListBoxTags ) :
def __init__ ( self , parent , service_key = None , show_sibling_text = True , sort_tags = True ) :
ListBoxTags . __init__ ( self , parent )
if service_key is not None :
service_key = CC . COMBINED_TAG_SERVICE_KEY
self . _service_key = service_key
self . _show_sibling_text = show_sibling_text
self . _sort_tags = sort_tags
2017-03-22 22:38:15 +00:00
def _GetNamespaceFromTerm ( self , term ) :
tag = term
( namespace , subtag ) = HydrusTags . SplitTag ( tag )
return namespace
def _GetSimplifiedTextFromTerm ( self , term ) :
tag = term
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
return HydrusData . ToUnicode ( tag )
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
def _GetTextFromTerm ( self , term ) :
2017-02-01 21:11:17 +00:00
2017-05-10 21:33:58 +00:00
siblings_manager = HG . client_controller . GetManager ( ' tag_siblings ' )
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
tag = term
tag_string = ClientTags . RenderTag ( tag , True )
if self . _show_sibling_text :
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
sibling = siblings_manager . GetSibling ( self . _service_key , tag )
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
if sibling is not None :
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
tag_string + = ' (will display as ' + ClientTags . RenderTag ( sibling , True ) + ' ) '
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
return tag_string
def _RecalcTags ( self ) :
self . _RefreshTexts ( )
2017-02-01 21:11:17 +00:00
if self . _sort_tags :
2017-03-22 22:38:15 +00:00
self . _SortByText ( )
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
self . _DataHasChanged ( )
2017-02-01 21:11:17 +00:00
def GetTags ( self ) :
2017-03-22 22:38:15 +00:00
return set ( self . _terms )
2017-02-01 21:11:17 +00:00
def SetTags ( self , tags ) :
2017-03-22 22:38:15 +00:00
self . _Clear ( )
for tag in tags :
self . _AppendTerm ( tag )
2017-02-01 21:11:17 +00:00
self . _RecalcTags ( )
def SiblingsHaveChanged ( self ) :
self . _RecalcTags ( )
class ListBoxTagsStringsAddRemove ( ListBoxTagsStrings ) :
def __init__ ( self , parent , service_key = None , removed_callable = None , show_sibling_text = True ) :
ListBoxTagsStrings . __init__ ( self , parent , service_key = service_key , show_sibling_text = show_sibling_text )
self . _removed_callable = removed_callable
def _Activate ( self ) :
if len ( self . _selected_terms ) > 0 :
tags = set ( self . _selected_terms )
self . _RemoveTags ( tags )
def _RemoveTags ( self , tags ) :
for tag in tags :
2017-03-22 22:38:15 +00:00
self . _RemoveTerm ( tag )
2017-02-01 21:11:17 +00:00
self . _RecalcTags ( )
if self . _removed_callable is not None :
self . _removed_callable ( tags )
def AddTags ( self , tags ) :
for tag in tags :
2017-03-22 22:38:15 +00:00
self . _AppendTerm ( tag )
2017-02-01 21:11:17 +00:00
self . _RecalcTags ( )
def Clear ( self ) :
2017-03-22 22:38:15 +00:00
self . _Clear ( )
2017-02-01 21:11:17 +00:00
self . _RecalcTags ( )
def EnterTags ( self , tags ) :
removed = set ( )
for tag in tags :
2017-03-22 22:38:15 +00:00
if tag in self . _terms :
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
self . _RemoveTerm ( tag )
2017-02-01 21:11:17 +00:00
removed . add ( tag )
else :
2017-03-22 22:38:15 +00:00
self . _AppendTerm ( tag )
2017-02-01 21:11:17 +00:00
self . _RecalcTags ( )
if len ( removed ) > 0 and self . _removed_callable is not None :
self . _removed_callable ( removed )
2017-04-19 20:58:30 +00:00
def EventCharHook ( self , event ) :
2017-02-01 21:11:17 +00:00
2018-05-16 20:09:50 +00:00
( modifier , key ) = ClientGUIShortcuts . ConvertKeyEventToSimpleTuple ( event )
2017-04-05 21:16:40 +00:00
if key in CC . DELETE_KEYS :
2017-02-01 21:11:17 +00:00
self . _Activate ( )
else :
event . Skip ( )
def RemoveTags ( self , tags ) :
self . _RemoveTags ( tags )
class ListBoxTagsSelection ( ListBoxTags ) :
2017-03-22 22:38:15 +00:00
render_for_user = True
2017-02-01 21:11:17 +00:00
has_counts = True
def __init__ ( self , parent , include_counts = True , collapse_siblings = False ) :
2018-05-23 21:05:06 +00:00
ListBoxTags . __init__ ( self , parent , height_num_chars = 12 )
2017-02-01 21:11:17 +00:00
self . _sort = HC . options [ ' default_tag_sort ' ]
self . _last_media = set ( )
self . _tag_service_key = CC . COMBINED_TAG_SERVICE_KEY
self . _include_counts = include_counts
self . _collapse_siblings = collapse_siblings
self . _current_tags_to_count = collections . Counter ( )
self . _deleted_tags_to_count = collections . Counter ( )
self . _pending_tags_to_count = collections . Counter ( )
self . _petitioned_tags_to_count = collections . Counter ( )
self . _show_current = True
self . _show_deleted = False
self . _show_pending = True
self . _show_petitioned = True
def _GetAllTagsForClipboard ( self , with_counts = False ) :
if with_counts :
2017-03-22 22:38:15 +00:00
return [ self . _terms_to_texts [ term ] for term in self . _ordered_terms ]
2017-02-01 21:11:17 +00:00
else :
2017-03-22 22:38:15 +00:00
return self . _ordered_terms
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
def _GetNamespaceFromTerm ( self , term ) :
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
tag = term
( namespace , subtag ) = HydrusTags . SplitTag ( tag )
return namespace
def _GetSimplifiedTextFromTerm ( self , term ) :
tag = term
return HydrusData . ToUnicode ( tag )
def _GetTextFromTerm ( self , term ) :
tag = term
tag_string = ClientTags . RenderTag ( tag , self . render_for_user )
2017-02-01 21:11:17 +00:00
if self . _include_counts :
2018-07-04 20:48:28 +00:00
if self . _show_current and tag in self . _current_tags_to_count : tag_string + = ' ( ' + HydrusData . ToHumanInt ( self . _current_tags_to_count [ tag ] ) + ' ) '
if self . _show_pending and tag in self . _pending_tags_to_count : tag_string + = ' (+ ' + HydrusData . ToHumanInt ( self . _pending_tags_to_count [ tag ] ) + ' ) '
if self . _show_petitioned and tag in self . _petitioned_tags_to_count : tag_string + = ' (- ' + HydrusData . ToHumanInt ( self . _petitioned_tags_to_count [ tag ] ) + ' ) '
if self . _show_deleted and tag in self . _deleted_tags_to_count : tag_string + = ' (X ' + HydrusData . ToHumanInt ( self . _deleted_tags_to_count [ tag ] ) + ' ) '
2017-02-01 21:11:17 +00:00
else :
if self . _show_pending and tag in self . _pending_tags_to_count : tag_string + = ' (+) '
if self . _show_petitioned and tag in self . _petitioned_tags_to_count : tag_string + = ' (-) '
if self . _show_deleted and tag in self . _deleted_tags_to_count : tag_string + = ' (X) '
if not self . _collapse_siblings :
2017-05-10 21:33:58 +00:00
siblings_manager = HG . client_controller . GetManager ( ' tag_siblings ' )
2017-02-01 21:11:17 +00:00
sibling = siblings_manager . GetSibling ( self . _tag_service_key , tag )
if sibling is not None :
2017-03-22 22:38:15 +00:00
sibling = ClientTags . RenderTag ( sibling , self . render_for_user )
tag_string + = ' (will display as ' + sibling + ' ) '
2017-02-01 21:11:17 +00:00
return tag_string
def _RecalcStrings ( self , limit_to_these_tags = None ) :
2017-04-12 21:46:46 +00:00
previous_selected_terms = set ( self . _selected_terms )
2017-02-01 21:11:17 +00:00
if limit_to_these_tags is None :
2017-03-22 22:38:15 +00:00
self . _Clear ( )
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
nonzero_tags = set ( )
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
if self . _show_current : nonzero_tags . update ( ( tag for ( tag , count ) in self . _current_tags_to_count . items ( ) if count > 0 ) )
if self . _show_deleted : nonzero_tags . update ( ( tag for ( tag , count ) in self . _deleted_tags_to_count . items ( ) if count > 0 ) )
if self . _show_pending : nonzero_tags . update ( ( tag for ( tag , count ) in self . _pending_tags_to_count . items ( ) if count > 0 ) )
if self . _show_petitioned : nonzero_tags . update ( ( tag for ( tag , count ) in self . _petitioned_tags_to_count . items ( ) if count > 0 ) )
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
for tag in nonzero_tags :
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
self . _AppendTerm ( tag )
2017-02-01 21:11:17 +00:00
else :
2017-03-22 22:38:15 +00:00
if not isinstance ( limit_to_these_tags , set ) :
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
limit_to_these_tags = set ( limit_to_these_tags )
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
for tag in limit_to_these_tags :
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
self . _RemoveTerm ( tag )
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
nonzero_tags = set ( )
if self . _show_current : nonzero_tags . update ( ( tag for ( tag , count ) in self . _current_tags_to_count . items ( ) if count > 0 and tag in limit_to_these_tags ) )
if self . _show_deleted : nonzero_tags . update ( ( tag for ( tag , count ) in self . _deleted_tags_to_count . items ( ) if count > 0 and tag in limit_to_these_tags ) )
if self . _show_pending : nonzero_tags . update ( ( tag for ( tag , count ) in self . _pending_tags_to_count . items ( ) if count > 0 and tag in limit_to_these_tags ) )
if self . _show_petitioned : nonzero_tags . update ( ( tag for ( tag , count ) in self . _petitioned_tags_to_count . items ( ) if count > 0 and tag in limit_to_these_tags ) )
for tag in nonzero_tags :
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
self . _AppendTerm ( tag )
2017-02-01 21:11:17 +00:00
2017-04-12 21:46:46 +00:00
for term in previous_selected_terms :
if term in self . _terms :
self . _selected_terms . add ( term )
2017-03-22 22:38:15 +00:00
self . _SortTags ( )
2017-02-01 21:11:17 +00:00
def _SortTags ( self ) :
2018-09-19 21:54:51 +00:00
tags_to_count = collections . Counter ( )
2017-03-22 22:38:15 +00:00
2018-09-19 21:54:51 +00:00
if self . _show_current : tags_to_count . update ( self . _current_tags_to_count )
if self . _show_deleted : tags_to_count . update ( self . _deleted_tags_to_count )
if self . _show_pending : tags_to_count . update ( self . _pending_tags_to_count )
if self . _show_petitioned : tags_to_count . update ( self . _petitioned_tags_to_count )
2017-03-22 22:38:15 +00:00
2018-09-19 21:54:51 +00:00
ClientTags . SortTags ( self . _sort , self . _ordered_terms , tags_to_count )
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
self . _DataHasChanged ( )
2017-02-01 21:11:17 +00:00
def ChangeTagService ( self , service_key ) :
self . _tag_service_key = service_key
self . SetTagsByMedia ( self . _last_media , force_reload = True )
def SetSort ( self , sort ) :
self . _sort = sort
self . _SortTags ( )
def SetShow ( self , show_type , value ) :
if show_type == ' current ' : self . _show_current = value
elif show_type == ' deleted ' : self . _show_deleted = value
elif show_type == ' pending ' : self . _show_pending = value
elif show_type == ' petitioned ' : self . _show_petitioned = value
self . _RecalcStrings ( )
def IncrementTagsByMedia ( self , media ) :
media = set ( media )
media = media . difference ( self . _last_media )
( current_tags_to_count , deleted_tags_to_count , pending_tags_to_count , petitioned_tags_to_count ) = ClientData . GetMediasTagCount ( media , tag_service_key = self . _tag_service_key , collapse_siblings = self . _collapse_siblings )
self . _current_tags_to_count . update ( current_tags_to_count )
self . _deleted_tags_to_count . update ( deleted_tags_to_count )
self . _pending_tags_to_count . update ( pending_tags_to_count )
self . _petitioned_tags_to_count . update ( petitioned_tags_to_count )
tags_changed = set ( )
if self . _show_current : tags_changed . update ( current_tags_to_count . keys ( ) )
if self . _show_deleted : tags_changed . update ( deleted_tags_to_count . keys ( ) )
if self . _show_pending : tags_changed . update ( pending_tags_to_count . keys ( ) )
if self . _show_petitioned : tags_changed . update ( petitioned_tags_to_count . keys ( ) )
if len ( tags_changed ) > 0 :
self . _RecalcStrings ( tags_changed )
self . _last_media . update ( media )
def SetTagsByMedia ( self , media , force_reload = False ) :
media = set ( media )
2018-08-15 20:40:30 +00:00
if len ( media ) < len ( self . _last_media ) / 10 : # if we are dropping to a much smaller selection (e.g. 5000 -> 1), we should just recalculate from scratch
force_reload = True
2017-02-01 21:11:17 +00:00
if force_reload :
( current_tags_to_count , deleted_tags_to_count , pending_tags_to_count , petitioned_tags_to_count ) = ClientData . GetMediasTagCount ( media , tag_service_key = self . _tag_service_key , collapse_siblings = self . _collapse_siblings )
self . _current_tags_to_count = current_tags_to_count
self . _deleted_tags_to_count = deleted_tags_to_count
self . _pending_tags_to_count = pending_tags_to_count
self . _petitioned_tags_to_count = petitioned_tags_to_count
self . _RecalcStrings ( )
else :
removees = self . _last_media . difference ( media )
adds = media . difference ( self . _last_media )
( current_tags_to_count , deleted_tags_to_count , pending_tags_to_count , petitioned_tags_to_count ) = ClientData . GetMediasTagCount ( removees , tag_service_key = self . _tag_service_key , collapse_siblings = self . _collapse_siblings )
self . _current_tags_to_count . subtract ( current_tags_to_count )
self . _deleted_tags_to_count . subtract ( deleted_tags_to_count )
self . _pending_tags_to_count . subtract ( pending_tags_to_count )
self . _petitioned_tags_to_count . subtract ( petitioned_tags_to_count )
( current_tags_to_count , deleted_tags_to_count , pending_tags_to_count , petitioned_tags_to_count ) = ClientData . GetMediasTagCount ( adds , tag_service_key = self . _tag_service_key , collapse_siblings = self . _collapse_siblings )
self . _current_tags_to_count . update ( current_tags_to_count )
self . _deleted_tags_to_count . update ( deleted_tags_to_count )
self . _pending_tags_to_count . update ( pending_tags_to_count )
self . _petitioned_tags_to_count . update ( petitioned_tags_to_count )
for counter in ( self . _current_tags_to_count , self . _deleted_tags_to_count , self . _pending_tags_to_count , self . _petitioned_tags_to_count ) :
tags = counter . keys ( )
for tag in tags :
2018-08-15 20:40:30 +00:00
if counter [ tag ] == 0 :
del counter [ tag ]
2017-02-01 21:11:17 +00:00
if len ( removees ) == 0 :
tags_changed = set ( )
if self . _show_current : tags_changed . update ( current_tags_to_count . keys ( ) )
if self . _show_deleted : tags_changed . update ( deleted_tags_to_count . keys ( ) )
if self . _show_pending : tags_changed . update ( pending_tags_to_count . keys ( ) )
if self . _show_petitioned : tags_changed . update ( petitioned_tags_to_count . keys ( ) )
if len ( tags_changed ) > 0 :
self . _RecalcStrings ( tags_changed )
else :
self . _RecalcStrings ( )
self . _last_media = media
2017-03-22 22:38:15 +00:00
self . _DataHasChanged ( )
2017-02-01 21:11:17 +00:00
def SiblingsHaveChanged ( self ) :
self . SetTagsByMedia ( self . _last_media , force_reload = True )
class ListBoxTagsSelectionHoverFrame ( ListBoxTagsSelection ) :
def __init__ ( self , parent , canvas_key ) :
ListBoxTagsSelection . __init__ ( self , parent , include_counts = False , collapse_siblings = True )
self . _canvas_key = canvas_key
def _Activate ( self ) :
2017-05-10 21:33:58 +00:00
HG . client_controller . pub ( ' canvas_manage_tags ' , self . _canvas_key )
2017-02-01 21:11:17 +00:00
class ListBoxTagsSelectionManagementPanel ( ListBoxTagsSelection ) :
def __init__ ( self , parent , page_key , predicates_callable = None ) :
ListBoxTagsSelection . __init__ ( self , parent , include_counts = True , collapse_siblings = True )
self . _page_key = page_key
2017-03-22 22:38:15 +00:00
self . _get_current_predicates_callable = predicates_callable
2017-02-01 21:11:17 +00:00
2017-05-10 21:33:58 +00:00
HG . client_controller . sub ( self , ' IncrementTagsByMediaPubsub ' , ' increment_tags_selection ' )
HG . client_controller . sub ( self , ' SetTagsByMediaPubsub ' , ' new_tags_selection ' )
HG . client_controller . sub ( self , ' ChangeTagServicePubsub ' , ' change_tag_service ' )
2017-02-01 21:11:17 +00:00
def _Activate ( self ) :
predicates = [ ClientSearch . Predicate ( HC . PREDICATE_TYPE_TAG , term ) for term in self . _selected_terms ]
if len ( predicates ) > 0 :
2017-05-10 21:33:58 +00:00
HG . client_controller . pub ( ' enter_predicates ' , self . _page_key , predicates )
2017-02-01 21:11:17 +00:00
def _ProcessMenuPredicateEvent ( self , command ) :
( include_predicates , exclude_predicates ) = self . _GetSelectedIncludeExcludePredicates ( )
if command == ' add_include_predicates ' :
2017-05-10 21:33:58 +00:00
HG . client_controller . pub ( ' enter_predicates ' , self . _page_key , include_predicates , permit_remove = False )
2017-02-01 21:11:17 +00:00
elif command == ' remove_include_predicates ' :
2017-05-10 21:33:58 +00:00
HG . client_controller . pub ( ' enter_predicates ' , self . _page_key , include_predicates , permit_add = False )
2017-02-01 21:11:17 +00:00
elif command == ' add_exclude_predicates ' :
2017-05-10 21:33:58 +00:00
HG . client_controller . pub ( ' enter_predicates ' , self . _page_key , exclude_predicates , permit_remove = False )
2017-02-01 21:11:17 +00:00
elif command == ' remove_exclude_predicates ' :
2017-05-10 21:33:58 +00:00
HG . client_controller . pub ( ' enter_predicates ' , self . _page_key , exclude_predicates , permit_add = False )
2017-02-01 21:11:17 +00:00
def ChangeTagServicePubsub ( self , page_key , service_key ) :
if page_key == self . _page_key :
self . ChangeTagService ( service_key )
def IncrementTagsByMediaPubsub ( self , page_key , media ) :
if page_key == self . _page_key :
self . IncrementTagsByMedia ( media )
def SetTagsByMediaPubsub ( self , page_key , media , force_reload = False ) :
if page_key == self . _page_key :
self . SetTagsByMedia ( media , force_reload = force_reload )
class ListBoxTagsSelectionTagsDialog ( ListBoxTagsSelection ) :
2017-03-22 22:38:15 +00:00
render_for_user = False
2017-02-01 21:11:17 +00:00
2017-03-29 19:39:34 +00:00
def __init__ ( self , parent , add_func , delete_func ) :
2017-02-01 21:11:17 +00:00
ListBoxTagsSelection . __init__ ( self , parent , include_counts = True , collapse_siblings = False )
2017-03-29 19:39:34 +00:00
self . _add_func = add_func
self . _delete_func = delete_func
2017-02-01 21:11:17 +00:00
def _Activate ( self ) :
if len ( self . _selected_terms ) > 0 :
2017-04-12 21:46:46 +00:00
self . _add_func ( set ( self . _selected_terms ) )
2017-02-01 21:11:17 +00:00
2017-03-29 19:39:34 +00:00
def _DeleteActivate ( self ) :
if len ( self . _selected_terms ) > 0 :
2017-04-12 21:46:46 +00:00
self . _delete_func ( set ( self . _selected_terms ) )
2017-03-29 19:39:34 +00:00