2015-06-17 20:01:41 +00:00
import os
2020-04-22 21:00:35 +00:00
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
2020-04-22 21:00:35 +00:00
from hydrus . core import HydrusConstants as HC
from hydrus . core import HydrusData
from hydrus . core import HydrusGlobals as HG
from hydrus . core import HydrusSerialisable
2020-07-29 20:52:44 +00:00
2020-07-08 22:00:33 +00:00
from hydrus . client import ClientApplicationCommand as CAC
2020-04-22 21:00:35 +00:00
from hydrus . client import ClientConstants as CC
from hydrus . client import ClientData
from hydrus . client . gui import ClientGUIDragDrop
from hydrus . client . gui import ClientGUICore as CGC
from hydrus . client . gui import ClientGUIFunctions
2022-04-13 21:39:26 +00:00
from hydrus . client . gui import ClientGUIMediaActions
2020-04-22 21:00:35 +00:00
from hydrus . client . gui import ClientGUIMediaControls
from hydrus . client . gui import ClientGUIMenus
2020-08-05 20:10:36 +00:00
from hydrus . client . gui import ClientGUIRatings
2020-04-22 21:00:35 +00:00
from hydrus . client . gui import ClientGUIScrolledPanelsEdit
from hydrus . client . gui import ClientGUIShortcuts
from hydrus . client . gui import ClientGUIShortcutControls
2020-04-29 21:44:12 +00:00
from hydrus . client . gui import ClientGUITopLevelWindowsPanels
2020-04-22 21:00:35 +00:00
from hydrus . client . gui import QtPorting as QP
2022-07-27 21:18:33 +00:00
from hydrus . client . gui . canvas import ClientGUIMPV
2020-07-15 20:52:09 +00:00
from hydrus . client . gui . lists import ClientGUIListBoxes
2021-03-17 21:59:28 +00:00
from hydrus . client . gui . widgets import ClientGUICommon
from hydrus . client . gui . widgets import ClientGUIMenuButton
2020-07-29 20:52:44 +00:00
from hydrus . client . media import ClientMedia
2020-08-05 20:10:36 +00:00
from hydrus . client . metadata import ClientRatings
2015-06-17 20:01:41 +00:00
2020-08-05 20:10:36 +00:00
class RatingLikeCanvas ( ClientGUIRatings . RatingLike ) :
2020-03-25 21:15:57 +00:00
def __init__ ( self , parent , service_key , canvas_key ) :
2020-08-05 20:10:36 +00:00
ClientGUIRatings . RatingLike . __init__ ( self , parent , service_key )
2020-03-25 21:15:57 +00:00
self . _canvas_key = canvas_key
self . _current_media = None
HG . client_controller . sub ( self , ' ProcessContentUpdates ' , ' content_updates_gui ' )
HG . client_controller . sub ( self , ' SetDisplayMedia ' , ' canvas_new_display_media ' )
def _Draw ( self , painter ) :
painter . setBackground ( QG . QBrush ( QP . GetBackgroundColour ( self . parentWidget ( ) ) ) )
painter . eraseRect ( painter . viewport ( ) )
if self . _current_media is not None :
2020-08-05 20:10:36 +00:00
ClientGUIRatings . DrawLike ( painter , 0 , 0 , self . _service_key , self . _rating_state )
2020-03-25 21:15:57 +00:00
self . _dirty = False
def EventLeftDown ( self , event ) :
if self . _current_media is not None :
if self . _rating_state == ClientRatings . LIKE : rating = None
else : rating = 1
content_update = HydrusData . ContentUpdate ( HC . CONTENT_TYPE_RATINGS , HC . CONTENT_UPDATE_ADD , ( rating , self . _hashes ) )
HG . client_controller . Write ( ' content_updates ' , { self . _service_key : ( content_update , ) } )
def EventRightDown ( self , event ) :
if self . _current_media is not None :
if self . _rating_state == ClientRatings . DISLIKE : rating = None
else : rating = 0
content_update = HydrusData . ContentUpdate ( HC . CONTENT_TYPE_RATINGS , HC . CONTENT_UPDATE_ADD , ( rating , self . _hashes ) )
HG . client_controller . Write ( ' content_updates ' , { self . _service_key : ( content_update , ) } )
def ProcessContentUpdates ( self , service_keys_to_content_updates ) :
if self . _current_media is not None :
2021-04-28 21:43:16 +00:00
for ( service_key , content_updates ) in service_keys_to_content_updates . items ( ) :
2020-03-25 21:15:57 +00:00
for content_update in content_updates :
( data_type , action , row ) = content_update . ToTuple ( )
if data_type == HC . CONTENT_TYPE_RATINGS :
hashes = content_update . GetHashes ( )
2020-10-28 22:20:33 +00:00
if HydrusData . SetsIntersect ( self . _hashes , hashes ) :
2020-03-25 21:15:57 +00:00
2022-07-13 21:35:17 +00:00
self . _SetRatingFromCurrentMedia ( )
2020-03-25 21:15:57 +00:00
self . _dirty = True
self . update ( )
return
2022-07-13 21:35:17 +00:00
def _SetRatingFromCurrentMedia ( self ) :
if self . _current_media is None :
rating_state = ClientRatings . NULL
else :
rating_state = ClientRatings . GetLikeStateFromMedia ( ( self . _current_media , ) , self . _service_key )
self . _SetRating ( rating_state )
2020-03-25 21:15:57 +00:00
def SetDisplayMedia ( self , canvas_key , media ) :
if canvas_key == self . _canvas_key :
self . _current_media = media
if self . _current_media is None :
self . _hashes = set ( )
else :
self . _hashes = self . _current_media . GetHashes ( )
2022-07-13 21:35:17 +00:00
self . _SetRatingFromCurrentMedia ( )
2020-03-25 21:15:57 +00:00
self . _dirty = True
self . update ( )
2020-08-05 20:10:36 +00:00
class RatingNumericalCanvas ( ClientGUIRatings . RatingNumerical ) :
2020-03-25 21:15:57 +00:00
def __init__ ( self , parent , service_key , canvas_key ) :
2020-08-05 20:10:36 +00:00
ClientGUIRatings . RatingNumerical . __init__ ( self , parent , service_key )
2020-03-25 21:15:57 +00:00
self . _canvas_key = canvas_key
self . _current_media = None
self . _rating_state = None
self . _rating = None
self . _hashes = set ( )
HG . client_controller . sub ( self , ' ProcessContentUpdates ' , ' content_updates_gui ' )
HG . client_controller . sub ( self , ' SetDisplayMedia ' , ' canvas_new_display_media ' )
def _ClearRating ( self ) :
2020-08-05 20:10:36 +00:00
ClientGUIRatings . RatingNumerical . _ClearRating ( self )
2020-03-25 21:15:57 +00:00
if self . _current_media is not None :
rating = None
content_update = HydrusData . ContentUpdate ( HC . CONTENT_TYPE_RATINGS , HC . CONTENT_UPDATE_ADD , ( rating , self . _hashes ) )
HG . client_controller . Write ( ' content_updates ' , { self . _service_key : ( content_update , ) } )
def _Draw ( self , painter ) :
painter . setBackground ( QG . QBrush ( QP . GetBackgroundColour ( self . parentWidget ( ) ) ) )
painter . eraseRect ( painter . viewport ( ) )
if self . _current_media is not None :
( self . _rating_state , self . _rating ) = ClientRatings . GetNumericalStateFromMedia ( ( self . _current_media , ) , self . _service_key )
2020-08-05 20:10:36 +00:00
ClientGUIRatings . DrawNumerical ( painter , 0 , 0 , self . _service_key , self . _rating_state , self . _rating )
2020-03-25 21:15:57 +00:00
self . _dirty = False
def _SetRating ( self , rating ) :
2020-08-05 20:10:36 +00:00
ClientGUIRatings . RatingNumerical . _SetRating ( self , rating )
2020-03-25 21:15:57 +00:00
if self . _current_media is not None and rating is not None :
content_update = HydrusData . ContentUpdate ( HC . CONTENT_TYPE_RATINGS , HC . CONTENT_UPDATE_ADD , ( rating , self . _hashes ) )
HG . client_controller . Write ( ' content_updates ' , { self . _service_key : ( content_update , ) } )
def ProcessContentUpdates ( self , service_keys_to_content_updates ) :
if self . _current_media is not None :
for ( service_key , content_updates ) in service_keys_to_content_updates . items ( ) :
for content_update in content_updates :
( data_type , action , row ) = content_update . ToTuple ( )
if data_type == HC . CONTENT_TYPE_RATINGS :
hashes = content_update . GetHashes ( )
2020-10-28 22:20:33 +00:00
if HydrusData . SetsIntersect ( self . _hashes , hashes ) :
2020-03-25 21:15:57 +00:00
self . _dirty = True
self . update ( )
2022-07-13 21:35:17 +00:00
self . _UpdateTooltip ( )
2020-03-25 21:15:57 +00:00
return
def SetDisplayMedia ( self , canvas_key , media ) :
if canvas_key == self . _canvas_key :
self . _current_media = media
if self . _current_media is None :
self . _hashes = set ( )
else :
self . _hashes = self . _current_media . GetHashes ( )
self . _dirty = True
self . update ( )
2022-07-13 21:35:17 +00:00
self . _UpdateTooltip ( )
2020-03-25 21:15:57 +00:00
2022-04-13 21:39:26 +00:00
# Note that I go setFocusPolicy( QC.Qt.TabFocus ) on all the icon buttons in the hover windows
# this means that a user can click a button and not give it focus, allowing the arrow keys and space to still propagate up to the main canvas
2020-03-25 21:15:57 +00:00
class CanvasHoverFrame ( QW . QFrame ) :
2015-06-17 20:01:41 +00:00
2022-05-04 21:40:27 +00:00
sendApplicationCommand = QC . Signal ( CAC . ApplicationCommand )
def __init__ ( self , parent : QW . QWidget , my_canvas , canvas_key ) :
2015-06-17 20:01:41 +00:00
2022-04-06 20:40:17 +00:00
# TODO: Clean up old references to window stuff, decide on lower/hide/show/raise options
# OK, so I converted these from this "self.setWindowFlags( QC.Qt.FramelessWindowHint | QC.Qt.Tool )" to normal raise/lower widgets embedded in the canvas
# this took some hacks, and there is still a bunch of focus and TLW checking code going on here that needs to be cleaned up
# note I tried to have them just lower rather than hide and it looked really stupid, so that thought is dead for the current moment. atm I just want to do the same thing as before with no graphics errors
2015-06-17 20:01:41 +00:00
2022-04-06 20:40:17 +00:00
QW . QFrame . __init__ ( self , parent )
2019-12-05 05:29:32 +00:00
self . setFrameStyle ( QW . QFrame . Panel | QW . QFrame . Raised )
self . setLineWidth ( 2 )
2022-04-13 21:39:26 +00:00
# We need this, or else if the QSS does not define a Widget background color (the default), these 'raised' windows are transparent lmao
self . setAutoFillBackground ( True )
2022-04-06 20:40:17 +00:00
2018-12-05 22:35:30 +00:00
self . _my_canvas = my_canvas
2015-06-17 20:01:41 +00:00
self . _canvas_key = canvas_key
self . _current_media = None
2019-05-08 21:06:42 +00:00
self . _always_on_top = False
2015-12-02 22:32:18 +00:00
self . _last_ideal_position = None
2015-06-17 20:01:41 +00:00
2022-04-06 20:40:17 +00:00
self . hide ( )
self . _is_currently_up = False
2015-06-17 20:01:41 +00:00
2022-04-06 20:40:17 +00:00
self . setCursor ( QG . QCursor ( QC . Qt . ArrowCursor ) )
2016-12-07 22:12:52 +00:00
2020-01-22 21:04:43 +00:00
self . _position_initialised = False
2019-06-26 21:27:18 +00:00
2022-04-06 20:40:17 +00:00
parent . installEventFilter ( self )
2020-08-19 22:38:20 +00:00
2017-05-10 21:33:58 +00:00
HG . client_controller . sub ( self , ' SetDisplayMedia ' , ' canvas_new_display_media ' )
2015-06-17 20:01:41 +00:00
def _GetIdealSizeAndPosition ( self ) :
raise NotImplementedError ( )
2022-04-06 20:40:17 +00:00
def _LowerHover ( self ) :
if self . _is_currently_up :
if HG . hover_window_report_mode :
HydrusData . ShowText ( repr ( self ) + ' - lowering ' )
self . hide ( )
self . _is_currently_up = False
self . parentWidget ( ) . setFocus ( QC . Qt . OtherFocusReason )
pass
def _RaiseHover ( self ) :
if not self . _is_currently_up :
if HG . hover_window_report_mode :
HydrusData . ShowText ( repr ( self ) + ' - raising ' )
self . show ( )
self . raise_ ( )
self . _is_currently_up = True
2022-04-13 21:39:26 +00:00
def _ShouldBeHidden ( self ) :
return self . _current_media is None or not self . _my_canvas . isVisible ( )
def _ShouldBeShown ( self ) :
return self . _always_on_top
2019-12-11 23:18:37 +00:00
def _SizeAndPosition ( self , force = False ) :
2015-06-17 20:01:41 +00:00
2019-12-11 23:18:37 +00:00
if self . parentWidget ( ) . isVisible ( ) or force :
2017-05-17 21:53:02 +00:00
2017-05-24 20:28:24 +00:00
( should_resize , my_ideal_size , my_ideal_position ) = self . _GetIdealSizeAndPosition ( )
2017-05-17 21:53:02 +00:00
2017-05-24 20:28:24 +00:00
if should_resize :
2020-08-19 22:38:20 +00:00
self . resize ( my_ideal_size )
2020-02-26 22:28:52 +00:00
2020-08-19 22:38:20 +00:00
if my_ideal_position != self . pos ( ) :
2020-02-26 22:28:52 +00:00
self . move ( my_ideal_position )
2017-05-24 20:28:24 +00:00
2015-06-17 20:01:41 +00:00
2020-01-22 21:04:43 +00:00
self . _position_initialised = True
2015-06-17 20:01:41 +00:00
2016-12-07 22:12:52 +00:00
2022-04-06 20:40:17 +00:00
def eventFilter ( self , object , event ) :
2020-08-19 22:38:20 +00:00
2022-04-06 20:40:17 +00:00
if event . type ( ) == QC . QEvent . Resize :
2020-08-19 22:38:20 +00:00
2022-04-06 20:40:17 +00:00
self . _SizeAndPosition ( )
2020-08-19 22:38:20 +00:00
return False
2022-04-13 21:39:26 +00:00
def mouseReleaseEvent ( self , event ) :
# we eat mouse events to stop interfering with archive/delete and duplicate filter on greyspace clicks
event . accept ( )
def mousePressEvent ( self , event ) :
# we eat mouse events to stop interfering with archive/delete and duplicate filter on greyspace clicks
event . accept ( )
2022-04-06 20:40:17 +00:00
def PositionIsInitialised ( self ) :
return self . _position_initialised
2015-06-17 20:01:41 +00:00
def SetDisplayMedia ( self , canvas_key , media ) :
if canvas_key == self . _canvas_key :
self . _current_media = media
2022-04-06 20:40:17 +00:00
def DoRegularHideShow ( self ) :
2018-01-03 22:37:30 +00:00
2020-01-22 21:04:43 +00:00
if not self . _position_initialised :
self . _SizeAndPosition ( )
2019-12-11 23:18:37 +00:00
current_focus_tlw = QW . QApplication . activeWindow ( )
2019-05-15 20:35:00 +00:00
2022-04-13 21:39:26 +00:00
focus_is_good = current_focus_tlw == self . window ( )
2019-05-15 20:35:00 +00:00
2020-02-05 22:55:21 +00:00
mouse_is_over_self_or_child = False
2022-07-20 19:17:03 +00:00
for tlw in list ( QW . QApplication . topLevelWidgets ( ) ) :
if not tlw . isVisible ( ) :
continue
2020-02-05 22:55:21 +00:00
if tlw == self or ClientGUIFunctions . IsQtAncestor ( tlw , self , through_tlws = True ) :
2021-12-22 22:31:23 +00:00
if ClientGUIFunctions . MouseIsOverWidget ( tlw ) :
2020-02-05 22:55:21 +00:00
mouse_is_over_self_or_child = True
break
2022-04-13 21:39:26 +00:00
if self . _ShouldBeShown ( ) :
2015-06-17 20:01:41 +00:00
2022-04-06 20:40:17 +00:00
self . _RaiseHover ( )
2017-09-13 20:50:41 +00:00
2018-01-03 22:37:30 +00:00
return
2016-12-07 22:12:52 +00:00
2018-01-03 22:37:30 +00:00
2022-04-13 21:39:26 +00:00
if self . _ShouldBeHidden ( ) :
2018-01-03 22:37:30 +00:00
2022-04-06 20:40:17 +00:00
self . _LowerHover ( )
2018-01-03 22:37:30 +00:00
2022-04-13 21:39:26 +00:00
return
2018-01-03 22:37:30 +00:00
2022-04-13 21:39:26 +00:00
mouse_pos = self . parentWidget ( ) . mapFromGlobal ( QG . QCursor . pos ( ) )
mouse_x = mouse_pos . x ( )
mouse_y = mouse_pos . y ( )
my_size = self . size ( )
my_width = my_size . width ( )
my_height = my_size . height ( )
my_pos = self . pos ( )
my_x = my_pos . x ( )
my_y = my_pos . y ( )
( should_resize , my_ideal_size , my_ideal_pos ) = self . _GetIdealSizeAndPosition ( )
my_ideal_width = my_ideal_size . width ( )
my_ideal_height = my_ideal_size . height ( )
my_ideal_x = my_ideal_pos . x ( )
my_ideal_y = my_ideal_pos . y ( )
if my_ideal_width == - 1 :
2018-01-03 22:37:30 +00:00
2022-04-13 21:39:26 +00:00
my_ideal_width = max ( my_width , 50 )
2018-01-03 22:37:30 +00:00
2022-04-13 21:39:26 +00:00
if my_ideal_height == - 1 :
2018-01-03 22:37:30 +00:00
2022-04-13 21:39:26 +00:00
my_ideal_height = max ( my_height , 50 )
2018-01-03 22:37:30 +00:00
2022-04-13 21:39:26 +00:00
in_ideal_x = my_ideal_x < = mouse_x < = my_ideal_x + my_ideal_width
in_ideal_y = my_ideal_y < = mouse_y < = my_ideal_y + my_ideal_height
in_actual_x = my_x < = mouse_x < = my_x + my_width
in_actual_y = my_y < = mouse_y < = my_y + my_height
# we test both ideal and actual here because setposition is not always honoured by the OS
# for instance, in some Linux window managers on a fullscreen view, the top taskbar is hidden, but when hover window is shown, it takes focus and causes taskbar to reappear
# the reappearance shuffles the screen coordinates down a bit so the hover sits +20px y despite wanting to be lined up with the underlying fullscreen viewer
# wew lad
in_position = ( in_ideal_x or in_actual_x ) and ( in_ideal_y or in_actual_y )
menu_open = CGC . core ( ) . MenuIsOpen ( )
dialog_is_open = ClientGUIFunctions . DialogIsOpen ( )
mouse_is_near_animation_bar = self . _my_canvas . MouseIsNearAnimationBar ( )
# this used to have the flash media window test to ensure mouse over flash window hid hovers going over it
mouse_is_over_something_else_important = mouse_is_near_animation_bar
hide_focus_is_good = focus_is_good or current_focus_tlw is None # don't hide if focus is either gone to another problem or temporarily sperging-out due to a click-transition or similar
ready_to_show = in_position and not mouse_is_over_something_else_important and focus_is_good and not dialog_is_open and not menu_open
ready_to_hide = not menu_open and not mouse_is_over_self_or_child and ( not in_position or dialog_is_open or not hide_focus_is_good )
def get_logic_report_string ( ) :
2018-01-03 22:37:30 +00:00
2022-04-13 21:39:26 +00:00
tuples = [ ]
2018-01-03 22:37:30 +00:00
2022-04-13 21:39:26 +00:00
tuples . append ( ( ' mouse: ' , ( mouse_x , mouse_y ) ) )
tuples . append ( ( ' winpos: ' , ( my_x , my_y ) ) )
tuples . append ( ( ' ideal winpos: ' , ( my_ideal_x , my_ideal_y ) ) )
tuples . append ( ( ' winsize: ' , ( my_width , my_height ) ) )
tuples . append ( ( ' ideal winsize: ' , ( my_ideal_width , my_ideal_height ) ) )
tuples . append ( ( ' in position: ' , in_position ) )
tuples . append ( ( ' menu open: ' , menu_open ) )
tuples . append ( ( ' dialog open: ' , dialog_is_open ) )
tuples . append ( ( ' mouse near animation bar: ' , mouse_is_near_animation_bar ) )
tuples . append ( ( ' focus is good: ' , focus_is_good ) )
tuples . append ( ( ' current focus tlw: ' , current_focus_tlw ) )
2018-01-03 22:37:30 +00:00
2022-04-13 21:39:26 +00:00
message = os . linesep * 2 + os . linesep . join ( ( a + str ( b ) for ( a , b ) in tuples ) )
2015-11-18 22:44:07 +00:00
2022-04-13 21:39:26 +00:00
return message
2015-11-18 22:44:07 +00:00
2022-04-13 21:39:26 +00:00
if ready_to_show :
2015-11-18 22:44:07 +00:00
2022-04-13 21:39:26 +00:00
self . _SizeAndPosition ( )
2019-06-26 21:27:18 +00:00
2022-04-13 21:39:26 +00:00
self . _RaiseHover ( )
2018-01-03 22:37:30 +00:00
2022-04-13 21:39:26 +00:00
elif ready_to_hide :
2018-01-17 22:52:10 +00:00
2022-04-13 21:39:26 +00:00
self . _LowerHover ( )
2018-01-03 22:37:30 +00:00
2017-03-29 19:39:34 +00:00
2022-04-06 20:40:17 +00:00
class CanvasHoverFrameTop ( CanvasHoverFrame ) :
2019-05-08 21:06:42 +00:00
def __init__ ( self , parent , my_canvas , canvas_key ) :
2020-03-25 21:15:57 +00:00
CanvasHoverFrame . __init__ ( self , parent , my_canvas , canvas_key )
2019-05-08 21:06:42 +00:00
2022-04-06 20:40:17 +00:00
self . _current_zoom = 1.0
2019-05-08 21:06:42 +00:00
self . _current_index_string = ' '
2022-04-06 20:40:17 +00:00
self . _top_hbox = QP . HBoxLayout ( )
2019-06-05 19:42:39 +00:00
2022-04-06 20:40:17 +00:00
self . _title_text = ClientGUICommon . BetterStaticText ( self , ' title ' , ellipsize_end = True )
self . _info_text = ClientGUICommon . BetterStaticText ( self , ' info ' , ellipsize_end = True )
2019-06-05 19:42:39 +00:00
2022-04-06 20:40:17 +00:00
self . _title_text . setAlignment ( QC . Qt . AlignHCenter | QC . Qt . AlignVCenter )
self . _info_text . setAlignment ( QC . Qt . AlignHCenter | QC . Qt . AlignVCenter )
2019-05-08 21:06:42 +00:00
2022-04-06 20:40:17 +00:00
self . _PopulateLeftButtons ( )
self . _top_hbox . addStretch ( 1 )
self . _PopulateCenterButtons ( )
self . _top_hbox . addStretch ( 1 )
self . _PopulateRightButtons ( )
2019-05-08 21:06:42 +00:00
2019-11-14 03:56:30 +00:00
vbox = QP . VBoxLayout ( )
2019-05-08 21:06:42 +00:00
2022-04-06 20:40:17 +00:00
QP . AddToLayout ( vbox , self . _top_hbox , CC . FLAGS_EXPAND_SIZER_PERPENDICULAR )
QP . AddToLayout ( vbox , self . _title_text , CC . FLAGS_EXPAND_PERPENDICULAR )
QP . AddToLayout ( vbox , self . _info_text , CC . FLAGS_EXPAND_PERPENDICULAR )
2019-05-08 21:06:42 +00:00
2019-11-14 03:56:30 +00:00
self . setLayout ( vbox )
2019-05-08 21:06:42 +00:00
2022-04-06 20:40:17 +00:00
HG . client_controller . sub ( self , ' ProcessContentUpdates ' , ' content_updates_gui ' )
2019-05-08 21:06:42 +00:00
HG . client_controller . sub ( self , ' SetIndexString ' , ' canvas_new_index_string ' )
2022-04-06 20:40:17 +00:00
def _Archive ( self ) :
2019-05-08 21:06:42 +00:00
2022-04-06 20:40:17 +00:00
if self . _current_media . HasInbox ( ) :
2019-05-08 21:06:42 +00:00
2022-04-06 20:40:17 +00:00
command = CAC . ApplicationCommand . STATICCreateSimpleCommand ( CAC . SIMPLE_ARCHIVE_FILE )
2019-05-08 21:06:42 +00:00
2022-04-06 20:40:17 +00:00
else :
2019-05-08 21:06:42 +00:00
2022-04-06 20:40:17 +00:00
command = CAC . ApplicationCommand . STATICCreateSimpleCommand ( CAC . SIMPLE_INBOX_FILE )
2019-05-08 21:06:42 +00:00
2022-05-04 21:40:27 +00:00
self . sendApplicationCommand . emit ( command )
2019-05-08 21:06:42 +00:00
def _GetIdealSizeAndPosition ( self ) :
2022-04-06 20:40:17 +00:00
# clip this and friends to availableScreenGeometry for size and position, not rely 100% on parent
2019-11-14 03:56:30 +00:00
parent_window = self . parentWidget ( ) . window ( )
2019-05-08 21:06:42 +00:00
2020-02-26 22:28:52 +00:00
parent_size = parent_window . size ( )
parent_width = parent_size . width ( )
my_size = self . size ( )
2019-05-08 21:06:42 +00:00
2020-02-26 22:28:52 +00:00
my_width = my_size . width ( )
my_height = my_size . height ( )
2019-05-08 21:06:42 +00:00
2022-04-06 20:40:17 +00:00
my_ideal_width = max ( int ( parent_width * 0.6 ) , self . sizeHint ( ) . width ( ) )
2020-07-22 20:59:16 +00:00
my_ideal_height = self . sizeHint ( ) . height ( )
2019-05-08 21:06:42 +00:00
2020-01-02 03:05:35 +00:00
should_resize = my_ideal_width != my_width or my_ideal_height != my_height
2019-05-08 21:06:42 +00:00
2020-02-26 22:28:52 +00:00
ideal_size = QC . QSize ( my_ideal_width , my_ideal_height )
2022-04-06 20:40:17 +00:00
ideal_position = QC . QPoint ( int ( parent_width * 0.2 ) , 0 )
2019-05-08 21:06:42 +00:00
2020-02-26 22:28:52 +00:00
return ( should_resize , ideal_size , ideal_position )
2019-05-08 21:06:42 +00:00
2022-04-06 20:40:17 +00:00
def _PopulateCenterButtons ( self ) :
2019-05-08 21:06:42 +00:00
2022-04-06 20:40:17 +00:00
self . _archive_button = ClientGUICommon . BetterBitmapButton ( self , CC . global_pixmaps ( ) . archive , self . _Archive )
2022-04-13 21:39:26 +00:00
self . _archive_button . setFocusPolicy ( QC . Qt . TabFocus )
2017-03-29 19:39:34 +00:00
2020-03-11 21:52:11 +00:00
self . _trash_button = ClientGUICommon . BetterBitmapButton ( self , CC . global_pixmaps ( ) . delete , HG . client_controller . pub , ' canvas_delete ' , self . _canvas_key )
2019-11-14 03:56:30 +00:00
self . _trash_button . setToolTip ( ' send to trash ' )
2022-04-13 21:39:26 +00:00
self . _trash_button . setFocusPolicy ( QC . Qt . TabFocus )
2015-08-05 18:42:35 +00:00
2020-03-11 21:52:11 +00:00
self . _delete_button = ClientGUICommon . BetterBitmapButton ( self , CC . global_pixmaps ( ) . trash_delete , HG . client_controller . pub , ' canvas_delete ' , self . _canvas_key )
2019-11-14 03:56:30 +00:00
self . _delete_button . setToolTip ( ' delete completely ' )
2022-04-13 21:39:26 +00:00
self . _delete_button . setFocusPolicy ( QC . Qt . TabFocus )
2015-08-05 18:42:35 +00:00
2020-03-11 21:52:11 +00:00
self . _undelete_button = ClientGUICommon . BetterBitmapButton ( self , CC . global_pixmaps ( ) . undelete , HG . client_controller . pub , ' canvas_undelete ' , self . _canvas_key )
2019-11-14 03:56:30 +00:00
self . _undelete_button . setToolTip ( ' undelete ' )
2022-04-13 21:39:26 +00:00
self . _undelete_button . setFocusPolicy ( QC . Qt . TabFocus )
2015-06-17 20:01:41 +00:00
2020-07-29 20:52:44 +00:00
QP . AddToLayout ( self . _top_hbox , self . _archive_button , CC . FLAGS_CENTER_PERPENDICULAR )
QP . AddToLayout ( self . _top_hbox , self . _trash_button , CC . FLAGS_CENTER_PERPENDICULAR )
QP . AddToLayout ( self . _top_hbox , self . _delete_button , CC . FLAGS_CENTER_PERPENDICULAR )
QP . AddToLayout ( self . _top_hbox , self . _undelete_button , CC . FLAGS_CENTER_PERPENDICULAR )
2017-03-29 19:39:34 +00:00
def _PopulateLeftButtons ( self ) :
2017-04-19 20:58:30 +00:00
self . _index_text = ClientGUICommon . BetterStaticText ( self , ' index ' )
2017-03-29 19:39:34 +00:00
2020-07-29 20:52:44 +00:00
QP . AddToLayout ( self . _top_hbox , self . _index_text , CC . FLAGS_CENTER_PERPENDICULAR )
2017-03-29 19:39:34 +00:00
def _PopulateRightButtons ( self ) :
2017-04-19 20:58:30 +00:00
self . _zoom_text = ClientGUICommon . BetterStaticText ( self , ' zoom ' )
2015-06-17 20:01:41 +00:00
2022-05-04 21:40:27 +00:00
zoom_in = ClientGUICommon . BetterBitmapButton ( self , CC . global_pixmaps ( ) . zoom_in , self . sendApplicationCommand . emit , CAC . ApplicationCommand . STATICCreateSimpleCommand ( CAC . SIMPLE_ZOOM_IN_VIEWER_CENTER ) )
2020-07-08 22:00:33 +00:00
zoom_in . SetToolTipWithShortcuts ( ' zoom in ' , CAC . SIMPLE_ZOOM_IN )
2022-04-13 21:39:26 +00:00
zoom_in . setFocusPolicy ( QC . Qt . TabFocus )
2015-06-17 20:01:41 +00:00
2022-05-04 21:40:27 +00:00
zoom_out = ClientGUICommon . BetterBitmapButton ( self , CC . global_pixmaps ( ) . zoom_out , self . sendApplicationCommand . emit , CAC . ApplicationCommand . STATICCreateSimpleCommand ( CAC . SIMPLE_ZOOM_OUT_VIEWER_CENTER ) )
2020-07-08 22:00:33 +00:00
zoom_out . SetToolTipWithShortcuts ( ' zoom out ' , CAC . SIMPLE_ZOOM_OUT )
2022-04-13 21:39:26 +00:00
zoom_out . setFocusPolicy ( QC . Qt . TabFocus )
2015-06-17 20:01:41 +00:00
2022-05-04 21:40:27 +00:00
zoom_switch = ClientGUICommon . BetterBitmapButton ( self , CC . global_pixmaps ( ) . zoom_switch , self . sendApplicationCommand . emit , CAC . ApplicationCommand . STATICCreateSimpleCommand ( CAC . SIMPLE_SWITCH_BETWEEN_100_PERCENT_AND_CANVAS_ZOOM_VIEWER_CENTER ) )
2020-07-08 22:00:33 +00:00
zoom_switch . SetToolTipWithShortcuts ( ' zoom switch ' , CAC . SIMPLE_SWITCH_BETWEEN_100_PERCENT_AND_CANVAS_ZOOM )
2022-04-13 21:39:26 +00:00
zoom_switch . setFocusPolicy ( QC . Qt . TabFocus )
2015-06-17 20:01:41 +00:00
2022-01-26 21:57:04 +00:00
self . _volume_control = ClientGUIMediaControls . VolumeControl ( self , CC . CANVAS_MEDIA_VIEWER )
2020-01-22 21:04:43 +00:00
if not ClientGUIMPV . MPV_IS_AVAILABLE :
2020-02-05 22:55:21 +00:00
self . _volume_control . hide ( )
2020-01-22 21:04:43 +00:00
2020-03-11 21:52:11 +00:00
shortcuts = ClientGUICommon . BetterBitmapButton ( self , CC . global_pixmaps ( ) . keyboard , self . _ShowShortcutMenu )
2019-11-14 03:56:30 +00:00
shortcuts . setToolTip ( ' shortcuts ' )
2022-04-13 21:39:26 +00:00
shortcuts . setFocusPolicy ( QC . Qt . TabFocus )
2015-06-17 20:01:41 +00:00
2022-11-09 22:24:07 +00:00
self . _show_embedded_metadata_button = ClientGUICommon . BetterBitmapButton ( self , CC . global_pixmaps ( ) . listctrl , self . _ShowFileEmbeddedMetadata )
self . _show_embedded_metadata_button . setFocusPolicy ( QC . Qt . TabFocus )
2022-07-27 21:18:33 +00:00
2020-03-11 21:52:11 +00:00
fullscreen_switch = ClientGUICommon . BetterBitmapButton ( self , CC . global_pixmaps ( ) . fullscreen_switch , HG . client_controller . pub , ' canvas_fullscreen_switch ' , self . _canvas_key )
2019-11-14 03:56:30 +00:00
fullscreen_switch . setToolTip ( ' fullscreen switch ' )
2022-04-13 21:39:26 +00:00
fullscreen_switch . setFocusPolicy ( QC . Qt . TabFocus )
2015-08-05 18:42:35 +00:00
2019-11-20 23:10:46 +00:00
if HC . PLATFORM_MACOS :
2019-11-14 03:56:30 +00:00
fullscreen_switch . hide ( )
2018-03-28 21:55:58 +00:00
2022-05-04 21:40:27 +00:00
open_externally = ClientGUICommon . BetterBitmapButton ( self , CC . global_pixmaps ( ) . open_externally , self . sendApplicationCommand . emit , CAC . ApplicationCommand . STATICCreateSimpleCommand ( CAC . SIMPLE_OPEN_FILE_IN_EXTERNAL_PROGRAM ) )
2020-07-08 22:00:33 +00:00
open_externally . SetToolTipWithShortcuts ( ' open externally ' , CAC . SIMPLE_OPEN_FILE_IN_EXTERNAL_PROGRAM )
2022-04-13 21:39:26 +00:00
open_externally . setFocusPolicy ( QC . Qt . TabFocus )
2015-06-17 20:01:41 +00:00
2019-11-14 03:56:30 +00:00
drag_button = QW . QPushButton ( self )
2020-03-11 21:52:11 +00:00
drag_button . setIcon ( QG . QIcon ( CC . global_pixmaps ( ) . drag ) )
drag_button . setIconSize ( CC . global_pixmaps ( ) . drag . size ( ) )
2019-11-14 03:56:30 +00:00
drag_button . setToolTip ( ' drag from here to export file ' )
drag_button . pressed . connect ( self . EventDragButton )
2022-04-13 21:39:26 +00:00
drag_button . setFocusPolicy ( QC . Qt . TabFocus )
2019-11-14 03:56:30 +00:00
2020-03-11 21:52:11 +00:00
close = ClientGUICommon . BetterBitmapButton ( self , CC . global_pixmaps ( ) . stop , HG . client_controller . pub , ' canvas_close ' , self . _canvas_key )
2019-11-14 03:56:30 +00:00
close . setToolTip ( ' close ' )
2022-04-13 21:39:26 +00:00
close . setFocusPolicy ( QC . Qt . TabFocus )
2019-11-14 03:56:30 +00:00
2020-07-29 20:52:44 +00:00
QP . AddToLayout ( self . _top_hbox , self . _zoom_text , CC . FLAGS_CENTER_PERPENDICULAR )
QP . AddToLayout ( self . _top_hbox , zoom_in , CC . FLAGS_CENTER_PERPENDICULAR )
QP . AddToLayout ( self . _top_hbox , zoom_out , CC . FLAGS_CENTER_PERPENDICULAR )
QP . AddToLayout ( self . _top_hbox , zoom_switch , CC . FLAGS_CENTER_PERPENDICULAR )
QP . AddToLayout ( self . _top_hbox , self . _volume_control , CC . FLAGS_CENTER_PERPENDICULAR )
QP . AddToLayout ( self . _top_hbox , shortcuts , CC . FLAGS_CENTER_PERPENDICULAR )
2022-11-09 22:24:07 +00:00
QP . AddToLayout ( self . _top_hbox , self . _show_embedded_metadata_button , CC . FLAGS_CENTER_PERPENDICULAR )
2020-07-29 20:52:44 +00:00
QP . AddToLayout ( self . _top_hbox , fullscreen_switch , CC . FLAGS_CENTER_PERPENDICULAR )
QP . AddToLayout ( self . _top_hbox , open_externally , CC . FLAGS_CENTER_PERPENDICULAR )
QP . AddToLayout ( self . _top_hbox , drag_button , CC . FLAGS_CENTER_PERPENDICULAR )
QP . AddToLayout ( self . _top_hbox , close , CC . FLAGS_CENTER_PERPENDICULAR )
2015-06-17 20:01:41 +00:00
2017-03-29 19:39:34 +00:00
def _ResetArchiveButton ( self ) :
2015-06-17 20:01:41 +00:00
2017-03-29 19:39:34 +00:00
if self . _current_media . HasInbox ( ) :
2020-03-11 21:52:11 +00:00
ClientGUIFunctions . SetBitmapButtonBitmap ( self . _archive_button , CC . global_pixmaps ( ) . archive )
2019-11-14 03:56:30 +00:00
self . _archive_button . setToolTip ( ' archive ' )
2017-03-29 19:39:34 +00:00
else :
2020-03-11 21:52:11 +00:00
ClientGUIFunctions . SetBitmapButtonBitmap ( self . _archive_button , CC . global_pixmaps ( ) . to_inbox )
2019-11-14 03:56:30 +00:00
self . _archive_button . setToolTip ( ' return to inbox ' )
2017-03-29 19:39:34 +00:00
2015-06-17 20:01:41 +00:00
def _ResetButtons ( self ) :
if self . _current_media is not None :
2017-03-29 19:39:34 +00:00
self . _ResetArchiveButton ( )
2015-06-17 20:01:41 +00:00
2021-04-28 21:43:16 +00:00
locations_manager = self . _current_media . GetLocationsManager ( )
2015-08-05 18:42:35 +00:00
2022-02-09 21:04:42 +00:00
if locations_manager . IsTrashed ( ) :
self . _trash_button . hide ( )
self . _delete_button . show ( )
elif locations_manager . IsLocal ( ) :
2015-08-05 18:42:35 +00:00
2019-11-14 03:56:30 +00:00
self . _trash_button . show ( )
self . _delete_button . hide ( )
2022-02-09 21:04:42 +00:00
if set ( locations_manager . GetDeleted ( ) ) . isdisjoint ( HG . client_controller . services_manager . GetServiceKeys ( ( HC . LOCAL_FILE_DOMAIN , ) ) ) :
2019-11-14 03:56:30 +00:00
self . _undelete_button . hide ( )
2015-08-05 18:42:35 +00:00
2022-02-09 21:04:42 +00:00
else :
2015-08-05 18:42:35 +00:00
2019-11-14 03:56:30 +00:00
self . _undelete_button . show ( )
2015-08-05 18:42:35 +00:00
2022-11-09 22:24:07 +00:00
has_exif = self . _current_media . GetMediaResult ( ) . GetFileInfoManager ( ) . has_exif
has_human_readable_embedded_metadata = self . _current_media . GetMediaResult ( ) . GetFileInfoManager ( ) . has_human_readable_embedded_metadata
2022-07-27 21:18:33 +00:00
2022-11-09 22:24:07 +00:00
if has_exif or has_human_readable_embedded_metadata :
tt_components = [ ]
if has_exif :
tt_components . append ( ' exif ' )
if has_human_readable_embedded_metadata :
tt_components . append ( ' non-exif human-readable embedded metadata ' )
tt = ' show {} ' . format ( ' and ' . join ( tt_components ) )
self . _show_embedded_metadata_button . setToolTip ( tt )
self . _show_embedded_metadata_button . setVisible ( has_exif or has_human_readable_embedded_metadata )
2022-07-27 21:18:33 +00:00
2015-06-17 20:01:41 +00:00
def _ResetText ( self ) :
if self . _current_media is None :
2019-11-14 03:56:30 +00:00
self . _title_text . hide ( )
self . _info_text . hide ( )
2015-06-17 20:01:41 +00:00
else :
label = self . _current_media . GetTitleString ( )
if len ( label ) > 0 :
2019-11-14 03:56:30 +00:00
self . _title_text . setText ( label )
2015-06-17 20:01:41 +00:00
2019-11-14 03:56:30 +00:00
self . _title_text . show ( )
2015-06-17 20:01:41 +00:00
2019-11-14 03:56:30 +00:00
else : self . _title_text . hide ( )
2015-06-17 20:01:41 +00:00
2022-05-04 21:40:27 +00:00
lines = self . _current_media . GetPrettyInfoLines ( only_interesting_lines = True )
2016-04-20 20:42:21 +00:00
label = ' | ' . join ( lines )
2015-06-17 20:01:41 +00:00
2019-11-14 03:56:30 +00:00
self . _info_text . setText ( label )
2015-06-17 20:01:41 +00:00
2019-11-14 03:56:30 +00:00
self . _info_text . show ( )
2015-06-17 20:01:41 +00:00
2018-12-05 22:35:30 +00:00
def _FlipActiveDefaultCustomShortcut ( self , name ) :
2017-04-19 20:58:30 +00:00
2017-12-06 22:06:56 +00:00
new_options = HG . client_controller . new_options
2017-04-19 20:58:30 +00:00
2018-12-05 22:35:30 +00:00
default_media_viewer_custom_shortcuts = list ( new_options . GetStringList ( ' default_media_viewer_custom_shortcuts ' ) )
if name in default_media_viewer_custom_shortcuts :
default_media_viewer_custom_shortcuts . remove ( name )
else :
default_media_viewer_custom_shortcuts . append ( name )
default_media_viewer_custom_shortcuts . sort ( )
new_options . SetStringList ( ' default_media_viewer_custom_shortcuts ' , default_media_viewer_custom_shortcuts )
2022-11-09 22:24:07 +00:00
def _ShowFileEmbeddedMetadata ( self ) :
2022-07-27 21:18:33 +00:00
if self . _current_media is None :
return
2022-11-09 22:24:07 +00:00
ClientGUIMediaActions . ShowFileEmbeddedMetadata ( self , self . _current_media )
2022-07-27 21:18:33 +00:00
2018-12-05 22:35:30 +00:00
def _ShowShortcutMenu ( self ) :
2017-04-19 20:58:30 +00:00
2019-06-05 19:42:39 +00:00
all_shortcut_names = HG . client_controller . Read ( ' serialisable_names ' , HydrusSerialisable . SERIALISABLE_TYPE_SHORTCUT_SET )
2017-04-19 20:58:30 +00:00
2020-02-19 21:48:36 +00:00
custom_shortcuts_names = [ name for name in all_shortcut_names if name not in ClientGUIShortcuts . SHORTCUTS_RESERVED_NAMES ]
2017-04-19 20:58:30 +00:00
2019-11-14 03:56:30 +00:00
menu = QW . QMenu ( )
2022-07-27 21:18:33 +00:00
2020-03-25 21:15:57 +00:00
ClientGUIMenus . AppendMenuItem ( menu , ' edit shortcuts ' , ' edit your sets of shortcuts, and change what shortcuts are currently active on this media viewer ' , ClientGUIShortcutControls . ManageShortcuts , self )
2018-12-05 22:35:30 +00:00
if len ( custom_shortcuts_names ) > 0 :
2017-04-19 20:58:30 +00:00
2018-12-05 22:35:30 +00:00
my_canvas_active_custom_shortcuts = self . _my_canvas . GetActiveCustomShortcutNames ( )
default_media_viewer_custom_shortcuts = HG . client_controller . new_options . GetStringList ( ' default_media_viewer_custom_shortcuts ' )
2017-04-19 20:58:30 +00:00
2019-11-14 03:56:30 +00:00
current_menu = QW . QMenu ( menu )
2017-04-19 20:58:30 +00:00
2018-12-05 22:35:30 +00:00
for name in custom_shortcuts_names :
2019-11-14 03:56:30 +00:00
ClientGUIMenus . AppendMenuCheckItem ( current_menu , name , ' turn this shortcut set on/off ' , name in my_canvas_active_custom_shortcuts , self . _my_canvas . FlipActiveCustomShortcutName , name )
2018-12-05 22:35:30 +00:00
2017-04-19 20:58:30 +00:00
2018-12-05 22:35:30 +00:00
ClientGUIMenus . AppendMenu ( menu , current_menu , ' set current shortcuts ' )
2017-04-19 20:58:30 +00:00
2019-11-14 03:56:30 +00:00
defaults_menu = QW . QMenu ( menu )
2017-04-19 20:58:30 +00:00
2018-12-05 22:35:30 +00:00
for name in custom_shortcuts_names :
2017-04-19 20:58:30 +00:00
2019-11-14 03:56:30 +00:00
ClientGUIMenus . AppendMenuCheckItem ( defaults_menu , name , ' turn this shortcut set on/off by default ' , name in default_media_viewer_custom_shortcuts , self . _FlipActiveDefaultCustomShortcut , name )
2017-04-19 20:58:30 +00:00
2018-12-05 22:35:30 +00:00
ClientGUIMenus . AppendMenu ( menu , defaults_menu , ' set default shortcuts ' )
2020-03-04 22:12:53 +00:00
CGC . core ( ) . PopupMenu ( self , menu )
2017-04-19 20:58:30 +00:00
2019-11-14 03:56:30 +00:00
def EventDragButton ( self ) :
2018-03-28 21:55:58 +00:00
if self . _current_media is None :
2019-11-14 03:56:30 +00:00
return True # was: event.ignore()
2018-03-28 21:55:58 +00:00
page_key = None
media = [ self . _current_media ]
2019-11-14 03:56:30 +00:00
alt_down = QW . QApplication . keyboardModifiers ( ) & QC . Qt . AltModifier
2018-03-28 21:55:58 +00:00
2020-03-11 21:52:11 +00:00
result = ClientGUIDragDrop . DoFileExportDragDrop ( self , page_key , media , alt_down )
2018-03-28 21:55:58 +00:00
2019-11-14 03:56:30 +00:00
if result != QC . Qt . IgnoreAction :
2018-03-28 21:55:58 +00:00
2022-05-04 21:40:27 +00:00
self . sendApplicationCommand . emit ( CAC . ApplicationCommand . STATICCreateSimpleCommand ( CAC . SIMPLE_PAUSE_MEDIA ) )
2018-03-28 21:55:58 +00:00
2019-11-14 03:56:30 +00:00
def resizeEvent ( self , event ) :
# reset wrap width
self . _ResetText ( )
event . ignore ( )
2015-06-17 20:01:41 +00:00
def ProcessContentUpdates ( self , service_keys_to_content_updates ) :
if self . _current_media is not None :
my_hash = self . _current_media . GetHash ( )
do_redraw = False
2021-04-28 21:43:16 +00:00
for ( service_key , content_updates ) in service_keys_to_content_updates . items ( ) :
2015-06-17 20:01:41 +00:00
if True in ( my_hash in content_update . GetHashes ( ) for content_update in content_updates ) :
do_redraw = True
break
if do_redraw :
2021-08-18 21:10:01 +00:00
self . _ResetText ( )
2015-06-17 20:01:41 +00:00
self . _ResetButtons ( )
2022-08-17 20:54:59 +00:00
def SetCurrentZoom ( self , zoom : float ) :
2015-06-17 20:01:41 +00:00
2022-08-17 20:54:59 +00:00
self . _current_zoom = zoom
label = ClientData . ConvertZoomToPercentage ( self . _current_zoom )
self . _zoom_text . setText ( label )
2015-06-17 20:01:41 +00:00
def SetDisplayMedia ( self , canvas_key , media ) :
if canvas_key == self . _canvas_key :
2020-03-25 21:15:57 +00:00
CanvasHoverFrame . SetDisplayMedia ( self , canvas_key , media )
2015-06-17 20:01:41 +00:00
self . _ResetText ( )
2017-03-29 19:39:34 +00:00
self . _ResetButtons ( )
2015-07-15 20:28:26 +00:00
2019-12-11 23:18:37 +00:00
# minimumsize is not immediately updated without this
self . layout ( ) . activate ( )
self . _SizeAndPosition ( force = True )
2015-06-17 20:01:41 +00:00
def SetIndexString ( self , canvas_key , text ) :
if canvas_key == self . _canvas_key :
self . _current_index_string = text
2019-11-14 03:56:30 +00:00
self . _index_text . setText ( self . _current_index_string )
2015-06-17 20:01:41 +00:00
2020-03-25 21:15:57 +00:00
class CanvasHoverFrameTopArchiveDeleteFilter ( CanvasHoverFrameTop ) :
2017-05-10 21:33:58 +00:00
def _Archive ( self ) :
2022-05-04 21:40:27 +00:00
self . sendApplicationCommand . emit ( CAC . ApplicationCommand . STATICCreateSimpleCommand ( CAC . SIMPLE_ARCHIVE_FILE ) )
2017-05-10 21:33:58 +00:00
def _PopulateLeftButtons ( self ) :
2022-05-04 21:40:27 +00:00
self . _back_button = ClientGUICommon . BetterBitmapButton ( self , CC . global_pixmaps ( ) . previous , self . sendApplicationCommand . emit , CAC . ApplicationCommand . STATICCreateSimpleCommand ( CAC . SIMPLE_ARCHIVE_DELETE_FILTER_BACK ) )
2020-07-08 22:00:33 +00:00
self . _back_button . SetToolTipWithShortcuts ( ' back ' , CAC . SIMPLE_ARCHIVE_DELETE_FILTER_BACK )
2022-04-13 21:39:26 +00:00
self . _back_button . setFocusPolicy ( QC . Qt . TabFocus )
2017-05-31 21:50:53 +00:00
2020-07-29 20:52:44 +00:00
QP . AddToLayout ( self . _top_hbox , self . _back_button , CC . FLAGS_CENTER_PERPENDICULAR )
2017-05-31 21:50:53 +00:00
2020-03-25 21:15:57 +00:00
CanvasHoverFrameTop . _PopulateLeftButtons ( self )
2017-05-10 21:33:58 +00:00
2022-05-04 21:40:27 +00:00
self . _skip_button = ClientGUICommon . BetterBitmapButton ( self , CC . global_pixmaps ( ) . next_bmp , self . sendApplicationCommand . emit , CAC . ApplicationCommand . STATICCreateSimpleCommand ( CAC . SIMPLE_ARCHIVE_DELETE_FILTER_SKIP ) )
2020-07-08 22:00:33 +00:00
self . _skip_button . SetToolTipWithShortcuts ( ' skip ' , CAC . SIMPLE_ARCHIVE_DELETE_FILTER_SKIP )
2022-04-13 21:39:26 +00:00
self . _skip_button . setFocusPolicy ( QC . Qt . TabFocus )
2017-05-31 21:50:53 +00:00
2020-07-29 20:52:44 +00:00
QP . AddToLayout ( self . _top_hbox , self . _skip_button , CC . FLAGS_CENTER_PERPENDICULAR )
2017-05-10 21:33:58 +00:00
def _ResetArchiveButton ( self ) :
2020-03-11 21:52:11 +00:00
ClientGUIFunctions . SetBitmapButtonBitmap ( self . _archive_button , CC . global_pixmaps ( ) . archive )
2019-11-14 03:56:30 +00:00
self . _archive_button . setToolTip ( ' archive ' )
2017-05-10 21:33:58 +00:00
2020-03-25 21:15:57 +00:00
class CanvasHoverFrameTopNavigable ( CanvasHoverFrameTop ) :
2017-05-31 21:50:53 +00:00
def _PopulateLeftButtons ( self ) :
2022-05-04 21:40:27 +00:00
self . _previous_button = ClientGUICommon . BetterBitmapButton ( self , CC . global_pixmaps ( ) . previous , self . sendApplicationCommand . emit , CAC . ApplicationCommand . STATICCreateSimpleCommand ( CAC . SIMPLE_VIEW_PREVIOUS ) )
2020-07-08 22:00:33 +00:00
self . _previous_button . SetToolTipWithShortcuts ( ' previous ' , CAC . SIMPLE_VIEW_PREVIOUS )
2022-04-13 21:39:26 +00:00
self . _previous_button . setFocusPolicy ( QC . Qt . TabFocus )
2017-05-31 21:50:53 +00:00
self . _index_text = ClientGUICommon . BetterStaticText ( self , ' index ' )
2022-05-04 21:40:27 +00:00
self . _next_button = ClientGUICommon . BetterBitmapButton ( self , CC . global_pixmaps ( ) . next_bmp , self . sendApplicationCommand . emit , CAC . ApplicationCommand . STATICCreateSimpleCommand ( CAC . SIMPLE_VIEW_NEXT ) )
2020-07-08 22:00:33 +00:00
self . _next_button . SetToolTipWithShortcuts ( ' next ' , CAC . SIMPLE_VIEW_NEXT )
2022-04-13 21:39:26 +00:00
self . _next_button . setFocusPolicy ( QC . Qt . TabFocus )
2017-05-31 21:50:53 +00:00
2020-07-29 20:52:44 +00:00
QP . AddToLayout ( self . _top_hbox , self . _previous_button , CC . FLAGS_CENTER_PERPENDICULAR )
QP . AddToLayout ( self . _top_hbox , self . _index_text , CC . FLAGS_CENTER_PERPENDICULAR )
QP . AddToLayout ( self . _top_hbox , self . _next_button , CC . FLAGS_CENTER_PERPENDICULAR )
2017-05-31 21:50:53 +00:00
2020-03-25 21:15:57 +00:00
class CanvasHoverFrameTopDuplicatesFilter ( CanvasHoverFrameTopNavigable ) :
2017-03-29 19:39:34 +00:00
def _PopulateLeftButtons ( self ) :
2022-05-04 21:40:27 +00:00
self . _first_button = ClientGUICommon . BetterBitmapButton ( self , CC . global_pixmaps ( ) . first , self . sendApplicationCommand . emit , CAC . ApplicationCommand . STATICCreateSimpleCommand ( CAC . SIMPLE_DUPLICATE_FILTER_BACK ) )
2020-07-08 22:00:33 +00:00
self . _first_button . SetToolTipWithShortcuts ( ' go back a pair ' , CAC . SIMPLE_DUPLICATE_FILTER_BACK )
2022-04-13 21:39:26 +00:00
self . _first_button . setFocusPolicy ( QC . Qt . TabFocus )
2017-05-17 21:53:02 +00:00
2020-07-29 20:52:44 +00:00
QP . AddToLayout ( self . _top_hbox , self . _first_button , CC . FLAGS_CENTER_PERPENDICULAR )
2017-05-17 21:53:02 +00:00
2020-03-25 21:15:57 +00:00
CanvasHoverFrameTopNavigable . _PopulateLeftButtons ( self )
2017-03-29 19:39:34 +00:00
2022-05-04 21:40:27 +00:00
self . _last_button = ClientGUICommon . BetterBitmapButton ( self , CC . global_pixmaps ( ) . last , self . sendApplicationCommand . emit , CAC . ApplicationCommand . STATICCreateSimpleCommand ( CAC . SIMPLE_DUPLICATE_FILTER_SKIP ) )
2020-07-08 22:00:33 +00:00
self . _last_button . SetToolTipWithShortcuts ( ' show a different pair ' , CAC . SIMPLE_DUPLICATE_FILTER_SKIP )
2022-04-13 21:39:26 +00:00
self . _last_button . setFocusPolicy ( QC . Qt . TabFocus )
2017-03-29 19:39:34 +00:00
2020-07-29 20:52:44 +00:00
QP . AddToLayout ( self . _top_hbox , self . _last_button , CC . FLAGS_CENTER_PERPENDICULAR )
2017-03-29 19:39:34 +00:00
2020-03-25 21:15:57 +00:00
class CanvasHoverFrameTopNavigableList ( CanvasHoverFrameTopNavigable ) :
2017-03-29 19:39:34 +00:00
def _PopulateLeftButtons ( self ) :
2022-05-04 21:40:27 +00:00
self . _first_button = ClientGUICommon . BetterBitmapButton ( self , CC . global_pixmaps ( ) . first , self . sendApplicationCommand . emit , CAC . ApplicationCommand . STATICCreateSimpleCommand ( CAC . SIMPLE_VIEW_FIRST ) )
2020-07-08 22:00:33 +00:00
self . _first_button . SetToolTipWithShortcuts ( ' first ' , CAC . SIMPLE_VIEW_FIRST )
2022-04-13 21:39:26 +00:00
self . _first_button . setFocusPolicy ( QC . Qt . TabFocus )
2017-03-29 19:39:34 +00:00
2020-07-29 20:52:44 +00:00
QP . AddToLayout ( self . _top_hbox , self . _first_button , CC . FLAGS_CENTER_PERPENDICULAR )
2017-03-29 19:39:34 +00:00
2020-03-25 21:15:57 +00:00
CanvasHoverFrameTopNavigable . _PopulateLeftButtons ( self )
2017-03-29 19:39:34 +00:00
2022-05-04 21:40:27 +00:00
self . _last_button = ClientGUICommon . BetterBitmapButton ( self , CC . global_pixmaps ( ) . last , self . sendApplicationCommand . emit , CAC . ApplicationCommand . STATICCreateSimpleCommand ( CAC . SIMPLE_VIEW_LAST ) )
2020-07-08 22:00:33 +00:00
self . _last_button . SetToolTipWithShortcuts ( ' last ' , CAC . SIMPLE_VIEW_LAST )
2022-04-13 21:39:26 +00:00
self . _last_button . setFocusPolicy ( QC . Qt . TabFocus )
2017-03-29 19:39:34 +00:00
2020-07-29 20:52:44 +00:00
QP . AddToLayout ( self . _top_hbox , self . _last_button , CC . FLAGS_CENTER_PERPENDICULAR )
2017-03-29 19:39:34 +00:00
2020-03-25 21:15:57 +00:00
class CanvasHoverFrameTopRight ( CanvasHoverFrame ) :
2015-06-17 20:01:41 +00:00
2020-08-05 20:10:36 +00:00
def __init__ ( self , parent , my_canvas , top_hover : CanvasHoverFrameTop , canvas_key ) :
2015-06-17 20:01:41 +00:00
2020-03-25 21:15:57 +00:00
CanvasHoverFrame . __init__ ( self , parent , my_canvas , canvas_key )
2015-06-17 20:01:41 +00:00
2020-08-05 20:10:36 +00:00
self . _top_hover = top_hover
2019-11-14 03:56:30 +00:00
vbox = QP . VBoxLayout ( )
2015-06-17 20:01:41 +00:00
2019-11-14 03:56:30 +00:00
self . _icon_panel = QW . QWidget ( self )
2015-06-17 20:01:41 +00:00
2020-03-11 21:52:11 +00:00
self . _trash_icon = ClientGUICommon . BufferedWindowIcon ( self . _icon_panel , CC . global_pixmaps ( ) . trash )
2020-05-06 21:31:41 +00:00
self . _inbox_icon = ClientGUICommon . BufferedWindowIcon ( self . _icon_panel , CC . global_pixmaps ( ) . inbox , click_callable = self . _Archive )
2015-06-17 20:01:41 +00:00
2019-11-14 03:56:30 +00:00
icon_hbox = QP . HBoxLayout ( spacing = 0 )
2015-06-17 20:01:41 +00:00
2020-07-22 20:59:16 +00:00
icon_hbox . addStretch ( 1 )
2020-07-29 20:52:44 +00:00
QP . AddToLayout ( icon_hbox , self . _inbox_icon , CC . FLAGS_CENTER_PERPENDICULAR )
QP . AddToLayout ( icon_hbox , self . _trash_icon , CC . FLAGS_CENTER_PERPENDICULAR )
2015-06-17 20:01:41 +00:00
2019-11-14 03:56:30 +00:00
self . _icon_panel . setLayout ( icon_hbox )
2015-06-17 20:01:41 +00:00
# repo strings
2022-03-30 20:28:13 +00:00
self . _file_repos = ClientGUICommon . BetterStaticText ( self , ' ' )
self . _file_repos . setAlignment ( QC . Qt . AlignRight | QC . Qt . AlignVCenter )
2015-06-17 20:01:41 +00:00
2017-04-26 21:58:12 +00:00
# urls
self . _last_seen_urls = [ ]
2019-11-14 03:56:30 +00:00
self . _urls_vbox = QP . VBoxLayout ( )
2017-04-26 21:58:12 +00:00
2015-06-17 20:01:41 +00:00
# likes
2019-11-14 03:56:30 +00:00
like_hbox = QP . HBoxLayout ( spacing = 0 )
2015-06-17 20:01:41 +00:00
2020-03-11 21:52:11 +00:00
like_services = HG . client_controller . services_manager . GetServices ( ( HC . LOCAL_RATING_LIKE , ) )
2015-06-17 20:01:41 +00:00
2018-08-15 20:40:30 +00:00
if len ( like_services ) > 0 :
2020-07-22 20:59:16 +00:00
like_hbox . addStretch ( 1 )
2018-08-15 20:40:30 +00:00
2015-06-17 20:01:41 +00:00
for service in like_services :
service_key = service . GetServiceKey ( )
2020-03-25 21:15:57 +00:00
control = RatingLikeCanvas ( self , service_key , canvas_key )
2015-06-17 20:01:41 +00:00
2019-11-14 03:56:30 +00:00
QP . AddToLayout ( like_hbox , control , CC . FLAGS_NONE )
2015-06-17 20:01:41 +00:00
# each numerical one in turn
2019-11-14 03:56:30 +00:00
QP . AddToLayout ( vbox , like_hbox , CC . FLAGS_EXPAND_SIZER_BOTH_WAYS )
2015-06-17 20:01:41 +00:00
2020-03-11 21:52:11 +00:00
numerical_services = HG . client_controller . services_manager . GetServices ( ( HC . LOCAL_RATING_NUMERICAL , ) )
2015-06-17 20:01:41 +00:00
for service in numerical_services :
service_key = service . GetServiceKey ( )
2020-03-25 21:15:57 +00:00
control = RatingNumericalCanvas ( self , service_key , canvas_key )
2015-06-17 20:01:41 +00:00
2020-07-22 20:59:16 +00:00
QP . AddToLayout ( vbox , control , CC . FLAGS_NONE )
2015-06-17 20:01:41 +00:00
2020-07-22 20:59:16 +00:00
vbox . setAlignment ( control , QC . Qt . AlignRight )
2015-06-17 20:01:41 +00:00
2019-11-14 03:56:30 +00:00
QP . AddToLayout ( vbox , self . _icon_panel , CC . FLAGS_EXPAND_SIZER_PERPENDICULAR )
QP . AddToLayout ( vbox , self . _file_repos , CC . FLAGS_EXPAND_PERPENDICULAR )
QP . AddToLayout ( vbox , self . _urls_vbox , CC . FLAGS_EXPAND_SIZER_PERPENDICULAR )
2017-05-10 21:33:58 +00:00
2019-11-14 03:56:30 +00:00
self . setLayout ( vbox )
2015-06-17 20:01:41 +00:00
self . _ResetData ( )
2017-05-10 21:33:58 +00:00
HG . client_controller . sub ( self , ' ProcessContentUpdates ' , ' content_updates_gui ' )
2015-09-16 18:11:00 +00:00
2015-06-17 20:01:41 +00:00
2020-05-06 21:31:41 +00:00
def _Archive ( self ) :
if self . _current_media . HasInbox ( ) :
2021-08-25 21:59:05 +00:00
command = CAC . ApplicationCommand . STATICCreateSimpleCommand ( CAC . SIMPLE_ARCHIVE_FILE )
2020-05-06 21:31:41 +00:00
else :
2021-08-25 21:59:05 +00:00
command = CAC . ApplicationCommand . STATICCreateSimpleCommand ( CAC . SIMPLE_INBOX_FILE )
2020-05-06 21:31:41 +00:00
2022-05-04 21:40:27 +00:00
self . sendApplicationCommand . emit ( command )
2020-05-06 21:31:41 +00:00
2015-06-17 20:01:41 +00:00
def _GetIdealSizeAndPosition ( self ) :
2019-11-14 03:56:30 +00:00
parent_window = self . parentWidget ( ) . window ( )
2015-06-17 20:01:41 +00:00
2020-02-26 22:28:52 +00:00
parent_size = parent_window . size ( )
parent_width = parent_size . width ( )
2015-06-17 20:01:41 +00:00
2020-02-26 22:28:52 +00:00
my_size = self . size ( )
my_width = my_size . width ( )
my_height = my_size . height ( )
2015-06-17 20:01:41 +00:00
2022-04-06 20:40:17 +00:00
my_ideal_width = self . sizeHint ( ) . width ( )
2020-08-19 22:38:20 +00:00
2022-04-06 20:40:17 +00:00
if not self . _top_hover . PositionIsInitialised ( ) :
self . _top_hover . DoRegularHideShow ( )
2020-08-05 20:10:36 +00:00
2022-04-06 20:40:17 +00:00
if self . _top_hover . PositionIsInitialised ( ) :
# don't use .rect() here, it (sometimes) isn't updated on a hidden window until next show, I think
top_hover_bottom_right = QC . QPoint ( self . _top_hover . x ( ) + self . _top_hover . width ( ) , self . _top_hover . y ( ) + self . _top_hover . height ( ) )
width_beside_top_hover = parent_window . rect ( ) . topRight ( ) . x ( ) - top_hover_bottom_right . x ( )
my_ideal_width = max ( my_ideal_width , width_beside_top_hover )
2015-06-17 20:01:41 +00:00
2020-07-22 20:59:16 +00:00
my_ideal_height = self . sizeHint ( ) . height ( )
2015-06-17 20:01:41 +00:00
2019-11-14 03:56:30 +00:00
should_resize = my_ideal_width != my_width or my_ideal_height != my_height
2020-02-26 22:28:52 +00:00
ideal_size = QC . QSize ( my_ideal_width , my_ideal_height )
2020-08-05 20:10:36 +00:00
2022-04-06 20:40:17 +00:00
ideal_position = QC . QPoint ( int ( parent_width - my_ideal_width ) , 0 )
2015-06-17 20:01:41 +00:00
2022-04-06 20:40:17 +00:00
if self . _top_hover . PositionIsInitialised ( ) :
2020-08-05 20:10:36 +00:00
2022-04-06 20:40:17 +00:00
if top_hover_bottom_right . x ( ) > ideal_position . x ( ) :
ideal_position . setY ( top_hover_bottom_right . y ( ) )
2020-08-05 20:10:36 +00:00
2020-02-26 22:28:52 +00:00
return ( should_resize , ideal_size , ideal_position )
2015-06-17 20:01:41 +00:00
def _ResetData ( self ) :
if self . _current_media is not None :
2015-07-08 21:45:38 +00:00
has_inbox = self . _current_media . HasInbox ( )
2021-04-28 21:43:16 +00:00
has_trash = self . _current_media . GetLocationsManager ( ) . IsTrashed ( )
2015-07-08 21:45:38 +00:00
2022-04-06 20:40:17 +00:00
if has_inbox or has_trash :
2015-06-17 20:01:41 +00:00
2019-11-14 03:56:30 +00:00
self . _icon_panel . show ( )
2015-06-17 20:01:41 +00:00
2015-07-08 21:45:38 +00:00
if has_inbox :
2019-11-14 03:56:30 +00:00
self . _inbox_icon . show ( )
2015-07-08 21:45:38 +00:00
else :
2019-11-14 03:56:30 +00:00
self . _inbox_icon . hide ( )
2015-07-08 21:45:38 +00:00
if has_trash :
2019-11-14 03:56:30 +00:00
self . _trash_icon . show ( )
2015-07-08 21:45:38 +00:00
else :
2019-11-14 03:56:30 +00:00
self . _trash_icon . hide ( )
2015-07-08 21:45:38 +00:00
2015-06-17 20:01:41 +00:00
else :
2019-11-14 03:56:30 +00:00
self . _icon_panel . setVisible ( False )
2015-06-17 20:01:41 +00:00
2016-02-24 21:42:54 +00:00
remote_strings = self . _current_media . GetLocationsManager ( ) . GetRemoteLocationStrings ( )
2015-06-17 20:01:41 +00:00
2016-02-24 21:42:54 +00:00
if len ( remote_strings ) == 0 :
2015-06-17 20:01:41 +00:00
2019-11-14 03:56:30 +00:00
self . _file_repos . hide ( )
2015-06-17 20:01:41 +00:00
else :
2016-02-24 21:42:54 +00:00
remote_string = os . linesep . join ( remote_strings )
2015-06-17 20:01:41 +00:00
2019-11-14 03:56:30 +00:00
self . _file_repos . setText ( remote_string )
2015-06-17 20:01:41 +00:00
2019-11-14 03:56:30 +00:00
self . _file_repos . show ( )
2015-06-17 20:01:41 +00:00
2017-04-26 21:58:12 +00:00
# urls
urls = self . _current_media . GetLocationsManager ( ) . GetURLs ( )
if urls != self . _last_seen_urls :
self . _last_seen_urls = list ( urls )
2019-12-05 05:29:32 +00:00
QP . ClearLayout ( self . _urls_vbox , delete_widgets = True )
2017-04-26 21:58:12 +00:00
2017-12-06 22:06:56 +00:00
url_tuples = HG . client_controller . network_engine . domain_manager . ConvertURLsToMediaViewerTuples ( urls )
for ( display_string , url ) in url_tuples :
2017-04-26 21:58:12 +00:00
2018-08-29 20:20:41 +00:00
link = ClientGUICommon . BetterHyperLink ( self , display_string , url )
2017-09-20 19:47:31 +00:00
2020-07-22 20:59:16 +00:00
link . setAlignment ( QC . Qt . AlignRight )
2019-12-05 05:29:32 +00:00
2020-07-22 20:59:16 +00:00
QP . AddToLayout ( self . _urls_vbox , link , CC . FLAGS_EXPAND_PERPENDICULAR )
2019-12-05 05:29:32 +00:00
2015-06-17 20:01:41 +00:00
self . _SizeAndPosition ( )
def ProcessContentUpdates ( self , service_keys_to_content_updates ) :
if self . _current_media is not None :
my_hash = self . _current_media . GetHash ( )
do_redraw = False
2021-04-28 21:43:16 +00:00
for ( service_key , content_updates ) in service_keys_to_content_updates . items ( ) :
2015-06-17 20:01:41 +00:00
2017-07-27 00:47:13 +00:00
# ratings updates do not change the shape of this hover but file changes of several kinds do
if True in ( my_hash in content_update . GetHashes ( ) for content_update in content_updates if content_update . GetDataType ( ) == HC . CONTENT_TYPE_FILES ) :
2015-06-17 20:01:41 +00:00
2017-05-10 21:33:58 +00:00
do_redraw = True
break
2015-06-17 20:01:41 +00:00
if do_redraw :
self . _ResetData ( )
def SetDisplayMedia ( self , canvas_key , media ) :
if canvas_key == self . _canvas_key :
2020-03-25 21:15:57 +00:00
CanvasHoverFrame . SetDisplayMedia ( self , canvas_key , media )
2015-06-17 20:01:41 +00:00
self . _ResetData ( )
2015-07-15 20:28:26 +00:00
2020-07-22 20:59:16 +00:00
# size is not immediately updated without this
2019-12-11 23:18:37 +00:00
self . layout ( ) . activate ( )
self . _SizeAndPosition ( force = True )
2015-07-15 20:28:26 +00:00
2017-04-19 20:58:30 +00:00
2022-04-13 21:39:26 +00:00
class NotePanel ( QW . QWidget ) :
editNote = QC . Signal ( str )
def __init__ ( self , parent : QW . QWidget , name : str , note : str , note_visible : bool ) :
QW . QWidget . __init__ ( self , parent )
self . _name = name
self . _note_visible = note_visible
self . _note_name = ClientGUICommon . BetterStaticText ( self , label = name )
self . _note_name . setAlignment ( QC . Qt . AlignHCenter )
self . _note_name . setWordWrap ( True )
font = QG . QFont ( self . _note_name . font ( ) )
font . setBold ( True )
self . _note_name . setFont ( font )
self . _note_text = ClientGUICommon . BetterStaticText ( self , label = note )
self . _note_text . setAlignment ( QC . Qt . AlignJustify )
self . _note_text . setWordWrap ( True )
vbox = QP . VBoxLayout ( margin = 0 )
QP . AddToLayout ( vbox , self . _note_name , CC . FLAGS_EXPAND_PERPENDICULAR )
2022-08-24 21:06:25 +00:00
QP . AddToLayout ( vbox , self . _note_text , CC . FLAGS_EXPAND_PERPENDICULAR )
2022-04-13 21:39:26 +00:00
self . _note_text . setVisible ( self . _note_visible )
self . setLayout ( vbox )
self . _note_name . installEventFilter ( self )
self . _note_text . installEventFilter ( self )
def eventFilter ( self , object , event ) :
if event . type ( ) == QC . QEvent . MouseButtonPress :
if event . button ( ) == QC . Qt . LeftButton :
self . editNote . emit ( self . _name )
else :
self . _note_text . setVisible ( not self . _note_text . isVisible ( ) )
self . _note_visible = self . _note_text . isVisible ( )
return True
2022-09-07 21:16:25 +00:00
return False
2022-04-13 21:39:26 +00:00
def heightForWidth ( self , width : int ) :
spacing = self . layout ( ) . spacing ( )
2022-05-04 21:40:27 +00:00
margin = self . layout ( ) . contentsMargins ( ) . top ( )
2022-04-13 21:39:26 +00:00
2022-08-24 21:06:25 +00:00
total_height = 0
expected_widget_height = self . _note_name . heightForWidth ( width )
if self . _note_name . width ( ) > = width and self . _note_name . height ( ) > expected_widget_height :
# there's some mysterious padding that I can't explain, probably a layout flag legacy issue, so we override here if the width seems correct
expected_widget_height = self . _note_name . height ( )
total_height + = expected_widget_height
2022-04-13 21:39:26 +00:00
if self . _note_text . isVisibleTo ( self ) :
2022-08-24 21:06:25 +00:00
total_height + = spacing
2022-04-13 21:39:26 +00:00
2022-08-24 21:06:25 +00:00
expected_widget_height = self . _note_text . heightForWidth ( width )
if self . _note_text . width ( ) > = width and self . _note_text . height ( ) > expected_widget_height :
# there's some mysterious padding that I can't explain, probably a layout flag legacy issue, so we override here if the width seems correct
expected_widget_height = self . _note_text . height ( )
total_height + = expected_widget_height
2022-04-13 21:39:26 +00:00
2022-08-24 21:06:25 +00:00
total_height + = margin * 2
return total_height
2022-04-13 21:39:26 +00:00
def IsNoteVisible ( self ) - > bool :
return self . _note_visible
2022-04-06 20:40:17 +00:00
class CanvasHoverFrameRightNotes ( CanvasHoverFrame ) :
def __init__ ( self , parent , my_canvas , top_right_hover : CanvasHoverFrameTopRight , canvas_key ) :
CanvasHoverFrame . __init__ ( self , parent , my_canvas , canvas_key )
self . _top_right_hover = top_right_hover
self . _vbox = QP . VBoxLayout ( )
2022-04-13 21:39:26 +00:00
self . _names_to_note_panels = { }
2022-04-06 20:40:17 +00:00
self . setSizePolicy ( QW . QSizePolicy . Fixed , QW . QSizePolicy . Expanding )
self . setLayout ( self . _vbox )
self . _ResetNotes ( )
HG . client_controller . sub ( self , ' ProcessContentUpdates ' , ' content_updates_gui ' )
def _EditNotes ( self , name ) :
2022-04-13 21:39:26 +00:00
ClientGUIMediaActions . EditFileNotes ( self , self . _current_media , name_to_start_on = name )
2022-04-06 20:40:17 +00:00
def _GetIdealSizeAndPosition ( self ) :
2022-04-13 21:39:26 +00:00
if len ( self . _names_to_note_panels ) == 0 :
2022-04-06 20:40:17 +00:00
2022-04-13 21:39:26 +00:00
return ( True , QC . QSize ( 20 , 20 ) , QC . QPoint ( - 100 , - 100 ) )
2022-04-06 20:40:17 +00:00
parent_window = self . parentWidget ( ) . window ( )
parent_size = parent_window . size ( )
parent_width = parent_size . width ( )
my_size = self . size ( )
my_width = my_size . width ( )
my_height = my_size . height ( )
my_ideal_width = self . sizeHint ( ) . width ( )
ideal_position = QC . QPoint ( parent_width - my_width , 0 )
if not self . _top_right_hover . PositionIsInitialised ( ) :
self . _top_right_hover . DoRegularHideShow ( )
if self . _top_right_hover . PositionIsInitialised ( ) :
my_ideal_width = self . _top_right_hover . width ( )
ideal_position = self . _top_right_hover . geometry ( ) . bottomRight ( ) + QC . QPoint ( 0 , 2 ) - QC . QPoint ( my_ideal_width , 0 )
max_possible_height = parent_size . height ( ) - ideal_position . y ( )
# now let's go full meme
# the problem here is that sizeHint produces what width the static text wants based on its own word wrap rules
# we want to say 'with this fixed width, how tall are we?'
# VBoxLayout doesn't support heightForWidth, but statictext does, so let's hack it
# ideal solution here is to write a new layout that delivers heightforwidth, but lmao. maybe Qt6 will do it
2022-04-13 21:39:26 +00:00
spacing = self . layout ( ) . spacing ( )
2022-05-04 21:40:27 +00:00
margin = self . layout ( ) . contentsMargins ( ) . top ( )
2022-04-13 21:39:26 +00:00
2022-08-24 21:06:25 +00:00
my_axis_frame_width = self . frameWidth ( ) * 2
my_axis_margin = margin * 2
note_panel_width = my_ideal_width - ( my_axis_frame_width + my_axis_margin )
best_guess_at_height_for_width = sum ( ( spacing + ( margin * 2 ) + note_panel . heightForWidth ( note_panel_width ) for note_panel in self . _names_to_note_panels . values ( ) ) ) - spacing
2022-04-13 21:39:26 +00:00
best_guess_at_height_for_width + = self . frameWidth ( ) * 2
2022-04-06 20:40:17 +00:00
#
my_ideal_height = min ( best_guess_at_height_for_width , max_possible_height )
should_resize = my_ideal_width != my_width or abs ( my_height - my_ideal_height ) > 10
ideal_size = QC . QSize ( my_ideal_width , my_ideal_height )
return ( should_resize , ideal_size , ideal_position )
def _ResetNotes ( self ) :
2022-04-13 21:39:26 +00:00
note_panel_names_with_hidden_notes = set ( )
for ( name , note_panel ) in self . _names_to_note_panels . items ( ) :
if not note_panel . IsNoteVisible ( ) :
note_panel_names_with_hidden_notes . add ( name )
2022-04-06 20:40:17 +00:00
self . _vbox . removeWidget ( note_panel )
note_panel . deleteLater ( )
2022-04-13 21:39:26 +00:00
self . _names_to_note_panels = { }
2022-04-06 20:40:17 +00:00
if self . _current_media is not None and self . _current_media . HasNotes ( ) :
names_to_notes = self . _current_media . GetNotesManager ( ) . GetNamesToNotes ( )
for name in sorted ( names_to_notes . keys ( ) ) :
note = names_to_notes [ name ]
2022-04-13 21:39:26 +00:00
note_visible = name not in note_panel_names_with_hidden_notes
2022-04-06 20:40:17 +00:00
2022-04-13 21:39:26 +00:00
note_panel = NotePanel ( self , name , note , note_visible )
2022-04-06 20:40:17 +00:00
2022-08-24 21:06:25 +00:00
QP . AddToLayout ( self . _vbox , note_panel , CC . FLAGS_EXPAND_PERPENDICULAR )
2022-04-06 20:40:17 +00:00
2022-04-13 21:39:26 +00:00
self . _names_to_note_panels [ name ] = note_panel
2022-04-06 20:40:17 +00:00
2022-04-13 21:39:26 +00:00
note_panel . editNote . connect ( self . _EditNotes )
2022-04-06 20:40:17 +00:00
self . _SizeAndPosition ( )
2022-04-13 21:39:26 +00:00
def _ShouldBeHidden ( self ) :
2022-04-06 20:40:17 +00:00
2022-04-13 21:39:26 +00:00
if len ( self . _names_to_note_panels ) == 0 :
2022-04-06 20:40:17 +00:00
2022-04-13 21:39:26 +00:00
return True
2022-04-06 20:40:17 +00:00
2022-04-13 21:39:26 +00:00
return CanvasHoverFrame . _ShouldBeHidden ( self )
2022-04-06 20:40:17 +00:00
def ProcessContentUpdates ( self , service_keys_to_content_updates ) :
if self . _current_media is not None :
my_hash = self . _current_media . GetHash ( )
do_redraw = False
for ( service_key , content_updates ) in service_keys_to_content_updates . items ( ) :
# ratings updates do not change the shape of this hover but file changes of several kinds do
if True in ( my_hash in content_update . GetHashes ( ) for content_update in content_updates if content_update . GetDataType ( ) == HC . CONTENT_TYPE_NOTES ) :
do_redraw = True
break
if do_redraw :
self . _ResetNotes ( )
def SetDisplayMedia ( self , canvas_key , media ) :
if canvas_key == self . _canvas_key :
CanvasHoverFrame . SetDisplayMedia ( self , canvas_key , media )
if self . _is_currently_up :
# magical refresh that makes the labels look correct and not be hidden???
self . _LowerHover ( )
self . _ResetNotes ( )
self . _RaiseHover ( )
else :
self . _ResetNotes ( )
class CanvasHoverFrameRightDuplicates ( CanvasHoverFrame ) :
2022-06-01 21:19:26 +00:00
showPairInPage = QC . Signal ( )
2022-04-06 20:40:17 +00:00
def __init__ ( self , parent : QW . QWidget , my_canvas : QW . QWidget , right_notes_hover : CanvasHoverFrameRightNotes , canvas_key : bytes ) :
CanvasHoverFrame . __init__ ( self , parent , my_canvas , canvas_key )
self . _right_notes_hover = right_notes_hover
self . _always_on_top = True
self . _current_index_string = ' '
self . _comparison_media = None
2022-06-01 21:19:26 +00:00
self . _show_in_a_page_button = ClientGUICommon . BetterBitmapButton ( self , CC . global_pixmaps ( ) . fullscreen_switch , self . showPairInPage . emit )
self . _show_in_a_page_button . setToolTip ( ' send pair to the duplicates media page, for later processing ' )
self . _show_in_a_page_button . setFocusPolicy ( QC . Qt . TabFocus )
2022-04-06 20:40:17 +00:00
self . _trash_button = ClientGUICommon . BetterBitmapButton ( self , CC . global_pixmaps ( ) . delete , HG . client_controller . pub , ' canvas_delete ' , self . _canvas_key )
self . _trash_button . setToolTip ( ' send to trash ' )
2022-04-13 21:39:26 +00:00
self . _trash_button . setFocusPolicy ( QC . Qt . TabFocus )
2022-04-06 20:40:17 +00:00
menu_items = [ ]
menu_items . append ( ( ' normal ' , ' edit duplicate metadata merge options for \' this is better \' ' , ' edit what content is merged when you filter files ' , HydrusData . Call ( self . _EditMergeOptions , HC . DUPLICATE_BETTER ) ) )
menu_items . append ( ( ' normal ' , ' edit duplicate metadata merge options for \' same quality \' ' , ' edit what content is merged when you filter files ' , HydrusData . Call ( self . _EditMergeOptions , HC . DUPLICATE_SAME_QUALITY ) ) )
if HG . client_controller . new_options . GetBoolean ( ' advanced_mode ' ) :
menu_items . append ( ( ' normal ' , ' edit duplicate metadata merge options for \' alternates \' (advanced!) ' , ' edit what content is merged when you filter files ' , HydrusData . Call ( self . _EditMergeOptions , HC . DUPLICATE_ALTERNATE ) ) )
menu_items . append ( ( ' separator ' , None , None , None ) )
menu_items . append ( ( ' normal ' , ' edit background lighten/darken switch intensity ' , ' edit how much the background will brighten or darken as you switch between the pair ' , self . _EditBackgroundSwitchIntensity ) )
self . _cog_button = ClientGUIMenuButton . MenuBitmapButton ( self , CC . global_pixmaps ( ) . cog , menu_items )
2022-06-08 19:46:00 +00:00
self . _cog_button . setFocusPolicy ( QC . Qt . TabFocus )
2022-04-06 20:40:17 +00:00
close_button = ClientGUICommon . BetterBitmapButton ( self , CC . global_pixmaps ( ) . stop , HG . client_controller . pub , ' canvas_close ' , self . _canvas_key )
close_button . setToolTip ( ' close filter ' )
2022-04-13 21:39:26 +00:00
close_button . setFocusPolicy ( QC . Qt . TabFocus )
2022-04-06 20:40:17 +00:00
2022-05-04 21:40:27 +00:00
self . _back_a_pair = ClientGUICommon . BetterBitmapButton ( self , CC . global_pixmaps ( ) . first , self . sendApplicationCommand . emit , CAC . ApplicationCommand . STATICCreateSimpleCommand ( CAC . SIMPLE_DUPLICATE_FILTER_BACK ) )
2022-04-06 20:40:17 +00:00
self . _back_a_pair . SetToolTipWithShortcuts ( ' go back a pair ' , CAC . SIMPLE_DUPLICATE_FILTER_BACK )
2022-04-13 21:39:26 +00:00
self . _back_a_pair . setFocusPolicy ( QC . Qt . TabFocus )
2022-04-06 20:40:17 +00:00
self . _index_text = ClientGUICommon . BetterStaticText ( self , ' index ' )
2022-05-04 21:40:27 +00:00
self . _next_button = ClientGUICommon . BetterBitmapButton ( self , CC . global_pixmaps ( ) . pair , self . sendApplicationCommand . emit , CAC . ApplicationCommand . STATICCreateSimpleCommand ( CAC . SIMPLE_VIEW_NEXT ) )
2022-04-06 20:40:17 +00:00
self . _next_button . SetToolTipWithShortcuts ( ' next ' , CAC . SIMPLE_VIEW_NEXT )
2022-04-13 21:39:26 +00:00
self . _next_button . setFocusPolicy ( QC . Qt . TabFocus )
2022-04-06 20:40:17 +00:00
2022-05-04 21:40:27 +00:00
self . _skip_a_pair = ClientGUICommon . BetterBitmapButton ( self , CC . global_pixmaps ( ) . last , self . sendApplicationCommand . emit , CAC . ApplicationCommand . STATICCreateSimpleCommand ( CAC . SIMPLE_DUPLICATE_FILTER_SKIP ) )
2022-04-06 20:40:17 +00:00
self . _skip_a_pair . SetToolTipWithShortcuts ( ' show a different pair ' , CAC . SIMPLE_DUPLICATE_FILTER_SKIP )
2022-04-13 21:39:26 +00:00
self . _skip_a_pair . setFocusPolicy ( QC . Qt . TabFocus )
2022-04-06 20:40:17 +00:00
command_button_vbox = QP . VBoxLayout ( )
dupe_boxes = [ ]
dupe_commands = [ ]
dupe_commands . append ( ( ' this is better, and delete the other ' , ' Set that the current file you are looking at is better than the other in the pair, and set the other file to be deleted. ' , CAC . ApplicationCommand . STATICCreateSimpleCommand ( CAC . SIMPLE_DUPLICATE_FILTER_THIS_IS_BETTER_AND_DELETE_OTHER ) ) )
dupe_commands . append ( ( ' this is better, but keep both ' , ' Set that the current file you are looking at is better than the other in the pair, but keep both files. ' , CAC . ApplicationCommand . STATICCreateSimpleCommand ( CAC . SIMPLE_DUPLICATE_FILTER_THIS_IS_BETTER_BUT_KEEP_BOTH ) ) )
dupe_commands . append ( ( ' they are the same quality ' , ' Set that the two files are duplicates of very similar quality. ' , CAC . ApplicationCommand . STATICCreateSimpleCommand ( CAC . SIMPLE_DUPLICATE_FILTER_EXACTLY_THE_SAME ) ) )
dupe_boxes . append ( ( ' they are duplicates ' , dupe_commands ) )
dupe_commands = [ ]
dupe_commands . append ( ( ' they are related alternates ' , ' Set that the files are not duplicates, but that one is derived from the other or that they are both descendants of a common ancestor. ' , CAC . ApplicationCommand . STATICCreateSimpleCommand ( CAC . SIMPLE_DUPLICATE_FILTER_ALTERNATES ) ) )
dupe_commands . append ( ( ' they are not related ' , ' Set that the files are not duplicates or otherwise related--that this potential pair is a false positive match. ' , CAC . ApplicationCommand . STATICCreateSimpleCommand ( CAC . SIMPLE_DUPLICATE_FILTER_FALSE_POSITIVE ) ) )
dupe_commands . append ( ( ' custom action ' , ' Choose one of the other actions but customise the merge and delete options for this specific decision. ' , CAC . ApplicationCommand . STATICCreateSimpleCommand ( CAC . SIMPLE_DUPLICATE_FILTER_CUSTOM_ACTION ) ) )
dupe_boxes . append ( ( ' other ' , dupe_commands ) )
2022-07-20 19:17:03 +00:00
self . _this_is_better_and_delete_other = None
2022-04-06 20:40:17 +00:00
for ( panel_name , dupe_commands ) in dupe_boxes :
button_panel = ClientGUICommon . StaticBox ( self , panel_name )
for ( label , tooltip , command ) in dupe_commands :
2022-05-04 21:40:27 +00:00
command_button = ClientGUICommon . BetterButton ( button_panel , label , self . sendApplicationCommand . emit , command )
2022-04-13 21:39:26 +00:00
command_button . setFocusPolicy ( QC . Qt . TabFocus )
2022-04-06 20:40:17 +00:00
command_button . SetToolTipWithShortcuts ( tooltip , command . GetSimpleAction ( ) )
button_panel . Add ( command_button , CC . FLAGS_EXPAND_PERPENDICULAR )
2022-07-20 19:17:03 +00:00
if command == CAC . ApplicationCommand . STATICCreateSimpleCommand ( CAC . SIMPLE_DUPLICATE_FILTER_THIS_IS_BETTER_AND_DELETE_OTHER ) :
self . _this_is_better_and_delete_other = command_button
2022-04-06 20:40:17 +00:00
QP . AddToLayout ( command_button_vbox , button_panel , CC . FLAGS_EXPAND_PERPENDICULAR )
self . _comparison_statements_vbox = QP . VBoxLayout ( )
2022-11-09 22:24:07 +00:00
self . _comparison_statement_names = [ ' filesize ' , ' resolution ' , ' ratio ' , ' mime ' , ' num_tags ' , ' time_imported ' , ' jpeg_quality ' , ' pixel_duplicates ' , ' exif_data ' , ' embedded_metadata ' , ' icc_profile ' ]
2022-04-06 20:40:17 +00:00
self . _comparison_statements_sts = { }
for name in self . _comparison_statement_names :
panel = QW . QWidget ( self )
st = ClientGUICommon . BetterStaticText ( panel , ' init ' )
self . _comparison_statements_sts [ name ] = ( panel , st )
hbox = QP . HBoxLayout ( )
QP . AddToLayout ( hbox , st , CC . FLAGS_CENTER )
panel . setLayout ( hbox )
panel . setVisible ( False )
QP . AddToLayout ( self . _comparison_statements_vbox , panel , CC . FLAGS_EXPAND_SIZER_PERPENDICULAR )
#
top_button_hbox = QP . HBoxLayout ( )
QP . AddToLayout ( top_button_hbox , self . _next_button , CC . FLAGS_EXPAND_BOTH_WAYS )
2022-06-01 21:19:26 +00:00
QP . AddToLayout ( top_button_hbox , self . _show_in_a_page_button , CC . FLAGS_CENTER_PERPENDICULAR )
2022-04-06 20:40:17 +00:00
QP . AddToLayout ( top_button_hbox , self . _trash_button , CC . FLAGS_CENTER_PERPENDICULAR )
QP . AddToLayout ( top_button_hbox , self . _cog_button , CC . FLAGS_CENTER_PERPENDICULAR )
QP . AddToLayout ( top_button_hbox , close_button , CC . FLAGS_CENTER_PERPENDICULAR )
navigation_button_hbox = QP . HBoxLayout ( )
QP . AddToLayout ( navigation_button_hbox , self . _back_a_pair , CC . FLAGS_CENTER_PERPENDICULAR )
navigation_button_hbox . addStretch ( 1 )
QP . AddToLayout ( navigation_button_hbox , self . _index_text , CC . FLAGS_CENTER_PERPENDICULAR )
navigation_button_hbox . addStretch ( 1 )
QP . AddToLayout ( navigation_button_hbox , self . _skip_a_pair , CC . FLAGS_CENTER_PERPENDICULAR )
vbox = QP . VBoxLayout ( )
QP . AddToLayout ( vbox , navigation_button_hbox , CC . FLAGS_EXPAND_SIZER_PERPENDICULAR )
#QP.AddToLayout( vbox, self._next_button, CC.FLAGS_EXPAND_PERPENDICULAR )
QP . AddToLayout ( vbox , top_button_hbox , CC . FLAGS_EXPAND_PERPENDICULAR )
QP . AddToLayout ( vbox , command_button_vbox , CC . FLAGS_EXPAND_SIZER_PERPENDICULAR )
QP . AddToLayout ( vbox , self . _comparison_statements_vbox , CC . FLAGS_EXPAND_SIZER_PERPENDICULAR )
self . setLayout ( vbox )
HG . client_controller . sub ( self , ' SetDuplicatePair ' , ' canvas_new_duplicate_pair ' )
HG . client_controller . sub ( self , ' SetIndexString ' , ' canvas_new_index_string ' )
def _EditBackgroundSwitchIntensity ( self ) :
new_options = HG . client_controller . new_options
value = new_options . GetNoneableInteger ( ' duplicate_background_switch_intensity ' )
with ClientGUITopLevelWindowsPanels . DialogEdit ( self , ' edit lighten/darken intensity ' ) as dlg :
panel = ClientGUIScrolledPanelsEdit . EditNoneableIntegerPanel ( dlg , value , message = ' intensity: ' , none_phrase = ' do not change ' , min = 1 , max = 9 )
dlg . SetPanel ( panel )
if dlg . exec ( ) == QW . QDialog . Accepted :
new_value = panel . GetValue ( )
new_options . SetNoneableInteger ( ' duplicate_background_switch_intensity ' , new_value )
def _EditMergeOptions ( self , duplicate_type ) :
new_options = HG . client_controller . new_options
duplicate_action_options = new_options . GetDuplicateActionOptions ( duplicate_type )
with ClientGUITopLevelWindowsPanels . DialogEdit ( self , ' edit duplicate merge options ' ) as dlg :
panel = ClientGUIScrolledPanelsEdit . EditDuplicateActionOptionsPanel ( dlg , duplicate_type , duplicate_action_options )
dlg . SetPanel ( panel )
if dlg . exec ( ) == QW . QDialog . Accepted :
duplicate_action_options = panel . GetValue ( )
new_options . SetDuplicateActionOptions ( duplicate_type , duplicate_action_options )
2022-07-20 19:17:03 +00:00
def _EnableDisableButtons ( self ) :
disabled = self . _comparison_media is not None and self . _comparison_media . HasDeleteLocked ( )
self . _this_is_better_and_delete_other . setEnabled ( not disabled )
2022-04-06 20:40:17 +00:00
def _GetIdealSizeAndPosition ( self ) :
parent_window = self . parentWidget ( ) . window ( )
parent_size = parent_window . size ( )
parent_width = parent_size . width ( )
parent_height = parent_size . height ( )
my_size = self . size ( )
my_width = my_size . width ( )
my_height = my_size . height ( )
my_ideal_width = max ( int ( parent_width * 0.2 ) , self . sizeHint ( ) . width ( ) )
my_ideal_height = self . sizeHint ( ) . height ( )
should_resize = my_ideal_width != my_width or my_ideal_height != my_height
ideal_size = QC . QSize ( my_ideal_width , my_ideal_height )
ideal_position = QC . QPoint ( int ( parent_width - my_ideal_width ) , int ( parent_height * 0.3 ) )
ideal_rect = QC . QRect ( ideal_position , ideal_size )
right_notes_hover_geometry = self . _right_notes_hover . geometry ( )
if ideal_rect . intersects ( right_notes_hover_geometry ) :
# the notes are tall enough to overlap us
right_notes_correct_bottom = right_notes_hover_geometry . y ( ) + right_notes_hover_geometry . height ( )
if self . _my_canvas . height ( ) - right_notes_correct_bottom > my_ideal_height :
# if we can slide down and still fit in the gap, do that
ideal_position . setY ( right_notes_correct_bottom )
else :
# slide it right
ideal_position . setX ( right_notes_hover_geometry . x ( ) - my_ideal_width )
return ( should_resize , ideal_size , ideal_position )
def _ResetComparisonStatements ( self ) :
statements_and_scores = ClientMedia . GetDuplicateComparisonStatements ( self . _current_media , self . _comparison_media )
for name in self . _comparison_statement_names :
( panel , st ) = self . _comparison_statements_sts [ name ]
got_data = name in statements_and_scores
show_panel = got_data
if panel . isVisible ( ) != show_panel :
panel . setVisible ( show_panel )
if got_data :
( statement , score ) = statements_and_scores [ name ]
st . setText ( statement )
if score > 0 :
object_name = ' HydrusValid '
elif score < 0 :
object_name = ' HydrusInvalid '
else :
object_name = ' HydrusIndeterminate '
st . setObjectName ( object_name )
st . style ( ) . polish ( st )
def SetDuplicatePair ( self , canvas_key , shown_media , comparison_media ) :
if canvas_key == self . _canvas_key :
self . _current_media = shown_media
self . _comparison_media = comparison_media
2022-07-20 19:17:03 +00:00
self . _EnableDisableButtons ( )
2022-04-06 20:40:17 +00:00
self . _ResetComparisonStatements ( )
# minimumsize is not immediately updated without this
self . layout ( ) . activate ( )
self . _SizeAndPosition ( force = True )
def SetIndexString ( self , canvas_key , text ) :
if canvas_key == self . _canvas_key :
self . _current_index_string = text
self . _index_text . setText ( self . _current_index_string )
2020-03-25 21:15:57 +00:00
class CanvasHoverFrameTags ( CanvasHoverFrame ) :
2015-06-17 20:01:41 +00:00
2020-08-05 20:10:36 +00:00
def __init__ ( self , parent , my_canvas , top_hover : CanvasHoverFrameTop , canvas_key ) :
2015-06-17 20:01:41 +00:00
2020-03-25 21:15:57 +00:00
CanvasHoverFrame . __init__ ( self , parent , my_canvas , canvas_key )
2015-06-17 20:01:41 +00:00
2020-08-05 20:10:36 +00:00
self . _top_hover = top_hover
2019-11-14 03:56:30 +00:00
vbox = QP . VBoxLayout ( )
2015-06-17 20:01:41 +00:00
2020-03-25 21:15:57 +00:00
self . _tags = ClientGUIListBoxes . ListBoxTagsMediaHoverFrame ( self , self . _canvas_key )
2015-06-17 20:01:41 +00:00
2019-11-14 03:56:30 +00:00
QP . AddToLayout ( vbox , self . _tags , CC . FLAGS_EXPAND_SIZER_BOTH_WAYS )
2015-06-17 20:01:41 +00:00
2019-11-14 03:56:30 +00:00
self . setLayout ( vbox )
2015-06-17 20:01:41 +00:00
2017-05-10 21:33:58 +00:00
HG . client_controller . sub ( self , ' ProcessContentUpdates ' , ' content_updates_gui ' )
2015-06-17 20:01:41 +00:00
def _GetIdealSizeAndPosition ( self ) :
2019-11-14 03:56:30 +00:00
parent_window = self . parentWidget ( ) . window ( )
2015-06-17 20:01:41 +00:00
2020-02-26 22:28:52 +00:00
parent_size = parent_window . size ( )
parent_width = parent_size . width ( )
parent_height = parent_size . height ( )
my_size = self . size ( )
2015-06-17 20:01:41 +00:00
2020-02-26 22:28:52 +00:00
my_width = my_size . width ( )
my_height = my_size . height ( )
2015-06-17 20:01:41 +00:00
my_ideal_width = int ( parent_width * 0.2 )
my_ideal_height = parent_height
should_resize = my_ideal_width != my_width or my_ideal_height != my_height
2020-02-26 22:28:52 +00:00
ideal_size = QC . QSize ( my_ideal_width , my_ideal_height )
2022-04-06 20:40:17 +00:00
ideal_position = QC . QPoint ( 0 , 0 )
2015-06-17 20:01:41 +00:00
2020-02-26 22:28:52 +00:00
return ( should_resize , ideal_size , ideal_position )
2015-06-17 20:01:41 +00:00
def _ResetTags ( self ) :
2015-10-28 21:29:05 +00:00
if self . _current_media is not None :
2015-06-17 20:01:41 +00:00
2020-03-25 21:15:57 +00:00
self . _tags . SetTagsByMedia ( [ self . _current_media ] )
2015-06-17 20:01:41 +00:00
def ProcessContentUpdates ( self , service_keys_to_content_updates ) :
if self . _current_media is not None :
my_hash = self . _current_media . GetHash ( )
do_redraw = False
2021-04-28 21:43:16 +00:00
for ( service_key , content_updates ) in service_keys_to_content_updates . items ( ) :
2015-06-17 20:01:41 +00:00
if True in ( my_hash in content_update . GetHashes ( ) for content_update in content_updates ) :
do_redraw = True
break
if do_redraw :
self . _ResetTags ( )
def SetDisplayMedia ( self , canvas_key , media ) :
if canvas_key == self . _canvas_key :
2020-03-25 21:15:57 +00:00
CanvasHoverFrame . SetDisplayMedia ( self , canvas_key , media )
2015-06-17 20:01:41 +00:00
self . _ResetTags ( )
2016-12-07 22:12:52 +00:00
2022-05-11 21:16:33 +00:00
def wheelEvent ( self , event ) :
# need the mouse test here since some weird event passing happens on mouse events on other stuff, I think because this hover is child 0 of the parent, it somehow gets 'focus'
if self . rect ( ) . contains ( self . mapFromGlobal ( QG . QCursor . pos ( ) ) ) :
# we do not want to send taglist wheel events up to the canvas lad
event . accept ( )
return
CanvasHoverFrame . wheelEvent ( self , event )