2017-07-27 00:47:13 +00:00
import os
import sys
import traceback
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
2020-04-22 21:00:35 +00:00
2021-12-15 22:16:22 +00:00
from hydrus . core import HydrusConstants as HC
2020-04-22 21:00:35 +00:00
from hydrus . core import HydrusData
from hydrus . core import HydrusGlobals as HG
2020-07-29 20:52:44 +00:00
2020-04-22 21:00:35 +00:00
from hydrus . client import ClientConstants as CC
from hydrus . client import ClientData
2022-01-19 21:28:59 +00:00
from hydrus . client import ClientLocation
2020-04-22 21:00:35 +00:00
from hydrus . client import ClientThreading
from hydrus . client . gui import ClientGUIDialogsQuick
from hydrus . client . gui import ClientGUIFunctions
from hydrus . client . gui import ClientGUITopLevelWindows
from hydrus . client . gui import QtPorting as QP
2021-04-07 21:26:45 +00:00
from hydrus . client . gui . networking import ClientGUINetworkJobControl
2021-03-17 21:59:28 +00:00
from hydrus . client . gui . widgets import ClientGUICommon
2017-07-27 00:47:13 +00:00
2019-11-14 03:56:30 +00:00
class PopupWindow ( QW . QFrame ) :
2017-07-27 00:47:13 +00:00
2019-06-26 21:27:18 +00:00
def __init__ ( self , parent , manager ) :
2017-07-27 00:47:13 +00:00
2019-11-14 03:56:30 +00:00
QW . QFrame . __init__ ( self , parent )
self . setFrameStyle ( QW . QFrame . Box | QW . QFrame . Plain )
2017-07-27 00:47:13 +00:00
2019-06-26 21:27:18 +00:00
self . _manager = manager
2019-11-14 03:56:30 +00:00
self . _widget_event_filter = QP . WidgetEventFilter ( self )
self . _widget_event_filter . EVT_RIGHT_DOWN ( self . EventDismiss )
2017-07-27 00:47:13 +00:00
def TryToDismiss ( self ) :
2019-06-26 21:27:18 +00:00
self . _manager . Dismiss ( self )
2017-07-27 00:47:13 +00:00
def EventDismiss ( self , event ) :
self . TryToDismiss ( )
class PopupMessage ( PopupWindow ) :
TEXT_CUTOFF = 1024
2021-06-09 20:28:09 +00:00
def __init__ ( self , parent , manager , job_key : ClientThreading . JobKey ) :
2017-07-27 00:47:13 +00:00
2019-06-26 21:27:18 +00:00
PopupWindow . __init__ ( self , parent , manager )
2017-07-27 00:47:13 +00:00
2019-11-28 01:11:46 +00:00
self . setSizePolicy ( QW . QSizePolicy . MinimumExpanding , QW . QSizePolicy . Fixed )
2017-07-27 00:47:13 +00:00
self . _job_key = job_key
2019-11-14 03:56:30 +00:00
vbox = QP . VBoxLayout ( )
2017-07-27 00:47:13 +00:00
2019-11-14 03:56:30 +00:00
self . _title = ClientGUICommon . BetterStaticText ( self )
self . _title . setAlignment ( QC . Qt . AlignHCenter | QC . Qt . AlignVCenter )
2019-11-28 01:11:46 +00:00
font = self . _title . font ( )
font . setBold ( True )
self . _title . setFont ( font )
2018-04-18 22:10:15 +00:00
popup_message_character_width = HG . client_controller . new_options . GetInteger ( ' popup_message_character_width ' )
2019-11-28 01:11:46 +00:00
popup_char_width = ClientGUIFunctions . ConvertTextToPixelWidth ( self . _title , popup_message_character_width )
2018-04-18 22:10:15 +00:00
2018-06-20 20:20:22 +00:00
if HG . client_controller . new_options . GetBoolean ( ' popup_message_force_min_width ' ) :
2019-11-28 01:11:46 +00:00
#QP.SetMinClientSize( self, ( wrap_width, -1 ) )
self . setFixedWidth ( popup_char_width )
else :
self . setMaximumWidth ( popup_char_width )
2018-06-20 20:20:22 +00:00
2019-11-20 23:10:46 +00:00
self . _title . setWordWrap ( True )
2019-11-14 03:56:30 +00:00
self . _title_ev = QP . WidgetEventFilter ( self . _title )
self . _title_ev . EVT_RIGHT_DOWN ( self . EventDismiss )
self . _title . hide ( )
2017-07-27 00:47:13 +00:00
2019-11-20 23:10:46 +00:00
self . _text_1 = ClientGUICommon . BetterStaticText ( self )
self . _text_1 . setWordWrap ( True )
2019-11-14 03:56:30 +00:00
self . _text_1_ev = QP . WidgetEventFilter ( self . _text_1 )
self . _text_1_ev . EVT_RIGHT_DOWN ( self . EventDismiss )
self . _text_1 . hide ( )
2017-07-27 00:47:13 +00:00
2019-11-14 03:56:30 +00:00
self . _gauge_1 = ClientGUICommon . Gauge ( self )
self . _gauge_1_ev = QP . WidgetEventFilter ( self . _gauge_1 )
self . _gauge_1_ev . EVT_RIGHT_DOWN ( self . EventDismiss )
2019-11-28 01:11:46 +00:00
self . _gauge_1 . setMinimumWidth ( int ( popup_char_width * 0.9 ) )
2019-11-14 03:56:30 +00:00
self . _gauge_1 . hide ( )
2017-07-27 00:47:13 +00:00
2019-11-20 23:10:46 +00:00
self . _text_2 = ClientGUICommon . BetterStaticText ( self )
self . _text_2 . setWordWrap ( True )
2019-11-14 03:56:30 +00:00
self . _text_2_ev = QP . WidgetEventFilter ( self . _text_2 )
self . _text_2_ev . EVT_RIGHT_DOWN ( self . EventDismiss )
self . _text_2 . hide ( )
2017-07-27 00:47:13 +00:00
2019-11-14 03:56:30 +00:00
self . _gauge_2 = ClientGUICommon . Gauge ( self )
self . _gauge_2_ev = QP . WidgetEventFilter ( self . _gauge_2 )
self . _gauge_2_ev . EVT_RIGHT_DOWN ( self . EventDismiss )
2019-11-28 01:11:46 +00:00
self . _gauge_2 . setMinimumWidth ( int ( popup_char_width * 0.9 ) )
2019-11-14 03:56:30 +00:00
self . _gauge_2 . hide ( )
2017-07-27 00:47:13 +00:00
2018-06-06 21:27:02 +00:00
self . _text_yes_no = ClientGUICommon . BetterStaticText ( self )
2019-11-14 03:56:30 +00:00
self . _text_yes_no_ev = QP . WidgetEventFilter ( self . _text_yes_no )
self . _text_yes_no_ev . EVT_RIGHT_DOWN ( self . EventDismiss )
self . _text_yes_no . hide ( )
2017-10-04 17:51:58 +00:00
self . _yes = ClientGUICommon . BetterButton ( self , ' yes ' , self . _YesButton )
2019-11-14 03:56:30 +00:00
self . _yes . hide ( )
2017-10-04 17:51:58 +00:00
self . _no = ClientGUICommon . BetterButton ( self , ' no ' , self . _NoButton )
2019-11-14 03:56:30 +00:00
self . _no . hide ( )
2017-10-04 17:51:58 +00:00
2021-03-17 21:59:28 +00:00
self . _network_job_ctrl = ClientGUINetworkJobControl . NetworkJobControl ( self )
2019-11-14 03:56:30 +00:00
self . _network_job_ctrl . hide ( )
2022-04-20 20:18:56 +00:00
self . _time_network_job_disappeared = 0
2017-07-27 00:47:13 +00:00
self . _copy_to_clipboard_button = ClientGUICommon . BetterButton ( self , ' copy to clipboard ' , self . CopyToClipboard )
2019-11-14 03:56:30 +00:00
self . _copy_to_clipboard_button_ev = QP . WidgetEventFilter ( self . _copy_to_clipboard_button )
self . _copy_to_clipboard_button_ev . EVT_RIGHT_DOWN ( self . EventDismiss )
self . _copy_to_clipboard_button . hide ( )
2017-07-27 00:47:13 +00:00
self . _show_files_button = ClientGUICommon . BetterButton ( self , ' show files ' , self . ShowFiles )
2019-11-14 03:56:30 +00:00
self . _show_files_button_ev = QP . WidgetEventFilter ( self . _show_files_button )
self . _show_files_button_ev . EVT_RIGHT_DOWN ( self . EventDismiss )
self . _show_files_button . hide ( )
2017-07-27 00:47:13 +00:00
2021-06-09 20:28:09 +00:00
self . _user_callable_button = ClientGUICommon . BetterButton ( self , ' run command ' , self . CallUserCallable )
self . _user_callable_button_ev = QP . WidgetEventFilter ( self . _user_callable_button )
self . _user_callable_button_ev . EVT_RIGHT_DOWN ( self . EventDismiss )
self . _user_callable_button . hide ( )
2017-07-27 00:47:13 +00:00
self . _show_tb_button = ClientGUICommon . BetterButton ( self , ' show traceback ' , self . ShowTB )
2019-11-14 03:56:30 +00:00
self . _show_tb_button_ev = QP . WidgetEventFilter ( self . _show_tb_button )
self . _show_tb_button_ev . EVT_RIGHT_DOWN ( self . EventDismiss )
self . _show_tb_button . hide ( )
2017-07-27 00:47:13 +00:00
2018-06-06 21:27:02 +00:00
self . _tb_text = ClientGUICommon . BetterStaticText ( self )
2019-11-14 03:56:30 +00:00
self . _tb_text_ev = QP . WidgetEventFilter ( self . _tb_text )
self . _tb_text_ev . EVT_RIGHT_DOWN ( self . EventDismiss )
2019-11-20 23:10:46 +00:00
self . _tb_text . setWordWrap ( True )
2019-11-14 03:56:30 +00:00
self . _tb_text . hide ( )
2017-07-27 00:47:13 +00:00
self . _copy_tb_button = ClientGUICommon . BetterButton ( self , ' copy traceback information ' , self . CopyTB )
2019-11-14 03:56:30 +00:00
self . _copy_tb_button_ev = QP . WidgetEventFilter ( self . _copy_tb_button )
self . _copy_tb_button_ev . EVT_RIGHT_DOWN ( self . EventDismiss )
self . _copy_tb_button . hide ( )
2020-03-11 21:52:11 +00:00
self . _pause_button = ClientGUICommon . BetterBitmapButton ( self , CC . global_pixmaps ( ) . pause , self . PausePlay )
2019-11-14 03:56:30 +00:00
self . _pause_button_ev = QP . WidgetEventFilter ( self . _pause_button )
self . _pause_button_ev . EVT_RIGHT_DOWN ( self . EventDismiss )
self . _pause_button . hide ( )
2020-03-11 21:52:11 +00:00
self . _cancel_button = ClientGUICommon . BetterBitmapButton ( self , CC . global_pixmaps ( ) . stop , self . Cancel )
2019-11-14 03:56:30 +00:00
self . _cancel_button_ev = QP . WidgetEventFilter ( self . _cancel_button )
self . _cancel_button_ev . EVT_RIGHT_DOWN ( self . EventDismiss )
self . _cancel_button . hide ( )
hbox = QP . HBoxLayout ( )
2020-07-29 20:52:44 +00:00
QP . AddToLayout ( hbox , self . _pause_button , CC . FLAGS_CENTER_PERPENDICULAR )
QP . AddToLayout ( hbox , self . _cancel_button , CC . FLAGS_CENTER_PERPENDICULAR )
2019-11-14 03:56:30 +00:00
yes_no_hbox = QP . HBoxLayout ( )
2020-07-29 20:52:44 +00:00
QP . AddToLayout ( yes_no_hbox , self . _yes , CC . FLAGS_CENTER_PERPENDICULAR )
QP . AddToLayout ( yes_no_hbox , self . _no , CC . FLAGS_CENTER_PERPENDICULAR )
2019-11-14 03:56:30 +00:00
2019-11-28 01:11:46 +00:00
QP . AddToLayout ( vbox , self . _title , CC . FLAGS_EXPAND_PERPENDICULAR )
QP . AddToLayout ( vbox , self . _text_1 , CC . FLAGS_EXPAND_PERPENDICULAR )
QP . AddToLayout ( vbox , self . _gauge_1 , CC . FLAGS_EXPAND_PERPENDICULAR )
QP . AddToLayout ( vbox , self . _text_2 , CC . FLAGS_EXPAND_PERPENDICULAR )
QP . AddToLayout ( vbox , self . _gauge_2 , CC . FLAGS_EXPAND_PERPENDICULAR )
QP . AddToLayout ( vbox , self . _text_yes_no , CC . FLAGS_EXPAND_PERPENDICULAR )
2019-11-14 03:56:30 +00:00
QP . AddToLayout ( vbox , yes_no_hbox )
QP . AddToLayout ( vbox , self . _network_job_ctrl )
QP . AddToLayout ( vbox , self . _copy_to_clipboard_button )
QP . AddToLayout ( vbox , self . _show_files_button )
2021-06-09 20:28:09 +00:00
QP . AddToLayout ( vbox , self . _user_callable_button )
2019-11-14 03:56:30 +00:00
QP . AddToLayout ( vbox , self . _show_tb_button )
QP . AddToLayout ( vbox , self . _tb_text )
QP . AddToLayout ( vbox , self . _copy_tb_button )
2020-07-29 20:52:44 +00:00
QP . AddToLayout ( vbox , hbox , CC . FLAGS_ON_RIGHT )
2019-11-14 03:56:30 +00:00
self . setLayout ( vbox )
2017-07-27 00:47:13 +00:00
2017-10-04 17:51:58 +00:00
def _NoButton ( self ) :
self . _job_key . SetVariable ( ' popup_yes_no_answer ' , False )
2017-10-11 17:38:14 +00:00
self . _job_key . Delete ( )
2019-11-14 03:56:30 +00:00
self . _yes . hide ( )
self . _no . hide ( )
2017-10-11 17:38:14 +00:00
2017-10-04 17:51:58 +00:00
2017-07-27 00:47:13 +00:00
def _ProcessText ( self , text ) :
2019-01-09 22:59:03 +00:00
text = str ( text )
2017-07-27 00:47:13 +00:00
if len ( text ) > self . TEXT_CUTOFF :
new_text = ' The text is too long to display here. Here is the start of it (the rest is printed to the log): '
new_text + = os . linesep * 2
2020-03-04 22:12:53 +00:00
new_text + = text [ : self . TEXT_CUTOFF ]
2017-07-27 00:47:13 +00:00
text = new_text
return text
2017-10-04 17:51:58 +00:00
def _YesButton ( self ) :
self . _job_key . SetVariable ( ' popup_yes_no_answer ' , True )
2017-10-11 17:38:14 +00:00
self . _job_key . Delete ( )
2019-11-14 03:56:30 +00:00
self . _yes . hide ( )
self . _no . hide ( )
2017-10-11 17:38:14 +00:00
2017-10-04 17:51:58 +00:00
2021-06-09 20:28:09 +00:00
def CallUserCallable ( self ) :
user_callable = self . _job_key . GetUserCallable ( )
if user_callable is not None :
user_callable ( )
2017-07-27 00:47:13 +00:00
def Cancel ( self ) :
self . _job_key . Cancel ( )
2019-11-14 03:56:30 +00:00
self . _pause_button . setEnabled ( False )
self . _cancel_button . setEnabled ( False )
2017-07-27 00:47:13 +00:00
def CopyTB ( self ) :
2021-12-15 22:16:22 +00:00
info = ' v {} , {} , {} ' . format ( HC . SOFTWARE_VERSION , sys . platform . lower ( ) , ' frozen ' if HC . RUNNING_FROM_FROZEN_BUILD else ' source ' )
trace = self . _job_key . ToString ( )
full_text = info + os . linesep + trace
HG . client_controller . pub ( ' clipboard ' , ' text ' , full_text )
2017-07-27 00:47:13 +00:00
def CopyToClipboard ( self ) :
result = self . _job_key . GetIfHasVariable ( ' popup_clipboard ' )
if result is not None :
( title , text ) = result
HG . client_controller . pub ( ' clipboard ' , ' text ' , text )
def PausePlay ( self ) :
self . _job_key . PausePlay ( )
if self . _job_key . IsPaused ( ) :
2020-03-11 21:52:11 +00:00
ClientGUIFunctions . SetBitmapButtonBitmap ( self . _pause_button , CC . global_pixmaps ( ) . play )
2017-07-27 00:47:13 +00:00
else :
2020-03-11 21:52:11 +00:00
ClientGUIFunctions . SetBitmapButtonBitmap ( self . _pause_button , CC . global_pixmaps ( ) . pause )
2017-07-27 00:47:13 +00:00
def ShowFiles ( self ) :
result = self . _job_key . GetIfHasVariable ( ' popup_files ' )
if result is not None :
2017-08-02 21:32:54 +00:00
( popup_files , popup_files_name ) = result
2017-07-27 00:47:13 +00:00
2022-05-25 21:30:53 +00:00
location_context = ClientLocation . LocationContext . STATICCreateSimple ( CC . COMBINED_LOCAL_MEDIA_SERVICE_KEY )
2022-01-19 21:28:59 +00:00
HG . client_controller . pub ( ' new_page_query ' , location_context , initial_hashes = popup_files , page_name = popup_files_name )
2017-07-27 00:47:13 +00:00
def ShowTB ( self ) :
2019-11-14 03:56:30 +00:00
if self . _tb_text . isVisible ( ) :
2017-07-27 00:47:13 +00:00
2019-11-14 03:56:30 +00:00
self . _show_tb_button . setText ( ' show traceback ' )
2017-07-27 00:47:13 +00:00
2019-11-14 03:56:30 +00:00
self . _tb_text . hide ( )
2017-07-27 00:47:13 +00:00
else :
2019-11-14 03:56:30 +00:00
self . _show_tb_button . setText ( ' hide traceback ' )
2017-07-27 00:47:13 +00:00
2019-11-14 03:56:30 +00:00
self . _tb_text . show ( )
2017-07-27 00:47:13 +00:00
2019-06-26 21:27:18 +00:00
self . _manager . MakeSureEverythingFits ( )
2017-07-27 00:47:13 +00:00
def GetJobKey ( self ) :
return self . _job_key
def IsDeleted ( self ) :
return self . _job_key . IsDeleted ( )
def TryToDismiss ( self ) :
if self . _job_key . IsPausable ( ) or self . _job_key . IsCancellable ( ) :
return
else :
PopupWindow . TryToDismiss ( self )
2018-08-15 20:40:30 +00:00
def UpdateMessage ( self ) :
2017-07-27 00:47:13 +00:00
2021-06-09 20:28:09 +00:00
title = self . _job_key . GetStatusTitle ( )
2017-07-27 00:47:13 +00:00
if title is not None :
2019-11-14 03:56:30 +00:00
self . _title . show ( )
2017-07-27 00:47:13 +00:00
2019-11-14 03:56:30 +00:00
self . _title . setText ( title )
2018-07-04 20:48:28 +00:00
2017-07-27 00:47:13 +00:00
else :
2019-11-14 03:56:30 +00:00
self . _title . hide ( )
2017-07-27 00:47:13 +00:00
2021-06-09 20:28:09 +00:00
#
paused = self . _job_key . IsPaused ( )
2017-07-27 00:47:13 +00:00
popup_text_1 = self . _job_key . GetIfHasVariable ( ' popup_text_1 ' )
if popup_text_1 is not None or paused :
if paused :
text = ' paused '
else :
text = popup_text_1
2019-11-14 03:56:30 +00:00
self . _text_1 . show ( )
2017-07-27 00:47:13 +00:00
2019-11-14 03:56:30 +00:00
self . _text_1 . setText ( text )
2018-07-04 20:48:28 +00:00
2017-07-27 00:47:13 +00:00
else :
2019-11-14 03:56:30 +00:00
self . _text_1 . hide ( )
2017-07-27 00:47:13 +00:00
2021-06-09 20:28:09 +00:00
#
2017-07-27 00:47:13 +00:00
popup_gauge_1 = self . _job_key . GetIfHasVariable ( ' popup_gauge_1 ' )
if popup_gauge_1 is not None and not paused :
( gauge_value , gauge_range ) = popup_gauge_1
self . _gauge_1 . SetRange ( gauge_range )
self . _gauge_1 . SetValue ( gauge_value )
2019-11-14 03:56:30 +00:00
self . _gauge_1 . show ( )
2017-07-27 00:47:13 +00:00
else :
2019-11-14 03:56:30 +00:00
self . _gauge_1 . hide ( )
2017-07-27 00:47:13 +00:00
2021-06-09 20:28:09 +00:00
#
2017-07-27 00:47:13 +00:00
popup_text_2 = self . _job_key . GetIfHasVariable ( ' popup_text_2 ' )
if popup_text_2 is not None and not paused :
text = popup_text_2
2019-11-14 03:56:30 +00:00
self . _text_2 . setText ( self . _ProcessText ( text ) )
2017-07-27 00:47:13 +00:00
2019-11-14 03:56:30 +00:00
self . _text_2 . show ( )
2017-07-27 00:47:13 +00:00
else :
2019-11-14 03:56:30 +00:00
self . _text_2 . hide ( )
2017-07-27 00:47:13 +00:00
2021-06-09 20:28:09 +00:00
#
2017-07-27 00:47:13 +00:00
popup_gauge_2 = self . _job_key . GetIfHasVariable ( ' popup_gauge_2 ' )
if popup_gauge_2 is not None and not paused :
( gauge_value , gauge_range ) = popup_gauge_2
self . _gauge_2 . SetRange ( gauge_range )
self . _gauge_2 . SetValue ( gauge_value )
2019-11-14 03:56:30 +00:00
self . _gauge_2 . show ( )
2017-07-27 00:47:13 +00:00
else :
2019-11-14 03:56:30 +00:00
self . _gauge_2 . hide ( )
2017-07-27 00:47:13 +00:00
2021-06-09 20:28:09 +00:00
#
2017-10-04 17:51:58 +00:00
popup_yes_no_question = self . _job_key . GetIfHasVariable ( ' popup_yes_no_question ' )
if popup_yes_no_question is not None and not paused :
text = popup_yes_no_question
2021-06-09 20:28:09 +00:00
self . _text_yes_no . setText ( self . _ProcessText ( text ) )
2017-10-04 17:51:58 +00:00
2019-11-14 03:56:30 +00:00
self . _text_yes_no . show ( )
2018-07-04 20:48:28 +00:00
2019-11-14 03:56:30 +00:00
self . _yes . show ( )
self . _no . show ( )
2017-10-04 17:51:58 +00:00
else :
2019-11-14 03:56:30 +00:00
self . _text_yes_no . hide ( )
self . _yes . hide ( )
self . _no . hide ( )
2017-10-04 17:51:58 +00:00
2021-06-09 20:28:09 +00:00
#
network_job = self . _job_key . GetNetworkJob ( )
if network_job is None :
2017-07-27 00:47:13 +00:00
2022-04-20 20:18:56 +00:00
if self . _network_job_ctrl . HasNetworkJob ( ) :
self . _network_job_ctrl . ClearNetworkJob ( )
self . _time_network_job_disappeared = HydrusData . GetNow ( )
2017-07-27 00:47:13 +00:00
2022-04-20 20:18:56 +00:00
if self . _network_job_ctrl . isVisible ( ) and HydrusData . TimeHasPassed ( self . _time_network_job_disappeared + 10 ) :
self . _network_job_ctrl . hide ( )
2017-07-27 00:47:13 +00:00
else :
2021-06-09 20:28:09 +00:00
self . _network_job_ctrl . SetNetworkJob ( network_job )
2017-08-02 21:32:54 +00:00
2021-06-09 20:28:09 +00:00
self . _network_job_ctrl . show ( )
2017-07-27 00:47:13 +00:00
2021-06-09 20:28:09 +00:00
#
2017-07-27 00:47:13 +00:00
popup_clipboard = self . _job_key . GetIfHasVariable ( ' popup_clipboard ' )
if popup_clipboard is not None :
( title , text ) = popup_clipboard
2019-11-14 03:56:30 +00:00
if self . _copy_to_clipboard_button . text ( ) != title :
2017-07-27 00:47:13 +00:00
2019-11-14 03:56:30 +00:00
self . _copy_to_clipboard_button . setText ( title )
2017-07-27 00:47:13 +00:00
2019-11-14 03:56:30 +00:00
self . _copy_to_clipboard_button . show ( )
2017-07-27 00:47:13 +00:00
else :
2019-11-14 03:56:30 +00:00
self . _copy_to_clipboard_button . hide ( )
2017-07-27 00:47:13 +00:00
2021-06-09 20:28:09 +00:00
#
2017-08-02 21:32:54 +00:00
result = self . _job_key . GetIfHasVariable ( ' popup_files ' )
2017-07-27 00:47:13 +00:00
2017-08-02 21:32:54 +00:00
if result is not None :
( popup_files , popup_files_name ) = result
2017-07-27 00:47:13 +00:00
hashes = popup_files
2018-07-04 20:48:28 +00:00
text = popup_files_name + ' - show ' + HydrusData . ToHumanInt ( len ( hashes ) ) + ' files '
2017-07-27 00:47:13 +00:00
2019-11-14 03:56:30 +00:00
if self . _show_files_button . text ( ) != text :
2017-07-27 00:47:13 +00:00
2019-11-14 03:56:30 +00:00
self . _show_files_button . setText ( text )
2017-07-27 00:47:13 +00:00
2019-11-14 03:56:30 +00:00
self . _show_files_button . show ( )
2017-07-27 00:47:13 +00:00
else :
2019-11-14 03:56:30 +00:00
self . _show_files_button . hide ( )
2017-07-27 00:47:13 +00:00
2021-06-09 20:28:09 +00:00
#
2017-07-27 00:47:13 +00:00
2021-06-09 20:28:09 +00:00
user_callable = self . _job_key . GetUserCallable ( )
if user_callable is None :
2017-07-27 00:47:13 +00:00
2021-06-09 20:28:09 +00:00
self . _user_callable_button . hide ( )
2017-07-27 00:47:13 +00:00
else :
2021-06-09 20:28:09 +00:00
self . _user_callable_button . setText ( user_callable . GetLabel ( ) )
self . _user_callable_button . show ( )
2017-07-27 00:47:13 +00:00
2021-06-09 20:28:09 +00:00
#
popup_traceback = self . _job_key . GetTraceback ( )
2017-07-27 00:47:13 +00:00
if popup_traceback is not None :
2021-06-09 20:28:09 +00:00
self . _copy_tb_button . show ( )
self . _show_tb_button . show ( )
2017-07-27 00:47:13 +00:00
text = popup_traceback
2020-03-04 22:12:53 +00:00
self . _tb_text . setText ( self . _ProcessText ( text ) )
2017-07-27 00:47:13 +00:00
2021-06-09 20:28:09 +00:00
# do not show automatically--that is up to the show button
2017-07-27 00:47:13 +00:00
else :
2021-06-09 20:28:09 +00:00
self . _copy_tb_button . hide ( )
2019-11-14 03:56:30 +00:00
self . _show_tb_button . hide ( )
self . _tb_text . hide ( )
2017-07-27 00:47:13 +00:00
2021-06-09 20:28:09 +00:00
#
2017-07-27 00:47:13 +00:00
if self . _job_key . IsPausable ( ) :
2019-11-14 03:56:30 +00:00
self . _pause_button . show ( )
2017-07-27 00:47:13 +00:00
else :
2019-11-14 03:56:30 +00:00
self . _pause_button . hide ( )
2017-07-27 00:47:13 +00:00
if self . _job_key . IsCancellable ( ) :
2019-11-14 03:56:30 +00:00
self . _cancel_button . show ( )
2017-07-27 00:47:13 +00:00
else :
2019-11-14 03:56:30 +00:00
self . _cancel_button . hide ( )
# Dirty hack to reduce unnecessary resizing
if self . minimumWidth ( ) < self . sizeHint ( ) . width ( ) :
self . setMinimumWidth ( self . sizeHint ( ) . width ( ) )
2017-07-27 00:47:13 +00:00
2022-09-07 21:16:25 +00:00
2019-11-14 03:56:30 +00:00
class PopupMessageManager ( QW . QWidget ) :
2017-07-27 00:47:13 +00:00
def __init__ ( self , parent ) :
2019-11-14 03:56:30 +00:00
QW . QWidget . __init__ ( self , parent )
self . setWindowFlags ( QC . Qt . Tool | QC . Qt . FramelessWindowHint )
2019-12-05 05:29:32 +00:00
2019-11-14 03:56:30 +00:00
self . setAttribute ( QC . Qt . WA_ShowWithoutActivating )
2017-07-27 00:47:13 +00:00
2019-12-05 05:29:32 +00:00
self . setSizePolicy ( QW . QSizePolicy . MinimumExpanding , QW . QSizePolicy . Preferred )
2018-08-08 20:29:54 +00:00
self . _last_best_size_i_fit_on = ( 0 , 0 )
2017-07-27 00:47:13 +00:00
self . _max_messages_to_display = 10
2019-11-14 03:56:30 +00:00
vbox = QP . VBoxLayout ( )
2017-07-27 00:47:13 +00:00
2019-11-14 03:56:30 +00:00
self . _message_panel = QW . QWidget ( self )
2019-06-26 21:27:18 +00:00
2019-11-14 03:56:30 +00:00
self . _message_vbox = QP . VBoxLayout ( margin = 0 )
2019-11-28 01:11:46 +00:00
2019-11-14 03:56:30 +00:00
vbox . setSizeConstraint ( QW . QLayout . SetFixedSize )
2017-07-27 00:47:13 +00:00
2019-11-14 03:56:30 +00:00
self . _message_panel . setLayout ( self . _message_vbox )
self . _message_panel . setSizePolicy ( QW . QSizePolicy . MinimumExpanding , QW . QSizePolicy . Preferred )
2019-06-26 21:27:18 +00:00
self . _summary_bar = PopupMessageSummaryBar ( self , self )
2019-11-14 03:56:30 +00:00
self . _summary_bar . setSizePolicy ( QW . QSizePolicy . MinimumExpanding , QW . QSizePolicy . Preferred )
2017-07-27 00:47:13 +00:00
2019-11-14 03:56:30 +00:00
QP . AddToLayout ( vbox , self . _message_panel )
QP . AddToLayout ( vbox , self . _summary_bar )
2017-07-27 00:47:13 +00:00
2019-11-14 03:56:30 +00:00
self . setLayout ( vbox )
2017-07-27 00:47:13 +00:00
self . _pending_job_keys = [ ]
2022-09-07 21:16:25 +00:00
parent . installEventFilter ( self )
2017-07-27 00:47:13 +00:00
HG . client_controller . sub ( self , ' AddMessage ' , ' message ' )
self . _old_excepthook = sys . excepthook
self . _old_show_exception = HydrusData . ShowException
2021-04-07 21:26:45 +00:00
self . _old_show_exception_tuple = HydrusData . ShowExceptionTuple
self . _old_show_text = HydrusData . ShowText
2017-07-27 00:47:13 +00:00
sys . excepthook = ClientData . CatchExceptionClient
HydrusData . ShowException = ClientData . ShowExceptionClient
2021-04-07 21:26:45 +00:00
HydrusData . ShowExceptionTuple = ClientData . ShowExceptionTupleClient
2017-07-27 00:47:13 +00:00
HydrusData . ShowText = ClientData . ShowTextClient
job_key = ClientThreading . JobKey ( )
2019-01-09 22:59:03 +00:00
job_key . SetVariable ( ' popup_text_1 ' , ' initialising popup message manager \u2026 ' )
2017-07-27 00:47:13 +00:00
2021-06-23 21:11:38 +00:00
self . _update_job = HG . client_controller . CallRepeatingQtSafe ( self , 0.25 , 0.5 , ' repeating popup message update ' , self . REPEATINGUpdate )
2017-07-27 00:47:13 +00:00
2020-09-23 21:02:02 +00:00
self . _summary_bar . expandCollapse . connect ( self . ExpandCollapse )
2021-06-23 21:11:38 +00:00
HG . client_controller . CallLaterQtSafe ( self , 0.5 , ' initialise message ' , self . AddMessage , job_key )
2017-07-27 00:47:13 +00:00
2021-06-23 21:11:38 +00:00
HG . client_controller . CallLaterQtSafe ( self , 1.0 , ' delete initial message ' , job_key . Delete )
2017-07-27 00:47:13 +00:00
def _CheckPending ( self ) :
self . _pending_job_keys = [ job_key for job_key in self . _pending_job_keys if not job_key . IsDeleted ( ) ]
2019-11-14 03:56:30 +00:00
while len ( self . _pending_job_keys ) > 0 and self . _message_vbox . count ( ) < self . _max_messages_to_display :
2017-07-27 00:47:13 +00:00
job_key = self . _pending_job_keys . pop ( 0 )
2019-06-26 21:27:18 +00:00
window = PopupMessage ( self . _message_panel , self , job_key )
2017-07-27 00:47:13 +00:00
2018-08-15 20:40:30 +00:00
window . UpdateMessage ( )
2017-07-27 00:47:13 +00:00
2019-11-14 03:56:30 +00:00
QP . AddToLayout ( self . _message_vbox , window )
2017-07-27 00:47:13 +00:00
2019-11-14 03:56:30 +00:00
total_messages = len ( self . _pending_job_keys ) + self . _message_vbox . count ( )
2017-07-27 00:47:13 +00:00
2019-11-14 03:56:30 +00:00
self . _summary_bar . SetNumMessages ( total_messages )
2018-05-09 20:23:00 +00:00
2018-05-16 20:09:50 +00:00
if self . _NeedsSizeOrShow ( ) :
2017-07-27 00:47:13 +00:00
self . _SizeAndPositionAndShow ( )
def _DisplayingError ( self ) :
2019-11-14 03:56:30 +00:00
for i in range ( self . _message_vbox . count ( ) ) :
2017-07-27 00:47:13 +00:00
2019-11-14 03:56:30 +00:00
sizer_item = self . _message_vbox . itemAt ( i )
message_window = sizer_item . widget ( )
2021-06-09 20:28:09 +00:00
if not message_window :
continue
2017-07-27 00:47:13 +00:00
job_key = message_window . GetJobKey ( )
2021-06-09 20:28:09 +00:00
if job_key . HadError ( ) :
2017-07-27 00:47:13 +00:00
return True
return False
2018-05-09 20:23:00 +00:00
def _DoDebugHide ( self ) :
2021-10-06 20:59:30 +00:00
if not QP . isValid ( self ) :
return
2018-05-09 20:23:00 +00:00
2019-11-14 03:56:30 +00:00
parent = self . parentWidget ( )
2018-05-09 20:23:00 +00:00
2020-04-29 21:44:12 +00:00
possibly_on_hidden_virtual_desktop = not ClientGUIFunctions . MouseIsOnMyDisplay ( parent )
2018-05-09 20:23:00 +00:00
2019-11-14 03:56:30 +00:00
going_to_bug_out_at_hide_or_show = possibly_on_hidden_virtual_desktop
2018-05-09 20:23:00 +00:00
new_options = HG . client_controller . new_options
2019-11-14 03:56:30 +00:00
if new_options . GetBoolean ( ' hide_message_manager_on_gui_iconise ' ) and not self . _DisplayingError ( ) :
2018-05-09 20:23:00 +00:00
2019-11-14 03:56:30 +00:00
if parent . isMinimized ( ) :
2018-05-09 20:23:00 +00:00
2019-11-14 03:56:30 +00:00
self . hide ( )
2018-05-09 20:23:00 +00:00
return
2019-12-11 23:18:37 +00:00
current_focus_tlw = QW . QApplication . activeWindow ( )
2018-05-09 20:23:00 +00:00
2019-12-11 23:18:37 +00:00
main_gui_is_active = current_focus_tlw in ( self , parent )
2018-05-09 20:23:00 +00:00
2019-11-14 03:56:30 +00:00
if new_options . GetBoolean ( ' hide_message_manager_on_gui_deactive ' ) and not self . _DisplayingError ( ) :
2018-05-09 20:23:00 +00:00
if not main_gui_is_active :
if not going_to_bug_out_at_hide_or_show :
2019-11-14 03:56:30 +00:00
self . hide ( )
2018-05-09 20:23:00 +00:00
2018-05-16 20:09:50 +00:00
def _NeedsSizeOrShow ( self ) :
2019-11-14 03:56:30 +00:00
num_messages_displayed = self . _message_vbox . count ( )
2018-05-16 20:09:50 +00:00
there_is_stuff_to_display = num_messages_displayed > 0
2019-11-14 03:56:30 +00:00
is_shown = self . isVisible ( )
2018-05-16 20:09:50 +00:00
if there_is_stuff_to_display :
if not is_shown :
return True
2019-11-14 03:56:30 +00:00
best_size = self . sizeHint ( )
2018-05-16 20:09:50 +00:00
2019-11-14 03:56:30 +00:00
if best_size != self . size ( ) :
2018-05-16 20:09:50 +00:00
return True
else :
if is_shown :
return True
return False
2017-07-27 00:47:13 +00:00
def _SizeAndPositionAndShow ( self ) :
try :
2022-09-07 21:16:25 +00:00
gui_frame = HG . client_controller . gui
2017-09-06 20:18:20 +00:00
2020-04-01 21:51:42 +00:00
gui_is_hidden = not gui_frame . isVisible ( )
2021-10-13 20:16:57 +00:00
going_to_bug_out_at_hide_or_show = gui_is_hidden
2017-07-27 00:47:13 +00:00
2019-12-11 23:18:37 +00:00
current_focus_tlw = QW . QApplication . activeWindow ( )
2017-07-27 00:47:13 +00:00
2019-12-11 23:18:37 +00:00
main_gui_or_child_window_is_active = ClientGUIFunctions . TLWOrChildIsActive ( gui_frame )
2017-07-27 00:47:13 +00:00
2019-11-14 03:56:30 +00:00
num_messages_displayed = self . _message_vbox . count ( )
2017-07-27 00:47:13 +00:00
there_is_stuff_to_display = num_messages_displayed > 0
if there_is_stuff_to_display :
2022-09-07 21:16:25 +00:00
# Unhiding tends to raise the main gui tlw in some window managers, which is annoying if a media viewer window has focus
show_is_not_annoying = main_gui_or_child_window_is_active or self . _DisplayingError ( )
ok_to_show = show_is_not_annoying and not going_to_bug_out_at_hide_or_show
if ok_to_show :
self . show ( )
#
2020-02-26 22:28:52 +00:00
parent_size = gui_frame . size ( )
2018-08-15 20:40:30 +00:00
2020-02-26 22:28:52 +00:00
my_size = self . size ( )
2018-08-15 20:40:30 +00:00
2020-02-26 22:28:52 +00:00
my_x = ( parent_size . width ( ) - my_size . width ( ) ) - 20
my_y = ( parent_size . height ( ) - my_size . height ( ) ) - 25
2017-07-27 00:47:13 +00:00
2019-12-05 05:29:32 +00:00
if gui_frame . isVisible ( ) :
2017-07-27 00:47:13 +00:00
2020-02-26 22:28:52 +00:00
my_position = ClientGUIFunctions . ClientToScreen ( gui_frame , QC . QPoint ( my_x , my_y ) )
2017-07-27 00:47:13 +00:00
2019-11-14 03:56:30 +00:00
if my_position != self . pos ( ) :
2017-07-27 00:47:13 +00:00
2019-11-14 03:56:30 +00:00
self . move ( my_position )
2017-07-27 00:47:13 +00:00
else :
if not going_to_bug_out_at_hide_or_show :
2019-11-14 03:56:30 +00:00
self . hide ( )
2017-07-27 00:47:13 +00:00
except :
text = ' The popup message manager experienced a fatal error and will now stop working! Please restart the client as soon as possible! If this keeps happening, please email the details and your client.log to the hydrus developer. '
HydrusData . Print ( text )
HydrusData . Print ( traceback . format_exc ( ) )
2019-12-05 05:29:32 +00:00
QW . QMessageBox . critical ( gui_frame , ' Error ' , text )
2017-07-27 00:47:13 +00:00
2018-02-14 21:47:18 +00:00
self . _update_job . Cancel ( )
2017-07-27 00:47:13 +00:00
self . CleanBeforeDestroy ( )
2019-11-14 03:56:30 +00:00
self . deleteLater ( )
2017-07-27 00:47:13 +00:00
2018-02-14 21:47:18 +00:00
def _GetAllMessageJobKeys ( self ) :
job_keys = [ ]
2019-11-14 03:56:30 +00:00
for i in range ( self . _message_vbox . count ( ) ) :
2018-02-14 21:47:18 +00:00
2019-11-14 03:56:30 +00:00
sizer_item = self . _message_vbox . itemAt ( i )
message_window = sizer_item . widget ( )
if not message_window : continue
2018-02-14 21:47:18 +00:00
job_key = message_window . GetJobKey ( )
job_keys . append ( job_key )
job_keys . extend ( self . _pending_job_keys )
return job_keys
2018-05-09 20:23:00 +00:00
def _OKToAlterUI ( self ) :
2019-11-14 03:56:30 +00:00
if not QP . isValid ( self ) : return
2018-05-09 20:23:00 +00:00
2019-11-14 03:56:30 +00:00
main_gui = self . parentWidget ( )
2018-05-09 20:23:00 +00:00
2021-10-13 20:16:57 +00:00
gui_is_hidden = not main_gui . isVisible ( )
if gui_is_hidden :
return False
if HG . client_controller . new_options . GetBoolean ( ' freeze_message_manager_when_mouse_on_other_monitor ' ) :
# test both because when user uses a shortcut to send gui to a diff monitor, we can't chase it
# this may need a better test for virtual display dismissal
# this is also a proxy for hidden/virtual displays, which is really what it is going on about
on_my_monitor = ClientGUIFunctions . MouseIsOnMyDisplay ( main_gui ) or ClientGUIFunctions . MouseIsOnMyDisplay ( self )
if not on_my_monitor :
return False
2018-05-09 20:23:00 +00:00
2021-10-13 20:16:57 +00:00
if HG . client_controller . new_options . GetBoolean ( ' freeze_message_manager_when_main_gui_minimised ' ) :
main_gui_up = not main_gui . isMinimized ( )
if not main_gui_up :
return False
2018-05-09 20:23:00 +00:00
2021-10-13 20:16:57 +00:00
return True
2018-05-09 20:23:00 +00:00
2018-02-14 21:47:18 +00:00
def _TryToMergeMessage ( self , job_key ) :
if not job_key . HasVariable ( ' popup_files_mergable ' ) :
return False
result = job_key . GetIfHasVariable ( ' popup_files ' )
if result is not None :
( hashes , name ) = result
existing_job_keys = self . _GetAllMessageJobKeys ( )
for existing_job_key in existing_job_keys :
if existing_job_key . HasVariable ( ' popup_files_mergable ' ) :
result = existing_job_key . GetIfHasVariable ( ' popup_files ' )
if result is not None :
( existing_hashes , existing_name ) = result
if existing_name == name :
if isinstance ( existing_hashes , list ) :
existing_hashes . extend ( hashes )
elif isinstance ( existing_hashes , set ) :
existing_hashes . update ( hashes )
return True
return False
2017-07-27 00:47:13 +00:00
def _Update ( self ) :
2022-01-19 21:28:59 +00:00
if HG . started_shutdown :
2017-07-27 00:47:13 +00:00
2018-02-14 21:47:18 +00:00
self . _update_job . Cancel ( )
self . CleanBeforeDestroy ( )
2017-07-27 00:47:13 +00:00
2019-11-14 03:56:30 +00:00
self . deleteLater ( )
2017-07-27 00:47:13 +00:00
return
2019-11-14 03:56:30 +00:00
for i in range ( self . _message_vbox . count ( ) ) :
2017-07-27 00:47:13 +00:00
2019-11-14 03:56:30 +00:00
sizer_item = self . _message_vbox . itemAt ( i )
2017-07-27 00:47:13 +00:00
2019-11-14 03:56:30 +00:00
message_window = sizer_item . widget ( )
if message_window :
2017-07-27 00:47:13 +00:00
2019-11-14 03:56:30 +00:00
if message_window . IsDeleted ( ) :
message_window . TryToDismiss ( )
break
else :
message_window . UpdateMessage ( )
2017-07-27 00:47:13 +00:00
def AddMessage ( self , job_key ) :
try :
2018-02-14 21:47:18 +00:00
was_merged = self . _TryToMergeMessage ( job_key )
if was_merged :
return
2017-07-27 00:47:13 +00:00
self . _pending_job_keys . append ( job_key )
2018-05-09 20:23:00 +00:00
if self . _OKToAlterUI ( ) :
2017-09-13 20:50:41 +00:00
self . _CheckPending ( )
2017-07-27 00:47:13 +00:00
except :
HydrusData . Print ( traceback . format_exc ( ) )
def CleanBeforeDestroy ( self ) :
for job_key in self . _pending_job_keys :
if job_key . IsCancellable ( ) :
job_key . Cancel ( )
2019-11-14 03:56:30 +00:00
for i in range ( self . _message_vbox . count ( ) ) :
message_window = self . _message_vbox . itemAt ( i ) . widget ( )
2017-07-27 00:47:13 +00:00
2019-11-14 03:56:30 +00:00
if not message_window : continue
2017-07-27 00:47:13 +00:00
job_key = message_window . GetJobKey ( )
if job_key . IsCancellable ( ) :
job_key . Cancel ( )
sys . excepthook = self . _old_excepthook
HydrusData . ShowException = self . _old_show_exception
2021-04-07 21:26:45 +00:00
HydrusData . ShowExceptionTuple = self . _old_show_exception_tuple
HydrusData . ShowText = self . _old_show_text
2017-07-27 00:47:13 +00:00
def Dismiss ( self , window ) :
2019-11-14 03:56:30 +00:00
self . _message_vbox . removeWidget ( window )
2017-07-27 00:47:13 +00:00
2019-11-14 03:56:30 +00:00
window . deleteLater ( )
2017-07-27 00:47:13 +00:00
2018-05-09 20:23:00 +00:00
if self . _OKToAlterUI ( ) :
self . _CheckPending ( )
2017-07-27 00:47:13 +00:00
def DismissAll ( self ) :
self . _pending_job_keys = [ job_key for job_key in self . _pending_job_keys if job_key . IsPausable ( ) or job_key . IsCancellable ( ) ]
2019-11-14 03:56:30 +00:00
items = [ ]
for i in range ( self . _message_vbox . count ( ) ) :
items . append ( self . _message_vbox . itemAt ( i ) )
2017-07-27 00:47:13 +00:00
2019-11-14 03:56:30 +00:00
for item in items :
message_window = item . widget ( )
2017-07-27 00:47:13 +00:00
2019-11-14 03:56:30 +00:00
if not message_window : continue
2017-07-27 00:47:13 +00:00
message_window . TryToDismiss ( )
self . _CheckPending ( )
2019-06-26 21:27:18 +00:00
def ExpandCollapse ( self ) :
2019-11-14 03:56:30 +00:00
if self . _message_panel . isVisible ( ) :
2019-06-26 21:27:18 +00:00
2019-11-14 03:56:30 +00:00
self . _message_panel . setVisible ( False )
2019-06-26 21:27:18 +00:00
else :
2019-11-14 03:56:30 +00:00
self . _message_panel . show ( )
2020-09-23 21:02:02 +00:00
2019-11-14 03:56:30 +00:00
self . MakeSureEverythingFits ( )
2022-09-07 21:16:25 +00:00
def eventFilter ( self , watched , event ) :
2019-11-14 03:56:30 +00:00
2022-09-07 21:16:25 +00:00
if watched == self . parentWidget ( ) :
2019-06-26 21:27:18 +00:00
2022-09-07 21:16:25 +00:00
if event . type ( ) in ( QC . QEvent . Resize , QC . QEvent . Move ) :
if self . _OKToAlterUI ( ) :
self . _SizeAndPositionAndShow ( )
2019-06-26 21:27:18 +00:00
2022-09-07 21:16:25 +00:00
return False
2019-06-26 21:27:18 +00:00
2022-09-07 21:16:25 +00:00
def resizeEvent ( self , event ) :
2017-07-27 00:47:13 +00:00
2019-11-14 03:56:30 +00:00
if not self or not QP . isValid ( self ) : # funny runtime error caused this
2019-05-22 22:35:06 +00:00
return
2018-05-09 20:23:00 +00:00
if self . _OKToAlterUI ( ) :
self . _SizeAndPositionAndShow ( )
2017-07-27 00:47:13 +00:00
2022-09-07 21:16:25 +00:00
event . ignore ( )
2017-07-27 00:47:13 +00:00
def MakeSureEverythingFits ( self ) :
2018-05-09 20:23:00 +00:00
if self . _OKToAlterUI ( ) :
self . _SizeAndPositionAndShow ( )
2017-07-27 00:47:13 +00:00
2018-02-14 21:47:18 +00:00
def REPEATINGUpdate ( self ) :
2017-07-27 00:47:13 +00:00
try :
2018-05-09 20:23:00 +00:00
self . _DoDebugHide ( )
if self . _OKToAlterUI ( ) :
2017-09-13 20:50:41 +00:00
self . _Update ( )
self . _CheckPending ( )
2017-07-27 00:47:13 +00:00
except :
2018-02-14 21:47:18 +00:00
self . _update_job . Cancel ( )
2017-07-27 00:47:13 +00:00
raise
2021-10-06 20:59:30 +00:00
2019-11-14 03:56:30 +00:00
# This was originally a reviewpanel subclass which is a scroll area subclass, but having it in a scroll area didn't work out with dynamically updating size as the widget contents change.
class PopupMessageDialogPanel ( QW . QWidget ) :
2017-07-27 00:47:13 +00:00
2020-09-02 21:10:41 +00:00
def __init__ ( self , parent , job_key , hide_main_gui = False ) :
2017-07-27 00:47:13 +00:00
2019-11-14 03:56:30 +00:00
QW . QWidget . __init__ ( self , parent )
2017-07-27 00:47:13 +00:00
2019-09-25 21:34:18 +00:00
self . _yesno_open = False
2020-09-02 21:10:41 +00:00
self . _hide_main_gui = hide_main_gui
2017-07-27 00:47:13 +00:00
self . _job_key = job_key
2019-06-26 21:27:18 +00:00
self . _message_window = PopupMessage ( self , self , self . _job_key )
2017-07-27 00:47:13 +00:00
2019-11-14 03:56:30 +00:00
vbox = QP . VBoxLayout ( )
2017-07-27 00:47:13 +00:00
2019-11-14 03:56:30 +00:00
QP . AddToLayout ( vbox , self . _message_window )
2017-07-27 00:47:13 +00:00
2019-11-14 03:56:30 +00:00
self . setLayout ( vbox )
2017-07-27 00:47:13 +00:00
2018-03-22 00:03:33 +00:00
self . _windows_hidden = [ ]
2018-01-17 22:52:10 +00:00
2018-03-22 00:03:33 +00:00
self . _HideOtherWindows ( )
2018-01-17 22:52:10 +00:00
2017-07-27 00:47:13 +00:00
self . _message_pubbed = False
2021-06-23 21:11:38 +00:00
self . _update_job = HG . client_controller . CallRepeatingQtSafe ( self , 0.25 , 0.5 , ' repeating popup dialog update ' , self . REPEATINGUpdate )
2019-11-28 01:11:46 +00:00
2020-04-29 21:44:12 +00:00
2019-11-14 03:56:30 +00:00
def CleanBeforeDestroy ( self ) :
pass
2018-03-22 00:03:33 +00:00
def _HideOtherWindows ( self ) :
2018-01-17 22:52:10 +00:00
2020-09-02 21:10:41 +00:00
from hydrus . client . gui import ClientGUI
2022-07-20 19:17:03 +00:00
for tlw in list ( QW . QApplication . topLevelWidgets ( ) ) :
2018-01-17 22:52:10 +00:00
2020-09-02 21:10:41 +00:00
if isinstance ( tlw , ClientGUI . FrameGUI ) :
pass
if tlw == self . window ( ) :
2018-01-17 22:52:10 +00:00
continue
2020-09-02 21:10:41 +00:00
if not isinstance ( tlw , ( ClientGUITopLevelWindows . Frame , ClientGUITopLevelWindows . MainFrame , ClientGUITopLevelWindows . NewDialog ) ) :
2018-01-17 22:52:10 +00:00
continue
2019-11-14 03:56:30 +00:00
if ClientGUIFunctions . IsQtAncestor ( self , tlw , through_tlws = True ) :
2019-03-27 22:01:02 +00:00
continue
2020-09-02 21:10:41 +00:00
if isinstance ( tlw , ClientGUI . FrameGUI ) and not self . _hide_main_gui :
2018-01-17 22:52:10 +00:00
continue
2019-11-14 03:56:30 +00:00
if not tlw . isVisible ( ) or tlw . isMinimized ( ) :
2018-01-17 22:52:10 +00:00
continue
2019-11-14 03:56:30 +00:00
tlw . hide ( )
2018-01-17 22:52:10 +00:00
2018-03-22 00:03:33 +00:00
self . _windows_hidden . append ( tlw )
2018-01-17 22:52:10 +00:00
2017-07-27 00:47:13 +00:00
def _ReleaseMessage ( self ) :
if not self . _message_pubbed :
HG . client_controller . pub ( ' message ' , self . _job_key )
self . _message_pubbed = True
2018-01-17 22:52:10 +00:00
self . _RestoreOtherWindows ( )
def _RestoreOtherWindows ( self ) :
2018-03-22 00:03:33 +00:00
for tlw in self . _windows_hidden :
2018-01-17 22:52:10 +00:00
2019-11-14 03:56:30 +00:00
tlw . show ( )
2018-01-17 22:52:10 +00:00
2018-03-22 00:03:33 +00:00
self . _windows_hidden = [ ]
2017-07-27 00:47:13 +00:00
def _Update ( self ) :
2018-08-15 20:40:30 +00:00
self . _message_window . UpdateMessage ( )
2017-07-27 00:47:13 +00:00
2019-11-14 03:56:30 +00:00
# Resize the window after updates
# The problem is that when the window is created, the initial size is too small because all widgets are empty before the first update,
# but after it updates it doesn't want to resize the window, rather it just adds scrollbars.
# This is a manual fix. Need to find a better solution...
2019-12-11 23:18:37 +00:00
2019-11-14 03:56:30 +00:00
self . layout ( ) . update ( )
self . _message_window . adjustSize ( )
self . adjustSize ( )
self . window ( ) . adjustSize ( )
2017-07-27 00:47:13 +00:00
def Dismiss ( self , window ) :
return
2020-04-29 21:44:12 +00:00
def CheckValid ( self ) :
return True
def UserIsOKToOK ( self ) :
return self . UserIsOKToCancel ( )
def UserIsOKToCancel ( self ) :
2017-07-27 00:47:13 +00:00
if self . _job_key . IsDone ( ) :
self . _ReleaseMessage ( )
2020-04-29 21:44:12 +00:00
elif self . _job_key . IsCancellable ( ) :
text = ' Cancel/stop job? '
self . _yesno_open = True
2017-07-27 00:47:13 +00:00
2020-04-29 21:44:12 +00:00
try :
2017-07-27 00:47:13 +00:00
2020-04-29 21:44:12 +00:00
result = ClientGUIDialogsQuick . GetYesNo ( self , text )
2019-07-24 21:39:02 +00:00
2020-04-29 21:44:12 +00:00
finally :
2019-09-25 21:34:18 +00:00
2020-04-29 21:44:12 +00:00
self . _yesno_open = False
2019-07-24 21:39:02 +00:00
2020-04-29 21:44:12 +00:00
if result == QW . QDialog . Accepted :
self . _job_key . Cancel ( )
self . _ReleaseMessage ( )
2017-07-27 00:47:13 +00:00
else :
2020-04-29 21:44:12 +00:00
return False
2017-08-02 21:32:54 +00:00
2017-07-27 00:47:13 +00:00
2020-04-29 21:44:12 +00:00
else :
QW . QMessageBox . warning ( self , ' Warning ' , ' Unfortunately, this job cannot be cancelled. If it really is taking too long, please kill the client through task manager. ' )
return False
return True
2017-07-27 00:47:13 +00:00
2018-02-14 21:47:18 +00:00
def REPEATINGUpdate ( self ) :
2017-07-27 00:47:13 +00:00
try :
if self . _job_key . IsDone ( ) :
2019-09-25 21:34:18 +00:00
if not self . _yesno_open : # don't close while a child dialog open m8
2019-11-14 03:56:30 +00:00
parent = self . parentWidget ( )
2017-07-27 00:47:13 +00:00
2019-11-14 03:56:30 +00:00
if parent . isModal ( ) : # event sometimes fires after modal done
2019-09-25 21:34:18 +00:00
parent . DoOK ( )
2017-07-27 00:47:13 +00:00
else :
self . _Update ( )
except :
2018-02-14 21:47:18 +00:00
self . _update_job . Cancel ( )
2017-07-27 00:47:13 +00:00
raise
2019-06-26 21:27:18 +00:00
class PopupMessageSummaryBar ( PopupWindow ) :
2020-09-23 21:02:02 +00:00
expandCollapse = QC . Signal ( )
2019-06-26 21:27:18 +00:00
def __init__ ( self , parent , manager ) :
PopupWindow . __init__ ( self , parent , manager )
2019-11-14 03:56:30 +00:00
hbox = QP . HBoxLayout ( )
2019-06-26 21:27:18 +00:00
self . _text = ClientGUICommon . BetterStaticText ( self )
self . _expand_collapse = ClientGUICommon . BetterButton ( self , ' \u25bc ' , self . ExpandCollapse )
dismiss_all = ClientGUICommon . BetterButton ( self , ' dismiss all ' , self . _manager . DismissAll )
2020-07-29 20:52:44 +00:00
QP . AddToLayout ( hbox , self . _text , CC . FLAGS_CENTER_PERPENDICULAR )
hbox . addStretch ( 1 )
QP . AddToLayout ( hbox , dismiss_all , CC . FLAGS_CENTER_PERPENDICULAR )
QP . AddToLayout ( hbox , self . _expand_collapse , CC . FLAGS_CENTER_PERPENDICULAR )
2019-06-26 21:27:18 +00:00
2019-11-14 03:56:30 +00:00
self . setLayout ( hbox )
2019-06-26 21:27:18 +00:00
def ExpandCollapse ( self ) :
2020-09-23 21:02:02 +00:00
self . expandCollapse . emit ( )
2019-06-26 21:27:18 +00:00
2019-11-14 03:56:30 +00:00
current_text = self . _expand_collapse . text ( )
2019-06-26 21:27:18 +00:00
if current_text == ' \u25bc ' :
new_text = ' \u25b2 '
else :
new_text = ' \u25bc '
2019-11-14 03:56:30 +00:00
self . _expand_collapse . setText ( new_text )
2019-06-26 21:27:18 +00:00
2017-07-27 00:47:13 +00:00
2019-06-26 21:27:18 +00:00
def TryToDismiss ( self ) :
pass
def SetNumMessages ( self , num_messages_pending ) :
if num_messages_pending == 1 :
2019-11-14 03:56:30 +00:00
self . _text . setText ( ' 1 message ' )
2019-06-26 21:27:18 +00:00
else :
2019-11-14 03:56:30 +00:00
self . _text . setText ( HydrusData . ToHumanInt ( num_messages_pending ) + ' messages ' )
2019-06-26 21:27:18 +00:00