hydrus/include/ClientGUIImport.py

1583 lines
56 KiB
Python
Raw Normal View History

2017-09-13 20:50:41 +00:00
import ClientConstants as CC
2017-11-15 22:35:49 +00:00
import ClientGUIACDropdown
2017-09-13 20:50:41 +00:00
import ClientGUICommon
2018-07-18 21:07:15 +00:00
import ClientGUIControls
import ClientGUIFileSeedCache
import ClientGUIGallerySeedLog
2017-11-15 22:35:49 +00:00
import ClientGUIListBoxes
import ClientGUIListCtrl
2018-07-11 20:23:51 +00:00
import ClientGUIMenus
2017-11-15 22:35:49 +00:00
import ClientGUIScrolledPanels
2017-09-13 20:50:41 +00:00
import ClientGUIScrolledPanelsEdit
2018-07-18 21:07:15 +00:00
import ClientGUIShortcuts
import ClientGUITime
2017-09-13 20:50:41 +00:00
import ClientGUITopLevelWindows
2017-11-15 22:35:49 +00:00
import ClientImporting
2018-04-18 22:10:15 +00:00
import ClientImportOptions
2017-11-15 22:35:49 +00:00
import collections
2017-09-13 20:50:41 +00:00
import HydrusConstants as HC
2017-11-15 22:35:49 +00:00
import HydrusData
import HydrusGlobals as HG
2018-07-11 20:23:51 +00:00
import HydrusSerialisable
2017-11-15 22:35:49 +00:00
import HydrusTags
2017-12-13 22:33:07 +00:00
import HydrusText
2017-11-15 22:35:49 +00:00
import os
import re
2017-09-13 20:50:41 +00:00
import wx
2018-01-03 22:37:30 +00:00
import wx.adv
2017-09-13 20:50:41 +00:00
2018-07-18 21:07:15 +00:00
class CheckerOptionsButton( ClientGUICommon.BetterButton ):
def __init__( self, parent, checker_options, update_callable = None ):
ClientGUICommon.BetterButton.__init__( self, parent, 'checker options', self._EditOptions )
self._checker_options = checker_options
self._update_callable = update_callable
self._SetToolTip()
def _EditOptions( self ):
with ClientGUITopLevelWindows.DialogEdit( self, 'edit checker options' ) as dlg:
panel = ClientGUITime.EditCheckerOptions( dlg, self._checker_options )
dlg.SetPanel( panel )
if dlg.ShowModal() == wx.ID_OK:
checker_options = panel.GetValue()
self._SetValue( checker_options )
def _SetToolTip( self ):
self.SetToolTip( self._checker_options.GetSummary() )
def _SetValue( self, checker_options ):
self._checker_options = checker_options
self._SetToolTip()
if self._update_callable is not None:
self._update_callable( self._checker_options )
def GetValue( self ):
return self._checker_options
def SetValue( self, checker_options ):
self._SetValue( checker_options )
2017-09-20 19:47:31 +00:00
class FileImportOptionsButton( ClientGUICommon.BetterButton ):
2017-09-13 20:50:41 +00:00
def __init__( self, parent, file_import_options, update_callable = None ):
ClientGUICommon.BetterButton.__init__( self, parent, 'file import options', self._EditOptions )
self._file_import_options = file_import_options
self._update_callable = update_callable
self._SetToolTip()
def _EditOptions( self ):
with ClientGUITopLevelWindows.DialogEdit( self, 'edit file import options' ) as dlg:
2017-09-20 19:47:31 +00:00
panel = ClientGUIScrolledPanelsEdit.EditFileImportOptions( dlg, self._file_import_options )
2017-09-13 20:50:41 +00:00
dlg.SetPanel( panel )
if dlg.ShowModal() == wx.ID_OK:
file_import_options = panel.GetValue()
self._SetValue( file_import_options )
def _SetToolTip( self ):
2018-01-03 22:37:30 +00:00
self.SetToolTip( self._file_import_options.GetSummary() )
2017-09-13 20:50:41 +00:00
def _SetValue( self, file_import_options ):
self._file_import_options = file_import_options
self._SetToolTip()
if self._update_callable is not None:
self._update_callable( self._file_import_options )
def GetValue( self ):
return self._file_import_options
def SetValue( self, file_import_options ):
self._SetValue( file_import_options )
2017-11-15 22:35:49 +00:00
class FilenameTaggingOptionsPanel( wx.Panel ):
def __init__( self, parent, service_key, tag_update_callable, filename_tagging_options = None, present_for_accompanying_file_list = False ):
if filename_tagging_options is None:
# pull from an options default
2018-04-18 22:10:15 +00:00
filename_tagging_options = ClientImportOptions.FilenameTaggingOptions()
2017-11-15 22:35:49 +00:00
wx.Panel.__init__( self, parent )
self._service_key = service_key
self._notebook = wx.Notebook( self )
# eventually these will take 'regexoptions' or whatever object and 'showspecificfiles' as well
self._simple_panel = self._SimplePanel( self._notebook, self._service_key, tag_update_callable, filename_tagging_options, present_for_accompanying_file_list )
self._advanced_panel = self._AdvancedPanel( self._notebook, self._service_key, tag_update_callable, filename_tagging_options, present_for_accompanying_file_list )
self._notebook.AddPage( self._simple_panel, 'simple', select = True )
self._notebook.AddPage( self._advanced_panel, 'advanced' )
vbox = wx.BoxSizer( wx.VERTICAL )
2018-01-03 22:37:30 +00:00
vbox.Add( self._notebook, CC.FLAGS_EXPAND_SIZER_BOTH_WAYS )
2017-11-15 22:35:49 +00:00
self.SetSizer( vbox )
def GetFilenameTaggingOptions( self ):
2018-04-18 22:10:15 +00:00
filename_tagging_options = ClientImportOptions.FilenameTaggingOptions()
2017-11-15 22:35:49 +00:00
self._advanced_panel.UpdateFilenameTaggingOptions( filename_tagging_options )
self._simple_panel.UpdateFilenameTaggingOptions( filename_tagging_options )
return filename_tagging_options
def GetTags( self, index, path ):
tags = set()
tags.update( self._simple_panel.GetTags( index, path ) )
tags.update( self._advanced_panel.GetTags( index, path ) )
tags = HydrusTags.CleanTags( tags )
siblings_manager = HG.client_controller.GetManager( 'tag_siblings' )
parents_manager = HG.client_controller.GetManager( 'tag_parents' )
tag_censorship_manager = HG.client_controller.GetManager( 'tag_censorship' )
tags = siblings_manager.CollapseTags( self._service_key, tags )
tags = parents_manager.ExpandTags( self._service_key, tags )
tags = tag_censorship_manager.FilterTags( self._service_key, tags )
return tags
def SetSelectedPaths( self, paths ):
self._simple_panel.SetSelectedPaths( paths )
class _AdvancedPanel( wx.Panel ):
def __init__( self, parent, service_key, refresh_callable, filename_tagging_options, present_for_accompanying_file_list ):
wx.Panel.__init__( self, parent )
self._service_key = service_key
self._refresh_callable = refresh_callable
self._present_for_accompanying_file_list = present_for_accompanying_file_list
#
self._quick_namespaces_panel = ClientGUICommon.StaticBox( self, 'quick namespaces' )
self._quick_namespaces_list = ClientGUIListCtrl.BetterListCtrl( self._quick_namespaces_panel, 'quick_namespaces', 4, 20, [ ( 'namespace', 12 ), ( 'regex', -1 ) ], self._ConvertQuickRegexDataToListCtrlTuples, delete_key_callback = self.DeleteQuickNamespaces, activation_callback = self.EditQuickNamespaces )
self._add_quick_namespace_button = wx.Button( self._quick_namespaces_panel, label = 'add' )
self._add_quick_namespace_button.Bind( wx.EVT_BUTTON, self.EventAddQuickNamespace )
self._add_quick_namespace_button.SetMinSize( ( 20, -1 ) )
self._edit_quick_namespace_button = wx.Button( self._quick_namespaces_panel, label = 'edit' )
self._edit_quick_namespace_button.Bind( wx.EVT_BUTTON, self.EventEditQuickNamespace )
self._edit_quick_namespace_button.SetMinSize( ( 20, -1 ) )
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._delete_quick_namespace_button.SetMinSize( ( 20, -1 ) )
#
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 )
self._regex_shortcuts = ClientGUICommon.RegexButton( self._regexes_panel )
2018-01-03 22:37:30 +00:00
self._regex_intro_link = wx.adv.HyperlinkCtrl( self._regexes_panel, id = -1, label = 'a good regex introduction', url = 'http://www.aivosto.com/vbtips/regex.html' )
self._regex_practise_link = wx.adv.HyperlinkCtrl( self._regexes_panel, id = -1, label = 'regex practise', url = 'http://regexr.com/3cvmf' )
2017-11-15 22:35:49 +00:00
#
self._num_panel = ClientGUICommon.StaticBox( self, '#' )
self._num_base = wx.SpinCtrl( self._num_panel, min = -10000000, max = 10000000, size = ( 60, -1 ) )
self._num_base.SetValue( 1 )
self._num_base.Bind( wx.EVT_SPINCTRL, self.EventRecalcNum )
self._num_step = wx.SpinCtrl( self._num_panel, min = -1000000, max = 1000000, size = ( 60, -1 ) )
self._num_step.SetValue( 1 )
self._num_step.Bind( wx.EVT_SPINCTRL, self.EventRecalcNum )
self._num_namespace = wx.TextCtrl( self._num_panel, size = ( 100, -1 ) )
self._num_namespace.Bind( wx.EVT_TEXT, self.EventNumNamespaceChanged )
if not self._present_for_accompanying_file_list:
self._num_panel.Hide()
#
( quick_namespaces, regexes ) = filename_tagging_options.AdvancedToTuple()
self._quick_namespaces_list.AddDatas( quick_namespaces )
for regex in regexes:
self._regexes.Append( regex )
#
button_box = wx.BoxSizer( wx.HORIZONTAL )
2018-01-03 22:37:30 +00:00
button_box.Add( self._add_quick_namespace_button, CC.FLAGS_EXPAND_BOTH_WAYS )
button_box.Add( self._edit_quick_namespace_button, CC.FLAGS_EXPAND_BOTH_WAYS )
button_box.Add( self._delete_quick_namespace_button, CC.FLAGS_EXPAND_BOTH_WAYS )
2017-11-15 22:35:49 +00:00
2018-01-03 22:37:30 +00:00
self._quick_namespaces_panel.Add( self._quick_namespaces_list, CC.FLAGS_EXPAND_BOTH_WAYS )
self._quick_namespaces_panel.Add( button_box, CC.FLAGS_EXPAND_SIZER_PERPENDICULAR )
2017-11-15 22:35:49 +00:00
#
2018-01-03 22:37:30 +00:00
self._regexes_panel.Add( self._regexes, CC.FLAGS_EXPAND_BOTH_WAYS )
self._regexes_panel.Add( self._regex_box, CC.FLAGS_EXPAND_PERPENDICULAR )
self._regexes_panel.Add( self._regex_shortcuts, CC.FLAGS_LONE_BUTTON )
self._regexes_panel.Add( self._regex_intro_link, CC.FLAGS_LONE_BUTTON )
self._regexes_panel.Add( self._regex_practise_link, CC.FLAGS_LONE_BUTTON )
2017-11-15 22:35:49 +00:00
#
hbox = wx.BoxSizer( wx.HORIZONTAL )
2018-01-03 22:37:30 +00:00
hbox.Add( wx.StaticText( self._num_panel, label = '# base/step: ' ), CC.FLAGS_VCENTER )
hbox.Add( self._num_base, CC.FLAGS_VCENTER )
hbox.Add( self._num_step, CC.FLAGS_VCENTER )
2017-11-15 22:35:49 +00:00
2018-01-03 22:37:30 +00:00
self._num_panel.Add( hbox, CC.FLAGS_EXPAND_SIZER_PERPENDICULAR )
2017-11-15 22:35:49 +00:00
hbox = wx.BoxSizer( wx.HORIZONTAL )
2018-01-03 22:37:30 +00:00
hbox.Add( wx.StaticText( self._num_panel, label = '# namespace: ' ), CC.FLAGS_VCENTER )
hbox.Add( self._num_namespace, CC.FLAGS_EXPAND_BOTH_WAYS )
2017-11-15 22:35:49 +00:00
2018-01-03 22:37:30 +00:00
self._num_panel.Add( hbox, CC.FLAGS_EXPAND_SIZER_PERPENDICULAR )
2017-11-15 22:35:49 +00:00
second_vbox = wx.BoxSizer( wx.VERTICAL )
2018-01-03 22:37:30 +00:00
second_vbox.Add( self._regexes_panel, CC.FLAGS_EXPAND_BOTH_WAYS )
second_vbox.Add( self._num_panel, CC.FLAGS_EXPAND_PERPENDICULAR )
2017-11-15 22:35:49 +00:00
#
hbox = wx.BoxSizer( wx.HORIZONTAL )
2018-01-03 22:37:30 +00:00
hbox.Add( self._quick_namespaces_panel, CC.FLAGS_EXPAND_BOTH_WAYS )
hbox.Add( second_vbox, CC.FLAGS_EXPAND_SIZER_BOTH_WAYS )
2017-11-15 22:35:49 +00:00
self.SetSizer( hbox )
def _ConvertQuickRegexDataToListCtrlTuples( self, data ):
( namespace, regex ) = data
display_tuple = ( namespace, regex )
sort_tuple = ( namespace, regex )
return ( display_tuple, sort_tuple )
def DeleteQuickNamespaces( self ):
import ClientGUIDialogs
with ClientGUIDialogs.DialogYesNo( self, 'Remove all selected?' ) as dlg:
if dlg.ShowModal() == wx.ID_YES:
self._quick_namespaces_list.DeleteSelected()
self._refresh_callable()
def EditQuickNamespaces( self ):
data_to_edit = self._quick_namespaces_list.GetData( only_selected = True )
for old_data in data_to_edit:
( namespace, regex ) = old_data
import ClientGUIDialogs
with ClientGUIDialogs.DialogInputNamespaceRegex( self, namespace = namespace, regex = regex ) as dlg:
if dlg.ShowModal() == wx.ID_OK:
( new_namespace, new_regex ) = dlg.GetInfo()
new_data = ( new_namespace, new_regex )
if new_data != old_data:
self._quick_namespaces_list.DeleteDatas( ( old_data, ) )
self._quick_namespaces_list.AddDatas( ( new_data, ) )
self._refresh_callable()
def EventAddRegex( self, event ):
regex = self._regex_box.GetValue()
if regex != '':
try:
re.compile( regex, flags = re.UNICODE )
except Exception as e:
text = 'That regex would not compile!'
text += os.linesep * 2
text += HydrusData.ToUnicode( e )
wx.MessageBox( text )
return
self._regexes.Append( regex )
self._regex_box.Clear()
self._refresh_callable()
def EventAddQuickNamespace( self, event ):
import ClientGUIDialogs
with ClientGUIDialogs.DialogInputNamespaceRegex( self ) as dlg:
if dlg.ShowModal() == wx.ID_OK:
( namespace, regex ) = dlg.GetInfo()
data = ( namespace, regex )
self._quick_namespaces_list.AddDatas( ( data, ) )
self._refresh_callable()
def EventDeleteQuickNamespace( self, event ):
self.DeleteQuickNamespaces()
def EventEditQuickNamespace( self, event ):
self.EditQuickNamespaces()
def EventNumNamespaceChanged( self, event ):
self._refresh_callable()
def EventRecalcNum( self, event ):
self._refresh_callable()
def EventRemoveRegex( self, event ):
selection = self._regexes.GetSelection()
if selection != wx.NOT_FOUND:
if len( self._regex_box.GetValue() ) == 0: self._regex_box.SetValue( self._regexes.GetString( selection ) )
self._regexes.Delete( selection )
self._refresh_callable()
def GetTags( self, index, path ):
tags = set()
num_namespace = self._num_namespace.GetValue()
if num_namespace != '':
num_base = self._num_base.GetValue()
num_step = self._num_step.GetValue()
tag_num = num_base + index * num_step
tags.add( num_namespace + ':' + str( tag_num ) )
return tags
def UpdateFilenameTaggingOptions( self, filename_tagging_options ):
quick_namespaces = self._quick_namespaces_list.GetData()
regexes = self._regexes.GetStrings()
filename_tagging_options.AdvancedSetTuple( quick_namespaces, regexes )
class _SimplePanel( wx.Panel ):
def __init__( self, parent, service_key, refresh_callable, filename_tagging_options, present_for_accompanying_file_list ):
wx.Panel.__init__( self, parent )
self._service_key = service_key
self._refresh_callable = refresh_callable
self._present_for_accompanying_file_list = present_for_accompanying_file_list
#
self._tags_panel = ClientGUICommon.StaticBox( self, 'tags for all' )
self._tags = ClientGUIListBoxes.ListBoxTagsStringsAddRemove( self._tags_panel, self._service_key, self.TagsRemoved )
expand_parents = True
self._tag_box = ClientGUIACDropdown.AutoCompleteDropdownTagsWrite( self._tags_panel, self.EnterTags, expand_parents, CC.LOCAL_FILE_SERVICE_KEY, service_key )
2017-11-29 21:48:23 +00:00
self._tags_paste_button = ClientGUICommon.BetterButton( self._tags_panel, 'paste tags', self._PasteTags )
2017-11-15 22:35:49 +00:00
#
self._single_tags_panel = ClientGUICommon.StaticBox( self, 'tags just for selected files' )
self._paths_to_single_tags = collections.defaultdict( set )
self._single_tags = ClientGUIListBoxes.ListBoxTagsStringsAddRemove( self._single_tags_panel, self._service_key, self.SingleTagsRemoved )
2017-11-29 21:48:23 +00:00
self._single_tags_paste_button = ClientGUICommon.BetterButton( self._single_tags_panel, 'paste tags', self._PasteSingleTags )
2017-11-15 22:35:49 +00:00
expand_parents = True
self._single_tag_box = ClientGUIACDropdown.AutoCompleteDropdownTagsWrite( self._single_tags_panel, self.EnterTagsSingle, expand_parents, CC.LOCAL_FILE_SERVICE_KEY, service_key )
self.SetSelectedPaths( [] )
if not self._present_for_accompanying_file_list:
self._single_tags_panel.Hide()
#
self._checkboxes_panel = ClientGUICommon.StaticBox( self, 'misc' )
self._load_from_txt_files_checkbox = wx.CheckBox( self._checkboxes_panel, label = 'try to load tags from neighbouring .txt files' )
txt_files_help_button = ClientGUICommon.BetterBitmapButton( self._checkboxes_panel, CC.GlobalBMPs.help, self._ShowTXTHelp )
2018-01-03 22:37:30 +00:00
txt_files_help_button.SetToolTip( 'Show help regarding importing tags from .txt files.' )
2017-11-15 22:35:49 +00:00
self._filename_namespace = wx.TextCtrl( self._checkboxes_panel )
self._filename_namespace.SetMinSize( ( 100, -1 ) )
self._filename_checkbox = wx.CheckBox( self._checkboxes_panel, label = 'add filename? [namespace]' )
self._dir_namespace_1 = wx.TextCtrl( self._checkboxes_panel )
self._dir_namespace_1.SetMinSize( ( 100, -1 ) )
self._dir_checkbox_1 = wx.CheckBox( self._checkboxes_panel, label = 'add first directory? [namespace]' )
self._dir_namespace_2 = wx.TextCtrl( self._checkboxes_panel )
self._dir_namespace_2.SetMinSize( ( 100, -1 ) )
self._dir_checkbox_2 = wx.CheckBox( self._checkboxes_panel, label = 'add second directory? [namespace]' )
self._dir_namespace_3 = wx.TextCtrl( self._checkboxes_panel )
self._dir_namespace_3.SetMinSize( ( 100, -1 ) )
self._dir_checkbox_3 = wx.CheckBox( self._checkboxes_panel, label = 'add third directory? [namespace]' )
#
( tags_for_all, load_from_neighbouring_txt_files, add_filename, add_first_directory, add_second_directory, add_third_directory ) = filename_tagging_options.SimpleToTuple()
self._tags.AddTags( tags_for_all )
self._load_from_txt_files_checkbox.SetValue( load_from_neighbouring_txt_files )
( add_filename_boolean, add_filename_namespace ) = add_filename
self._filename_checkbox.SetValue( add_filename_boolean )
self._filename_namespace.SetValue( add_filename_namespace )
( dir_1_boolean, dir_1_namespace ) = add_first_directory
self._dir_checkbox_1.SetValue( dir_1_boolean )
self._dir_namespace_1.SetValue( dir_1_namespace )
( dir_2_boolean, dir_2_namespace ) = add_second_directory
self._dir_checkbox_2.SetValue( dir_2_boolean )
self._dir_namespace_2.SetValue( dir_2_namespace )
( dir_3_boolean, dir_3_namespace ) = add_third_directory
self._dir_checkbox_3.SetValue( dir_3_boolean )
self._dir_namespace_3.SetValue( dir_3_namespace )
#
2018-01-03 22:37:30 +00:00
self._tags_panel.Add( self._tags, CC.FLAGS_EXPAND_BOTH_WAYS )
self._tags_panel.Add( self._tag_box, CC.FLAGS_EXPAND_PERPENDICULAR )
self._tags_panel.Add( self._tags_paste_button, CC.FLAGS_EXPAND_PERPENDICULAR )
2017-11-15 22:35:49 +00:00
2018-01-03 22:37:30 +00:00
self._single_tags_panel.Add( self._single_tags, CC.FLAGS_EXPAND_BOTH_WAYS )
self._single_tags_panel.Add( self._single_tag_box, CC.FLAGS_EXPAND_PERPENDICULAR )
self._single_tags_panel.Add( self._single_tags_paste_button, CC.FLAGS_EXPAND_PERPENDICULAR )
2017-11-15 22:35:49 +00:00
txt_hbox = wx.BoxSizer( wx.HORIZONTAL )
2018-01-03 22:37:30 +00:00
txt_hbox.Add( self._load_from_txt_files_checkbox, CC.FLAGS_EXPAND_BOTH_WAYS )
txt_hbox.Add( txt_files_help_button, CC.FLAGS_VCENTER )
2017-11-15 22:35:49 +00:00
filename_hbox = wx.BoxSizer( wx.HORIZONTAL )
2018-01-03 22:37:30 +00:00
filename_hbox.Add( self._filename_checkbox, CC.FLAGS_VCENTER )
filename_hbox.Add( self._filename_namespace, CC.FLAGS_EXPAND_BOTH_WAYS )
2017-11-15 22:35:49 +00:00
dir_hbox_1 = wx.BoxSizer( wx.HORIZONTAL )
2018-01-03 22:37:30 +00:00
dir_hbox_1.Add( self._dir_checkbox_1, CC.FLAGS_VCENTER )
dir_hbox_1.Add( self._dir_namespace_1, CC.FLAGS_EXPAND_BOTH_WAYS )
2017-11-15 22:35:49 +00:00
dir_hbox_2 = wx.BoxSizer( wx.HORIZONTAL )
2018-01-03 22:37:30 +00:00
dir_hbox_2.Add( self._dir_checkbox_2, CC.FLAGS_VCENTER )
dir_hbox_2.Add( self._dir_namespace_2, CC.FLAGS_EXPAND_BOTH_WAYS )
2017-11-15 22:35:49 +00:00
dir_hbox_3 = wx.BoxSizer( wx.HORIZONTAL )
2018-01-03 22:37:30 +00:00
dir_hbox_3.Add( self._dir_checkbox_3, CC.FLAGS_VCENTER )
dir_hbox_3.Add( self._dir_namespace_3, CC.FLAGS_EXPAND_BOTH_WAYS )
2017-11-15 22:35:49 +00:00
2018-01-03 22:37:30 +00:00
self._checkboxes_panel.Add( txt_hbox, CC.FLAGS_EXPAND_SIZER_PERPENDICULAR )
self._checkboxes_panel.Add( filename_hbox, CC.FLAGS_EXPAND_SIZER_PERPENDICULAR )
self._checkboxes_panel.Add( dir_hbox_1, CC.FLAGS_EXPAND_SIZER_PERPENDICULAR )
self._checkboxes_panel.Add( dir_hbox_2, CC.FLAGS_EXPAND_SIZER_PERPENDICULAR )
self._checkboxes_panel.Add( dir_hbox_3, CC.FLAGS_EXPAND_SIZER_PERPENDICULAR )
2017-11-15 22:35:49 +00:00
hbox = wx.BoxSizer( wx.HORIZONTAL )
2018-01-03 22:37:30 +00:00
hbox.Add( self._tags_panel, CC.FLAGS_EXPAND_BOTH_WAYS )
hbox.Add( self._single_tags_panel, CC.FLAGS_EXPAND_BOTH_WAYS )
hbox.Add( self._checkboxes_panel, CC.FLAGS_EXPAND_PERPENDICULAR )
2017-11-15 22:35:49 +00:00
self.SetSizer( hbox )
#
self._load_from_txt_files_checkbox.Bind( wx.EVT_CHECKBOX, self.EventRefresh )
self._filename_namespace.Bind( wx.EVT_TEXT, self.EventRefresh )
self._filename_checkbox.Bind( wx.EVT_CHECKBOX, self.EventRefresh )
self._dir_namespace_1.Bind( wx.EVT_TEXT, self.EventRefresh )
self._dir_checkbox_1.Bind( wx.EVT_CHECKBOX, self.EventRefresh )
self._dir_namespace_2.Bind( wx.EVT_TEXT, self.EventRefresh )
self._dir_checkbox_2.Bind( wx.EVT_CHECKBOX, self.EventRefresh )
self._dir_namespace_3.Bind( wx.EVT_TEXT, self.EventRefresh )
self._dir_checkbox_3.Bind( wx.EVT_CHECKBOX, self.EventRefresh )
2017-11-29 21:48:23 +00:00
def _GetTagsFromClipboard( self ):
2017-12-13 22:33:07 +00:00
text = HG.client_controller.GetClipboardText()
try:
2017-11-29 21:48:23 +00:00
2017-12-13 22:33:07 +00:00
tags = HydrusText.DeserialiseNewlinedTexts( text )
2017-11-29 21:48:23 +00:00
2017-12-13 22:33:07 +00:00
tags = HydrusTags.CleanTags( tags )
2017-11-29 21:48:23 +00:00
2017-12-13 22:33:07 +00:00
return tags
2017-11-29 21:48:23 +00:00
2017-12-13 22:33:07 +00:00
except:
2017-11-29 21:48:23 +00:00
2017-12-13 22:33:07 +00:00
raise Exception( 'I could not understand what was in the clipboard' )
2017-11-29 21:48:23 +00:00
def _PasteTags( self ):
try:
tags = self._GetTagsFromClipboard()
except Exception as e:
wx.MessageBox( HydrusData.ToUnicode( e ) )
return
self.EnterTags( tags )
def _PasteSingleTags( self ):
try:
tags = self._GetTagsFromClipboard()
except Exception as e:
wx.MessageBox( HydrusData.ToUnicode( e ) )
return
self.EnterTagsSingle( tags )
2017-11-15 22:35:49 +00:00
def _ShowTXTHelp( self ):
message = 'If you would like to add custom tags with your files, add a .txt file beside the file like so:'
message += os.linesep * 2
message += 'my_file.jpg'
message += os.linesep
message += 'my_file.jpg.txt'
message += os.linesep * 2
message += 'And include your tags inside the .txt file in a newline-separated list (if you know how to script, generating these files automatically from another source of tags can save a lot of time!).'
message += os.linesep * 2
message += 'Make sure you preview the results in the table above to be certain everything is parsing correctly. Until you are comfortable with this, you should test it on just one or two files.'
wx.MessageBox( message )
def EnterTags( self, tags ):
tag_parents_manager = HG.client_controller.GetManager( 'tag_parents' )
parents = set()
for tag in tags:
some_parents = tag_parents_manager.GetParents( self._service_key, tag )
parents.update( some_parents )
if len( tags ) > 0:
self._tags.AddTags( tags )
self._tags.AddTags( parents )
self._refresh_callable()
def EnterTagsSingle( self, tags ):
tag_parents_manager = HG.client_controller.GetManager( 'tag_parents' )
parents = set()
for tag in tags:
some_parents = tag_parents_manager.GetParents( self._service_key, tag )
parents.update( some_parents )
if len( tags ) > 0:
self._single_tags.AddTags( tags )
self._single_tags.AddTags( parents )
for path in self._selected_paths:
current_tags = self._paths_to_single_tags[ path ]
current_tags.update( tags )
current_tags.update( parents )
self._refresh_callable()
def EventRefresh( self, event ):
self._refresh_callable()
def GetTags( self, index, path ):
tags = set()
if path in self._paths_to_single_tags:
tags.update( self._paths_to_single_tags[ path ] )
return tags
def SingleTagsRemoved( self, tags ):
for path in self._selected_paths:
current_tags = self._paths_to_single_tags[ path ]
current_tags.difference_update( tags )
self._refresh_callable()
def SetSelectedPaths( self, paths ):
self._selected_paths = paths
single_tags = set()
if len( paths ) > 0:
for path in self._selected_paths:
if path in self._paths_to_single_tags:
single_tags.update( self._paths_to_single_tags[ path ] )
self._single_tag_box.Enable()
2017-11-29 21:48:23 +00:00
self._single_tags_paste_button.Enable()
2017-11-15 22:35:49 +00:00
else:
self._single_tag_box.Disable()
2017-11-29 21:48:23 +00:00
self._single_tags_paste_button.Disable()
2017-11-15 22:35:49 +00:00
self._single_tags.SetTags( single_tags )
def TagsRemoved( self, tag ):
self._refresh_callable()
def UpdateFilenameTaggingOptions( self, filename_tagging_options ):
tags_for_all = self._tags.GetTags()
load_from_neighbouring_txt_files = self._load_from_txt_files_checkbox.GetValue()
add_filename_boolean = self._filename_checkbox.GetValue()
add_filename_namespace = self._filename_namespace.GetValue()
add_filename = ( add_filename_boolean, add_filename_namespace )
dir_1_boolean = self._dir_checkbox_1.GetValue()
dir_1_namespace = self._dir_namespace_1.GetValue()
add_first_directory = ( dir_1_boolean, dir_1_namespace )
dir_2_boolean = self._dir_checkbox_2.GetValue()
dir_2_namespace = self._dir_namespace_2.GetValue()
add_second_directory = ( dir_2_boolean, dir_2_namespace )
dir_3_boolean = self._dir_checkbox_3.GetValue()
dir_3_namespace = self._dir_namespace_3.GetValue()
add_third_directory = ( dir_3_boolean, dir_3_namespace )
filename_tagging_options.SimpleSetTuple( tags_for_all, load_from_neighbouring_txt_files, add_filename, add_first_directory, add_second_directory, add_third_directory )
2017-11-22 21:03:07 +00:00
class EditLocalImportFilenameTaggingPanel( ClientGUIScrolledPanels.EditPanel ):
def __init__( self, parent, paths ):
ClientGUIScrolledPanels.EditPanel.__init__( self, parent )
self._paths = paths
self._tag_repositories = ClientGUICommon.ListBook( self )
#
services = HG.client_controller.services_manager.GetServices( ( HC.TAG_REPOSITORY, ) )
for service in services:
if service.HasPermission( HC.CONTENT_TYPE_MAPPINGS, HC.PERMISSION_ACTION_CREATE ):
service_key = service.GetServiceKey()
name = service.GetName()
self._tag_repositories.AddPageArgs( name, service_key, self._Panel, ( self._tag_repositories, service_key, paths ), {} )
page = self._Panel( self._tag_repositories, CC.LOCAL_TAG_SERVICE_KEY, paths )
name = CC.LOCAL_TAG_SERVICE_KEY
self._tag_repositories.AddPage( name, name, page )
default_tag_repository_key = HC.options[ 'default_tag_repository' ]
self._tag_repositories.Select( default_tag_repository_key )
#
vbox = wx.BoxSizer( wx.VERTICAL )
2018-01-03 22:37:30 +00:00
vbox.Add( self._tag_repositories, CC.FLAGS_EXPAND_BOTH_WAYS )
2017-11-22 21:03:07 +00:00
self.SetSizer( vbox )
def GetValue( self ):
paths_to_tags = collections.defaultdict( dict )
for page in self._tag_repositories.GetActivePages():
( service_key, page_of_paths_to_tags ) = page.GetInfo()
for ( path, tags ) in page_of_paths_to_tags.items(): paths_to_tags[ path ][ service_key ] = tags
return paths_to_tags
class _Panel( wx.Panel ):
def __init__( self, parent, service_key, paths ):
wx.Panel.__init__( self, parent )
self._service_key = service_key
self._paths = paths
self._paths_list = ClientGUIListCtrl.BetterListCtrl( self, 'paths_to_tags', 25, 40, [ ( '#', 4 ), ( 'path', 40 ), ( 'tags', -1 ) ], self._ConvertDataToListCtrlTuples )
self._paths_list.Bind( wx.EVT_LIST_ITEM_SELECTED, self.EventItemSelected )
self._paths_list.Bind( wx.EVT_LIST_ITEM_DESELECTED, self.EventItemSelected )
#
2018-05-30 20:13:21 +00:00
self._filename_tagging_panel = FilenameTaggingOptionsPanel( self, self._service_key, self.ScheduleRefreshFileList, present_for_accompanying_file_list = True )
self._schedule_refresh_file_list_job = None
2017-11-22 21:03:07 +00:00
#
# i.e. ( index, path )
self._paths_list.AddDatas( list( enumerate( self._paths ) ) )
#
vbox = wx.BoxSizer( wx.VERTICAL )
2018-01-03 22:37:30 +00:00
vbox.Add( self._paths_list, CC.FLAGS_EXPAND_BOTH_WAYS )
vbox.Add( self._filename_tagging_panel, CC.FLAGS_EXPAND_PERPENDICULAR )
2017-11-22 21:03:07 +00:00
self.SetSizer( vbox )
def _ConvertDataToListCtrlTuples( self, data ):
( index, path ) = data
tags = self._GetTags( index, path )
2018-07-04 20:48:28 +00:00
pretty_index = HydrusData.ToHumanInt( index + 1 )
2017-11-22 21:03:07 +00:00
pretty_path = path
pretty_tags = ', '.join( tags )
display_tuple = ( pretty_index, pretty_path, pretty_tags )
sort_tuple = ( index, path, tags )
return ( display_tuple, sort_tuple )
def _GetTags( self, index, path ):
filename_tagging_options = self._filename_tagging_panel.GetFilenameTaggingOptions()
tags = filename_tagging_options.GetTags( self._service_key, path )
tags.update( self._filename_tagging_panel.GetTags( index, path ) )
tags = list( tags )
tags.sort()
return tags
def EventItemSelected( self, event ):
paths = [ path for ( index, path ) in self._paths_list.GetData( only_selected = True ) ]
self._filename_tagging_panel.SetSelectedPaths( paths )
event.Skip()
def GetInfo( self ):
paths_to_tags = { path : self._GetTags( index, path ) for ( index, path ) in self._paths_list.GetData() }
return ( self._service_key, paths_to_tags )
def RefreshFileList( self ):
self._paths_list.UpdateDatas()
2018-05-30 20:13:21 +00:00
def ScheduleRefreshFileList( self ):
if self._schedule_refresh_file_list_job is not None:
self._schedule_refresh_file_list_job.Cancel()
self._schedule_refresh_file_list_job = None
self._schedule_refresh_file_list_job = HG.client_controller.CallLaterWXSafe( self, 0.5, self.RefreshFileList )
2017-11-15 22:35:49 +00:00
class EditFilenameTaggingOptionPanel( ClientGUIScrolledPanels.EditPanel ):
def __init__( self, parent, service_key, filename_tagging_options ):
ClientGUIScrolledPanels.EditPanel.__init__( self, parent )
self._service_key = service_key
self._example_path_input = wx.TextCtrl( self )
self._example_output = wx.TextCtrl( self )
2018-05-30 20:13:21 +00:00
self._filename_tagging_options_panel = FilenameTaggingOptionsPanel( self, self._service_key, self.ScheduleRefreshTags, filename_tagging_options = filename_tagging_options, present_for_accompanying_file_list = False )
self._schedule_refresh_tags_job = None
2017-11-15 22:35:49 +00:00
#
self._example_path_input.SetValue( 'enter example path here' )
self._example_output.Disable()
#
vbox = wx.BoxSizer( wx.VERTICAL )
2018-01-03 22:37:30 +00:00
vbox.Add( self._example_path_input, CC.FLAGS_EXPAND_PERPENDICULAR )
vbox.Add( self._example_output, CC.FLAGS_EXPAND_PERPENDICULAR )
vbox.Add( self._filename_tagging_options_panel, CC.FLAGS_EXPAND_BOTH_WAYS )
2017-11-15 22:35:49 +00:00
self.SetSizer( vbox )
#
self._example_path_input.Bind( wx.EVT_TEXT, self.EventText )
def EventText( self, event ):
2018-05-30 20:13:21 +00:00
self.ScheduleRefreshTags()
2017-11-15 22:35:49 +00:00
def GetValue( self ):
return self._filename_tagging_options_panel.GetFilenameTaggingOptions()
def RefreshTags( self ):
example_path_input = self._example_path_input.GetValue()
filename_tagging_options = self.GetValue()
try:
tags = filename_tagging_options.GetTags( self._service_key, example_path_input )
except:
tags = [ 'could not parse' ]
self._example_output.SetValue( ', '.join( tags ) )
2018-05-30 20:13:21 +00:00
def ScheduleRefreshTags( self ):
if self._schedule_refresh_tags_job is not None:
self._schedule_refresh_tags_job.Cancel()
self._schedule_refresh_tags_job = None
self._schedule_refresh_tags_job = HG.client_controller.CallLaterWXSafe( self, 0.5, self.RefreshTags )
2017-09-20 19:47:31 +00:00
class TagImportOptionsButton( ClientGUICommon.BetterButton ):
2018-07-11 20:23:51 +00:00
def __init__( self, parent, namespaces, tag_import_options, update_callable = None, show_downloader_options = True, allow_default_selection = False ):
2017-09-20 19:47:31 +00:00
ClientGUICommon.BetterButton.__init__( self, parent, 'tag import options', self._EditOptions )
self._namespaces = namespaces
self._tag_import_options = tag_import_options
self._update_callable = update_callable
2018-06-27 19:27:05 +00:00
self._show_downloader_options = show_downloader_options
2018-07-11 20:23:51 +00:00
self._allow_default_selection = allow_default_selection
2017-09-20 19:47:31 +00:00
self._SetToolTip()
2018-07-11 20:23:51 +00:00
#
self.Bind( wx.EVT_RIGHT_DOWN, self.EventShowMenu )
def _Copy( self ):
json_string = self._tag_import_options.DumpToString()
HG.client_controller.pub( 'clipboard', 'text', json_string )
2017-09-20 19:47:31 +00:00
def _EditOptions( self ):
with ClientGUITopLevelWindows.DialogEdit( self, 'edit tag import options' ) as dlg:
2018-07-11 20:23:51 +00:00
panel = ClientGUIScrolledPanelsEdit.EditTagImportOptionsPanel( dlg, self._namespaces, self._tag_import_options, show_downloader_options = self._show_downloader_options, allow_default_selection = self._allow_default_selection )
2017-09-20 19:47:31 +00:00
dlg.SetPanel( panel )
if dlg.ShowModal() == wx.ID_OK:
tag_import_options = panel.GetValue()
self._SetValue( tag_import_options )
2018-07-11 20:23:51 +00:00
def _Paste( self ):
2018-07-18 21:07:15 +00:00
2018-07-11 20:23:51 +00:00
raw_text = HG.client_controller.GetClipboardText()
try:
tag_import_options = HydrusSerialisable.CreateFromString( raw_text )
2018-07-18 21:07:15 +00:00
if not isinstance( tag_import_options, ClientImportOptions.TagImportOptions ):
raise Exception( 'Not a Tag Import Options!' )
2018-07-11 20:23:51 +00:00
self._tag_import_options = tag_import_options
except Exception as e:
wx.MessageBox( 'I could not understand what was in the clipboard' )
HydrusData.ShowException( e )
def _SetDefault( self ):
self._tag_import_options.SetDefault()
2017-09-20 19:47:31 +00:00
def _SetToolTip( self ):
2018-07-11 20:23:51 +00:00
summary = self._tag_import_options.GetSummary( self._show_downloader_options )
self.SetToolTip( summary )
2017-09-20 19:47:31 +00:00
def _SetValue( self, tag_import_options ):
self._tag_import_options = tag_import_options
self._SetToolTip()
if self._update_callable is not None:
self._update_callable( self._tag_import_options )
2018-07-11 20:23:51 +00:00
def EventShowMenu( self, event ):
menu = wx.Menu()
ClientGUIMenus.AppendMenuItem( self, menu, 'copy to clipboard', 'Serialise this tag import options and copy it to clipboard.', self._Copy )
ClientGUIMenus.AppendSeparator( menu )
ClientGUIMenus.AppendMenuItem( self, menu, 'paste from clipboard', 'Try to import serialised tag import options from the clipboard.', self._Paste )
if not self._tag_import_options.IsDefault():
ClientGUIMenus.AppendSeparator( menu )
ClientGUIMenus.AppendMenuItem( self, menu, 'set to default', 'Set this tag import options to defer to the defaults.', self._SetDefault )
HG.client_controller.PopupMenu( self, menu )
2017-09-20 19:47:31 +00:00
def GetValue( self ):
return self._tag_import_options
2017-11-01 20:37:39 +00:00
def SetNamespaces( self, namespaces ):
self._namespaces = namespaces
2017-09-20 19:47:31 +00:00
def SetValue( self, tag_import_options ):
self._SetValue( tag_import_options )
2018-07-18 21:07:15 +00:00
class WatcherReviewPanel( ClientGUICommon.StaticBox ):
def __init__( self, parent, page_key ):
ClientGUICommon.StaticBox.__init__( self, parent, 'watcher' )
self._page_key = page_key
self._watcher = None
self._watcher_subject = ClientGUICommon.BetterStaticText( self, style = wx.ST_ELLIPSIZE_END )
self._url_input = wx.TextCtrl( self, style = wx.TE_PROCESS_ENTER )
self._url_input.Bind( wx.EVT_KEY_DOWN, self.EventKeyDown )
self._options_panel = wx.Panel( self )
#
imports_panel = ClientGUICommon.StaticBox( self._options_panel, 'file imports' )
self._files_pause_button = wx.BitmapButton( imports_panel, bitmap = CC.GlobalBMPs.pause )
self._files_pause_button.Bind( wx.EVT_BUTTON, self.EventPauseFiles )
self._current_action = ClientGUICommon.BetterStaticText( imports_panel, style = wx.ST_ELLIPSIZE_END )
self._file_seed_cache_control = ClientGUIFileSeedCache.FileSeedCacheStatusControl( imports_panel, self._controller, self._page_key )
self._file_download_control = ClientGUIControls.NetworkJobControl( imports_panel )
#
checker_panel = ClientGUICommon.StaticBox( self._options_panel, 'checker' )
self._file_velocity_status = ClientGUICommon.BetterStaticText( checker_panel, style = wx.ST_ELLIPSIZE_END )
self._checking_pause_button = wx.BitmapButton( checker_panel, bitmap = CC.GlobalBMPs.pause )
self._checking_pause_button.Bind( wx.EVT_BUTTON, self.EventPauseChecker )
self._watcher_status = ClientGUICommon.BetterStaticText( checker_panel, style = wx.ST_ELLIPSIZE_END )
self._check_now_button = wx.Button( checker_panel, label = 'check now' )
self._check_now_button.Bind( wx.EVT_BUTTON, self.EventCheckNow )
self._gallery_seed_log_control = ClientGUIGallerySeedLog.GallerySeedLogStatusControl( checker_panel, self._controller, True, page_key = self._page_key )
checker_options = ClientImportOptions.CheckerOptions()
self._checker_options_button = CheckerOptionsButton( checker_panel, checker_options, update_callable = self._SetCheckerOptions )
self._checker_download_control = ClientGUIControls.NetworkJobControl( checker_panel )
namespaces = []
file_import_options = ClientImportOptions.FileImportOptions()
tag_import_options = ClientImportOptions.TagImportOptions( is_default = True )
self._file_import_options = FileImportOptionsButton( self._watcher_panel, file_import_options, self._SetFileImportOptions )
self._tag_import_options = TagImportOptionsButton( self._watcher_panel, namespaces, tag_import_options, update_callable = self._SetTagImportOptions, allow_default_selection = True )
#
hbox = wx.BoxSizer( wx.HORIZONTAL )
hbox.Add( self._current_action, CC.FLAGS_VCENTER_EXPAND_DEPTH_ONLY )
hbox.Add( self._files_pause_button, CC.FLAGS_VCENTER )
imports_panel.Add( hbox, CC.FLAGS_EXPAND_SIZER_PERPENDICULAR )
imports_panel.Add( self._file_seed_cache_control, CC.FLAGS_EXPAND_PERPENDICULAR )
imports_panel.Add( self._file_download_control, CC.FLAGS_EXPAND_PERPENDICULAR )
#
gridbox = wx.FlexGridSizer( 2 )
gridbox.AddGrowableCol( 0, 1 )
gridbox.Add( self._file_velocity_status, CC.FLAGS_VCENTER_EXPAND_DEPTH_ONLY )
gridbox.Add( self._checking_pause_button, CC.FLAGS_LONE_BUTTON )
gridbox.Add( self._watcher_status, CC.FLAGS_VCENTER_EXPAND_DEPTH_ONLY )
gridbox.Add( self._check_now_button, CC.FLAGS_VCENTER )
checker_panel.Add( gridbox, CC.FLAGS_EXPAND_SIZER_PERPENDICULAR )
checker_panel.Add( self._gallery_seed_log_control, CC.FLAGS_EXPAND_PERPENDICULAR )
checker_panel.Add( self._checker_options_button, CC.FLAGS_EXPAND_PERPENDICULAR )
checker_panel.Add( self._checker_download_control, CC.FLAGS_EXPAND_PERPENDICULAR )
vbox = wx.BoxSizer( wx.VERTICAL )
vbox.Add( imports_panel, CC.FLAGS_EXPAND_PERPENDICULAR )
vbox.Add( checker_panel, CC.FLAGS_EXPAND_PERPENDICULAR )
self._options_panel.SetSizer( vbox )
self._watcher_panel.Add( self._watcher_subject, CC.FLAGS_EXPAND_PERPENDICULAR )
self._watcher_panel.Add( self._url_input, CC.FLAGS_EXPAND_PERPENDICULAR )
self._watcher_panel.Add( self._options_panel, CC.FLAGS_EXPAND_SIZER_BOTH_WAYS )
self._watcher_panel.Add( self._file_import_options, CC.FLAGS_EXPAND_PERPENDICULAR )
self._watcher_panel.Add( self._tag_import_options, CC.FLAGS_EXPAND_PERPENDICULAR )
#
vbox = wx.BoxSizer( wx.VERTICAL )
vbox.Add( self._sort_by, CC.FLAGS_EXPAND_SIZER_PERPENDICULAR )
self._collect_by.Hide()
vbox.Add( self._watcher_panel, CC.FLAGS_EXPAND_PERPENDICULAR )
self._MakeCurrentSelectionTagsBox( vbox )
self.SetSizer( vbox )
#
self._UpdateStatus()
def _SetCheckerOptions( self, checker_options ):
if self._watcher is not None:
self._watcher_import.SetCheckerOptions( checker_options )
def _SetFileImportOptions( self, file_import_options ):
if self._watcher is not None:
self._watcher.SetFileImportOptions( file_import_options )
def _SetTagImportOptions( self, tag_import_options ):
if self._watcher is not None:
self._watcher.SetTagImportOptions( tag_import_options )
def _UpdateControlsForNewWatcher( self ):
if self._watcher is None:
pass # clear and disable everything
else:
# fetch url
url = 'blah'
if url is None or url == '':
pass # set up as a new url input, ready to init thread watcher
else:
pass # present everything else
# update CO button with value
# update FIO button with value
# update TIO button with value
file_seed_cache = self._watcher_import.GetFileSeedCache()
self._file_seed_cache_control.SetFileSeedCache( file_seed_cache )
gallery_seed_log = self._watcher_import.GetGallerySeedLog()
self._gallery_seed_log_control.SetGallerySeedLog( gallery_seed_log )
self._watcher_import.SetDownloadControlFile( self._file_download_control )
self._watcher_import.SetDownloadControlChecker( self._checker_download_control )
self._url_input.SetValue( url )
def _UpdateStatus( self ):
if self._watcher_import.HasURL():
self._url_input.SetEditable( False )
if not self._options_panel.IsShown():
self._watcher_subject.Show()
self._options_panel.Show()
self.Layout()
else:
if self._options_panel.IsShown():
self._watcher_subject.Hide()
self._options_panel.Hide()
self.Layout()
( current_action, files_paused, file_velocity_status, next_check_time, watcher_status, subject, checking_status, check_now, checking_paused ) = self._watcher_import.GetStatus()
if files_paused:
if current_action == '':
current_action = 'paused'
else:
current_action = 'pausing, ' + current_action
ClientGUICommon.SetBitmapButtonBitmap( self._files_pause_button, CC.GlobalBMPs.play )
else:
ClientGUICommon.SetBitmapButtonBitmap( self._files_pause_button, CC.GlobalBMPs.pause )
self._current_action.SetLabelText( current_action )
self._file_velocity_status.SetLabelText( file_velocity_status )
if checking_paused:
if watcher_status == '':
watcher_status = 'paused'
ClientGUICommon.SetBitmapButtonBitmap( self._checking_pause_button, CC.GlobalBMPs.play )
else:
if watcher_status == '' and next_check_time is not None:
if HydrusData.TimeHasPassed( next_check_time ):
watcher_status = 'checking imminently'
else:
watcher_status = 'next check ' + HydrusData.TimestampToPrettyTimeDelta( next_check_time, just_now_threshold = 0 )
ClientGUICommon.SetBitmapButtonBitmap( self._checking_pause_button, CC.GlobalBMPs.pause )
self._watcher_status.SetLabelText( watcher_status )
if checking_status == ClientImporting.CHECKER_STATUS_404:
self._checking_pause_button.Disable()
elif checking_status == ClientImporting.CHECKER_STATUS_DEAD:
self._checking_pause_button.Disable()
else:
self._checking_pause_button.Enable()
if subject in ( '', 'unknown subject' ):
subject = 'no subject'
self._watcher_subject.SetLabelText( subject )
if check_now:
self._check_now_button.Disable()
else:
self._check_now_button.Enable()
def EventCheckNow( self, event ):
self._watcher_import.CheckNow()
self._UpdateStatus()
def EventKeyDown( self, event ):
( modifier, key ) = ClientGUIShortcuts.ConvertKeyEventToSimpleTuple( event )
if key in ( wx.WXK_RETURN, wx.WXK_NUMPAD_ENTER ):
url = self._url_input.GetValue()
if url == '':
return
self._url_input.SetEditable( False )
self._watcher.SetURL( url )
publish_to_page = True
self._watcher.Start( self._page_key, publish_to_page )
self._UpdateControlsForNewWatcher()
else:
event.Skip()
def EventPauseFiles( self, event ):
self._watcher_import.PausePlayFiles()
self._UpdateStatus()
def EventPauseChecker( self, event ):
self._watcher_import.PausePlayChecker()
self._UpdateStatus()
def SetSearchFocus( self ):
wx.CallAfter( self._url_input.SetFocus )
def SetWatcher( self, watcher ):
self._watcher = watcher
self._UpdateControlsForNewWatcher()
def UpdateStatus( self ):
self._UpdateStatus()