1162 lines
41 KiB
Python
1162 lines
41 KiB
Python
import typing
|
|
|
|
from qtpy import QtWidgets as QW
|
|
|
|
from hydrus.core import HydrusConstants as HC
|
|
from hydrus.core import HydrusExceptions
|
|
from hydrus.core import HydrusGlobals as HG
|
|
from hydrus.core import HydrusSerialisable
|
|
|
|
from hydrus.client import ClientApplicationCommand as CAC
|
|
from hydrus.client import ClientConstants as CC
|
|
from hydrus.client import ClientGlobals as CG
|
|
from hydrus.client.gui import ClientGUIDialogsMessage
|
|
from hydrus.client.gui import ClientGUIScrolledPanels
|
|
from hydrus.client.gui import ClientGUIShortcuts
|
|
from hydrus.client.gui import QtPorting as QP
|
|
from hydrus.client.gui.search import ClientGUIACDropdown
|
|
from hydrus.client.gui.widgets import ClientGUICommon
|
|
from hydrus.client.media import ClientMediaFileFilter
|
|
|
|
class LocalFilesSubPanel( QW.QWidget ):
|
|
|
|
def __init__( self, parent: QW.QWidget ):
|
|
|
|
QW.QWidget.__init__( self, parent )
|
|
|
|
self._add_or_move_action = ClientGUICommon.BetterChoice( self )
|
|
|
|
self._add_or_move_action.addItem( 'add to', HC.CONTENT_UPDATE_ADD )
|
|
self._add_or_move_action.addItem( 'move to', HC.CONTENT_UPDATE_MOVE )
|
|
|
|
self._add_or_move_action.SetValue( HC.CONTENT_UPDATE_ADD )
|
|
|
|
self._service_keys = ClientGUICommon.BetterChoice( self )
|
|
|
|
#
|
|
|
|
services = CG.client_controller.services_manager.GetServices( ( HC.LOCAL_FILE_DOMAIN, ) )
|
|
|
|
for service in services:
|
|
|
|
service_name = service.GetName()
|
|
service_key = service.GetServiceKey()
|
|
|
|
self._service_keys.addItem( service_name, service_key )
|
|
|
|
|
|
#
|
|
|
|
vbox = QP.VBoxLayout()
|
|
|
|
ratings_numerical_hbox = QP.HBoxLayout()
|
|
|
|
QP.AddToLayout( vbox, self._add_or_move_action, CC.FLAGS_EXPAND_PERPENDICULAR )
|
|
QP.AddToLayout( vbox, self._service_keys, CC.FLAGS_EXPAND_PERPENDICULAR )
|
|
|
|
self.setLayout( vbox )
|
|
|
|
|
|
def GetValue( self ):
|
|
|
|
service_key = self._service_keys.GetValue()
|
|
|
|
if service_key is None:
|
|
|
|
raise HydrusExceptions.VetoException( 'Please select a service!' )
|
|
|
|
|
|
action = self._add_or_move_action.GetValue()
|
|
|
|
value = None
|
|
|
|
return CAC.ApplicationCommand( CAC.APPLICATION_COMMAND_TYPE_CONTENT, ( service_key, HC.CONTENT_TYPE_FILES, action, value ) )
|
|
|
|
|
|
def SetValue( self, action: int, service_key: bytes ):
|
|
|
|
self._add_or_move_action.SetValue( action )
|
|
|
|
self._service_keys.SetValue( service_key )
|
|
|
|
|
|
class RatingLikeSubPanel( QW.QWidget ):
|
|
|
|
def __init__( self, parent: QW.QWidget ):
|
|
|
|
QW.QWidget.__init__( self, parent )
|
|
|
|
self._flip_or_set_action = ClientGUICommon.BetterChoice( self )
|
|
|
|
self._flip_or_set_action.addItem( 'set', HC.CONTENT_UPDATE_SET )
|
|
self._flip_or_set_action.addItem( 'flip on and off', HC.CONTENT_UPDATE_FLIP )
|
|
|
|
self._flip_or_set_action.SetValue( HC.CONTENT_UPDATE_SET )
|
|
|
|
self._service_keys = ClientGUICommon.BetterChoice( self )
|
|
self._ratings_like_like = QW.QRadioButton( 'like', self )
|
|
self._ratings_like_dislike = QW.QRadioButton( 'dislike', self )
|
|
self._ratings_like_remove = QW.QRadioButton( 'remove rating', self )
|
|
|
|
#
|
|
|
|
services = CG.client_controller.services_manager.GetServices( ( HC.LOCAL_RATING_LIKE, ) )
|
|
|
|
if len( services ) == 0:
|
|
|
|
self._service_keys.addItem( 'you have no like/dislike rating services', None )
|
|
|
|
else:
|
|
|
|
for service in services:
|
|
|
|
service_name = service.GetName()
|
|
service_key = service.GetServiceKey()
|
|
|
|
self._service_keys.addItem( service_name, service_key )
|
|
|
|
|
|
|
|
self._ratings_like_like.setChecked( True )
|
|
|
|
#
|
|
|
|
vbox = QP.VBoxLayout()
|
|
|
|
ratings_like_hbox = QP.HBoxLayout()
|
|
|
|
QP.AddToLayout( ratings_like_hbox, self._service_keys, CC.FLAGS_EXPAND_BOTH_WAYS )
|
|
QP.AddToLayout( ratings_like_hbox, self._ratings_like_like, CC.FLAGS_CENTER_PERPENDICULAR )
|
|
QP.AddToLayout( ratings_like_hbox, self._ratings_like_dislike, CC.FLAGS_CENTER_PERPENDICULAR )
|
|
QP.AddToLayout( ratings_like_hbox, self._ratings_like_remove, CC.FLAGS_CENTER_PERPENDICULAR )
|
|
|
|
QP.AddToLayout( vbox, self._flip_or_set_action, CC.FLAGS_EXPAND_PERPENDICULAR )
|
|
QP.AddToLayout( vbox, ratings_like_hbox, CC.FLAGS_EXPAND_PERPENDICULAR )
|
|
|
|
self.setLayout( vbox )
|
|
|
|
self._ratings_like_remove.toggled.connect( self._UpdateFlipAllowed )
|
|
|
|
|
|
def _UpdateFlipAllowed( self ):
|
|
|
|
if self._ratings_like_remove.isChecked():
|
|
|
|
self._flip_or_set_action.SetValue( HC.CONTENT_UPDATE_SET )
|
|
self._flip_or_set_action.setEnabled( False )
|
|
|
|
else:
|
|
|
|
self._flip_or_set_action.setEnabled( True )
|
|
|
|
|
|
|
|
def GetValue( self ):
|
|
|
|
service_key = self._service_keys.GetValue()
|
|
|
|
if service_key is None:
|
|
|
|
raise HydrusExceptions.VetoException( 'Please select a rating service!' )
|
|
|
|
|
|
action = self._flip_or_set_action.GetValue()
|
|
|
|
if self._ratings_like_like.isChecked():
|
|
|
|
value = 1.0
|
|
|
|
elif self._ratings_like_dislike.isChecked():
|
|
|
|
value = 0.0
|
|
|
|
else:
|
|
|
|
value = None
|
|
|
|
|
|
return CAC.ApplicationCommand( CAC.APPLICATION_COMMAND_TYPE_CONTENT, ( service_key, HC.CONTENT_TYPE_RATINGS, action, value ) )
|
|
|
|
|
|
def SetValue( self, action: int, service_key: bytes, rating: typing.Optional[ float ] ):
|
|
|
|
self._flip_or_set_action.SetValue( action )
|
|
|
|
self._service_keys.SetValue( service_key )
|
|
|
|
self._ratings_like_remove.setChecked( rating is None )
|
|
self._ratings_like_like.setChecked( rating == 1.0 )
|
|
self._ratings_like_dislike.setChecked( rating == 0.0 )
|
|
|
|
|
|
class RatingNumericalSubPanel( QW.QWidget ):
|
|
|
|
def __init__( self, parent: QW.QWidget ):
|
|
|
|
QW.QWidget.__init__( self, parent )
|
|
|
|
self._current_ratings_numerical_service = None
|
|
|
|
self._flip_or_set_action = ClientGUICommon.BetterChoice( self )
|
|
|
|
self._flip_or_set_action.addItem( 'set', HC.CONTENT_UPDATE_SET )
|
|
self._flip_or_set_action.addItem( 'flip on and off', HC.CONTENT_UPDATE_FLIP )
|
|
|
|
self._flip_or_set_action.SetValue( HC.CONTENT_UPDATE_SET )
|
|
|
|
self._service_keys = ClientGUICommon.BetterChoice( self )
|
|
self._service_keys.currentIndexChanged.connect( self._UpdateSliderRange )
|
|
self._ratings_numerical_slider = QP.LabelledSlider( self )
|
|
self._ratings_numerical_remove = QW.QCheckBox( 'remove rating', self )
|
|
|
|
#
|
|
|
|
services = CG.client_controller.services_manager.GetServices( ( HC.LOCAL_RATING_NUMERICAL, ) )
|
|
|
|
if len( services ) == 0:
|
|
|
|
self._service_keys.addItem( 'you have no numerical rating services', None )
|
|
|
|
else:
|
|
|
|
for service in services:
|
|
|
|
service_name = service.GetName()
|
|
service_key = service.GetServiceKey()
|
|
|
|
self._service_keys.addItem( service_name, service_key )
|
|
|
|
|
|
|
|
self._UpdateSliderRange()
|
|
|
|
#
|
|
|
|
vbox = QP.VBoxLayout()
|
|
|
|
ratings_numerical_hbox = QP.HBoxLayout()
|
|
|
|
QP.AddToLayout( ratings_numerical_hbox, self._service_keys, CC.FLAGS_CENTER_PERPENDICULAR_EXPAND_DEPTH )
|
|
QP.AddToLayout( ratings_numerical_hbox, self._ratings_numerical_slider, CC.FLAGS_CENTER_PERPENDICULAR )
|
|
QP.AddToLayout( ratings_numerical_hbox, self._ratings_numerical_remove, CC.FLAGS_CENTER_PERPENDICULAR )
|
|
|
|
QP.AddToLayout( vbox, self._flip_or_set_action, CC.FLAGS_EXPAND_PERPENDICULAR )
|
|
QP.AddToLayout( vbox, ratings_numerical_hbox, CC.FLAGS_EXPAND_PERPENDICULAR )
|
|
|
|
self.setLayout( vbox )
|
|
|
|
self._ratings_numerical_remove.toggled.connect( self._UpdateFlipAllowed )
|
|
|
|
|
|
def _UpdateFlipAllowed( self ):
|
|
|
|
remove_on = self._ratings_numerical_remove.isChecked()
|
|
|
|
if remove_on:
|
|
|
|
self._flip_or_set_action.SetValue( HC.CONTENT_UPDATE_SET )
|
|
|
|
|
|
self._flip_or_set_action.setEnabled( not remove_on )
|
|
self._ratings_numerical_slider.setEnabled( not remove_on )
|
|
|
|
|
|
def _UpdateSliderRange( self ):
|
|
|
|
service_key = self._service_keys.GetValue()
|
|
|
|
if service_key is not None:
|
|
|
|
service = CG.client_controller.services_manager.GetService( service_key )
|
|
|
|
self._current_ratings_numerical_service = service
|
|
|
|
num_stars = service.GetNumStars()
|
|
|
|
allow_zero = service.AllowZero()
|
|
|
|
if allow_zero:
|
|
|
|
minimum = 0
|
|
|
|
else:
|
|
|
|
minimum = 1
|
|
|
|
|
|
self._ratings_numerical_slider.SetRange( minimum, num_stars )
|
|
|
|
|
|
|
|
def GetValue( self ):
|
|
|
|
service_key = self._service_keys.GetValue()
|
|
|
|
if service_key is None:
|
|
|
|
raise HydrusExceptions.VetoException( 'Please select a rating service!' )
|
|
|
|
|
|
action = self._flip_or_set_action.GetValue()
|
|
|
|
if self._ratings_numerical_remove.isChecked():
|
|
|
|
rating = None
|
|
|
|
else:
|
|
|
|
value = self._ratings_numerical_slider.GetValue()
|
|
|
|
rating = self._current_ratings_numerical_service.ConvertStarsToRating( value )
|
|
|
|
|
|
return CAC.ApplicationCommand( CAC.APPLICATION_COMMAND_TYPE_CONTENT, ( service_key, HC.CONTENT_TYPE_RATINGS, action, rating ) )
|
|
|
|
|
|
def SetValue( self, action: int, service_key: bytes, rating: typing.Optional[ float ] ):
|
|
|
|
self._flip_or_set_action.SetValue( action )
|
|
|
|
self._service_keys.SetValue( service_key )
|
|
|
|
self._UpdateSliderRange()
|
|
|
|
if rating is None:
|
|
|
|
self._ratings_numerical_remove.setChecked( True )
|
|
|
|
else:
|
|
|
|
slider_value = self._current_ratings_numerical_service.ConvertRatingToStars( rating )
|
|
|
|
self._ratings_numerical_slider.SetValue( slider_value )
|
|
|
|
|
|
|
|
|
|
class RatingIncDecSubPanel( QW.QWidget ):
|
|
|
|
def __init__( self, parent: QW.QWidget ):
|
|
|
|
QW.QWidget.__init__( self, parent )
|
|
|
|
self._service_keys = ClientGUICommon.BetterChoice( self )
|
|
|
|
self._ratings_incdec = ClientGUICommon.BetterChoice( self )
|
|
|
|
self._ratings_incdec.addItem( HC.content_update_string_lookup[ HC.CONTENT_UPDATE_INCREMENT ], HC.CONTENT_UPDATE_INCREMENT )
|
|
self._ratings_incdec.addItem( HC.content_update_string_lookup[ HC.CONTENT_UPDATE_DECREMENT ], HC.CONTENT_UPDATE_DECREMENT )
|
|
|
|
#
|
|
|
|
services = CG.client_controller.services_manager.GetServices( ( HC.LOCAL_RATING_NUMERICAL, HC.LOCAL_RATING_INCDEC ) )
|
|
|
|
if len( services ) == 0:
|
|
|
|
self._service_keys.addItem( 'you have no numerical or inc/dec rating services', None )
|
|
|
|
else:
|
|
|
|
for service in services:
|
|
|
|
service_name = service.GetName()
|
|
service_key = service.GetServiceKey()
|
|
|
|
self._service_keys.addItem( service_name, service_key )
|
|
|
|
|
|
|
|
#
|
|
|
|
hbox = QP.HBoxLayout()
|
|
|
|
QP.AddToLayout( hbox, self._service_keys, CC.FLAGS_CENTER_PERPENDICULAR_EXPAND_DEPTH )
|
|
QP.AddToLayout( hbox, self._ratings_incdec, CC.FLAGS_CENTER_PERPENDICULAR )
|
|
|
|
self.setLayout( hbox )
|
|
|
|
|
|
def GetValue( self ):
|
|
|
|
service_key = self._service_keys.GetValue()
|
|
|
|
if service_key is None:
|
|
|
|
raise HydrusExceptions.VetoException( 'Please select a rating service!' )
|
|
|
|
|
|
action = self._ratings_incdec.GetValue()
|
|
|
|
distance = 1
|
|
|
|
return CAC.ApplicationCommand( CAC.APPLICATION_COMMAND_TYPE_CONTENT, ( service_key, HC.CONTENT_TYPE_RATINGS, action, distance ) )
|
|
|
|
|
|
def SetValue( self, action: int, service_key: bytes, distance: int ):
|
|
|
|
self._service_keys.SetValue( service_key )
|
|
|
|
self._ratings_incdec.SetValue( action )
|
|
|
|
|
|
|
|
class SimpleSubPanel( QW.QWidget ):
|
|
|
|
def __init__( self, parent: QW.QWidget, shortcuts_name: str ):
|
|
|
|
QW.QWidget.__init__( self, parent )
|
|
|
|
if shortcuts_name in ClientGUIShortcuts.SHORTCUTS_RESERVED_NAMES:
|
|
|
|
simple_types = ClientGUIShortcuts.simple_shortcut_name_to_action_lookup[ shortcuts_name ]
|
|
|
|
else:
|
|
|
|
simple_types = ClientGUIShortcuts.simple_shortcut_name_to_action_lookup[ 'custom' ]
|
|
|
|
|
|
choices = sorted( [ ( CAC.simple_enum_to_str_lookup[ simple_type ], simple_type ) for simple_type in simple_types ] )
|
|
|
|
self._simple_actions = ClientGUICommon.BetterChoice( self )
|
|
|
|
for ( display_string, data ) in choices:
|
|
|
|
self._simple_actions.addItem( display_string, data )
|
|
|
|
|
|
#
|
|
|
|
self._duplicates_type_panel = QW.QWidget( self )
|
|
|
|
choices = [ ( HC.duplicate_type_string_lookup[ t ], t ) for t in ( HC.DUPLICATE_MEMBER, HC.DUPLICATE_ALTERNATE, HC.DUPLICATE_FALSE_POSITIVE, HC.DUPLICATE_POTENTIAL ) ]
|
|
|
|
self._duplicate_type = ClientGUICommon.BetterRadioBox( self._duplicates_type_panel, choices = choices )
|
|
|
|
vbox = QP.VBoxLayout()
|
|
|
|
QP.AddToLayout( vbox, self._duplicate_type, CC.FLAGS_EXPAND_BOTH_WAYS )
|
|
|
|
self._duplicates_type_panel.setLayout( vbox )
|
|
|
|
#
|
|
|
|
self._thumbnail_rearrange_panel = QW.QWidget( self )
|
|
|
|
self._thumbnail_rearrange_type = ClientGUICommon.BetterChoice( self )
|
|
|
|
for rearrange_type in [
|
|
CAC.MOVE_HOME,
|
|
CAC.MOVE_END,
|
|
CAC.MOVE_LEFT,
|
|
CAC.MOVE_RIGHT,
|
|
CAC.MOVE_TO_FOCUS
|
|
]:
|
|
|
|
self._thumbnail_rearrange_type.addItem( CAC.move_enum_to_str_lookup[ rearrange_type ], rearrange_type )
|
|
|
|
|
|
vbox = QP.VBoxLayout()
|
|
|
|
QP.AddToLayout( vbox, self._thumbnail_rearrange_type, CC.FLAGS_EXPAND_BOTH_WAYS )
|
|
|
|
self._thumbnail_rearrange_panel.setLayout( vbox )
|
|
|
|
#
|
|
|
|
self._seek_panel = QW.QWidget( self )
|
|
|
|
choices = [
|
|
( 'back', -1 ),
|
|
( 'forwards', 1 )
|
|
]
|
|
|
|
self._seek_direction = ClientGUICommon.BetterRadioBox( self._seek_panel, choices = choices )
|
|
|
|
self._seek_duration_s = ClientGUICommon.BetterSpinBox( self._seek_panel, max=3599, width = 60 )
|
|
self._seek_duration_ms = ClientGUICommon.BetterSpinBox( self._seek_panel, max=999, width = 60 )
|
|
|
|
self._seek_duration_s.setValue( 5 )
|
|
self._seek_duration_ms.setValue( 0 )
|
|
|
|
self._seek_duration_s.value() * 1000 + self._seek_duration_ms.value()
|
|
|
|
hbox = QP.HBoxLayout()
|
|
|
|
QP.AddToLayout( hbox, self._seek_direction, CC.FLAGS_EXPAND_BOTH_WAYS )
|
|
QP.AddToLayout( hbox, self._seek_duration_s, CC.FLAGS_CENTER )
|
|
QP.AddToLayout( hbox, ClientGUICommon.BetterStaticText( self._seek_panel, label = 's' ), CC.FLAGS_CENTER )
|
|
QP.AddToLayout( hbox, self._seek_duration_ms, CC.FLAGS_CENTER )
|
|
QP.AddToLayout( hbox, ClientGUICommon.BetterStaticText( self._seek_panel, label = 'ms' ), CC.FLAGS_CENTER )
|
|
|
|
self._seek_panel.setLayout( hbox )
|
|
|
|
#
|
|
|
|
self._thumbnail_move_panel = QW.QWidget( self )
|
|
|
|
choices = [ ( CAC.selection_status_enum_to_str_lookup[ s ], s ) for s in [ CAC.SELECTION_STATUS_NORMAL, CAC.SELECTION_STATUS_SHIFT ] ]
|
|
|
|
self._selection_status = ClientGUICommon.BetterRadioBox( self._thumbnail_move_panel, choices = choices )
|
|
|
|
self._selection_status.SetValue( CAC.SELECTION_STATUS_NORMAL )
|
|
|
|
self._move_direction = ClientGUICommon.BetterChoice( self._thumbnail_move_panel )
|
|
|
|
for m in [ CAC.MOVE_LEFT, CAC.MOVE_RIGHT, CAC.MOVE_UP, CAC.MOVE_DOWN, CAC.MOVE_HOME, CAC.MOVE_END, CAC.MOVE_PAGE_UP, CAC.MOVE_PAGE_DOWN ]:
|
|
|
|
self._move_direction.addItem( CAC.move_enum_to_str_lookup[ m ], m )
|
|
|
|
|
|
hbox = QP.HBoxLayout()
|
|
|
|
QP.AddToLayout( hbox, self._selection_status, CC.FLAGS_CENTER )
|
|
QP.AddToLayout( hbox, self._move_direction, CC.FLAGS_CENTER )
|
|
|
|
self._thumbnail_move_panel.setLayout( hbox )
|
|
|
|
#
|
|
|
|
self._file_filter_panel = QW.QWidget( self )
|
|
|
|
self._file_filter = ClientGUICommon.BetterChoice( self._file_filter_panel )
|
|
|
|
for file_filter in [
|
|
ClientMediaFileFilter.FileFilter( ClientMediaFileFilter.FILE_FILTER_ALL ),
|
|
ClientMediaFileFilter.FileFilter( ClientMediaFileFilter.FILE_FILTER_NONE ),
|
|
ClientMediaFileFilter.FileFilter( ClientMediaFileFilter.FILE_FILTER_INBOX ),
|
|
ClientMediaFileFilter.FileFilter( ClientMediaFileFilter.FILE_FILTER_ARCHIVE ),
|
|
ClientMediaFileFilter.FileFilter( ClientMediaFileFilter.FILE_FILTER_LOCAL ),
|
|
ClientMediaFileFilter.FileFilter( ClientMediaFileFilter.FILE_FILTER_FILE_SERVICE, filter_data = CC.TRASH_SERVICE_KEY )
|
|
]:
|
|
|
|
self._file_filter.addItem( file_filter.ToString(), file_filter )
|
|
|
|
|
|
hbox = QP.HBoxLayout()
|
|
|
|
QP.AddToLayout( hbox, self._file_filter, CC.FLAGS_CENTER )
|
|
|
|
self._file_filter_panel.setLayout( hbox )
|
|
|
|
#
|
|
|
|
self._hamming_distance_panel = QW.QWidget( self )
|
|
|
|
self._hamming_distance = ClientGUICommon.BetterSpinBox( self._hamming_distance_panel, min = 0, max = 64 )
|
|
|
|
rows = []
|
|
|
|
rows.append( ( 'Search distance:', self._hamming_distance ) )
|
|
|
|
gridbox = ClientGUICommon.WrapInGrid( self._hamming_distance_panel, rows )
|
|
|
|
self._hamming_distance_panel.setLayout( gridbox )
|
|
|
|
#
|
|
|
|
self._file_command_target_panel = QW.QWidget( self )
|
|
|
|
choices = [ ( CAC.file_command_target_enum_to_str_lookup[ file_command_target ], file_command_target ) for file_command_target in ( CAC.FILE_COMMAND_TARGET_SELECTED_FILES, CAC.FILE_COMMAND_TARGET_FOCUSED_FILE ) ]
|
|
|
|
self._file_command_target = ClientGUICommon.BetterRadioBox( self._file_command_target_panel, choices = choices )
|
|
|
|
self._file_command_target.SetValue( CAC.FILE_COMMAND_TARGET_SELECTED_FILES )
|
|
|
|
self._file_command_target.setToolTip( 'This is only important in the thumbnail view, where the "focused file" means the one currently in the preview view, usually the one you last clicked on. In the media viewer, actions are always applied to the current file.' )
|
|
|
|
rows = []
|
|
|
|
rows.append( ( 'Files to apply to:', self._file_command_target ) )
|
|
|
|
gridbox = ClientGUICommon.WrapInGrid( self._file_command_target_panel, rows )
|
|
|
|
self._file_command_target_panel.setLayout( gridbox )
|
|
|
|
#
|
|
|
|
self._bitmap_type_panel = QW.QWidget( self )
|
|
|
|
self._bitmap_type = ClientGUICommon.BetterChoice( self._bitmap_type_panel )
|
|
|
|
for bitmap_type in (
|
|
CAC.BITMAP_TYPE_FULL,
|
|
CAC.BITMAP_TYPE_SOURCE_LOOKUPS,
|
|
CAC.BITMAP_TYPE_THUMBNAIL,
|
|
CAC.BITMAP_TYPE_FULL_OR_FILE
|
|
):
|
|
|
|
self._bitmap_type.addItem( CAC.bitmap_type_enum_to_str_lookup[ bitmap_type ], bitmap_type )
|
|
|
|
|
|
self._bitmap_type.SetValue( CAC.BITMAP_TYPE_FULL )
|
|
|
|
rows = []
|
|
|
|
rows.append( ( 'Bitmap to copy:', self._bitmap_type ) )
|
|
|
|
gridbox = ClientGUICommon.WrapInGrid( self._bitmap_type_panel, rows )
|
|
|
|
self._bitmap_type_panel.setLayout( gridbox )
|
|
|
|
#
|
|
|
|
self._hash_type_panel = QW.QWidget( self )
|
|
|
|
self._hash_type = ClientGUICommon.BetterChoice( self._hash_type_panel )
|
|
|
|
for hash_type in (
|
|
'sha256',
|
|
'md5',
|
|
'sha1',
|
|
'sha512',
|
|
'blurhash',
|
|
'pixel_hash'
|
|
):
|
|
|
|
self._hash_type.addItem( hash_type, hash_type )
|
|
|
|
|
|
self._hash_type.SetValue( 'sha256' )
|
|
|
|
rows = []
|
|
|
|
rows.append( ( 'Hash type to copy:', self._hash_type ) )
|
|
|
|
gridbox = ClientGUICommon.WrapInGrid( self._hash_type_panel, rows )
|
|
|
|
self._hash_type_panel.setLayout( gridbox )
|
|
|
|
#
|
|
|
|
self._ipfs_service_panel = QW.QWidget( self )
|
|
|
|
self._ipfs_service_key = ClientGUICommon.BetterChoice( self._ipfs_service_panel )
|
|
|
|
for service in CG.client_controller.services_manager.GetServices( ( HC.IPFS, ) ):
|
|
|
|
name = service.GetName()
|
|
service_key = service.GetServiceKey()
|
|
|
|
self._ipfs_service_key.addItem( name, service_key )
|
|
|
|
|
|
rows = []
|
|
|
|
rows.append( ( 'Service to copy:', self._ipfs_service_key ) )
|
|
|
|
gridbox = ClientGUICommon.WrapInGrid( self._ipfs_service_panel, rows )
|
|
|
|
self._ipfs_service_panel.setLayout( gridbox )
|
|
|
|
#
|
|
|
|
vbox = QP.VBoxLayout()
|
|
|
|
QP.AddToLayout( vbox, self._simple_actions, CC.FLAGS_EXPAND_SIZER_BOTH_WAYS )
|
|
QP.AddToLayout( vbox, self._duplicates_type_panel, CC.FLAGS_EXPAND_SIZER_BOTH_WAYS )
|
|
QP.AddToLayout( vbox, self._seek_panel, CC.FLAGS_EXPAND_SIZER_BOTH_WAYS )
|
|
QP.AddToLayout( vbox, self._thumbnail_move_panel, CC.FLAGS_EXPAND_SIZER_BOTH_WAYS )
|
|
QP.AddToLayout( vbox, self._file_filter_panel, CC.FLAGS_EXPAND_SIZER_BOTH_WAYS )
|
|
QP.AddToLayout( vbox, self._hamming_distance_panel, CC.FLAGS_EXPAND_SIZER_BOTH_WAYS )
|
|
QP.AddToLayout( vbox, self._thumbnail_rearrange_panel, CC.FLAGS_EXPAND_SIZER_BOTH_WAYS )
|
|
QP.AddToLayout( vbox, self._file_command_target_panel, CC.FLAGS_EXPAND_SIZER_BOTH_WAYS )
|
|
QP.AddToLayout( vbox, self._bitmap_type_panel, CC.FLAGS_EXPAND_SIZER_BOTH_WAYS )
|
|
QP.AddToLayout( vbox, self._hash_type_panel, CC.FLAGS_EXPAND_SIZER_BOTH_WAYS )
|
|
QP.AddToLayout( vbox, self._ipfs_service_panel, CC.FLAGS_EXPAND_SIZER_BOTH_WAYS )
|
|
|
|
self.setLayout( vbox )
|
|
|
|
self._simple_actions.currentIndexChanged.connect( self._UpdateControls )
|
|
|
|
self._UpdateControls()
|
|
|
|
|
|
def _UpdateControls( self ):
|
|
|
|
action = self._simple_actions.GetValue()
|
|
|
|
file_command_target_actions = {
|
|
CAC.SIMPLE_COPY_FILES,
|
|
CAC.SIMPLE_COPY_FILE_PATHS,
|
|
CAC.SIMPLE_COPY_FILE_ID,
|
|
CAC.SIMPLE_COPY_FILE_HASHES,
|
|
CAC.SIMPLE_COPY_FILE_SERVICE_FILENAMES
|
|
}
|
|
|
|
self._thumbnail_rearrange_panel.setVisible( action == CAC.SIMPLE_REARRANGE_THUMBNAILS )
|
|
self._duplicates_type_panel.setVisible( action == CAC.SIMPLE_SHOW_DUPLICATES )
|
|
self._seek_panel.setVisible( action == CAC.SIMPLE_MEDIA_SEEK_DELTA )
|
|
self._thumbnail_move_panel.setVisible( action == CAC.SIMPLE_MOVE_THUMBNAIL_FOCUS )
|
|
self._file_filter_panel.setVisible( action == CAC.SIMPLE_SELECT_FILES )
|
|
self._hamming_distance_panel.setVisible( action == CAC.SIMPLE_OPEN_SIMILAR_LOOKING_FILES )
|
|
self._hash_type_panel.setVisible( action == CAC.SIMPLE_COPY_FILE_HASHES )
|
|
self._ipfs_service_panel.setVisible( action == CAC.SIMPLE_COPY_FILE_SERVICE_FILENAMES )
|
|
self._file_command_target_panel.setVisible( action in file_command_target_actions )
|
|
self._bitmap_type_panel.setVisible( action == CAC.SIMPLE_COPY_FILE_BITMAP )
|
|
|
|
|
|
def GetValue( self ):
|
|
|
|
action = self._simple_actions.GetValue()
|
|
|
|
if action == '':
|
|
|
|
raise HydrusExceptions.VetoException( 'Please select an action!' )
|
|
|
|
else:
|
|
|
|
if action == CAC.SIMPLE_SHOW_DUPLICATES:
|
|
|
|
duplicate_type = self._duplicate_type.GetValue()
|
|
|
|
simple_data = duplicate_type
|
|
|
|
elif action == CAC.SIMPLE_MEDIA_SEEK_DELTA:
|
|
|
|
direction = self._seek_direction.GetValue()
|
|
|
|
s = self._seek_duration_s.value()
|
|
ms = self._seek_duration_ms.value() + ( 1000 * s )
|
|
|
|
simple_data = ( direction, ms )
|
|
|
|
elif action == CAC.SIMPLE_MOVE_THUMBNAIL_FOCUS:
|
|
|
|
move_direction = self._move_direction.GetValue()
|
|
selection_status = self._selection_status.GetValue()
|
|
|
|
simple_data = ( move_direction, selection_status )
|
|
|
|
elif action == CAC.SIMPLE_SELECT_FILES:
|
|
|
|
file_filter = self._file_filter.GetValue()
|
|
|
|
simple_data = file_filter
|
|
|
|
elif action == CAC.SIMPLE_OPEN_SIMILAR_LOOKING_FILES:
|
|
|
|
hamming_distance = self._hamming_distance.value()
|
|
|
|
simple_data = hamming_distance
|
|
|
|
elif action == CAC.SIMPLE_REARRANGE_THUMBNAILS:
|
|
|
|
rearrange_type = self._thumbnail_rearrange_type.GetValue()
|
|
|
|
simple_data = ( CAC.REARRANGE_THUMBNAILS_TYPE_COMMAND, rearrange_type )
|
|
|
|
elif action in ( CAC.SIMPLE_COPY_FILES, CAC.SIMPLE_COPY_FILE_PATHS, CAC.SIMPLE_COPY_FILE_ID ):
|
|
|
|
file_command_target = self._file_command_target.GetValue()
|
|
|
|
simple_data = file_command_target
|
|
|
|
elif action == CAC.SIMPLE_COPY_FILE_BITMAP:
|
|
|
|
bitmap_type = self._bitmap_type.GetValue()
|
|
|
|
simple_data = bitmap_type
|
|
|
|
elif action == CAC.SIMPLE_COPY_FILE_HASHES:
|
|
|
|
file_command_target = self._file_command_target.GetValue()
|
|
hash_type = self._hash_type.GetValue()
|
|
|
|
simple_data = ( file_command_target, hash_type )
|
|
|
|
elif action == CAC.SIMPLE_COPY_FILE_SERVICE_FILENAMES:
|
|
|
|
file_command_target = self._file_command_target.GetValue()
|
|
ipfs_service_key = self._ipfs_service_key.GetValue()
|
|
|
|
hacky_ipfs_dict = HydrusSerialisable.SerialisableDictionary()
|
|
|
|
hacky_ipfs_dict[ 'file_command_target' ] = file_command_target
|
|
hacky_ipfs_dict[ 'ipfs_service_key' ] = ipfs_service_key
|
|
|
|
simple_data = hacky_ipfs_dict
|
|
|
|
else:
|
|
|
|
simple_data = None
|
|
|
|
|
|
return CAC.ApplicationCommand.STATICCreateSimpleCommand( action, simple_data = simple_data )
|
|
|
|
|
|
|
|
def SetValue( self, command: CAC.ApplicationCommand ):
|
|
|
|
action = command.GetSimpleAction()
|
|
|
|
self._simple_actions.SetValue( action )
|
|
|
|
if action == CAC.SIMPLE_SHOW_DUPLICATES:
|
|
|
|
duplicate_type = command.GetSimpleData()
|
|
|
|
self._duplicate_type.SetValue( duplicate_type )
|
|
|
|
elif action == CAC.SIMPLE_MEDIA_SEEK_DELTA:
|
|
|
|
( direction, ms ) = command.GetSimpleData()
|
|
|
|
self._seek_direction.SetValue( direction )
|
|
|
|
s = ms // 1000
|
|
|
|
ms = ms % 1000
|
|
|
|
self._seek_duration_s.setValue( s )
|
|
self._seek_duration_ms.setValue( ms )
|
|
|
|
elif action == CAC.SIMPLE_MOVE_THUMBNAIL_FOCUS:
|
|
|
|
( move_direction, selection_status ) = command.GetSimpleData()
|
|
|
|
self._move_direction.SetValue( move_direction )
|
|
self._selection_status.SetValue( selection_status )
|
|
|
|
elif action == CAC.SIMPLE_SELECT_FILES:
|
|
|
|
file_filter = command.GetSimpleData()
|
|
|
|
self._file_filter.SetValue( file_filter )
|
|
|
|
elif action == CAC.SIMPLE_OPEN_SIMILAR_LOOKING_FILES:
|
|
|
|
hamming_distance = command.GetSimpleData()
|
|
|
|
self._hamming_distance.setValue( hamming_distance )
|
|
|
|
elif action == CAC.SIMPLE_REARRANGE_THUMBNAILS:
|
|
|
|
( rearrange_type, rearrange_data ) = command.GetSimpleData()
|
|
|
|
self._thumbnail_rearrange_type.SetValue( rearrange_data )
|
|
|
|
elif action in ( CAC.SIMPLE_COPY_FILES, CAC.SIMPLE_COPY_FILE_PATHS, CAC.SIMPLE_COPY_FILE_ID ):
|
|
|
|
file_command_target = command.GetSimpleData()
|
|
|
|
self._file_command_target.SetValue( file_command_target )
|
|
|
|
elif action == CAC.SIMPLE_COPY_FILE_BITMAP:
|
|
|
|
bitmap_type = command.GetSimpleData()
|
|
|
|
self._bitmap_type.SetValue( bitmap_type )
|
|
|
|
elif action == CAC.SIMPLE_COPY_FILE_HASHES:
|
|
|
|
( file_command_target, hash_type ) = command.GetSimpleData()
|
|
|
|
self._file_command_target.SetValue( file_command_target )
|
|
self._hash_type.SetValue( hash_type )
|
|
|
|
elif action == CAC.SIMPLE_COPY_FILE_SERVICE_FILENAMES:
|
|
|
|
hacky_ipfs_dict = command.GetSimpleData()
|
|
|
|
self._file_command_target.SetValue( hacky_ipfs_dict[ 'file_command_target' ] )
|
|
self._ipfs_service_key.SetValue( hacky_ipfs_dict[ 'ipfs_service_key' ] )
|
|
|
|
|
|
self._UpdateControls()
|
|
|
|
|
|
|
|
class TagSubPanel( QW.QWidget ):
|
|
|
|
def __init__( self, parent: QW.QWidget ):
|
|
|
|
QW.QWidget.__init__( self, parent )
|
|
|
|
self._flip_or_set_action = ClientGUICommon.BetterChoice( self )
|
|
|
|
self._flip_or_set_action.addItem( 'set', HC.CONTENT_UPDATE_SET )
|
|
self._flip_or_set_action.addItem( 'flip on and off', HC.CONTENT_UPDATE_FLIP )
|
|
|
|
self._flip_or_set_action.SetValue( HC.CONTENT_UPDATE_SET )
|
|
|
|
self._service_keys = ClientGUICommon.BetterChoice( self )
|
|
|
|
self._tag_value = QW.QLineEdit( self )
|
|
self._tag_value.setReadOnly( True )
|
|
|
|
default_location_context = CG.client_controller.new_options.GetDefaultLocalLocationContext()
|
|
|
|
self._tag_input = ClientGUIACDropdown.AutoCompleteDropdownTagsWrite( self, self.SetTags, default_location_context, CC.COMBINED_TAG_SERVICE_KEY )
|
|
|
|
#
|
|
|
|
services = CG.client_controller.services_manager.GetServices( ( HC.LOCAL_TAG, HC.TAG_REPOSITORY ) )
|
|
|
|
for service in services:
|
|
|
|
service_name = service.GetName()
|
|
service_key = service.GetServiceKey()
|
|
|
|
self._service_keys.addItem( service_name, service_key )
|
|
|
|
|
|
self._tag_input.SetTagServiceKey( self._service_keys.GetValue() )
|
|
|
|
#
|
|
|
|
vbox = QP.VBoxLayout()
|
|
|
|
tag_sub_vbox = QP.VBoxLayout()
|
|
|
|
QP.AddToLayout( tag_sub_vbox, self._tag_value, CC.FLAGS_EXPAND_PERPENDICULAR )
|
|
QP.AddToLayout( tag_sub_vbox, self._tag_input, CC.FLAGS_EXPAND_SIZER_BOTH_WAYS )
|
|
|
|
tag_hbox = QP.HBoxLayout()
|
|
|
|
QP.AddToLayout( tag_hbox, self._service_keys, CC.FLAGS_CENTER_PERPENDICULAR_EXPAND_DEPTH )
|
|
QP.AddToLayout( tag_hbox, tag_sub_vbox, CC.FLAGS_EXPAND_SIZER_BOTH_WAYS )
|
|
|
|
QP.AddToLayout( vbox, self._flip_or_set_action, CC.FLAGS_EXPAND_PERPENDICULAR )
|
|
QP.AddToLayout( vbox, tag_hbox, CC.FLAGS_EXPAND_SIZER_PERPENDICULAR )
|
|
|
|
self.setLayout( vbox )
|
|
|
|
#
|
|
|
|
self._service_keys.currentIndexChanged.connect( self._NewServiceKey )
|
|
|
|
|
|
def _NewServiceKey( self ):
|
|
|
|
self._tag_input.SetTagServiceKey( self._service_keys.GetValue() )
|
|
|
|
|
|
def GetValue( self ):
|
|
|
|
service_key = self._service_keys.GetValue()
|
|
|
|
if service_key is None:
|
|
|
|
raise HydrusExceptions.VetoException( 'Please select a tag service!' )
|
|
|
|
|
|
action = self._flip_or_set_action.GetValue()
|
|
|
|
tag = self._tag_value.text()
|
|
|
|
if tag == '':
|
|
|
|
raise HydrusExceptions.VetoException( 'Please enter a tag!' )
|
|
|
|
|
|
return CAC.ApplicationCommand( CAC.APPLICATION_COMMAND_TYPE_CONTENT, ( service_key, HC.CONTENT_TYPE_MAPPINGS, action, tag ) )
|
|
|
|
|
|
def SetTags( self, tags ):
|
|
|
|
if len( tags ) > 0:
|
|
|
|
tag = list( tags )[0]
|
|
|
|
self._tag_value.setText( tag )
|
|
|
|
|
|
|
|
def SetValue( self, action: int, service_key: bytes, tag: str ):
|
|
|
|
self._flip_or_set_action.SetValue( action )
|
|
|
|
self._service_keys.SetValue( service_key )
|
|
|
|
self._tag_value.setText( tag )
|
|
|
|
|
|
|
|
class ApplicationCommandWidget( ClientGUIScrolledPanels.EditPanel ):
|
|
|
|
PANEL_SIMPLE = 0
|
|
PANEL_TAG = 1
|
|
PANEL_RATING_LIKE = 2
|
|
PANEL_RATING_NUMERICAL = 3
|
|
PANEL_RATING_INCDEC = 4
|
|
PANEL_LOCAL_FILES = 5
|
|
|
|
def __init__( self, parent: QW.QWidget, command: CAC.ApplicationCommand, shortcuts_name: str ):
|
|
|
|
ClientGUIScrolledPanels.EditPanel.__init__( self, parent )
|
|
|
|
#
|
|
|
|
is_custom_or_media = shortcuts_name not in ClientGUIShortcuts.SHORTCUTS_RESERVED_NAMES or shortcuts_name == 'media'
|
|
|
|
self._panel_choice = ClientGUICommon.BetterChoice( self )
|
|
|
|
self._panel_choice.addItem( 'simple command', self.PANEL_SIMPLE )
|
|
|
|
if is_custom_or_media:
|
|
|
|
self._panel_choice.addItem( 'tag command', self.PANEL_TAG )
|
|
self._panel_choice.addItem( 'local file command', self.PANEL_LOCAL_FILES )
|
|
self._panel_choice.addItem( 'like/dislike rating command', self.PANEL_RATING_LIKE )
|
|
self._panel_choice.addItem( 'numerical rating command', self.PANEL_RATING_NUMERICAL )
|
|
self._panel_choice.addItem( 'rating increment/decrement command', self.PANEL_RATING_INCDEC )
|
|
|
|
else:
|
|
|
|
self._panel_choice.hide()
|
|
|
|
|
|
self._simple_sub_panel = SimpleSubPanel( self, shortcuts_name )
|
|
|
|
self._tag_sub_panel = TagSubPanel( self )
|
|
|
|
self._rating_like_sub_panel = RatingLikeSubPanel( self )
|
|
|
|
self._rating_numerical_sub_panel = RatingNumericalSubPanel( self )
|
|
|
|
self._rating_inc_dec_sub_panel = RatingIncDecSubPanel( self )
|
|
|
|
self._local_files_sub_panel = LocalFilesSubPanel( self )
|
|
|
|
#
|
|
|
|
if command.IsSimpleCommand():
|
|
|
|
self._simple_sub_panel.SetValue( command )
|
|
|
|
self._panel_choice.SetValue( self.PANEL_SIMPLE )
|
|
|
|
elif command.IsContentCommand():
|
|
|
|
service_key = command.GetContentServiceKey()
|
|
|
|
if CG.client_controller.services_manager.ServiceExists( service_key ):
|
|
|
|
service = CG.client_controller.services_manager.GetService( service_key )
|
|
|
|
action = command.GetContentAction()
|
|
value = command.GetContentValue()
|
|
|
|
else:
|
|
|
|
ClientGUIDialogsMessage.ShowWarning( self, 'The service that this command relies upon no longer exists! This command will reset to a default form.' )
|
|
|
|
local_tag_services = list( CG.client_controller.services_manager.GetServices( ( HC.LOCAL_TAG, ) ) )
|
|
|
|
service = local_tag_services[0]
|
|
|
|
service_key = service.GetServiceKey()
|
|
action = HC.CONTENT_UPDATE_SET
|
|
value = 'tag'
|
|
|
|
|
|
service_type = service.GetServiceType()
|
|
|
|
if service_type in HC.REAL_TAG_SERVICES:
|
|
|
|
tag = value
|
|
|
|
self._tag_sub_panel.SetValue( action, service_key, tag )
|
|
|
|
self._panel_choice.SetValue( self.PANEL_TAG )
|
|
|
|
elif service_type == HC.LOCAL_FILE_DOMAIN:
|
|
|
|
self._local_files_sub_panel.SetValue( action, service_key )
|
|
|
|
self._panel_choice.SetValue( self.PANEL_LOCAL_FILES )
|
|
|
|
elif service_type == HC.LOCAL_RATING_LIKE:
|
|
|
|
rating = value
|
|
|
|
self._rating_like_sub_panel.SetValue( action, service_key, rating )
|
|
|
|
self._panel_choice.SetValue( self.PANEL_RATING_LIKE )
|
|
|
|
elif service_type == ( HC.LOCAL_RATING_NUMERICAL, HC.LOCAL_RATING_INCDEC ):
|
|
|
|
if action in ( HC.CONTENT_UPDATE_SET, HC.CONTENT_UPDATE_FLIP ):
|
|
|
|
rating = value
|
|
|
|
self._rating_numerical_sub_panel.SetValue( action, service_key, rating )
|
|
|
|
self._panel_choice.SetValue( self.PANEL_RATING_NUMERICAL )
|
|
|
|
elif action in ( HC.CONTENT_UPDATE_INCREMENT, HC.CONTENT_UPDATE_DECREMENT ):
|
|
|
|
distance = 1
|
|
|
|
self._rating_inc_dec_sub_panel.SetValue( action, service_key, distance )
|
|
|
|
self._panel_choice.SetValue( self.PANEL_RATING_INCDEC )
|
|
|
|
|
|
|
|
|
|
#
|
|
|
|
vbox = QP.VBoxLayout()
|
|
|
|
QP.AddToLayout( vbox, self._panel_choice, CC.FLAGS_EXPAND_PERPENDICULAR )
|
|
QP.AddToLayout( vbox, self._simple_sub_panel, CC.FLAGS_EXPAND_PERPENDICULAR )
|
|
QP.AddToLayout( vbox, self._tag_sub_panel, CC.FLAGS_EXPAND_SIZER_PERPENDICULAR )
|
|
QP.AddToLayout( vbox, self._local_files_sub_panel, CC.FLAGS_EXPAND_SIZER_PERPENDICULAR )
|
|
QP.AddToLayout( vbox, self._rating_like_sub_panel, CC.FLAGS_EXPAND_SIZER_PERPENDICULAR )
|
|
QP.AddToLayout( vbox, self._rating_numerical_sub_panel, CC.FLAGS_EXPAND_SIZER_PERPENDICULAR )
|
|
QP.AddToLayout( vbox, self._rating_inc_dec_sub_panel, CC.FLAGS_EXPAND_SIZER_PERPENDICULAR )
|
|
vbox.addStretch( 1 )
|
|
|
|
self.widget().setLayout( vbox )
|
|
|
|
self._UpdateVisibleControls()
|
|
|
|
#
|
|
|
|
self._panel_choice.currentIndexChanged.connect( self._UpdateVisibleControls )
|
|
|
|
|
|
def _UpdateVisibleControls( self ):
|
|
|
|
panel_type = self._panel_choice.GetValue()
|
|
|
|
self._simple_sub_panel.setVisible( panel_type == self.PANEL_SIMPLE )
|
|
self._tag_sub_panel.setVisible( panel_type == self.PANEL_TAG )
|
|
self._local_files_sub_panel.setVisible( panel_type == self.PANEL_LOCAL_FILES )
|
|
self._rating_like_sub_panel.setVisible( panel_type == self.PANEL_RATING_LIKE )
|
|
self._rating_numerical_sub_panel.setVisible( panel_type == self.PANEL_RATING_NUMERICAL )
|
|
self._rating_inc_dec_sub_panel.setVisible( panel_type == self.PANEL_RATING_INCDEC )
|
|
|
|
|
|
def GetValue( self ):
|
|
|
|
panel_type = self._panel_choice.GetValue()
|
|
|
|
if panel_type == self.PANEL_SIMPLE:
|
|
|
|
return self._simple_sub_panel.GetValue()
|
|
|
|
elif panel_type == self.PANEL_TAG:
|
|
|
|
return self._tag_sub_panel.GetValue()
|
|
|
|
elif panel_type == self.PANEL_LOCAL_FILES:
|
|
|
|
return self._local_files_sub_panel.GetValue()
|
|
|
|
elif panel_type == self.PANEL_RATING_LIKE:
|
|
|
|
return self._rating_like_sub_panel.GetValue()
|
|
|
|
elif panel_type == self.PANEL_RATING_NUMERICAL:
|
|
|
|
return self._rating_numerical_sub_panel.GetValue()
|
|
|
|
elif panel_type == self.PANEL_RATING_INCDEC:
|
|
|
|
return self._rating_inc_dec_sub_panel.GetValue()
|
|
|
|
|
|
|