2019-01-09 22:59:03 +00:00
from . import ClientConstants as CC
from . import ClientData
from . import ClientGUICommon
2019-06-26 21:27:18 +00:00
from . import ClientGUIFunctions
2019-09-11 21:51:09 +00:00
from . import ClientGUIScrolledPanels
from . import ClientGUITopLevelWindows
2019-01-09 22:59:03 +00:00
from . import HydrusConstants as HC
from . import HydrusData
from . import HydrusGlobals as HG
from . import HydrusSerialisable
2019-11-14 03:56:30 +00:00
from qtpy import QtCore as QC
from qtpy import QtWidgets as QW
from qtpy import QtGui as QG
from . import QtPorting as QP
2017-05-31 21:50:53 +00:00
2018-05-16 20:09:50 +00:00
def ConvertKeyEventToShortcut ( event ) :
2019-11-14 03:56:30 +00:00
key = event . key ( )
2018-05-16 20:09:50 +00:00
2019-11-14 03:56:30 +00:00
if key in CC . special_key_shortcut_enum_lookup or ClientData . OrdIsSensibleASCII ( key ) :
if key in CC . special_key_shortcut_enum_lookup :
shortcut_type = CC . SHORTCUT_TYPE_KEYBOARD_SPECIAL
key = CC . special_key_shortcut_enum_lookup [ key ]
else :
shortcut_type = CC . SHORTCUT_TYPE_KEYBOARD_ASCII
key = int ( key )
2018-05-16 20:09:50 +00:00
modifiers = [ ]
2019-11-14 03:56:30 +00:00
if event . modifiers ( ) & QC . Qt . AltModifier :
2018-05-16 20:09:50 +00:00
modifiers . append ( CC . SHORTCUT_MODIFIER_ALT )
2019-11-14 03:56:30 +00:00
if HC . PLATFORM_OSX :
ctrl = QC . Qt . MetaModifier
else :
ctrl = QC . Qt . ControlModifier
if event . modifiers ( ) & ctrl :
2018-05-16 20:09:50 +00:00
modifiers . append ( CC . SHORTCUT_MODIFIER_CTRL )
2019-11-14 03:56:30 +00:00
if event . modifiers ( ) & QC . Qt . ShiftModifier :
2018-05-16 20:09:50 +00:00
modifiers . append ( CC . SHORTCUT_MODIFIER_SHIFT )
2019-11-14 03:56:30 +00:00
if event . modifiers ( ) & QC . Qt . GroupSwitchModifier :
modifiers . append ( CC . SHORTCUT_MODIFIER_GROUP_SWITCH )
if event . modifiers ( ) & QC . Qt . KeypadModifier :
modifiers . append ( CC . SHORTCUT_MODIFIER_KEYPAD )
shortcut = Shortcut ( shortcut_type , key , modifiers )
2018-05-16 20:09:50 +00:00
if HG . gui_report_mode :
HydrusData . ShowText ( ' key event caught: ' + repr ( shortcut ) )
return shortcut
return None
def ConvertKeyEventToSimpleTuple ( event ) :
2019-11-14 03:56:30 +00:00
modifier = QC . Qt . NoModifier
2018-05-16 20:09:50 +00:00
2019-11-14 03:56:30 +00:00
if event . modifiers ( ) & QC . Qt . AltModifier : modifier = QC . Qt . AltModifier
elif event . modifiers ( ) & QC . Qt . ControlModifier : modifier = QC . Qt . ControlModifier
elif event . modifiers ( ) & QC . Qt . ShiftModifier : modifier = QC . Qt . ShiftModifier
elif event . modifiers ( ) & QC . Qt . KeypadModifier : modifier = QC . Qt . KeypadModifier
elif event . modifiers ( ) & QC . Qt . GroupSwitchModifier : modifier = QC . Qt . GroupSwitchModifier
2018-05-16 20:09:50 +00:00
2019-11-14 03:56:30 +00:00
key = event . key ( )
2018-05-16 20:09:50 +00:00
return ( modifier , key )
def ConvertMouseEventToShortcut ( event ) :
key = None
2019-11-14 03:56:30 +00:00
if ( event . type ( ) == QC . QEvent . MouseButtonPress and event . buttons ( ) & QC . Qt . LeftButton ) or ( event . type ( ) == QC . QEvent . MouseButtonDblClick and event . button ( ) == QC . Qt . LeftButton ) :
2018-05-16 20:09:50 +00:00
key = CC . SHORTCUT_MOUSE_LEFT
2019-11-14 03:56:30 +00:00
elif ( event . type ( ) == QC . QEvent . MouseButtonPress and event . buttons ( ) & QC . Qt . MiddleButton ) or ( event . type ( ) == QC . QEvent . MouseButtonDblClick and event . button ( ) == QC . Qt . MiddleButton ) :
2018-05-16 20:09:50 +00:00
key = CC . SHORTCUT_MOUSE_MIDDLE
2019-11-14 03:56:30 +00:00
elif ( event . type ( ) == QC . QEvent . MouseButtonPress and event . buttons ( ) & QC . Qt . RightButton ) or ( event . type ( ) == QC . QEvent . MouseButtonDblClick and event . button ( ) == QC . Qt . RightButton ) :
2018-05-16 20:09:50 +00:00
key = CC . SHORTCUT_MOUSE_RIGHT
2019-11-14 03:56:30 +00:00
elif event . type ( ) == QC . QEvent . Wheel and event . angleDelta ( ) . y ( ) > 0 :
2018-05-16 20:09:50 +00:00
key = CC . SHORTCUT_MOUSE_SCROLL_UP
2019-11-14 03:56:30 +00:00
elif event . type ( ) == QC . QEvent . Wheel and event . angleDelta ( ) . y ( ) < 0 :
2018-05-16 20:09:50 +00:00
key = CC . SHORTCUT_MOUSE_SCROLL_DOWN
if key is not None :
modifiers = [ ]
2019-11-14 03:56:30 +00:00
if event . modifiers ( ) & QC . Qt . AltModifier :
2018-05-16 20:09:50 +00:00
modifiers . append ( CC . SHORTCUT_MODIFIER_ALT )
2019-11-14 03:56:30 +00:00
if event . modifiers ( ) & QC . Qt . ControlModifier :
2018-05-16 20:09:50 +00:00
modifiers . append ( CC . SHORTCUT_MODIFIER_CTRL )
2019-11-14 03:56:30 +00:00
if event . modifiers ( ) & QC . Qt . ShiftModifier :
2018-05-16 20:09:50 +00:00
modifiers . append ( CC . SHORTCUT_MODIFIER_SHIFT )
2019-11-14 03:56:30 +00:00
if event . modifiers ( ) & QC . Qt . GroupSwitchModifier :
modifiers . append ( CC . SHORTCUT_MODIFIER_GROUP_SWITCH )
if event . modifiers ( ) & QC . Qt . KeypadModifier :
modifiers . append ( CC . SHORTCUT_MODIFIER_KEYPAD )
2018-05-16 20:09:50 +00:00
shortcut = Shortcut ( CC . SHORTCUT_TYPE_MOUSE , key , modifiers )
if HG . gui_report_mode :
HydrusData . ShowText ( ' mouse event caught: ' + repr ( shortcut ) )
return shortcut
return None
2019-07-03 22:49:27 +00:00
def IShouldCatchShortcutEvent ( evt_handler , event = None , child_tlp_classes_who_can_pass_up = None ) :
2017-04-19 20:58:30 +00:00
2019-07-03 22:49:27 +00:00
do_focus_test = True
2019-11-14 03:56:30 +00:00
if event is not None and isinstance ( event , QG . QWheelEvent ) :
2019-07-03 22:49:27 +00:00
2019-11-14 03:56:30 +00:00
do_focus_test = False
2019-06-26 21:27:18 +00:00
2019-07-03 22:49:27 +00:00
if do_focus_test :
if not ClientGUIFunctions . WindowOrSameTLPChildHasFocus ( evt_handler ) :
2019-06-26 21:27:18 +00:00
2019-07-03 22:49:27 +00:00
if child_tlp_classes_who_can_pass_up is not None :
2019-11-14 03:56:30 +00:00
child_tlp_has_focus = ClientGUIFunctions . WindowOrAnyTLPChildHasFocus ( evt_handler ) and isinstance ( QW . QApplication . activeWindow ( ) , child_tlp_classes_who_can_pass_up )
2019-07-03 22:49:27 +00:00
if not child_tlp_has_focus :
return False
else :
2019-06-26 21:27:18 +00:00
return False
2017-04-19 20:58:30 +00:00
return True
2018-05-16 20:09:50 +00:00
class Shortcut ( HydrusSerialisable . SerialisableBase ) :
SERIALISABLE_TYPE = HydrusSerialisable . SERIALISABLE_TYPE_SHORTCUT
SERIALISABLE_NAME = ' Shortcut '
2019-11-14 03:56:30 +00:00
SERIALISABLE_VERSION = 2
2018-05-16 20:09:50 +00:00
def __init__ ( self , shortcut_type = None , shortcut_key = None , modifiers = None ) :
if shortcut_type is None :
2019-11-14 03:56:30 +00:00
shortcut_type = CC . SHORTCUT_TYPE_KEYBOARD_SPECIAL
2018-05-16 20:09:50 +00:00
if shortcut_key is None :
2019-11-14 03:56:30 +00:00
shortcut_key = CC . SHORTCUT_KEY_SPECIAL_F7
2018-05-16 20:09:50 +00:00
if modifiers is None :
modifiers = [ ]
2019-11-14 03:56:30 +00:00
if shortcut_type == CC . SHORTCUT_TYPE_KEYBOARD_ASCII and ClientData . OrdIsAlphaUpper ( shortcut_key ) :
shortcut_key + = 32 # convert A to a
2018-05-16 20:09:50 +00:00
modifiers . sort ( )
HydrusSerialisable . SerialisableBase . __init__ ( self )
self . _shortcut_type = shortcut_type
self . _shortcut_key = shortcut_key
self . _modifiers = modifiers
def __eq__ ( self , other ) :
return self . __hash__ ( ) == other . __hash__ ( )
def __hash__ ( self ) :
return ( self . _shortcut_type , self . _shortcut_key , tuple ( self . _modifiers ) ) . __hash__ ( )
def __repr__ ( self ) :
return ' Shortcut: ' + self . ToString ( )
def _GetSerialisableInfo ( self ) :
return ( self . _shortcut_type , self . _shortcut_key , self . _modifiers )
def _InitialiseFromSerialisableInfo ( self , serialisable_info ) :
( self . _shortcut_type , self . _shortcut_key , self . _modifiers ) = serialisable_info
2019-11-14 03:56:30 +00:00
def _UpdateSerialisableInfo ( self , version , old_serialisable_info ) :
if version == 1 :
# these are dicts that convert fixed wx enums to new stuff
wx_to_qt_flat_conversion = {
32 : CC . SHORTCUT_KEY_SPECIAL_SPACE ,
8 : CC . SHORTCUT_KEY_SPECIAL_BACKSPACE ,
9 : CC . SHORTCUT_KEY_SPECIAL_TAB ,
13 : CC . SHORTCUT_KEY_SPECIAL_RETURN ,
310 : CC . SHORTCUT_KEY_SPECIAL_PAUSE ,
27 : CC . SHORTCUT_KEY_SPECIAL_ESCAPE ,
322 : CC . SHORTCUT_KEY_SPECIAL_INSERT ,
127 : CC . SHORTCUT_KEY_SPECIAL_DELETE ,
315 : CC . SHORTCUT_KEY_SPECIAL_UP ,
317 : CC . SHORTCUT_KEY_SPECIAL_DOWN ,
314 : CC . SHORTCUT_KEY_SPECIAL_LEFT ,
316 : CC . SHORTCUT_KEY_SPECIAL_RIGHT ,
313 : CC . SHORTCUT_KEY_SPECIAL_HOME ,
312 : CC . SHORTCUT_KEY_SPECIAL_END ,
367 : CC . SHORTCUT_KEY_SPECIAL_PAGE_DOWN ,
366 : CC . SHORTCUT_KEY_SPECIAL_PAGE_UP ,
340 : CC . SHORTCUT_KEY_SPECIAL_F1 ,
341 : CC . SHORTCUT_KEY_SPECIAL_F2 ,
342 : CC . SHORTCUT_KEY_SPECIAL_F3 ,
343 : CC . SHORTCUT_KEY_SPECIAL_F4 ,
344 : CC . SHORTCUT_KEY_SPECIAL_F5 ,
345 : CC . SHORTCUT_KEY_SPECIAL_F6 ,
346 : CC . SHORTCUT_KEY_SPECIAL_F7 ,
347 : CC . SHORTCUT_KEY_SPECIAL_F8 ,
348 : CC . SHORTCUT_KEY_SPECIAL_F9 ,
349 : CC . SHORTCUT_KEY_SPECIAL_F10 ,
350 : CC . SHORTCUT_KEY_SPECIAL_F11 ,
351 : CC . SHORTCUT_KEY_SPECIAL_F12
}
# regular keys, but numpad, that are tracked in wx by combined unique enum
wx_to_qt_numpad_ascii_conversion = {
324 : ord ( ' 0 ' ) ,
325 : ord ( ' 1 ' ) ,
326 : ord ( ' 2 ' ) ,
327 : ord ( ' 3 ' ) ,
328 : ord ( ' 4 ' ) ,
329 : ord ( ' 5 ' ) ,
330 : ord ( ' 6 ' ) ,
331 : ord ( ' 7 ' ) ,
332 : ord ( ' 8 ' ) ,
332 : ord ( ' 9 ' ) ,
388 : ord ( ' + ' ) ,
392 : ord ( ' / ' ) ,
390 : ord ( ' - ' ) ,
387 : ord ( ' * ' ) ,
391 : ord ( ' . ' )
}
wx_to_qt_numpad_conversion = {
377 : CC . SHORTCUT_KEY_SPECIAL_UP ,
379 : CC . SHORTCUT_KEY_SPECIAL_DOWN ,
376 : CC . SHORTCUT_KEY_SPECIAL_LEFT ,
378 : CC . SHORTCUT_KEY_SPECIAL_RIGHT ,
375 : CC . SHORTCUT_KEY_SPECIAL_HOME ,
382 : CC . SHORTCUT_KEY_SPECIAL_END ,
381 : CC . SHORTCUT_KEY_SPECIAL_PAGE_DOWN ,
380 : CC . SHORTCUT_KEY_SPECIAL_PAGE_UP ,
385 : CC . SHORTCUT_KEY_SPECIAL_DELETE ,
370 : CC . SHORTCUT_KEY_SPECIAL_ENTER
}
( shortcut_type , shortcut_key , modifiers ) = old_serialisable_info
if shortcut_type == CC . SHORTCUT_TYPE_KEYBOARD_ASCII :
if shortcut_key in wx_to_qt_flat_conversion :
shortcut_type = CC . SHORTCUT_TYPE_KEYBOARD_SPECIAL
shortcut_key = wx_to_qt_flat_conversion [ shortcut_key ]
elif shortcut_key in wx_to_qt_numpad_ascii_conversion :
shortcut_key = wx_to_qt_numpad_ascii_conversion [ shortcut_key ]
modifiers = list ( modifiers )
modifiers . append ( CC . SHORTCUT_MODIFIER_KEYPAD )
modifiers . sort ( )
elif shortcut_key in wx_to_qt_numpad_conversion :
shortcut_type = CC . SHORTCUT_TYPE_KEYBOARD_SPECIAL
shortcut_key = wx_to_qt_numpad_conversion [ shortcut_key ]
modifiers = list ( modifiers )
modifiers . append ( CC . SHORTCUT_MODIFIER_KEYPAD )
modifiers . sort ( )
if shortcut_type == CC . SHORTCUT_TYPE_KEYBOARD_ASCII :
if ClientData . OrdIsAlphaUpper ( shortcut_key ) :
shortcut_key + = 32 # convert 'A' to 'a'
new_serialisable_info = ( shortcut_type , shortcut_key , modifiers )
return ( 2 , new_serialisable_info )
2018-05-16 20:09:50 +00:00
def GetShortcutType ( self ) :
return self . _shortcut_type
def ToString ( self ) :
components = [ ]
if CC . SHORTCUT_MODIFIER_CTRL in self . _modifiers :
components . append ( ' ctrl ' )
if CC . SHORTCUT_MODIFIER_ALT in self . _modifiers :
components . append ( ' alt ' )
if CC . SHORTCUT_MODIFIER_SHIFT in self . _modifiers :
components . append ( ' shift ' )
2019-11-14 03:56:30 +00:00
if CC . SHORTCUT_MODIFIER_GROUP_SWITCH in self . _modifiers :
2018-05-16 20:09:50 +00:00
2019-11-14 03:56:30 +00:00
components . append ( ' Mode_switch ' )
if self . _shortcut_type == CC . SHORTCUT_TYPE_MOUSE and self . _shortcut_key in CC . shortcut_mouse_string_lookup :
components . append ( CC . shortcut_mouse_string_lookup [ self . _shortcut_key ] )
elif self . _shortcut_type == CC . SHORTCUT_TYPE_KEYBOARD_SPECIAL and self . _shortcut_key in CC . special_key_shortcut_str_lookup :
components . append ( CC . special_key_shortcut_str_lookup [ self . _shortcut_key ] )
elif self . _shortcut_type == CC . SHORTCUT_TYPE_KEYBOARD_ASCII and ClientData . OrdIsSensibleASCII ( self . _shortcut_key ) :
if ClientData . OrdIsAlphaUpper ( self . _shortcut_key ) :
2018-05-16 20:09:50 +00:00
components . append ( chr ( self . _shortcut_key + 32 ) ) # + 32 for converting ascii A -> a
else :
2019-11-14 03:56:30 +00:00
components . append ( chr ( self . _shortcut_key ) )
2018-05-16 20:09:50 +00:00
2019-11-14 03:56:30 +00:00
else :
2018-05-16 20:09:50 +00:00
2019-11-14 03:56:30 +00:00
components . append ( ' unknown key ' )
2018-05-16 20:09:50 +00:00
2019-11-14 03:56:30 +00:00
s = ' + ' . join ( components )
if CC . SHORTCUT_MODIFIER_KEYPAD in self . _modifiers :
s + = ' (on numpad) '
return s
2018-05-16 20:09:50 +00:00
HydrusSerialisable . SERIALISABLE_TYPES_TO_OBJECT_TYPES [ HydrusSerialisable . SERIALISABLE_TYPE_SHORTCUT ] = Shortcut
2019-11-14 03:56:30 +00:00
class ShortcutPanel ( QW . QWidget ) :
2018-05-16 20:09:50 +00:00
def __init__ ( self , parent ) :
2019-11-14 03:56:30 +00:00
QW . QWidget . __init__ ( self , parent )
2018-05-16 20:09:50 +00:00
2019-11-14 03:56:30 +00:00
self . _mouse_radio = QW . QRadioButton ( ' mouse ' , self )
2018-05-16 20:09:50 +00:00
self . _mouse_shortcut = ShortcutMouse ( self , self . _mouse_radio )
2019-11-14 03:56:30 +00:00
self . _keyboard_radio = QW . QRadioButton ( ' keyboard ' , self )
2018-05-16 20:09:50 +00:00
self . _keyboard_shortcut = ShortcutKeyboard ( self , self . _keyboard_radio )
#
2019-11-14 03:56:30 +00:00
vbox = QP . VBoxLayout ( )
2018-05-16 20:09:50 +00:00
2019-11-14 03:56:30 +00:00
QP . AddToLayout ( vbox , ClientGUICommon . BetterStaticText ( self , ' Mouse events only work for the duplicate and archive/delete filters atm! ' ) , CC . FLAGS_EXPAND_PERPENDICULAR )
2018-05-16 20:09:50 +00:00
2019-11-14 03:56:30 +00:00
gridbox = QP . GridLayout ( cols = 2 )
2018-05-16 20:09:50 +00:00
2019-11-14 03:56:30 +00:00
gridbox . setColumnStretch ( 1 , 1 )
2018-05-16 20:09:50 +00:00
2019-11-14 03:56:30 +00:00
QP . AddToLayout ( gridbox , self . _mouse_radio , CC . FLAGS_VCENTER )
QP . AddToLayout ( gridbox , self . _mouse_shortcut , CC . FLAGS_EXPAND_BOTH_WAYS )
QP . AddToLayout ( gridbox , self . _keyboard_radio , CC . FLAGS_VCENTER )
QP . AddToLayout ( gridbox , self . _keyboard_shortcut , CC . FLAGS_EXPAND_BOTH_WAYS )
2018-05-16 20:09:50 +00:00
2019-11-14 03:56:30 +00:00
QP . AddToLayout ( vbox , gridbox , CC . FLAGS_EXPAND_BOTH_WAYS )
2018-05-16 20:09:50 +00:00
2019-11-14 03:56:30 +00:00
self . setLayout ( vbox )
2018-05-16 20:09:50 +00:00
def GetValue ( self ) :
2019-11-14 03:56:30 +00:00
if self . _mouse_radio . isChecked ( ) :
2018-05-16 20:09:50 +00:00
return self . _mouse_shortcut . GetValue ( )
else :
return self . _keyboard_shortcut . GetValue ( )
def SetValue ( self , shortcut ) :
if shortcut . GetShortcutType ( ) == CC . SHORTCUT_TYPE_MOUSE :
2019-11-14 03:56:30 +00:00
self . _mouse_radio . setChecked ( True )
2018-05-16 20:09:50 +00:00
self . _mouse_shortcut . SetValue ( shortcut )
else :
2019-11-14 03:56:30 +00:00
self . _keyboard_radio . setChecked ( True )
2018-05-16 20:09:50 +00:00
self . _keyboard_shortcut . SetValue ( shortcut )
2019-11-14 03:56:30 +00:00
class ShortcutKeyboard ( QW . QLineEdit ) :
2018-05-16 20:09:50 +00:00
def __init__ ( self , parent , related_radio = None ) :
2019-11-14 03:56:30 +00:00
self . _shortcut = Shortcut ( )
2018-05-16 20:09:50 +00:00
self . _related_radio = related_radio
2019-11-14 03:56:30 +00:00
QW . QLineEdit . __init__ ( self , parent )
2018-05-16 20:09:50 +00:00
self . _SetShortcutString ( )
def _SetShortcutString ( self ) :
display_string = self . _shortcut . ToString ( )
2019-11-14 03:56:30 +00:00
self . setText ( display_string )
2018-05-16 20:09:50 +00:00
2019-11-14 03:56:30 +00:00
def keyPressEvent ( self , event ) :
2018-05-16 20:09:50 +00:00
shortcut = ConvertKeyEventToShortcut ( event )
if shortcut is not None :
self . _shortcut = shortcut
if self . _related_radio is not None :
2019-11-14 03:56:30 +00:00
self . _related_radio . setChecked ( True )
2018-05-16 20:09:50 +00:00
self . _SetShortcutString ( )
def GetValue ( self ) :
return self . _shortcut
def SetValue ( self , shortcut ) :
self . _shortcut = shortcut
self . _SetShortcutString ( )
2019-11-14 03:56:30 +00:00
class ShortcutMouse ( QW . QPushButton ) :
2018-05-16 20:09:50 +00:00
def __init__ ( self , parent , related_radio = None ) :
self . _shortcut = Shortcut ( CC . SHORTCUT_TYPE_MOUSE , CC . SHORTCUT_MOUSE_LEFT , [ ] )
self . _related_radio = related_radio
2019-11-14 03:56:30 +00:00
QW . QPushButton . __init__ ( self , parent )
2018-05-16 20:09:50 +00:00
self . _SetShortcutString ( )
def _SetShortcutString ( self ) :
display_string = self . _shortcut . ToString ( )
2019-11-14 03:56:30 +00:00
self . setText ( display_string )
2018-05-16 20:09:50 +00:00
2019-11-14 03:56:30 +00:00
def mousePressEvent ( self , event ) :
self . EventMouse ( event )
def mouseDoubleClickEvent ( self , event ) :
self . EventMouse ( event )
2018-05-16 20:09:50 +00:00
def EventMouse ( self , event ) :
2019-11-14 03:56:30 +00:00
self . setFocus ( QC . Qt . OtherFocusReason )
2018-05-16 20:09:50 +00:00
shortcut = ConvertMouseEventToShortcut ( event )
if shortcut is not None :
self . _shortcut = shortcut
if self . _related_radio is not None :
2019-11-14 03:56:30 +00:00
self . _related_radio . setChecked ( True )
2018-05-16 20:09:50 +00:00
self . _SetShortcutString ( )
def GetValue ( self ) :
return self . _shortcut
def SetValue ( self , shortcut ) :
self . _shortcut = shortcut
self . _SetShortcutString ( )
2019-06-05 19:42:39 +00:00
class ShortcutSet ( HydrusSerialisable . SerialisableBaseNamed ) :
2018-05-16 20:09:50 +00:00
2019-06-05 19:42:39 +00:00
SERIALISABLE_TYPE = HydrusSerialisable . SERIALISABLE_TYPE_SHORTCUT_SET
SERIALISABLE_NAME = ' Shortcut Set '
2018-05-16 20:09:50 +00:00
SERIALISABLE_VERSION = 2
def __init__ ( self , name ) :
HydrusSerialisable . SerialisableBaseNamed . __init__ ( self , name )
self . _shortcuts_to_commands = { }
def __iter__ ( self ) :
2019-05-22 22:35:06 +00:00
for ( shortcut , command ) in list ( self . _shortcuts_to_commands . items ( ) ) :
2018-05-16 20:09:50 +00:00
yield ( shortcut , command )
def __len__ ( self ) :
return len ( self . _shortcuts_to_commands )
def _GetSerialisableInfo ( self ) :
2019-01-09 22:59:03 +00:00
return [ ( shortcut . GetSerialisableTuple ( ) , command . GetSerialisableTuple ( ) ) for ( shortcut , command ) in list ( self . _shortcuts_to_commands . items ( ) ) ]
2018-05-16 20:09:50 +00:00
def _InitialiseFromSerialisableInfo ( self , serialisable_info ) :
for ( serialisable_shortcut , serialisable_command ) in serialisable_info :
shortcut = HydrusSerialisable . CreateFromSerialisableTuple ( serialisable_shortcut )
command = HydrusSerialisable . CreateFromSerialisableTuple ( serialisable_command )
self . _shortcuts_to_commands [ shortcut ] = command
def _UpdateSerialisableInfo ( self , version , old_serialisable_info ) :
if version == 1 :
( serialisable_mouse_actions , serialisable_keyboard_actions ) = old_serialisable_info
shortcuts_to_commands = { }
# this never stored mouse actions, so skip
services_manager = HG . client_controller . services_manager
for ( modifier , key , ( serialisable_service_key , data ) ) in serialisable_keyboard_actions :
2019-11-14 03:56:30 +00:00
# no longer updating modifier, as that was wx legacy
2018-05-16 20:09:50 +00:00
2019-11-14 03:56:30 +00:00
modifiers = [ ]
shortcut = Shortcut ( CC . SHORTCUT_TYPE_KEYBOARD_ASCII , key , modifiers )
2018-05-16 20:09:50 +00:00
if serialisable_service_key is None :
command = ClientData . ApplicationCommand ( CC . APPLICATION_COMMAND_TYPE_SIMPLE , data )
else :
2019-01-09 22:59:03 +00:00
service_key = bytes . fromhex ( serialisable_service_key )
2018-05-16 20:09:50 +00:00
if not services_manager . ServiceExists ( service_key ) :
continue
action = HC . CONTENT_UPDATE_FLIP
value = data
service = services_manager . GetService ( service_key )
service_type = service . GetServiceType ( )
if service_type in HC . TAG_SERVICES :
content_type = HC . CONTENT_TYPE_MAPPINGS
elif service_type in HC . RATINGS_SERVICES :
content_type = HC . CONTENT_TYPE_RATINGS
else :
continue
command = ClientData . ApplicationCommand ( CC . APPLICATION_COMMAND_TYPE_CONTENT , ( service_key , content_type , action , value ) )
shortcuts_to_commands [ shortcut ] = command
2019-01-09 22:59:03 +00:00
new_serialisable_info = ( ( shortcut . GetSerialisableTuple ( ) , command . GetSerialisableTuple ( ) ) for ( shortcut , command ) in list ( shortcuts_to_commands . items ( ) ) )
2018-05-16 20:09:50 +00:00
return ( 2 , new_serialisable_info )
def GetCommand ( self , shortcut ) :
if shortcut in self . _shortcuts_to_commands :
return self . _shortcuts_to_commands [ shortcut ]
else :
return None
2019-06-05 19:42:39 +00:00
def GetShortcuts ( self , simple_command ) :
shortcuts = [ ]
for ( shortcut , command ) in self . _shortcuts_to_commands . items ( ) :
if command . GetCommandType ( ) == CC . APPLICATION_COMMAND_TYPE_SIMPLE and command . GetData ( ) == simple_command :
shortcuts . append ( shortcut )
return shortcuts
2018-05-16 20:09:50 +00:00
def SetCommand ( self , shortcut , command ) :
self . _shortcuts_to_commands [ shortcut ] = command
2019-06-05 19:42:39 +00:00
HydrusSerialisable . SERIALISABLE_TYPES_TO_OBJECT_TYPES [ HydrusSerialisable . SERIALISABLE_TYPE_SHORTCUT_SET ] = ShortcutSet
2018-05-16 20:09:50 +00:00
2019-11-14 03:56:30 +00:00
class ShortcutsHandler ( QC . QObject ) :
2017-03-29 19:39:34 +00:00
2018-03-14 21:01:02 +00:00
def __init__ ( self , parent , initial_shortcuts_names = None ) :
2017-03-29 19:39:34 +00:00
2019-11-14 03:56:30 +00:00
QC . QObject . __init__ ( self , parent )
2018-03-14 21:01:02 +00:00
if initial_shortcuts_names is None :
2017-03-29 19:39:34 +00:00
2018-03-14 21:01:02 +00:00
initial_shortcuts_names = [ ]
2017-03-29 19:39:34 +00:00
self . _parent = parent
2019-11-14 03:56:30 +00:00
self . _parent . installEventFilter ( self )
2018-03-14 21:01:02 +00:00
self . _shortcuts_names = list ( initial_shortcuts_names )
2017-03-29 19:39:34 +00:00
2018-03-14 21:01:02 +00:00
def _ProcessShortcut ( self , shortcut ) :
shortcut_processed = False
command = HG . client_controller . GetCommandFromShortcut ( self . _shortcuts_names , shortcut )
if command is not None :
command_processed = self . _parent . ProcessApplicationCommand ( command )
2017-03-29 19:39:34 +00:00
2018-03-14 21:01:02 +00:00
if command_processed :
shortcut_processed = True
2017-03-29 19:39:34 +00:00
2018-03-22 00:03:33 +00:00
if HG . shortcut_report_mode :
message = ' Shortcut " ' + shortcut . ToString ( ) + ' " matched to command " ' + command . ToString ( ) + ' " on ' + repr ( self . _parent ) + ' . '
if command_processed :
message + = ' It was processed. '
else :
message + = ' It was not processed. '
HydrusData . ShowText ( message )
2017-03-29 19:39:34 +00:00
2018-03-14 21:01:02 +00:00
return shortcut_processed
2017-03-29 19:39:34 +00:00
2019-11-14 03:56:30 +00:00
def eventFilter ( self , watched , event ) :
2018-03-22 00:03:33 +00:00
2019-11-14 03:56:30 +00:00
if event . type ( ) == QC . QEvent . KeyPress :
2018-03-14 21:01:02 +00:00
2019-11-14 03:56:30 +00:00
shortcut = ConvertKeyEventToShortcut ( event )
if shortcut is not None :
2018-03-22 00:03:33 +00:00
2019-11-14 03:56:30 +00:00
if HG . shortcut_report_mode :
2018-03-22 00:03:33 +00:00
2019-11-14 03:56:30 +00:00
message = ' Key shortcut " ' + shortcut . ToString ( ) + ' " passing through ' + repr ( self . _parent ) + ' . '
2018-03-22 00:03:33 +00:00
2019-11-14 03:56:30 +00:00
if IShouldCatchShortcutEvent ( self . _parent , event = event ) :
message + = ' I am in a state to catch it. '
else :
message + = ' I am not in a state to catch it. '
2018-03-22 00:03:33 +00:00
2019-11-14 03:56:30 +00:00
HydrusData . ShowText ( message )
2018-03-22 00:03:33 +00:00
2019-11-14 03:56:30 +00:00
if IShouldCatchShortcutEvent ( self . _parent , event = event ) :
2018-03-14 21:01:02 +00:00
2019-11-14 03:56:30 +00:00
shortcut_processed = self . _ProcessShortcut ( shortcut )
if shortcut_processed :
return True
2018-03-14 21:01:02 +00:00
2019-11-14 03:56:30 +00:00
return False
2017-03-29 19:39:34 +00:00
2019-09-11 21:51:09 +00:00
def AddShortcuts ( self , shortcut_set_name ) :
2017-03-29 19:39:34 +00:00
2019-09-11 21:51:09 +00:00
if shortcut_set_name not in self . _shortcuts_names :
2018-03-14 21:01:02 +00:00
2019-09-11 21:51:09 +00:00
self . _shortcuts_names . append ( shortcut_set_name )
2018-03-14 21:01:02 +00:00
2017-03-29 19:39:34 +00:00
2019-09-11 21:51:09 +00:00
def RemoveShortcuts ( self , shortcut_set_name ) :
2017-03-29 19:39:34 +00:00
2019-09-11 21:51:09 +00:00
if shortcut_set_name in self . _shortcuts_names :
2017-03-29 19:39:34 +00:00
2019-09-11 21:51:09 +00:00
self . _shortcuts_names . remove ( shortcut_set_name )
2017-03-29 19:39:34 +00:00
2018-05-16 20:09:50 +00:00
2019-06-05 19:42:39 +00:00
class ShortcutsManager ( object ) :
def __init__ ( self , controller ) :
self . _controller = controller
self . _shortcuts = { }
self . _RefreshShortcuts ( )
self . _controller . sub ( self , ' RefreshShortcuts ' , ' notify_new_shortcuts_data ' )
def _RefreshShortcuts ( self ) :
self . _shortcuts = { }
all_shortcuts = HG . client_controller . Read ( ' serialisable_named ' , HydrusSerialisable . SERIALISABLE_TYPE_SHORTCUT_SET )
for shortcuts in all_shortcuts :
self . _shortcuts [ shortcuts . GetName ( ) ] = shortcuts
def GetCommand ( self , shortcuts_names , shortcut ) :
for name in shortcuts_names :
if name in self . _shortcuts :
command = self . _shortcuts [ name ] . GetCommand ( shortcut )
if command is not None :
if HG . gui_report_mode :
HydrusData . ShowText ( ' command matched: ' + repr ( command ) )
return command
return None
def GetNamesToShortcuts ( self , simple_command ) :
names_to_shortcuts = { }
for ( name , shortcut_set ) in self . _shortcuts . items ( ) :
shortcuts = shortcut_set . GetShortcuts ( simple_command )
if len ( shortcuts ) > 0 :
names_to_shortcuts [ name ] = shortcuts
return names_to_shortcuts
def RefreshShortcuts ( self ) :
self . _RefreshShortcuts ( )
HG . client_controller . pub ( ' notify_new_shortcuts_gui ' )