hydrus/hydrus/client/gui/ClientGUIDialogsQuick.py

368 lines
12 KiB
Python
Raw Normal View History

2023-08-09 21:12:17 +00:00
import os
2024-02-07 21:22:05 +00:00
import time
2023-08-09 21:12:17 +00:00
2019-11-14 03:56:30 +00:00
from qtpy import QtWidgets as QW
2018-11-14 23:10:55 +00:00
2020-04-22 21:00:35 +00:00
from hydrus.core import HydrusConstants as HC
2024-04-10 20:36:05 +00:00
from hydrus.core import HydrusData
2020-04-22 21:00:35 +00:00
from hydrus.core import HydrusExceptions
2024-04-10 20:36:05 +00:00
from hydrus.core import HydrusText
2024-02-07 21:22:05 +00:00
from hydrus.core import HydrusTime
2020-07-29 20:52:44 +00:00
2024-02-14 21:20:24 +00:00
from hydrus.client import ClientGlobals as CG
2023-08-09 21:12:17 +00:00
from hydrus.client import ClientPaths
2024-04-10 20:36:05 +00:00
from hydrus.client.gui import ClientGUIDialogsMessage
2020-04-22 21:00:35 +00:00
from hydrus.client.gui import ClientGUIScrolledPanelsButtonQuestions
from hydrus.client.gui import ClientGUIScrolledPanelsEdit
2020-04-29 21:44:12 +00:00
from hydrus.client.gui import ClientGUITopLevelWindowsPanels
2020-04-22 21:00:35 +00:00
2019-05-01 21:24:42 +00:00
def GetDeleteFilesJobs( win, media, default_reason, suggested_file_service_key = None ):
title = 'Delete files?'
2020-04-29 21:44:12 +00:00
with ClientGUITopLevelWindowsPanels.DialogEdit( win, title, frame_key = 'regular_center_dialog' ) as dlg:
2019-05-01 21:24:42 +00:00
panel = ClientGUIScrolledPanelsEdit.EditDeleteFilesPanel( dlg, media, default_reason, suggested_file_service_key = suggested_file_service_key )
dlg.SetPanel( panel )
if panel.QuestionIsAlreadyResolved():
2024-01-31 21:20:50 +00:00
( hashes_physically_deleted, content_update_packages ) = panel.GetValue()
2019-05-01 21:24:42 +00:00
2024-01-31 21:20:50 +00:00
return ( hashes_physically_deleted, content_update_packages )
2019-05-01 21:24:42 +00:00
2019-11-14 03:56:30 +00:00
if dlg.exec() == QW.QDialog.Accepted:
2019-05-01 21:24:42 +00:00
2024-01-31 21:20:50 +00:00
( hashes_physically_deleted, content_update_packages ) = panel.GetValue()
2019-05-01 21:24:42 +00:00
2024-01-31 21:20:50 +00:00
return ( hashes_physically_deleted, content_update_packages )
2019-05-01 21:24:42 +00:00
else:
2020-03-18 21:35:57 +00:00
raise HydrusExceptions.CancelledException( 'Dialog cancelled.' )
2019-05-01 21:24:42 +00:00
2024-04-10 20:36:05 +00:00
2022-06-22 20:43:12 +00:00
def GetFinishArchiveDeleteFilteringAnswer( win, kept_label, deletion_options ):
with ClientGUITopLevelWindowsPanels.DialogCustomButtonQuestion( win, 'filtering done?' ) as dlg:
panel = ClientGUIScrolledPanelsButtonQuestions.QuestionArchiveDeleteFinishFilteringPanel( dlg, kept_label, deletion_options )
dlg.SetPanel( panel )
result = dlg.exec()
location_context = panel.GetLocationContext()
was_cancelled = dlg.WasCancelled()
return ( result, location_context, was_cancelled )
2024-04-10 20:36:05 +00:00
2019-07-17 22:10:19 +00:00
def GetFinishFilteringAnswer( win, label ):
2020-04-29 21:44:12 +00:00
with ClientGUITopLevelWindowsPanels.DialogCustomButtonQuestion( win, label ) as dlg:
2019-07-17 22:10:19 +00:00
panel = ClientGUIScrolledPanelsButtonQuestions.QuestionFinishFilteringPanel( dlg, label )
dlg.SetPanel( panel )
2019-12-05 05:29:32 +00:00
result = ( dlg.exec(), dlg.WasCancelled() )
return result
2019-07-17 22:10:19 +00:00
def GetInterstitialFilteringAnswer( win, label ):
2020-04-29 21:44:12 +00:00
with ClientGUITopLevelWindowsPanels.DialogCustomButtonQuestion( win, label ) as dlg:
2019-07-17 22:10:19 +00:00
panel = ClientGUIScrolledPanelsButtonQuestions.QuestionCommitInterstitialFilteringPanel( dlg, label )
dlg.SetPanel( panel )
2019-12-05 05:29:32 +00:00
result = dlg.exec()
return result
2019-07-17 22:10:19 +00:00
2024-02-07 21:22:05 +00:00
def run_auto_yes_no_gubbins( dlg: QW.QDialog, time_to_fire, original_title, action_description, end_state ):
def qt_set_title():
time_string = HydrusTime.TimestampToPrettyTimeDelta( time_to_fire, just_now_threshold = 0, just_now_string = 'imminently' )
title = f'{original_title} (will {action_description} {time_string})'
dlg.setWindowTitle( title )
def qt_fire_button():
if dlg.isModal():
dlg.done( end_state )
while not HydrusTime.TimeHasPassed( time_to_fire ):
2024-02-14 21:20:24 +00:00
job = CG.client_controller.CallLaterQtSafe( dlg, 0.0, 'dialog auto yes/no title set', qt_set_title )
2024-02-07 21:22:05 +00:00
if job.IsDead(): # window closed
return
time.sleep( 1 )
2024-02-14 21:20:24 +00:00
job = CG.client_controller.CallLaterQtSafe( dlg, 0.0, 'dialog auto yes/no fire', qt_fire_button )
2024-02-07 21:22:05 +00:00
2019-11-14 03:56:30 +00:00
def GetYesNo( win, message, title = 'Are you sure?', yes_label = 'yes', no_label = 'no', auto_yes_time = None, auto_no_time = None, check_for_cancelled = False ):
2019-07-17 22:10:19 +00:00
2020-04-29 21:44:12 +00:00
with ClientGUITopLevelWindowsPanels.DialogCustomButtonQuestion( win, title ) as dlg:
2019-07-17 22:10:19 +00:00
panel = ClientGUIScrolledPanelsButtonQuestions.QuestionYesNoPanel( dlg, message, yes_label = yes_label, no_label = no_label )
dlg.SetPanel( panel )
2024-02-07 21:22:05 +00:00
if auto_yes_time is not None or auto_no_time is not None:
2019-08-07 22:59:53 +00:00
2019-09-05 00:05:32 +00:00
if auto_yes_time is not None:
2024-02-14 21:20:24 +00:00
CG.client_controller.CallToThread( run_auto_yes_no_gubbins, dlg, HydrusTime.GetNow() + auto_yes_time, dlg.windowTitle(), 'auto-yes', QW.QDialog.Accepted )
2019-09-05 00:05:32 +00:00
2019-09-11 21:51:09 +00:00
elif auto_no_time is not None:
2019-09-05 00:05:32 +00:00
2024-02-14 21:20:24 +00:00
CG.client_controller.CallToThread( run_auto_yes_no_gubbins, dlg, HydrusTime.GetNow() + auto_no_time, dlg.windowTitle(), 'auto-no', QW.QDialog.Rejected )
2019-08-07 22:59:53 +00:00
2019-07-17 22:10:19 +00:00
2024-02-07 21:22:05 +00:00
return dlg.exec() if not check_for_cancelled else ( dlg.exec(), dlg.WasCancelled() )
2019-07-17 22:10:19 +00:00
2024-02-07 21:22:05 +00:00
2022-06-08 19:46:00 +00:00
def GetYesYesNo( win, message, title = 'Are you sure?', yes_tuples = None, no_label = 'no' ):
with ClientGUITopLevelWindowsPanels.DialogCustomButtonQuestion( win, title ) as dlg:
panel = ClientGUIScrolledPanelsButtonQuestions.QuestionYesYesNoPanel( dlg, message, yes_tuples = yes_tuples, no_label = no_label )
dlg.SetPanel( panel )
if dlg.exec() == QW.QDialog.Accepted:
return panel.GetValue()
else:
raise HydrusExceptions.CancelledException( 'Dialog cancelled.' )
2024-04-10 20:36:05 +00:00
def OpenDocumentation( win: QW.QWidget, documentation_path: str ):
local_path = os.path.join( HC.HELP_DIR, documentation_path )
remote_url = "/".join( ( HC.REMOTE_HELP.rstrip( '/' ), documentation_path.lstrip( '/' ) ) )
local_launch_path = local_path
if "#" in local_path:
local_path = local_path[ : local_path.find( '#' ) ]
if os.path.isfile( local_path ):
ClientPaths.LaunchPathInWebBrowser( local_launch_path )
else:
message = 'You do not have a local help! Are you running from source? Would you like to open the online help or see a guide on how to build your own?'
yes_tuples = []
yes_tuples.append( ( 'open online help', 0 ) )
yes_tuples.append( ( 'open how to build guide', 1 ) )
try:
result = GetYesYesNo( win, message, yes_tuples = yes_tuples, no_label = 'forget it' )
except HydrusExceptions.CancelledException:
return
if result == 0:
url = remote_url
else:
url = '/'.join( ( HC.REMOTE_HELP.rstrip( '/' ), HC.DOCUMENTATION_ABOUT_DOCS.lstrip( '/' ) ) )
ClientPaths.LaunchURLInWebBrowser( url )
def PresentClipboardParseError( win: QW.QWidget, content: str, expected_content_description: str, e: Exception ):
MAX_CONTENT_SIZE = 1024
log_message = 'Clipboard Error!\nI was expecting: {}'.format( expected_content_description )
if len( content ) > MAX_CONTENT_SIZE:
log_message += '\nFirst {} of content received (total was {}):\n'.format( HydrusData.ToHumanBytes( MAX_CONTENT_SIZE ), HydrusData.ToHumanBytes( len( content ) ) ) + content[:MAX_CONTENT_SIZE]
else:
log_message += '\nContent received ({}):\n'.format( HydrusData.ToHumanBytes( len( content ) ) ) + content[:MAX_CONTENT_SIZE]
HydrusData.DebugPrint( log_message )
HydrusData.PrintException( e, do_wait = False )
message = 'Sorry, I could not understand what was in the clipboard. I was expecting "{}" but received this text:\n\n{}\n\nMore details have been written to the log, but the general error was:\n\n{}'.format( expected_content_description, HydrusText.ElideText( content, 64 ), repr( e ) )
ClientGUIDialogsMessage.ShowCritical( win, 'Clipboard Error!', message )
2018-11-14 23:10:55 +00:00
def SelectFromList( win, title, choice_tuples, value_to_select = None, sort_tuples = True ):
2021-04-28 21:43:16 +00:00
if len( choice_tuples ) == 1:
( ( text, data ), ) = choice_tuples
return data
2020-04-29 21:44:12 +00:00
with ClientGUITopLevelWindowsPanels.DialogEdit( win, title ) as dlg:
2018-11-14 23:10:55 +00:00
panel = ClientGUIScrolledPanelsEdit.EditSelectFromListPanel( dlg, choice_tuples, value_to_select = value_to_select, sort_tuples = sort_tuples )
dlg.SetPanel( panel )
2019-11-14 03:56:30 +00:00
if dlg.exec() == QW.QDialog.Accepted:
2018-11-14 23:10:55 +00:00
result = panel.GetValue()
return result
else:
2020-03-18 21:35:57 +00:00
raise HydrusExceptions.CancelledException( 'Dialog cancelled.' )
2018-11-14 23:10:55 +00:00
2024-04-10 20:36:05 +00:00
2020-07-29 20:52:44 +00:00
def SelectFromListButtons( win, title, choice_tuples, message = '' ):
2019-01-16 22:40:53 +00:00
2021-04-28 21:43:16 +00:00
if len( choice_tuples ) == 1:
( ( text, data, tooltip ), ) = choice_tuples
return data
2020-04-29 21:44:12 +00:00
with ClientGUITopLevelWindowsPanels.DialogEdit( win, title, hide_buttons = True ) as dlg:
2019-01-16 22:40:53 +00:00
2020-07-29 20:52:44 +00:00
panel = ClientGUIScrolledPanelsEdit.EditSelectFromListButtonsPanel( dlg, choice_tuples, message = message )
dlg.SetPanel( panel )
if dlg.exec() == QW.QDialog.Accepted:
result = panel.GetValue()
return result
else:
raise HydrusExceptions.CancelledException( 'Dialog cancelled.' )
2024-04-10 20:36:05 +00:00
2020-07-29 20:52:44 +00:00
def SelectMultipleFromList( win, title, choice_tuples ):
with ClientGUITopLevelWindowsPanels.DialogEdit( win, title ) as dlg:
panel = ClientGUIScrolledPanelsEdit.EditChooseMultiple( dlg, choice_tuples )
2019-01-16 22:40:53 +00:00
dlg.SetPanel( panel )
2019-11-14 03:56:30 +00:00
if dlg.exec() == QW.QDialog.Accepted:
2019-01-16 22:40:53 +00:00
result = panel.GetValue()
return result
else:
2020-03-18 21:35:57 +00:00
raise HydrusExceptions.CancelledException( 'Dialog cancelled.' )
2019-01-16 22:40:53 +00:00
2024-04-10 20:36:05 +00:00
2023-05-31 20:54:09 +00:00
def SelectServiceKey( service_types = None, service_keys = None, unallowed = None, message = 'select service' ):
if service_types is None:
service_types = HC.ALL_SERVICES
2020-03-04 22:12:53 +00:00
if service_keys is None:
2024-02-14 21:20:24 +00:00
services = CG.client_controller.services_manager.GetServices( service_types )
2020-03-04 22:12:53 +00:00
service_keys = [ service.GetServiceKey() for service in services ]
2022-10-26 20:43:00 +00:00
service_keys = set( service_keys )
2020-03-04 22:12:53 +00:00
if unallowed is not None:
service_keys.difference_update( unallowed )
if len( service_keys ) == 0:
return None
elif len( service_keys ) == 1:
( service_key, ) = service_keys
return service_key
else:
2024-02-14 21:20:24 +00:00
services = { CG.client_controller.services_manager.GetService( service_key ) for service_key in service_keys }
2020-03-04 22:12:53 +00:00
choice_tuples = [ ( service.GetName(), service.GetServiceKey() ) for service in services ]
try:
2024-02-14 21:20:24 +00:00
tlw = CG.client_controller.GetMainTLW()
2020-07-15 20:52:09 +00:00
2022-05-11 21:16:33 +00:00
service_key = SelectFromList( tlw, message, choice_tuples )
2020-03-04 22:12:53 +00:00
return service_key
except HydrusExceptions.CancelledException:
return None
2023-08-09 21:12:17 +00:00