2019-01-09 22:59:03 +00:00
from . import ClientConstants as CC
from . import ClientData
from . import ClientGUICommon
from . import ClientGUIControls
from . import ClientGUIDialogs
2019-07-24 21:39:02 +00:00
from . import ClientGUIDialogsQuick
2019-06-26 21:27:18 +00:00
from . import ClientGUIFunctions
2019-01-09 22:59:03 +00:00
from . import ClientGUIScrolledPanels
from . import ClientGUITopLevelWindows
from . import ClientThreading
from . import HydrusConstants as HC
from . import HydrusData
from . import HydrusExceptions
from . import HydrusGlobals as HG
2017-07-27 00:47:13 +00:00
import os
import sys
import traceback
2019-11-14 03:56:30 +00:00
from qtpy import QtCore as QC
from qtpy import QtWidgets as QW
from qtpy import QtGui as QG
from . import QtPorting as QP
from . import QtPorting as QP
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
2019-06-26 21:27:18 +00:00
def __init__ ( self , parent , manager , job_key ) :
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
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 )
self . setSizePolicy ( QW . QSizePolicy . MinimumExpanding , QW . QSizePolicy . Preferred )
2018-04-18 22:10:15 +00:00
popup_message_character_width = HG . client_controller . new_options . GetInteger ( ' popup_message_character_width ' )
2019-06-26 21:27:18 +00:00
wrap_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-14 03:56:30 +00:00
QP . SetMinClientSize ( self , ( wrap_width , - 1 ) )
2018-06-20 20:20:22 +00:00
2018-07-04 20:48:28 +00:00
self . _title . SetWrapWidth ( wrap_width )
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-14 03:56:30 +00:00
self . _text_1 = ClientGUICommon . BetterStaticText ( self , ellipsize_end = True )
2018-07-04 20:48:28 +00:00
self . _text_1 . SetWrapWidth ( wrap_width )
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 )
self . _gauge_1 . hide ( )
2017-07-27 00:47:13 +00:00
2019-11-14 03:56:30 +00:00
self . _text_2 = ClientGUICommon . BetterStaticText ( self , ellipsize_end = True )
2018-07-04 20:48:28 +00:00
self . _text_2 . SetWrapWidth ( wrap_width )
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 )
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 )
2018-07-04 20:48:28 +00:00
self . _text_yes_no . SetWrapWidth ( wrap_width )
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
2017-08-02 21:32:54 +00:00
self . _network_job_ctrl = ClientGUIControls . NetworkJobControl ( self )
2019-11-14 03:56:30 +00:00
self . _network_job_ctrl . hide ( )
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
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 )
2018-07-04 20:48:28 +00:00
self . _tb_text . SetWrapWidth ( wrap_width )
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 )
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 ( )
self . _pause_button = ClientGUICommon . BetterBitmapButton ( self , CC . GlobalPixmaps . pause , self . PausePlay )
self . _pause_button_ev = QP . WidgetEventFilter ( self . _pause_button )
self . _pause_button_ev . EVT_RIGHT_DOWN ( self . EventDismiss )
self . _pause_button . hide ( )
self . _cancel_button = ClientGUICommon . BetterBitmapButton ( self , CC . GlobalPixmaps . stop , self . Cancel )
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 ( )
QP . AddToLayout ( hbox , self . _pause_button , CC . FLAGS_VCENTER )
QP . AddToLayout ( hbox , self . _cancel_button , CC . FLAGS_VCENTER )
yes_no_hbox = QP . HBoxLayout ( )
QP . AddToLayout ( yes_no_hbox , self . _yes , CC . FLAGS_VCENTER )
QP . AddToLayout ( yes_no_hbox , self . _no , CC . FLAGS_VCENTER )
QP . AddToLayout ( vbox , self . _title , alignment = QC . Qt . AlignHCenter )
QP . AddToLayout ( vbox , self . _text_1 )
QP . AddToLayout ( vbox , self . _gauge_1 )
QP . AddToLayout ( vbox , self . _text_2 )
QP . AddToLayout ( vbox , self . _gauge_2 )
QP . AddToLayout ( vbox , self . _text_yes_no )
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 )
QP . AddToLayout ( vbox , self . _show_tb_button )
QP . AddToLayout ( vbox , self . _tb_text )
QP . AddToLayout ( vbox , self . _copy_tb_button )
QP . AddToLayout ( vbox , hbox , CC . FLAGS_BUTTON_SIZER )
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
new_text + = text [ : self . TEXT_CUTOFF ]
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
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 ) :
HG . client_controller . pub ( ' clipboard ' , ' text ' , self . _job_key . ToString ( ) )
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 ( ) :
2019-11-14 03:56:30 +00:00
ClientGUIFunctions . SetBitmapButtonBitmap ( self . _pause_button , CC . GlobalPixmaps . play )
2017-07-27 00:47:13 +00:00
else :
2019-11-14 03:56:30 +00:00
ClientGUIFunctions . SetBitmapButtonBitmap ( self . _pause_button , CC . GlobalPixmaps . 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
2017-08-02 21:32:54 +00:00
HG . client_controller . pub ( ' new_page_query ' , CC . LOCAL_FILE_SERVICE_KEY , 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
2018-07-04 20:48:28 +00:00
popup_message_character_width = HG . client_controller . new_options . GetInteger ( ' popup_message_character_width ' )
2019-06-26 21:27:18 +00:00
wrap_width = ClientGUIFunctions . ConvertTextToPixelWidth ( self . _title , popup_message_character_width )
2018-07-04 20:48:28 +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
2018-07-04 20:48:28 +00:00
popup_message_character_width = HG . client_controller . new_options . GetInteger ( ' popup_message_character_width ' )
2019-06-26 21:27:18 +00:00
wrap_width = ClientGUIFunctions . ConvertTextToPixelWidth ( self . _title , popup_message_character_width )
2018-07-04 20:48:28 +00:00
2017-07-27 00:47:13 +00:00
paused = self . _job_key . IsPaused ( )
title = self . _job_key . GetIfHasVariable ( ' popup_title ' )
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
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
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
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
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
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
2019-11-14 03:56:30 +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
2018-08-15 20:40:30 +00:00
if self . _job_key . HasVariable ( ' popup_network_job ' ) :
# this can be validly None, which confuses the getifhas result
popup_network_job = self . _job_key . GetIfHasVariable ( ' popup_network_job ' )
2017-07-27 00:47:13 +00:00
2017-08-02 21:32:54 +00:00
self . _network_job_ctrl . SetNetworkJob ( popup_network_job )
2017-07-27 00:47:13 +00:00
2019-11-14 03:56:30 +00:00
self . _network_job_ctrl . show ( )
2017-07-27 00:47:13 +00:00
else :
2017-08-02 21:32:54 +00:00
self . _network_job_ctrl . ClearNetworkJob ( )
2019-11-14 03:56:30 +00:00
self . _network_job_ctrl . hide ( )
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
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
popup_traceback = self . _job_key . GetIfHasVariable ( ' popup_traceback ' )
if popup_traceback is not None :
2019-11-14 03:56:30 +00:00
self . _copy_tb_button . show ( )
2017-07-27 00:47:13 +00:00
else :
2019-11-14 03:56:30 +00:00
self . _copy_tb_button . hide ( )
2017-07-27 00:47:13 +00:00
if popup_traceback is not None :
text = popup_traceback
2019-11-14 03:56:30 +00:00
self . _tb_text . setText ( self . _ProcessText ( text ) )
2017-07-27 00:47:13 +00:00
2019-11-14 03:56:30 +00:00
self . _show_tb_button . show ( )
2017-07-27 00:47:13 +00:00
else :
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
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
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 )
self . setSizePolicy ( QW . QSizePolicy . MinimumExpanding , QW . QSizePolicy . Preferred )
self . setAttribute ( QC . Qt . WA_ShowWithoutActivating )
2017-07-27 00:47:13 +00:00
2019-11-14 03:56:30 +00:00
QP . SetBackgroundColour ( self , QP . GetSystemColour ( QG . QPalette . Button ) )
2017-07-27 00:47:13 +00:00
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 )
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 = [ ]
2019-11-14 03:56:30 +00:00
self . _gui_event_filter = QP . WidgetEventFilter ( parent )
self . _gui_event_filter . EVT_SIZE ( self . EventParentMovedOrResized )
self . _gui_event_filter . EVT_MOVE ( self . EventParentMovedOrResized )
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
sys . excepthook = ClientData . CatchExceptionClient
HydrusData . ShowException = ClientData . ShowExceptionClient
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
2019-11-14 03:56:30 +00:00
self . _update_job = HG . client_controller . CallRepeatingQtSafe ( self , 0.25 , 0.5 , self . REPEATINGUpdate )
2017-07-27 00:47:13 +00:00
2019-11-14 03:56:30 +00:00
HG . client_controller . CallLaterQtSafe ( self , 0.5 , self . AddMessage , job_key )
2017-07-27 00:47:13 +00:00
2019-11-14 03:56:30 +00:00
HG . client_controller . CallLaterQtSafe ( self , 1.0 , 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 ( )
if not message_window : continue
2017-07-27 00:47:13 +00:00
job_key = message_window . GetJobKey ( )
if job_key . HasVariable ( ' popup_traceback ' ) :
return True
return False
2018-05-09 20:23:00 +00:00
def _DoDebugHide ( 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
parent = self . parentWidget ( )
2018-05-09 20:23:00 +00:00
possibly_on_hidden_virtual_desktop = not ClientGUITopLevelWindows . MouseIsOnMyDisplay ( parent )
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-11-14 03:56:30 +00:00
current_focus_tlp = QW . QApplication . activeWindow ( )
2018-05-09 20:23:00 +00:00
main_gui_is_active = current_focus_tlp in ( self , parent )
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 :
2019-11-14 03:56:30 +00:00
parent = self . parentWidget ( )
2017-09-06 20:18:20 +00:00
possibly_on_hidden_virtual_desktop = not ClientGUITopLevelWindows . MouseIsOnMyDisplay ( parent )
2019-11-14 03:56:30 +00:00
going_to_bug_out_at_hide_or_show = possibly_on_hidden_virtual_desktop
2017-07-27 00:47:13 +00:00
2019-11-14 03:56:30 +00:00
current_focus_tlp = QW . QApplication . activeWindow ( )
2017-07-27 00:47:13 +00:00
main_gui_is_active = current_focus_tlp in ( self , parent )
on_top_frame_is_active = False
if not main_gui_is_active :
2019-11-14 03:56:30 +00:00
c_f_tlp_is_child_frame_of_main_gui = current_focus_tlp is not None and current_focus_tlp . parentWidget ( ) == parent
2017-07-27 00:47:13 +00:00
2019-11-14 03:56:30 +00:00
if c_f_tlp_is_child_frame_of_main_gui :
2017-07-27 00:47:13 +00:00
on_top_frame_is_active = True
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 :
2019-11-14 03:56:30 +00:00
( parent_width , parent_height ) = parent . size ( ) . toTuple ( )
2018-08-15 20:40:30 +00:00
2019-11-14 03:56:30 +00:00
( my_width , my_height ) = self . size ( ) . toTuple ( )
2018-08-15 20:40:30 +00:00
2019-11-14 03:56:30 +00:00
my_x = ( parent_width - my_width ) - 20
my_y = ( parent_height - my_height ) - 25
2017-07-27 00:47:13 +00:00
2019-11-14 03:56:30 +00:00
if parent . isVisible ( ) :
2017-07-27 00:47:13 +00:00
2019-06-26 21:27:18 +00:00
my_position = ClientGUIFunctions . ClientToScreen ( parent , ( 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
# Unhiding tends to raise the main gui tlp, which is annoying if a media viewer window has focus
2019-11-14 03:56:30 +00:00
# Qt port note: the on_top_frame_is_active part was uncommented originally, but it IS annoying since it leads to flickering (e.g. open the options window with this uncommented to see it in action)
show_is_not_annoying = main_gui_is_active or self . _DisplayingError ( ) # or on_top_frame_is_active
2017-07-27 00:47:13 +00:00
ok_to_show = show_is_not_annoying and not going_to_bug_out_at_hide_or_show
if ok_to_show :
2019-11-14 03:56:30 +00:00
self . show ( )
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-11-14 03:56:30 +00:00
QW . QMessageBox . critical ( HG . client_controller . gui , ' 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
2019-06-19 22:08:48 +00:00
# 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
not_on_hidden_or_virtual_display = ClientGUITopLevelWindows . MouseIsOnMyDisplay ( main_gui ) or ClientGUITopLevelWindows . MouseIsOnMyDisplay ( self )
2018-05-09 20:23:00 +00:00
2019-11-14 03:56:30 +00:00
main_gui_up = not main_gui . isMinimized ( )
2018-05-09 20:23:00 +00:00
return not_on_hidden_or_virtual_display and main_gui_up
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 ) :
if HG . view_shutdown :
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
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 ( )
self . MakeSureEverythingFits ( )
def resizeEvent ( self , event ) :
if not self or not QP . isValid ( self ) : # funny runtime error caused this
return
if self . _OKToAlterUI ( ) :
2019-06-26 21:27:18 +00:00
2019-11-14 03:56:30 +00:00
self . _SizeAndPositionAndShow ( )
2019-06-26 21:27:18 +00:00
2019-11-14 03:56:30 +00:00
event . ignore ( )
2019-06-26 21:27:18 +00:00
2019-11-14 03:56:30 +00:00
def EventParentMovedOrResized ( 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
2019-11-14 03:56:30 +00:00
return True # was: 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
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
def __init__ ( self , parent , job_key ) :
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
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
2019-11-14 03:56:30 +00:00
self . _update_job = HG . client_controller . CallRepeatingQtSafe ( self , 0.25 , 0.5 , self . REPEATINGUpdate )
def CanCancel ( self ) :
return True
2018-01-03 22:37:30 +00:00
2019-11-14 03:56:30 +00:00
def CanOK ( self ) :
return True
def CleanBeforeDestroy ( self ) :
pass
2018-03-22 00:03:33 +00:00
def _HideOtherWindows ( self ) :
2018-01-17 22:52:10 +00:00
2019-11-14 03:56:30 +00:00
for tlw in QW . QApplication . topLevelWidgets ( ) :
2018-01-17 22:52:10 +00:00
if tlw == self :
continue
if not isinstance ( tlw , ( ClientGUITopLevelWindows . Frame , ClientGUITopLevelWindows . NewDialog ) ) :
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
2019-01-09 22:59:03 +00:00
from . import ClientGUI
2018-01-17 22:52:10 +00:00
if isinstance ( tlw , ClientGUI . FrameGUI ) :
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...
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
def TryToClose ( self ) :
if self . _job_key . IsDone ( ) :
self . _ReleaseMessage ( )
else :
if self . _job_key . IsCancellable ( ) :
2019-07-24 21:39:02 +00:00
text = ' Cancel/stop job? '
2019-09-25 21:34:18 +00:00
self . _yesno_open = True
try :
result = ClientGUIDialogsQuick . GetYesNo ( self , text )
finally :
self . _yesno_open = False
2019-07-24 21:39:02 +00:00
2019-11-14 03:56:30 +00:00
if result == QW . QDialog . Accepted :
2017-07-27 00:47:13 +00:00
2019-07-24 21:39:02 +00:00
self . _job_key . Cancel ( )
self . _ReleaseMessage ( )
else :
raise HydrusExceptions . VetoException ( )
2017-07-27 00:47:13 +00:00
else :
2017-12-13 22:33:07 +00:00
raise HydrusExceptions . VetoException ( ' Unfortunately, this job cannot be cancelled. If it really is taking too long, please kill the client through task manager. ' )
2017-08-02 21:32:54 +00:00
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 ) :
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 )
2019-11-14 03:56:30 +00:00
QP . AddToLayout ( hbox , self . _text , CC . FLAGS_VCENTER )
QP . AddToLayout ( hbox , ( 20 , 20 ) , CC . FLAGS_EXPAND_BOTH_WAYS )
QP . AddToLayout ( hbox , dismiss_all , CC . FLAGS_VCENTER )
QP . AddToLayout ( hbox , self . _expand_collapse , CC . FLAGS_VCENTER )
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 ) :
self . _manager . ExpandCollapse ( )
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