2018-05-02 20:45:20 +00:00
import collections
2021-09-22 21:12:34 +00:00
import hashlib
2013-02-19 00:11:43 +00:00
import os
2021-06-02 21:59:19 +00:00
import typing
2020-04-22 21:00:35 +00:00
2019-11-14 03:56:30 +00:00
from qtpy import QtCore as QC
from qtpy import QtWidgets as QW
from qtpy import QtGui as QG
2020-04-22 21:00:35 +00:00
from hydrus . core import HydrusConstants as HC
from hydrus . core import HydrusData
from hydrus . core import HydrusExceptions
from hydrus . core import HydrusGlobals as HG
from hydrus . core import HydrusSerialisable
from hydrus . core import HydrusText
2020-07-29 20:52:44 +00:00
2020-04-22 21:00:35 +00:00
from hydrus . client import ClientConstants as CC
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 ClientSearch
from hydrus . client import ClientThreading
2020-11-11 22:20:16 +00:00
from hydrus . client . gui import ClientGUIAsync
2020-04-22 21:00:35 +00:00
from hydrus . client . gui import ClientGUICore as CGC
from hydrus . client . gui import ClientGUIDialogs
from hydrus . client . gui import ClientGUIDialogsQuick
from hydrus . client . gui import ClientGUIFunctions
from hydrus . client . gui import ClientGUIMenus
from hydrus . client . gui import ClientGUIShortcuts
from hydrus . client . gui import QtPorting as QP
2021-05-05 20:12:11 +00:00
from hydrus . client . gui . canvas import ClientGUICanvas
2021-06-02 21:59:19 +00:00
from hydrus . client . gui . pages import ClientGUIManagement
from hydrus . client . gui . pages import ClientGUIResults
from hydrus . client . gui . pages import ClientGUISession
from hydrus . client . gui . pages import ClientGUISessionLegacy # to get serialisable data types loaded
2017-10-25 21:45:15 +00:00
2021-10-06 20:59:30 +00:00
def ConvertNumHashesToWeight ( num_hashes : int ) - > int :
return num_hashes
def ConvertNumHashesAndSeedsToWeight ( num_hashes : int , num_seeds : int ) - > int :
return ConvertNumHashesToWeight ( num_hashes ) + ConvertNumSeedsToWeight ( num_seeds )
def ConvertNumSeedsToWeight ( num_seeds : int ) - > int :
return num_seeds * 20
2017-08-16 21:58:06 +00:00
class DialogPageChooser ( ClientGUIDialogs . Dialog ) :
def __init__ ( self , parent , controller ) :
ClientGUIDialogs . Dialog . __init__ ( self , parent , ' new page ' , position = ' center ' )
self . _controller = controller
2020-01-16 02:08:23 +00:00
self . _action_picked = False
2017-08-16 21:58:06 +00:00
self . _result = None
2019-11-14 03:56:30 +00:00
# spawn and add to layout in this order, so focus precipitates from the graphical top
self . _button_7 = QW . QPushButton ( ' ' , self )
self . _button_8 = QW . QPushButton ( ' ' , self )
self . _button_9 = QW . QPushButton ( ' ' , self )
self . _button_4 = QW . QPushButton ( ' ' , self )
self . _button_5 = QW . QPushButton ( ' ' , self )
self . _button_6 = QW . QPushButton ( ' ' , self )
self . _button_1 = QW . QPushButton ( ' ' , self )
self . _button_2 = QW . QPushButton ( ' ' , self )
self . _button_3 = QW . QPushButton ( ' ' , self )
size_policy = self . _button_1 . sizePolicy ( )
size_policy . setVerticalPolicy ( QW . QSizePolicy . Expanding )
size_policy . setRetainSizeWhenHidden ( True )
self . _button_7 . setSizePolicy ( size_policy )
self . _button_8 . setSizePolicy ( size_policy )
self . _button_9 . setSizePolicy ( size_policy )
self . _button_4 . setSizePolicy ( size_policy )
self . _button_5 . setSizePolicy ( size_policy )
self . _button_6 . setSizePolicy ( size_policy )
self . _button_1 . setSizePolicy ( size_policy )
self . _button_2 . setSizePolicy ( size_policy )
self . _button_3 . setSizePolicy ( size_policy )
self . _button_7 . setObjectName ( ' 7 ' )
self . _button_8 . setObjectName ( ' 8 ' )
self . _button_9 . setObjectName ( ' 9 ' )
self . _button_4 . setObjectName ( ' 4 ' )
self . _button_5 . setObjectName ( ' 5 ' )
self . _button_6 . setObjectName ( ' 6 ' )
self . _button_1 . setObjectName ( ' 1 ' )
self . _button_2 . setObjectName ( ' 2 ' )
self . _button_3 . setObjectName ( ' 3 ' )
# this ensures these buttons won't get focus and receive key events, letting dialog handle arrow/number shortcuts
self . _button_7 . setFocusPolicy ( QC . Qt . NoFocus )
self . _button_8 . setFocusPolicy ( QC . Qt . NoFocus )
self . _button_9 . setFocusPolicy ( QC . Qt . NoFocus )
self . _button_4 . setFocusPolicy ( QC . Qt . NoFocus )
self . _button_5 . setFocusPolicy ( QC . Qt . NoFocus )
self . _button_6 . setFocusPolicy ( QC . Qt . NoFocus )
self . _button_1 . setFocusPolicy ( QC . Qt . NoFocus )
self . _button_2 . setFocusPolicy ( QC . Qt . NoFocus )
self . _button_3 . setFocusPolicy ( QC . Qt . NoFocus )
gridbox = QP . GridLayout ( cols = 3 )
QP . AddToLayout ( gridbox , self . _button_7 )
QP . AddToLayout ( gridbox , self . _button_8 )
QP . AddToLayout ( gridbox , self . _button_9 )
QP . AddToLayout ( gridbox , self . _button_4 )
QP . AddToLayout ( gridbox , self . _button_5 )
QP . AddToLayout ( gridbox , self . _button_6 )
QP . AddToLayout ( gridbox , self . _button_1 )
QP . AddToLayout ( gridbox , self . _button_2 )
QP . AddToLayout ( gridbox , self . _button_3 )
self . setLayout ( gridbox )
( width , height ) = ClientGUIFunctions . ConvertTextToPixels ( self , ( 64 , 14 ) )
self . setMinimumWidth ( width )
self . setMinimumHeight ( height )
2017-08-16 21:58:06 +00:00
2022-03-23 20:57:10 +00:00
self . _petition_service_keys = [ service . GetServiceKey ( ) for service in HG . client_controller . services_manager . GetServices ( HC . REPOSITORIES ) if True in ( service . HasPermission ( content_type , HC . PERMISSION_ACTION_MODERATE ) for content_type in HC . SERVICE_TYPES_TO_CONTENT_TYPES [ service . GetServiceType ( ) ] ) ]
2017-08-16 21:58:06 +00:00
self . _InitButtons ( ' home ' )
2019-11-14 03:56:30 +00:00
self . _button_7 . clicked . connect ( lambda : self . _HitButton ( 7 ) )
self . _button_8 . clicked . connect ( lambda : self . _HitButton ( 8 ) )
self . _button_9 . clicked . connect ( lambda : self . _HitButton ( 9 ) )
self . _button_4 . clicked . connect ( lambda : self . _HitButton ( 4 ) )
self . _button_5 . clicked . connect ( lambda : self . _HitButton ( 5 ) )
self . _button_6 . clicked . connect ( lambda : self . _HitButton ( 6 ) )
self . _button_1 . clicked . connect ( lambda : self . _HitButton ( 1 ) )
self . _button_2 . clicked . connect ( lambda : self . _HitButton ( 2 ) )
self . _button_3 . clicked . connect ( lambda : self . _HitButton ( 3 ) )
2017-08-16 21:58:06 +00:00
def _AddEntry ( self , button , entry ) :
2021-06-02 21:59:19 +00:00
button_id = int ( button . objectName ( ) )
2017-08-16 21:58:06 +00:00
2021-06-02 21:59:19 +00:00
self . _command_dict [ button_id ] = entry
2017-08-16 21:58:06 +00:00
( entry_type , obj ) = entry
if entry_type == ' menu ' :
2019-11-14 03:56:30 +00:00
button . setText ( obj )
2017-08-16 21:58:06 +00:00
elif entry_type == ' page_duplicate_filter ' :
2019-11-14 03:56:30 +00:00
button . setText ( ' duplicates processing ' )
2017-08-16 21:58:06 +00:00
elif entry_type == ' pages_notebook ' :
2019-11-14 03:56:30 +00:00
button . setText ( ' page of pages ' )
2017-08-16 21:58:06 +00:00
elif entry_type in ( ' page_query ' , ' page_petitions ' ) :
name = HG . client_controller . services_manager . GetService ( obj ) . GetName ( )
2019-11-14 03:56:30 +00:00
button . setText ( name )
2017-08-16 21:58:06 +00:00
elif entry_type == ' page_import_gallery ' :
2019-11-14 03:56:30 +00:00
button . setText ( ' gallery ' )
2017-08-16 21:58:06 +00:00
2018-04-05 01:22:26 +00:00
elif entry_type == ' page_import_simple_downloader ' :
2017-08-16 21:58:06 +00:00
2019-11-14 03:56:30 +00:00
button . setText ( ' simple downloader ' )
2017-08-16 21:58:06 +00:00
2018-05-23 21:05:06 +00:00
elif entry_type == ' page_import_watcher ' :
2017-08-16 21:58:06 +00:00
2019-11-14 03:56:30 +00:00
button . setText ( ' watcher ' )
2017-08-16 21:58:06 +00:00
elif entry_type == ' page_import_urls ' :
2019-11-14 03:56:30 +00:00
button . setText ( ' urls ' )
2017-08-16 21:58:06 +00:00
2019-11-14 03:56:30 +00:00
button . show ( )
2017-08-16 21:58:06 +00:00
2021-06-02 21:59:19 +00:00
def _HitButton ( self , button_id ) :
2017-08-16 21:58:06 +00:00
2021-06-02 21:59:19 +00:00
if button_id in self . _command_dict :
2017-08-16 21:58:06 +00:00
2021-06-02 21:59:19 +00:00
( entry_type , obj ) = self . _command_dict [ button_id ]
2017-08-16 21:58:06 +00:00
if entry_type == ' menu ' :
self . _InitButtons ( obj )
else :
if entry_type == ' page_query ' :
file_service_key = obj
page_name = ' files '
search_enabled = True
2017-12-06 22:06:56 +00:00
new_options = self . _controller . new_options
2017-08-16 21:58:06 +00:00
tag_service_key = new_options . GetKey ( ' default_tag_service_search_page ' )
if not self . _controller . services_manager . ServiceExists ( tag_service_key ) :
tag_service_key = CC . COMBINED_TAG_SERVICE_KEY
2022-01-19 21:28:59 +00:00
location_context = ClientLocation . LocationContext . STATICCreateSimple ( file_service_key )
2021-05-27 00:09:06 +00:00
2020-03-11 21:52:11 +00:00
tag_search_context = ClientSearch . TagSearchContext ( service_key = tag_service_key )
2022-01-19 21:28:59 +00:00
file_search_context = ClientSearch . FileSearchContext ( location_context = location_context , tag_search_context = tag_search_context )
2017-08-16 21:58:06 +00:00
2020-04-01 21:51:42 +00:00
self . _result = ( ' page ' , ClientGUIManagement . CreateManagementControllerQuery ( page_name , file_search_context , search_enabled ) )
2017-08-16 21:58:06 +00:00
elif entry_type == ' page_duplicate_filter ' :
self . _result = ( ' page ' , ClientGUIManagement . CreateManagementControllerDuplicateFilter ( ) )
elif entry_type == ' pages_notebook ' :
self . _result = ( ' pages ' , None )
elif entry_type == ' page_import_gallery ' :
2018-08-01 20:44:57 +00:00
self . _result = ( ' page ' , ClientGUIManagement . CreateManagementControllerImportGallery ( ) )
2017-08-16 21:58:06 +00:00
2018-04-05 01:22:26 +00:00
elif entry_type == ' page_import_simple_downloader ' :
2017-08-16 21:58:06 +00:00
2018-04-05 01:22:26 +00:00
self . _result = ( ' page ' , ClientGUIManagement . CreateManagementControllerImportSimpleDownloader ( ) )
2017-08-16 21:58:06 +00:00
2018-05-23 21:05:06 +00:00
elif entry_type == ' page_import_watcher ' :
2017-08-16 21:58:06 +00:00
2018-08-01 20:44:57 +00:00
self . _result = ( ' page ' , ClientGUIManagement . CreateManagementControllerImportMultipleWatcher ( ) )
2017-08-16 21:58:06 +00:00
elif entry_type == ' page_import_urls ' :
self . _result = ( ' page ' , ClientGUIManagement . CreateManagementControllerImportURLs ( ) )
elif entry_type == ' page_petitions ' :
petition_service_key = obj
self . _result = ( ' page ' , ClientGUIManagement . CreateManagementControllerPetitions ( petition_service_key ) )
2020-01-16 02:08:23 +00:00
self . _action_picked = True
2019-11-14 03:56:30 +00:00
self . done ( QW . QDialog . Accepted )
2017-08-16 21:58:06 +00:00
def _InitButtons ( self , menu_keyword ) :
self . _command_dict = { }
entries = [ ]
if menu_keyword == ' home ' :
2022-05-04 21:40:27 +00:00
entries . append ( ( ' menu ' , ' file search ' ) )
2017-08-16 21:58:06 +00:00
entries . append ( ( ' menu ' , ' download ' ) )
if len ( self . _petition_service_keys ) > 0 :
entries . append ( ( ' menu ' , ' petitions ' ) )
entries . append ( ( ' menu ' , ' special ' ) )
2022-05-04 21:40:27 +00:00
elif menu_keyword == ' file search ' :
2017-08-16 21:58:06 +00:00
2022-03-23 20:57:10 +00:00
for service_key in self . _controller . services_manager . GetServiceKeys ( ( HC . LOCAL_FILE_DOMAIN , ) ) :
entries . append ( ( ' page_query ' , service_key ) )
2022-05-25 21:30:53 +00:00
if len ( entries ) > 1 :
entries . append ( ( ' page_query ' , CC . COMBINED_LOCAL_MEDIA_SERVICE_KEY ) )
2017-08-16 21:58:06 +00:00
entries . append ( ( ' page_query ' , CC . TRASH_SERVICE_KEY ) )
2019-05-22 22:35:06 +00:00
2022-03-23 20:57:10 +00:00
if self . _controller . new_options . GetBoolean ( ' advanced_mode ' ) :
2019-05-22 22:35:06 +00:00
entries . append ( ( ' page_query ' , CC . COMBINED_LOCAL_FILE_SERVICE_KEY ) )
2017-08-16 21:58:06 +00:00
2022-03-23 20:57:10 +00:00
for service_key in self . _controller . services_manager . GetServiceKeys ( ( HC . FILE_REPOSITORY , ) ) :
2017-08-16 21:58:06 +00:00
2022-03-23 20:57:10 +00:00
entries . append ( ( ' page_query ' , service_key ) )
2017-08-16 21:58:06 +00:00
elif menu_keyword == ' download ' :
entries . append ( ( ' page_import_urls ' , None ) )
2018-05-23 21:05:06 +00:00
entries . append ( ( ' page_import_watcher ' , None ) )
2018-08-01 20:44:57 +00:00
entries . append ( ( ' page_import_gallery ' , None ) )
2018-04-05 01:22:26 +00:00
entries . append ( ( ' page_import_simple_downloader ' , None ) )
2017-08-16 21:58:06 +00:00
elif menu_keyword == ' petitions ' :
entries = [ ( ' page_petitions ' , service_key ) for service_key in self . _petition_service_keys ]
elif menu_keyword == ' special ' :
entries . append ( ( ' pages_notebook ' , None ) )
entries . append ( ( ' page_duplicate_filter ' , None ) )
if len ( entries ) < = 4 :
2019-11-14 03:56:30 +00:00
self . _button_1 . setVisible ( False )
self . _button_3 . setVisible ( False )
self . _button_5 . setVisible ( False )
self . _button_7 . setVisible ( False )
self . _button_9 . setVisible ( False )
2017-08-16 21:58:06 +00:00
potential_buttons = [ self . _button_8 , self . _button_4 , self . _button_6 , self . _button_2 ]
elif len ( entries ) < = 9 :
potential_buttons = [ self . _button_7 , self . _button_8 , self . _button_9 , self . _button_4 , self . _button_5 , self . _button_6 , self . _button_1 , self . _button_2 , self . _button_3 ]
else :
# sort out a multi-page solution? maybe only if this becomes a big thing; the person can always select from the menus, yeah?
potential_buttons = [ self . _button_7 , self . _button_8 , self . _button_9 , self . _button_4 , self . _button_5 , self . _button_6 , self . _button_1 , self . _button_2 , self . _button_3 ]
entries = entries [ : 9 ]
2018-04-18 22:10:15 +00:00
for entry in entries :
self . _AddEntry ( potential_buttons . pop ( 0 ) , entry )
2017-08-16 21:58:06 +00:00
unused_buttons = potential_buttons
2018-08-01 20:44:57 +00:00
for button in unused_buttons :
2019-11-14 03:56:30 +00:00
button . setVisible ( False )
2018-08-01 20:44:57 +00:00
2017-08-16 21:58:06 +00:00
2020-01-16 02:08:23 +00:00
def event ( self , event ) :
if event . type ( ) == QC . QEvent . WindowDeactivate and not self . _action_picked :
self . done ( QW . QDialog . Rejected )
return True
else :
return ClientGUIDialogs . Dialog . event ( self , event )
2019-11-14 03:56:30 +00:00
def keyPressEvent ( self , event ) :
2017-08-16 21:58:06 +00:00
2021-06-02 21:59:19 +00:00
button_id = None
2017-08-16 21:58:06 +00:00
2018-05-16 20:09:50 +00:00
( modifier , key ) = ClientGUIShortcuts . ConvertKeyEventToSimpleTuple ( event )
2017-08-16 21:58:06 +00:00
2021-06-02 21:59:19 +00:00
if key == QC . Qt . Key_Up : button_id = 8
elif key == QC . Qt . Key_Left : button_id = 4
elif key == QC . Qt . Key_Right : button_id = 6
elif key == QC . Qt . Key_Down : button_id = 2
elif key == QC . Qt . Key_1 and modifier == QC . Qt . KeypadModifier : button_id = 1
elif key == QC . Qt . Key_2 and modifier == QC . Qt . KeypadModifier : button_id = 2
elif key == QC . Qt . Key_3 and modifier == QC . Qt . KeypadModifier : button_id = 3
elif key == QC . Qt . Key_4 and modifier == QC . Qt . KeypadModifier : button_id = 4
elif key == QC . Qt . Key_5 and modifier == QC . Qt . KeypadModifier : button_id = 5
elif key == QC . Qt . Key_6 and modifier == QC . Qt . KeypadModifier : button_id = 6
elif key == QC . Qt . Key_7 and modifier == QC . Qt . KeypadModifier : button_id = 7
elif key == QC . Qt . Key_8 and modifier == QC . Qt . KeypadModifier : button_id = 8
elif key == QC . Qt . Key_9 and modifier == QC . Qt . KeypadModifier : button_id = 9
2020-01-16 02:08:23 +00:00
elif key in ( QC . Qt . Key_Enter , QC . Qt . Key_Return ) :
# get the 'first', scanning from top-left
for possible_id in ( 7 , 8 , 9 , 4 , 5 , 6 , 1 , 2 , 3 ) :
if possible_id in self . _command_dict :
2021-06-02 21:59:19 +00:00
button_id = possible_id
2020-01-16 02:08:23 +00:00
break
2019-11-14 03:56:30 +00:00
elif key == QC . Qt . Key_Escape :
self . done ( QW . QDialog . Rejected )
2017-08-16 21:58:06 +00:00
return
else :
2019-11-14 03:56:30 +00:00
event . ignore ( )
2017-08-16 21:58:06 +00:00
2021-06-02 21:59:19 +00:00
if button_id is not None :
2017-08-16 21:58:06 +00:00
2021-06-02 21:59:19 +00:00
self . _HitButton ( button_id )
2017-08-16 21:58:06 +00:00
def GetValue ( self ) :
return self . _result
2019-11-14 03:56:30 +00:00
class Page ( QW . QSplitter ) :
2013-02-19 00:11:43 +00:00
2017-07-05 21:09:28 +00:00
def __init__ ( self , parent , controller , management_controller , initial_hashes ) :
2015-06-24 22:10:14 +00:00
2019-11-14 03:56:30 +00:00
QW . QSplitter . __init__ ( self , parent )
2013-02-19 00:11:43 +00:00
2020-04-08 21:10:11 +00:00
self . _parent_notebook = parent
2015-11-25 22:00:57 +00:00
self . _controller = controller
2018-05-23 21:05:06 +00:00
self . _page_key = self . _controller . AcquirePageKey ( )
2015-06-24 22:10:14 +00:00
self . _management_controller = management_controller
2017-07-05 21:09:28 +00:00
self . _initial_hashes = initial_hashes
2015-06-24 22:10:14 +00:00
self . _management_controller . SetKey ( ' page ' , self . _page_key )
2015-03-04 22:44:32 +00:00
2020-11-11 22:20:16 +00:00
self . _initialised = len ( initial_hashes ) == 0
self . _pre_initialisation_media_results = [ ]
2017-08-16 21:58:06 +00:00
2013-02-19 00:11:43 +00:00
self . _pretty_status = ' '
2019-11-14 03:56:30 +00:00
self . _search_preview_split = QW . QSplitter ( self )
2013-02-19 00:11:43 +00:00
2020-05-13 19:03:16 +00:00
self . _done_split_setups = False
2019-11-14 03:56:30 +00:00
self . _management_panel = ClientGUIManagement . CreateManagementPanel ( self . _search_preview_split , self , self . _controller , self . _management_controller )
2013-02-19 00:11:43 +00:00
2019-11-14 03:56:30 +00:00
self . _preview_panel = QW . QFrame ( self . _search_preview_split )
2019-11-20 23:10:46 +00:00
self . _preview_panel . setFrameStyle ( QW . QFrame . Panel | QW . QFrame . Sunken )
self . _preview_panel . setLineWidth ( 2 )
2013-02-19 00:11:43 +00:00
2022-01-19 21:28:59 +00:00
self . _preview_canvas = ClientGUICanvas . CanvasPanel ( self . _preview_panel , self . _page_key , self . _management_controller . GetVariable ( ' location_context ' ) )
2021-04-28 21:43:16 +00:00
2022-01-19 21:28:59 +00:00
self . _management_panel . locationChanged . connect ( self . _preview_canvas . SetLocationContext )
2013-02-19 00:11:43 +00:00
2020-06-24 21:25:24 +00:00
self . _media_panel = self . _management_panel . GetDefaultEmptyMediaPanel ( )
2013-09-11 21:28:19 +00:00
2019-11-14 03:56:30 +00:00
vbox = QP . VBoxLayout ( margin = 0 )
2013-09-11 21:28:19 +00:00
2019-11-14 03:56:30 +00:00
QP . AddToLayout ( vbox , self . _preview_canvas , CC . FLAGS_EXPAND_SIZER_BOTH_WAYS )
2013-02-19 00:11:43 +00:00
2019-11-14 03:56:30 +00:00
self . _preview_panel . setLayout ( vbox )
2015-06-24 22:10:14 +00:00
2019-11-14 03:56:30 +00:00
self . widget ( 0 ) . setMinimumWidth ( 120 )
self . widget ( 1 ) . setMinimumWidth ( 120 )
self . setStretchFactor ( 0 , 0 )
self . setStretchFactor ( 1 , 1 )
self . _handle_event_filter = QP . WidgetEventFilter ( self . handle ( 1 ) )
self . _handle_event_filter . EVT_LEFT_DCLICK ( self . EventUnsplit )
self . _search_preview_split . widget ( 0 ) . setMinimumHeight ( 180 )
self . _search_preview_split . widget ( 1 ) . setMinimumHeight ( 180 )
self . _search_preview_split . setStretchFactor ( 0 , 1 )
self . _search_preview_split . setStretchFactor ( 1 , 0 )
2019-11-20 23:10:46 +00:00
2019-11-14 03:56:30 +00:00
self . _search_preview_split . _handle_event_filter = QP . WidgetEventFilter ( self . _search_preview_split . handle ( 1 ) )
self . _search_preview_split . _handle_event_filter . EVT_LEFT_DCLICK ( self . EventPreviewUnsplit )
2015-06-24 22:10:14 +00:00
2018-03-07 22:48:29 +00:00
self . _controller . sub ( self , ' SetSplitterPositions ' , ' set_splitter_positions ' )
2013-02-19 00:11:43 +00:00
2021-09-22 21:12:34 +00:00
self . _current_session_page_container = None
self . _current_session_page_container_hashes_hash = self . _GetCurrentSessionPageHashesHash ( )
self . _current_session_page_container_timestamp = 0
2020-03-25 21:15:57 +00:00
self . _ConnectMediaPanelSignals ( )
def _ConnectMediaPanelSignals ( self ) :
self . _media_panel . refreshQuery . connect ( self . RefreshQuery )
self . _media_panel . focusMediaChanged . connect ( self . _preview_canvas . SetMedia )
2020-04-01 21:51:42 +00:00
self . _media_panel . focusMediaCleared . connect ( self . _preview_canvas . ClearMedia )
2022-03-02 21:44:08 +00:00
self . _media_panel . focusMediaPaused . connect ( self . _preview_canvas . PauseMedia )
2020-06-24 21:25:24 +00:00
self . _media_panel . statusTextChanged . connect ( self . _SetPrettyStatus )
2020-03-25 21:15:57 +00:00
self . _management_panel . ConnectMediaPanelSignals ( self . _media_panel )
2017-07-05 21:09:28 +00:00
2021-09-22 21:12:34 +00:00
def _GetCurrentSessionPageHashesHash ( self ) :
hashlist = self . GetHashes ( )
hashlist_hashable = tuple ( hashlist )
return hash ( hashlist_hashable )
def _SetCurrentPageContainer ( self , page_container : ClientGUISession . GUISessionContainerPageSingle ) :
self . _current_session_page_container = page_container
self . _current_session_page_container_hashes_hash = self . _GetCurrentSessionPageHashesHash ( )
self . _current_session_page_container_timestamp = HydrusData . GetNow ( )
2020-06-24 21:25:24 +00:00
def _SetPrettyStatus ( self , status : str ) :
2017-07-05 21:09:28 +00:00
self . _pretty_status = status
2018-01-03 22:37:30 +00:00
self . _controller . gui . SetStatusBarDirty ( )
2017-07-05 21:09:28 +00:00
def _SwapMediaPanel ( self , new_panel ) :
2018-02-21 21:59:37 +00:00
# if a new media page comes in while its menu is open, we can enter program instability.
# so let's just put it off.
2019-11-14 03:56:30 +00:00
previous_sizes = self . sizes ( )
2020-03-25 21:15:57 +00:00
self . _preview_canvas . ClearMedia ( )
2017-07-05 21:09:28 +00:00
self . _media_panel . ClearPageKey ( )
2019-08-21 21:34:01 +00:00
media_collect = self . _management_panel . GetMediaCollect ( )
2019-05-15 20:35:00 +00:00
2019-08-21 21:34:01 +00:00
if media_collect . DoesACollect ( ) :
2019-05-15 20:35:00 +00:00
2019-08-21 21:34:01 +00:00
new_panel . Collect ( self . _page_key , media_collect )
2019-05-15 20:35:00 +00:00
2020-04-01 21:51:42 +00:00
media_sort = self . _management_panel . GetMediaSort ( )
2019-05-22 22:35:06 +00:00
2020-04-01 21:51:42 +00:00
new_panel . Sort ( media_sort )
2019-05-22 22:35:06 +00:00
2019-05-15 20:35:00 +00:00
2019-11-14 03:56:30 +00:00
self . _media_panel . setParent ( None )
2019-11-20 23:10:46 +00:00
old_panel = self . _media_panel
2019-11-14 03:56:30 +00:00
self . addWidget ( new_panel )
self . setSizes ( previous_sizes )
2017-07-05 21:09:28 +00:00
2019-11-20 23:10:46 +00:00
self . setStretchFactor ( 1 , 1 )
2018-05-16 20:09:50 +00:00
2017-07-05 21:09:28 +00:00
self . _media_panel = new_panel
2020-03-25 21:15:57 +00:00
self . _ConnectMediaPanelSignals ( )
2018-02-21 21:59:37 +00:00
self . _controller . pub ( ' refresh_page_name ' , self . _page_key )
2022-02-16 22:10:11 +00:00
self . _controller . pub ( ' notify_new_pages_count ' )
2019-11-20 23:10:46 +00:00
def clean_up_old_panel ( ) :
2020-03-04 22:12:53 +00:00
if CGC . core ( ) . MenuIsOpen ( ) :
2019-11-20 23:10:46 +00:00
2021-06-23 21:11:38 +00:00
self . _controller . CallLaterQtSafe ( self , 0.5 , ' menu closed panel swap loop ' , clean_up_old_panel )
2019-11-20 23:10:46 +00:00
return
old_panel . deleteLater ( )
clean_up_old_panel ( )
2013-02-19 00:11:43 +00:00
2020-11-11 22:20:16 +00:00
def AddMediaResults ( self , media_results ) :
if self . _initialised :
self . _media_panel . AddMediaResults ( self . _page_key , media_results )
else :
self . _pre_initialisation_media_results . extend ( media_results )
2018-05-02 20:45:20 +00:00
def CheckAbleToClose ( self ) :
self . _management_panel . CheckAbleToClose ( )
2019-06-19 22:08:48 +00:00
def CleanBeforeClose ( self ) :
self . _management_panel . CleanBeforeClose ( )
2020-03-25 21:15:57 +00:00
self . _media_panel . SetFocusedMedia ( None )
2019-06-19 22:08:48 +00:00
2017-07-05 21:09:28 +00:00
def CleanBeforeDestroy ( self ) :
self . _management_panel . CleanBeforeDestroy ( )
2019-11-14 03:56:30 +00:00
self . _preview_canvas . CleanBeforeDestroy ( )
2019-03-06 23:06:22 +00:00
2018-05-23 21:05:06 +00:00
self . _controller . ReleasePageKey ( self . _page_key )
2013-02-19 00:11:43 +00:00
2015-11-04 22:30:28 +00:00
def EventPreviewUnsplit ( self , event ) :
2019-11-14 03:56:30 +00:00
QP . Unsplit ( self . _search_preview_split , self . _preview_panel )
2015-11-04 22:30:28 +00:00
2020-03-25 21:15:57 +00:00
self . _media_panel . SetFocusedMedia ( None )
2015-11-04 22:30:28 +00:00
2013-02-19 00:11:43 +00:00
2015-11-04 22:30:28 +00:00
def EventUnsplit ( self , event ) :
2019-11-14 03:56:30 +00:00
QP . Unsplit ( self , self . _search_preview_split )
2015-11-04 22:30:28 +00:00
2020-03-25 21:15:57 +00:00
self . _media_panel . SetFocusedMedia ( None )
2015-11-04 22:30:28 +00:00
2013-02-19 00:11:43 +00:00
2019-08-21 21:34:01 +00:00
def GetAPIInfoDict ( self , simple ) :
d = { }
d [ ' name ' ] = self . _management_controller . GetPageName ( )
d [ ' page_key ' ] = self . _page_key . hex ( )
d [ ' page_type ' ] = self . _management_controller . GetType ( )
management_info = self . _management_controller . GetAPIInfoDict ( simple )
d [ ' management ' ] = management_info
media_info = self . _media_panel . GetAPIInfoDict ( simple )
d [ ' media ' ] = media_info
return d
2017-07-05 21:09:28 +00:00
def GetHashes ( self ) :
if self . _initialised :
2018-05-30 20:13:21 +00:00
return self . _media_panel . GetHashes ( ordered = True )
2017-07-05 21:09:28 +00:00
else :
2020-11-11 22:20:16 +00:00
hashes = list ( self . _initial_hashes )
hashes . extend ( ( media_result . GetHash ( ) for media_result in self . _pre_initialisation_media_results ) )
hashes = HydrusData . DedupeList ( hashes )
return hashes
2017-07-05 21:09:28 +00:00
2015-06-24 22:10:14 +00:00
def GetManagementController ( self ) :
2014-01-22 21:11:22 +00:00
2015-06-24 22:10:14 +00:00
return self . _management_controller
2014-01-22 21:11:22 +00:00
2013-02-19 00:11:43 +00:00
2019-02-27 23:03:30 +00:00
def GetManagementPanel ( self ) :
return self . _management_panel
2015-06-24 22:10:14 +00:00
# used by autocomplete
def GetMedia ( self ) :
2013-02-19 00:11:43 +00:00
2015-06-24 22:10:14 +00:00
return self . _media_panel . GetSortedMedia ( )
2013-02-19 00:11:43 +00:00
2015-06-24 22:10:14 +00:00
2017-12-20 22:55:48 +00:00
def GetMediaPanel ( self ) :
return self . _media_panel
2017-08-16 21:58:06 +00:00
def GetName ( self ) :
return self . _management_controller . GetPageName ( )
2022-02-16 22:10:11 +00:00
def GetNameForMenu ( self ) - > str :
name_for_menu = self . GetName ( )
( num_files , ( num_value , num_range ) ) = self . GetNumFileSummary ( )
if num_files > 0 :
name_for_menu = ' {} - {} files ' . format ( name_for_menu , HydrusData . ToHumanInt ( num_files ) )
if num_value != num_range :
name_for_menu = ' {} - {} ' . format ( name_for_menu , HydrusData . ConvertValueRangeToPrettyString ( num_value , num_range ) )
return HydrusText . ElideText ( name_for_menu , 32 , elide_center = True )
2018-05-02 20:45:20 +00:00
def GetNumFileSummary ( self ) :
2017-08-02 21:32:54 +00:00
if self . _initialised :
2018-05-02 20:45:20 +00:00
num_files = self . _media_panel . GetNumFiles ( )
2017-08-02 21:32:54 +00:00
else :
2018-05-02 20:45:20 +00:00
num_files = len ( self . _initial_hashes )
2017-08-02 21:32:54 +00:00
2018-05-02 20:45:20 +00:00
( num_value , num_range ) = self . _management_controller . GetValueRange ( )
if num_value == num_range :
( num_value , num_range ) = ( 0 , 0 )
return ( num_files , ( num_value , num_range ) )
2017-08-02 21:32:54 +00:00
2015-09-16 18:11:00 +00:00
def GetPageKey ( self ) :
return self . _page_key
2018-05-23 21:05:06 +00:00
def GetPageKeys ( self ) :
return { self . _page_key }
2020-04-08 21:10:11 +00:00
def GetParentNotebook ( self ) :
return self . _parent_notebook
2022-02-16 22:10:11 +00:00
def GetPrettyStatusForStatusBar ( self ) :
return self . _pretty_status
2021-09-22 21:12:34 +00:00
def GetSerialisablePage ( self , only_changed_page_data , about_to_save ) :
if only_changed_page_data and not self . IsCurrentSessionPageDirty ( ) :
hashes_to_page_data = { }
skipped_unchanged_page_hashes = { self . _current_session_page_container . GetPageDataHash ( ) }
return ( self . _current_session_page_container , hashes_to_page_data , skipped_unchanged_page_hashes )
2021-06-02 21:59:19 +00:00
name = self . GetName ( )
page_data = ClientGUISession . GUISessionPageData ( self . _management_controller , self . GetHashes ( ) )
# this is the only place this is generated. this will be its key/name/id from now on
# we won't regen the hash for identifier since it could change due to object updates etc...
page_data_hash = page_data . GetSerialisedHash ( )
page_container = ClientGUISession . GUISessionContainerPageSingle ( name , page_data_hash )
hashes_to_page_data = { page_data_hash : page_data }
2021-09-22 21:12:34 +00:00
if about_to_save :
self . _SetCurrentPageContainer ( page_container )
skipped_unchanged_page_hashes = set ( )
return ( page_container , hashes_to_page_data , skipped_unchanged_page_hashes )
2021-06-02 21:59:19 +00:00
2019-08-21 21:34:01 +00:00
def GetSessionAPIInfoDict ( self , is_selected = False ) :
2019-06-05 19:42:39 +00:00
root = { }
root [ ' name ' ] = self . GetName ( )
2019-06-26 21:27:18 +00:00
root [ ' page_key ' ] = self . _page_key . hex ( )
2019-06-05 19:42:39 +00:00
root [ ' page_type ' ] = self . _management_controller . GetType ( )
root [ ' focused ' ] = is_selected
return root
2013-02-19 00:11:43 +00:00
def GetSashPositions ( self ) :
2020-05-27 21:27:52 +00:00
hpos = HC . options [ ' hpos ' ]
2013-02-19 00:11:43 +00:00
2020-05-27 21:27:52 +00:00
sizes = self . sizes ( )
if len ( sizes ) > 1 :
2015-11-04 22:30:28 +00:00
2020-05-27 21:27:52 +00:00
if sizes [ 0 ] != 0 :
hpos = sizes [ 0 ]
2015-11-04 22:30:28 +00:00
2020-05-27 21:27:52 +00:00
vpos = HC . options [ ' vpos ' ]
sizes = self . _search_preview_split . sizes ( )
if len ( sizes ) > 1 :
2016-05-25 21:54:03 +00:00
2020-05-27 21:27:52 +00:00
if sizes [ 1 ] != 0 :
vpos = - sizes [ 1 ]
2016-05-25 21:54:03 +00:00
2020-05-27 21:27:52 +00:00
return ( hpos , vpos )
2013-02-19 00:11:43 +00:00
2022-05-18 20:18:25 +00:00
def GetTotalFileSize ( self ) :
if self . _initialised :
return self . _media_panel . GetTotalFileSize ( )
else :
return 0
2021-10-06 20:59:30 +00:00
def GetTotalNumHashesAndSeeds ( self ) :
2019-10-16 20:47:55 +00:00
num_hashes = len ( self . GetHashes ( ) )
num_seeds = self . _management_controller . GetNumSeeds ( )
2021-10-06 20:59:30 +00:00
return ( num_hashes , num_seeds )
def GetTotalWeight ( self ) - > int :
( num_hashes , num_seeds ) = self . GetTotalNumHashesAndSeeds ( )
return ConvertNumHashesAndSeedsToWeight ( num_hashes , num_seeds )
2019-10-16 20:47:55 +00:00
2021-09-22 21:12:34 +00:00
def IsCurrentSessionPageDirty ( self ) :
if self . _current_session_page_container is None :
return True
else :
if self . _GetCurrentSessionPageHashesHash ( ) != self . _current_session_page_container_hashes_hash :
return True
return self . _management_controller . HasSerialisableChangesSince ( self . _current_session_page_container_timestamp )
2021-06-09 20:28:09 +00:00
def IsGalleryDownloaderPage ( self ) :
2018-05-16 20:09:50 +00:00
2021-06-09 20:28:09 +00:00
return self . _management_controller . GetType ( ) == ClientGUIManagement . MANAGEMENT_TYPE_IMPORT_MULTIPLE_GALLERY
2018-05-16 20:09:50 +00:00
2017-08-16 21:58:06 +00:00
def IsImporter ( self ) :
return self . _management_controller . IsImporter ( )
2020-11-11 22:20:16 +00:00
def IsInitialised ( self ) :
return self . _initialised
2021-06-09 20:28:09 +00:00
def IsMultipleWatcherPage ( self ) :
return self . _management_controller . GetType ( ) == ClientGUIManagement . MANAGEMENT_TYPE_IMPORT_MULTIPLE_WATCHER
2017-05-17 21:53:02 +00:00
def IsURLImportPage ( self ) :
return self . _management_controller . GetType ( ) == ClientGUIManagement . MANAGEMENT_TYPE_IMPORT_URLS
2015-11-25 22:00:57 +00:00
def PageHidden ( self ) :
2017-09-27 21:52:54 +00:00
self . _management_panel . PageHidden ( )
self . _media_panel . PageHidden ( )
2020-03-25 21:15:57 +00:00
self . _preview_canvas . PageHidden ( )
2015-11-25 22:00:57 +00:00
2013-02-19 00:11:43 +00:00
2015-11-25 22:00:57 +00:00
def PageShown ( self ) :
2020-05-13 19:03:16 +00:00
if self . isVisible ( ) and not self . _done_split_setups :
2020-05-27 21:27:52 +00:00
self . SetSplitterPositions ( )
2020-05-20 21:36:02 +00:00
2020-05-13 19:03:16 +00:00
self . _done_split_setups = True
2017-09-27 21:52:54 +00:00
self . _management_panel . PageShown ( )
self . _media_panel . PageShown ( )
2020-03-25 21:15:57 +00:00
self . _preview_canvas . PageShown ( )
2015-11-25 22:00:57 +00:00
2013-02-19 00:11:43 +00:00
2015-11-25 22:00:57 +00:00
def RefreshQuery ( self ) :
2017-07-05 21:09:28 +00:00
if self . _initialised :
2020-03-25 21:15:57 +00:00
self . _management_panel . RefreshQuery ( )
2017-07-05 21:09:28 +00:00
2015-11-25 22:00:57 +00:00
2013-02-19 00:11:43 +00:00
2017-07-05 21:09:28 +00:00
def SetMediaFocus ( self ) :
2019-11-14 03:56:30 +00:00
self . _media_panel . setFocus ( QC . Qt . OtherFocusReason )
2017-07-05 21:09:28 +00:00
2019-04-10 22:50:53 +00:00
def SetName ( self , name ) :
2017-08-16 21:58:06 +00:00
return self . _management_controller . SetPageName ( name )
2021-09-22 21:12:34 +00:00
def SetPageContainerClean ( self , page_container : ClientGUISession . GUISessionContainerPageSingle ) :
self . _SetCurrentPageContainer ( page_container )
2015-06-24 22:10:14 +00:00
def SetPrettyStatus ( self , page_key , status ) :
if page_key == self . _page_key :
2017-07-05 21:09:28 +00:00
if self . _initialised :
self . _SetPrettyStatus ( status )
2015-06-24 22:10:14 +00:00
2015-11-25 22:00:57 +00:00
def SetSearchFocus ( self ) :
2018-03-28 21:55:58 +00:00
self . _management_panel . SetSearchFocus ( )
2015-11-25 22:00:57 +00:00
2015-06-24 22:10:14 +00:00
2020-05-27 21:27:52 +00:00
def SetSplitterPositions ( self , hpos = None , vpos = None ) :
if hpos is None :
hpos = HC . options [ ' hpos ' ]
if vpos is None :
vpos = HC . options [ ' vpos ' ]
2018-03-07 22:48:29 +00:00
2019-11-28 01:11:46 +00:00
QP . SplitHorizontally ( self . _search_preview_split , self . _management_panel , self . _preview_panel , vpos )
2018-03-07 22:48:29 +00:00
2019-11-28 01:11:46 +00:00
QP . SplitVertically ( self , self . _search_preview_split , self . _media_panel , hpos )
2018-03-07 22:48:29 +00:00
if HC . options [ ' hide_preview ' ] :
2019-11-14 03:56:30 +00:00
QP . CallAfter ( QP . Unsplit , self . _search_preview_split , self . _preview_panel )
2018-03-07 22:48:29 +00:00
2021-07-14 20:42:19 +00:00
def ShowHideSplit ( self ) :
if QP . SplitterVisibleCount ( self ) > 1 :
QP . Unsplit ( self , self . _search_preview_split )
self . _media_panel . SetFocusedMedia ( None )
else :
self . SetSplitterPositions ( )
2020-11-11 22:20:16 +00:00
def _StartInitialMediaResultsLoad ( self ) :
def qt_code_status ( status ) :
2021-05-05 20:12:11 +00:00
if not self . _initialised :
self . _SetPrettyStatus ( status )
2020-11-11 22:20:16 +00:00
controller = self . _controller
initial_hashes = HydrusData . DedupeList ( self . _initial_hashes )
def work_callable ( ) :
initial_media_results = [ ]
for group_of_initial_hashes in HydrusData . SplitListIntoChunks ( initial_hashes , 256 ) :
more_media_results = controller . Read ( ' media_results ' , group_of_initial_hashes )
initial_media_results . extend ( more_media_results )
status = ' Loading initial files \u2026 ' + HydrusData . ConvertValueRangeToPrettyString ( len ( initial_media_results ) , len ( initial_hashes ) )
2021-06-23 21:11:38 +00:00
controller . CallAfterQtSafe ( self , ' setting status bar loading string ' , qt_code_status , status )
2020-11-11 22:20:16 +00:00
QP . CallAfter ( qt_code_status , status )
hashes_to_media_results = { media_result . GetHash ( ) : media_result for media_result in initial_media_results }
sorted_initial_media_results = [ hashes_to_media_results [ hash ] for hash in initial_hashes if hash in hashes_to_media_results ]
return sorted_initial_media_results
def publish_callable ( media_results ) :
2021-05-05 20:12:11 +00:00
self . _SetPrettyStatus ( ' ' )
2022-01-19 21:28:59 +00:00
location_context = self . _management_controller . GetVariable ( ' location_context ' )
2020-11-11 22:20:16 +00:00
2022-01-19 21:28:59 +00:00
media_panel = ClientGUIResults . MediaPanelThumbnails ( self , self . _page_key , location_context , media_results )
2020-11-11 22:20:16 +00:00
self . _SwapMediaPanel ( media_panel )
if len ( self . _pre_initialisation_media_results ) > 0 :
media_panel . AddMediaResults ( self . _page_key , self . _pre_initialisation_media_results )
self . _pre_initialisation_media_results = [ ]
2021-07-07 20:48:57 +00:00
# do this 'after' so on a long session setup, it all boots once session loaded
HG . client_controller . CallAfterQtSafe ( self , ' starting page controller ' , self . _management_panel . Start )
2020-11-11 22:20:16 +00:00
self . _initialised = True
self . _initial_hashes = [ ]
job = ClientGUIAsync . AsyncQtJob ( self , work_callable , publish_callable )
job . start ( )
2017-08-16 21:58:06 +00:00
def Start ( self ) :
if self . _initial_hashes is not None and len ( self . _initial_hashes ) > 0 :
2020-11-11 22:20:16 +00:00
self . _StartInitialMediaResultsLoad ( )
2017-08-16 21:58:06 +00:00
else :
2021-07-07 20:48:57 +00:00
# do this 'after' so on a long session setup, it all boots once session loaded
HG . client_controller . CallAfterQtSafe ( self , ' starting page controller ' , self . _management_panel . Start )
2017-08-16 21:58:06 +00:00
2021-07-07 20:48:57 +00:00
self . _initialised = True
2017-08-16 21:58:06 +00:00
2018-02-21 21:59:37 +00:00
def SwapMediaPanel ( self , new_panel ) :
2013-02-19 00:11:43 +00:00
2018-02-21 21:59:37 +00:00
self . _SwapMediaPanel ( new_panel )
2017-07-05 21:09:28 +00:00
def TestAbleToClose ( self ) :
2018-05-02 20:45:20 +00:00
try :
self . _management_panel . CheckAbleToClose ( )
except HydrusExceptions . VetoException as e :
2019-01-09 22:59:03 +00:00
reason = str ( e )
2018-05-02 20:45:20 +00:00
2019-09-05 00:05:32 +00:00
message = ' {} Are you sure you want to close it? ' . format ( str ( e ) )
result = ClientGUIDialogsQuick . GetYesNo ( self , message )
2019-11-14 03:56:30 +00:00
if result == QW . QDialog . Rejected :
2018-05-02 20:45:20 +00:00
2019-09-05 00:05:32 +00:00
raise HydrusExceptions . VetoException ( )
2018-05-02 20:45:20 +00:00
2017-07-05 21:09:28 +00:00
2018-05-30 20:13:21 +00:00
def REPEATINGPageUpdate ( self ) :
2017-12-13 22:33:07 +00:00
2018-05-30 20:13:21 +00:00
self . _management_panel . REPEATINGPageUpdate ( )
2017-12-13 22:33:07 +00:00
2020-10-28 22:20:33 +00:00
directions_for_notebook_tabs = { }
directions_for_notebook_tabs [ CC . DIRECTION_UP ] = QW . QTabWidget . North
directions_for_notebook_tabs [ CC . DIRECTION_LEFT ] = QW . QTabWidget . West
directions_for_notebook_tabs [ CC . DIRECTION_RIGHT ] = QW . QTabWidget . East
directions_for_notebook_tabs [ CC . DIRECTION_DOWN ] = QW . QTabWidget . South
2019-11-14 03:56:30 +00:00
class PagesNotebook ( QP . TabWidgetWithDnD ) :
2017-08-09 21:33:51 +00:00
2021-09-22 21:12:34 +00:00
freshSessionLoaded = QC . Signal ( ClientGUISession . GUISessionContainer )
2017-08-16 21:58:06 +00:00
def __init__ ( self , parent , controller , name ) :
2017-08-09 21:33:51 +00:00
2019-11-14 03:56:30 +00:00
QP . TabWidgetWithDnD . __init__ ( self , parent )
2020-04-08 21:10:11 +00:00
self . _parent_notebook = parent
2020-10-28 22:20:33 +00:00
direction = controller . new_options . GetInteger ( ' notebook_tab_alignment ' )
self . setTabPosition ( directions_for_notebook_tabs [ direction ] )
2017-08-09 21:33:51 +00:00
self . _controller = controller
2018-05-23 21:05:06 +00:00
self . _page_key = self . _controller . AcquirePageKey ( )
2017-08-16 21:58:06 +00:00
self . _name = name
2017-08-09 21:33:51 +00:00
2017-08-16 21:58:06 +00:00
self . _next_new_page_index = None
2017-08-09 21:33:51 +00:00
2017-08-23 21:34:25 +00:00
self . _potential_drag_page = None
2017-08-16 21:58:06 +00:00
self . _closed_pages = [ ]
2017-08-09 21:33:51 +00:00
2017-08-16 21:58:06 +00:00
self . _controller . sub ( self , ' RefreshPageName ' , ' refresh_page_name ' )
self . _controller . sub ( self , ' NotifyPageUnclosed ' , ' notify_page_unclosed ' )
2020-10-28 22:20:33 +00:00
self . _controller . sub ( self , ' _UpdateOptions ' , ' notify_new_options ' )
2017-08-09 21:33:51 +00:00
2020-05-13 19:03:16 +00:00
self . currentChanged . connect ( self . pageJustChanged )
2019-11-14 03:56:30 +00:00
self . pageDragAndDropped . connect ( self . _RefreshPageNamesAfterDnD )
2020-07-15 20:52:09 +00:00
self . tabBar ( ) . tabDoubleLeftClicked . connect ( self . _RenamePage )
self . tabBar ( ) . tabMiddleClicked . connect ( self . _ClosePage )
2020-05-20 21:36:02 +00:00
2020-07-22 20:59:16 +00:00
self . tabBar ( ) . tabSpaceDoubleLeftClicked . connect ( self . ChooseNewPage )
self . tabBar ( ) . tabSpaceDoubleMiddleClicked . connect ( self . ChooseNewPage )
2019-11-14 03:56:30 +00:00
self . _previous_page_index = - 1
2017-08-09 21:33:51 +00:00
2020-10-28 22:20:33 +00:00
self . _UpdateOptions ( )
2020-06-11 12:01:08 +00:00
2021-03-17 21:59:28 +00:00
self . tabBar ( ) . installEventFilter ( self )
self . installEventFilter ( self )
2017-08-09 21:33:51 +00:00
2019-11-14 03:56:30 +00:00
def _RefreshPageNamesAfterDnD ( self , page_widget , source_widget ) :
if hasattr ( page_widget , ' GetPageKey ' ) :
self . _controller . pub ( ' refresh_page_name ' , page_widget . GetPageKey ( ) )
2020-04-08 21:10:11 +00:00
source_notebook = source_widget . parentWidget ( )
if hasattr ( source_notebook , ' GetPageKey ' ) :
2019-11-14 03:56:30 +00:00
2020-04-08 21:10:11 +00:00
self . _controller . pub ( ' refresh_page_name ' , source_notebook . GetPageKey ( ) )
2019-11-14 03:56:30 +00:00
2020-04-08 21:10:11 +00:00
2020-10-28 22:20:33 +00:00
def _UpdateOptions ( self ) :
2020-06-11 12:01:08 +00:00
if HG . client_controller . new_options . GetBoolean ( ' elide_page_tab_names ' ) :
self . tabBar ( ) . setElideMode ( QC . Qt . ElideMiddle )
else :
self . tabBar ( ) . setElideMode ( QC . Qt . ElideNone )
2020-10-28 22:20:33 +00:00
direction = HG . client_controller . new_options . GetInteger ( ' notebook_tab_alignment ' )
self . setTabPosition ( directions_for_notebook_tabs [ direction ] )
2020-06-11 12:01:08 +00:00
2019-11-14 03:56:30 +00:00
def _UpdatePreviousPageIndex ( self ) :
self . _previous_page_index = self . currentIndex ( )
2020-07-15 20:52:09 +00:00
2019-11-14 03:56:30 +00:00
2017-08-16 21:58:06 +00:00
def _ChooseNewPage ( self , insertion_index = None ) :
2017-08-09 21:33:51 +00:00
2017-08-16 21:58:06 +00:00
self . _next_new_page_index = insertion_index
with DialogPageChooser ( self , self . _controller ) as dlg :
2017-08-09 21:33:51 +00:00
2019-11-14 03:56:30 +00:00
if dlg . exec ( ) == QW . QDialog . Accepted :
2017-08-16 21:58:06 +00:00
( page_type , page_data ) = dlg . GetValue ( )
if page_type == ' pages ' :
self . NewPagesNotebook ( )
elif page_type == ' page ' :
management_controller = page_data
self . NewPage ( management_controller )
2017-08-09 21:33:51 +00:00
2018-05-16 20:09:50 +00:00
def _CloseAllPages ( self , polite = True , delete_pages = False ) :
2017-08-09 21:33:51 +00:00
2019-11-14 03:56:30 +00:00
closees = [ index for index in range ( self . count ( ) ) ]
2017-08-09 21:33:51 +00:00
2018-05-16 20:09:50 +00:00
self . _ClosePages ( closees , polite , delete_pages = delete_pages )
2017-08-09 21:33:51 +00:00
2017-08-16 21:58:06 +00:00
def _CloseLeftPages ( self , from_index ) :
2017-08-09 21:33:51 +00:00
2017-08-16 21:58:06 +00:00
message = ' Close all pages to the left? '
2019-09-05 00:05:32 +00:00
result = ClientGUIDialogsQuick . GetYesNo ( self , message )
2019-11-14 03:56:30 +00:00
if result == QW . QDialog . Accepted :
2017-08-16 21:58:06 +00:00
2019-11-14 03:56:30 +00:00
closees = [ index for index in range ( self . count ( ) ) if index < from_index ]
2019-09-05 00:05:32 +00:00
self . _ClosePages ( closees )
2017-08-16 21:58:06 +00:00
2017-08-09 21:33:51 +00:00
2017-08-16 21:58:06 +00:00
def _CloseOtherPages ( self , except_index ) :
2017-08-09 21:33:51 +00:00
2017-08-16 21:58:06 +00:00
message = ' Close all other pages? '
2017-08-09 21:33:51 +00:00
2019-09-05 00:05:32 +00:00
result = ClientGUIDialogsQuick . GetYesNo ( self , message )
2019-11-14 03:56:30 +00:00
if result == QW . QDialog . Accepted :
2017-08-09 21:33:51 +00:00
2019-11-14 03:56:30 +00:00
closees = [ index for index in range ( self . count ( ) ) if index != except_index ]
2019-09-05 00:05:32 +00:00
self . _ClosePages ( closees )
2017-08-09 21:33:51 +00:00
2018-05-16 20:09:50 +00:00
def _ClosePage ( self , index , polite = True , delete_page = False ) :
2017-08-09 21:33:51 +00:00
2017-08-16 21:58:06 +00:00
self . _controller . ResetIdleTimer ( )
self . _controller . ResetPageChangeTimer ( )
2017-08-09 21:33:51 +00:00
2019-11-14 03:56:30 +00:00
if index == - 1 or index > self . count ( ) - 1 :
2017-08-09 21:33:51 +00:00
2017-08-16 21:58:06 +00:00
return False
2017-08-09 21:33:51 +00:00
2019-11-14 03:56:30 +00:00
page = self . widget ( index )
2017-08-09 21:33:51 +00:00
2017-08-16 21:58:06 +00:00
if polite :
2017-08-09 21:33:51 +00:00
2017-08-16 21:58:06 +00:00
try :
2017-08-09 21:33:51 +00:00
2017-08-16 21:58:06 +00:00
page . TestAbleToClose ( )
2017-08-09 21:33:51 +00:00
2018-05-02 20:45:20 +00:00
except HydrusExceptions . VetoException :
2017-08-09 21:33:51 +00:00
2017-08-16 21:58:06 +00:00
return False
2017-08-09 21:33:51 +00:00
2019-06-19 22:08:48 +00:00
page . CleanBeforeClose ( )
2017-08-09 21:33:51 +00:00
2017-08-23 21:34:25 +00:00
page_key = page . GetPageKey ( )
self . _closed_pages . append ( ( index , page_key ) )
2017-08-09 21:33:51 +00:00
2019-11-14 03:56:30 +00:00
self . removeTab ( index )
self . _UpdatePreviousPageIndex ( )
2013-12-11 22:09:25 +00:00
2017-08-23 21:34:25 +00:00
self . _controller . pub ( ' refresh_page_name ' , self . _page_key )
2018-05-16 20:09:50 +00:00
if delete_page :
self . _controller . pub ( ' notify_deleted_page ' , page )
else :
self . _controller . pub ( ' notify_closed_page ' , page )
2013-12-11 22:09:25 +00:00
2017-08-16 21:58:06 +00:00
return True
2013-12-11 22:09:25 +00:00
2013-02-19 00:11:43 +00:00
2018-05-16 20:09:50 +00:00
def _ClosePages ( self , indices , polite = True , delete_pages = False ) :
2015-03-25 22:04:19 +00:00
2017-08-16 21:58:06 +00:00
indices = list ( indices )
2013-02-19 00:11:43 +00:00
2017-08-16 21:58:06 +00:00
indices . sort ( reverse = True ) # so we are closing from the end first
for index in indices :
2015-06-24 22:10:14 +00:00
2018-05-16 20:09:50 +00:00
successful = self . _ClosePage ( index , polite , delete_page = delete_pages )
2015-06-24 22:10:14 +00:00
2017-08-16 21:58:06 +00:00
if not successful :
break
2015-06-24 22:10:14 +00:00
2013-09-04 16:48:44 +00:00
2013-02-19 00:11:43 +00:00
2017-08-16 21:58:06 +00:00
def _CloseRightPages ( self , from_index ) :
2013-03-27 20:02:51 +00:00
2017-08-16 21:58:06 +00:00
message = ' Close all pages to the right? '
2019-09-05 00:05:32 +00:00
result = ClientGUIDialogsQuick . GetYesNo ( self , message )
2019-11-14 03:56:30 +00:00
if result == QW . QDialog . Accepted :
2014-01-22 21:11:22 +00:00
2019-11-14 03:56:30 +00:00
closees = [ index for index in range ( self . count ( ) ) if index > from_index ]
2019-09-05 00:05:32 +00:00
self . _ClosePages ( closees )
2017-08-16 21:58:06 +00:00
2020-03-04 22:12:53 +00:00
def _DuplicatePage ( self , index ) :
if index == - 1 or index > self . count ( ) - 1 :
return False
page = self . widget ( index )
2021-09-22 21:12:34 +00:00
only_changed_page_data = False
about_to_save = False
( container , hashes_to_page_data , skipped_unchanged_page_hashes ) = page . GetSerialisablePage ( only_changed_page_data , about_to_save )
2020-03-04 22:12:53 +00:00
2021-06-02 21:59:19 +00:00
top_notebook_container = ClientGUISession . GUISessionContainerPageNotebook ( ' dupe top notebook ' , page_containers = [ container ] )
2020-03-04 22:12:53 +00:00
2021-06-02 21:59:19 +00:00
session = ClientGUISession . GUISessionContainer ( ' dupe session ' , top_notebook_container = top_notebook_container , hashes_to_page_data = hashes_to_page_data )
2020-03-18 21:35:57 +00:00
2021-09-22 21:12:34 +00:00
self . InsertSession ( index + 1 , session , session_is_clean = False )
2020-03-04 22:12:53 +00:00
2017-08-16 21:58:06 +00:00
def _GetDefaultPageInsertionIndex ( self ) :
2017-12-06 22:06:56 +00:00
new_options = self . _controller . new_options
2017-08-16 21:58:06 +00:00
new_page_goes = new_options . GetInteger ( ' default_new_page_goes ' )
2019-11-14 03:56:30 +00:00
current_index = self . currentIndex ( )
2017-08-16 21:58:06 +00:00
2019-11-14 03:56:30 +00:00
if current_index == - 1 :
2017-08-16 21:58:06 +00:00
new_page_goes = CC . NEW_PAGE_GOES_FAR_LEFT
if new_page_goes == CC . NEW_PAGE_GOES_FAR_LEFT :
insertion_index = 0
elif new_page_goes == CC . NEW_PAGE_GOES_LEFT_OF_CURRENT :
insertion_index = current_index
elif new_page_goes == CC . NEW_PAGE_GOES_RIGHT_OF_CURRENT :
insertion_index = current_index + 1
elif new_page_goes == CC . NEW_PAGE_GOES_FAR_RIGHT :
2019-11-14 03:56:30 +00:00
insertion_index = self . count ( )
2017-08-16 21:58:06 +00:00
return insertion_index
def _GetMediaPages ( self , only_my_level ) :
results = [ ]
for page in self . _GetPages ( ) :
if isinstance ( page , PagesNotebook ) :
if not only_my_level :
results . extend ( page . GetMediaPages ( ) )
else :
results . append ( page )
return results
2017-08-23 21:34:25 +00:00
def _GetIndex ( self , page_key ) :
2019-11-14 03:56:30 +00:00
for ( page , index ) in ( ( self . widget ( index ) , index ) for index in range ( self . count ( ) ) ) :
2017-08-23 21:34:25 +00:00
if page . GetPageKey ( ) == page_key :
return index
raise HydrusExceptions . DataMissing ( )
2022-02-02 22:14:01 +00:00
def _GetNotebookFromScreenPosition ( self , screen_position ) - > " PagesNotebook " :
2017-08-16 21:58:06 +00:00
2019-11-14 03:56:30 +00:00
current_page = self . currentWidget ( )
2017-08-16 21:58:06 +00:00
if current_page is None or not isinstance ( current_page , PagesNotebook ) :
2017-08-23 21:34:25 +00:00
return self
2017-08-16 21:58:06 +00:00
else :
2022-02-09 21:04:42 +00:00
on_child_notebook_somewhere = current_page . mapFromGlobal ( screen_position ) . y ( ) > current_page . pos ( ) . y ( )
2017-08-30 20:27:47 +00:00
2017-12-20 22:55:48 +00:00
if on_child_notebook_somewhere :
2017-08-16 21:58:06 +00:00
2017-08-23 21:34:25 +00:00
return current_page . _GetNotebookFromScreenPosition ( screen_position )
2017-08-16 21:58:06 +00:00
2017-08-23 21:34:25 +00:00
return self
2017-08-16 21:58:06 +00:00
2017-08-23 21:34:25 +00:00
def _GetPages ( self ) :
2017-08-16 21:58:06 +00:00
2019-11-14 03:56:30 +00:00
return [ self . widget ( i ) for i in range ( self . count ( ) ) ]
2017-08-23 21:34:25 +00:00
2020-09-23 21:02:02 +00:00
def _GetPageFromName ( self , page_name , only_media_pages = False ) :
2018-02-14 21:47:18 +00:00
for page in self . _GetPages ( ) :
2019-04-10 22:50:53 +00:00
if page . GetName ( ) == page_name :
2018-02-14 21:47:18 +00:00
2020-09-23 21:02:02 +00:00
do_not_do_it = only_media_pages and isinstance ( page , PagesNotebook )
if not do_not_do_it :
return page
2018-02-14 21:47:18 +00:00
if isinstance ( page , PagesNotebook ) :
2020-09-23 21:02:02 +00:00
result = page . _GetPageFromName ( page_name , only_media_pages = only_media_pages )
2018-02-14 21:47:18 +00:00
if result is not None :
return result
2017-08-23 21:34:25 +00:00
return None
2017-08-16 21:58:06 +00:00
2017-10-04 17:51:58 +00:00
def _MovePage ( self , page , dest_notebook , insertion_tab_index , follow_dropped_page = False ) :
2020-04-08 21:10:11 +00:00
source_notebook = page . GetParentNotebook ( )
2017-10-04 17:51:58 +00:00
for ( index , p ) in enumerate ( source_notebook . _GetPages ( ) ) :
if p == page :
2019-11-14 03:56:30 +00:00
source_notebook . removeTab ( index )
source_notebook . _UpdatePreviousPageIndex ( )
2017-10-04 17:51:58 +00:00
break
if source_notebook != dest_notebook :
2019-11-14 03:56:30 +00:00
page . setParent ( dest_notebook )
2017-10-04 17:51:58 +00:00
self . _controller . pub ( ' refresh_page_name ' , source_notebook . GetPageKey ( ) )
2019-11-14 03:56:30 +00:00
insertion_tab_index = min ( insertion_tab_index , dest_notebook . count ( ) )
2017-10-04 17:51:58 +00:00
2019-11-14 03:56:30 +00:00
dest_notebook . insertTab ( insertion_tab_index , page , page . GetName ( ) )
2020-04-08 21:10:11 +00:00
2019-11-14 03:56:30 +00:00
if follow_dropped_page : dest_notebook . setCurrentIndex ( insertion_tab_index )
2017-10-04 17:51:58 +00:00
if follow_dropped_page :
self . ShowPage ( page )
self . _controller . pub ( ' refresh_page_name ' , page . GetPageKey ( ) )
2018-04-05 01:22:26 +00:00
def _MovePages ( self , pages , dest_notebook ) :
insertion_tab_index = dest_notebook . GetNumPages ( only_my_level = True )
for page in pages :
2020-04-08 21:10:11 +00:00
if page . GetParentNotebook ( ) != dest_notebook :
2018-04-05 01:22:26 +00:00
self . _MovePage ( page , dest_notebook , insertion_tab_index )
insertion_tab_index + = 1
2017-08-16 21:58:06 +00:00
def _RefreshPageName ( self , index ) :
2019-11-14 03:56:30 +00:00
if index == - 1 or index > self . count ( ) - 1 :
2017-08-16 21:58:06 +00:00
return
2017-12-06 22:06:56 +00:00
new_options = self . _controller . new_options
2017-08-16 21:58:06 +00:00
max_page_name_chars = new_options . GetInteger ( ' max_page_name_chars ' )
page_file_count_display = new_options . GetInteger ( ' page_file_count_display ' )
2018-05-16 20:09:50 +00:00
import_page_progress_display = new_options . GetBoolean ( ' import_page_progress_display ' )
2019-11-14 03:56:30 +00:00
page = self . widget ( index )
2017-08-16 21:58:06 +00:00
2020-11-11 22:20:16 +00:00
if isinstance ( page , Page ) and not page . IsInitialised ( ) :
page_name = ' initialising '
else :
page_name = page . GetName ( )
page_name = page_name . replace ( os . linesep , ' ' )
2018-02-07 23:40:33 +00:00
2020-01-02 03:05:35 +00:00
page_name = HydrusText . ElideText ( page_name , max_page_name_chars )
2017-08-16 21:58:06 +00:00
2018-05-16 20:09:50 +00:00
num_string = ' '
( num_files , ( num_value , num_range ) ) = page . GetNumFileSummary ( )
2017-08-16 21:58:06 +00:00
if page_file_count_display == CC . PAGE_FILE_COUNT_DISPLAY_ALL or ( page_file_count_display == CC . PAGE_FILE_COUNT_DISPLAY_ONLY_IMPORTERS and page . IsImporter ( ) ) :
2018-07-04 20:48:28 +00:00
num_string + = HydrusData . ToHumanInt ( num_files )
2018-05-02 20:45:20 +00:00
2018-05-16 20:09:50 +00:00
if import_page_progress_display :
2018-05-02 20:45:20 +00:00
if num_range > 0 and num_value != num_range :
2018-05-16 20:09:50 +00:00
if len ( num_string ) > 0 :
num_string + = ' , '
num_string + = HydrusData . ConvertValueRangeToPrettyString ( num_value , num_range )
2018-05-02 20:45:20 +00:00
2017-08-16 21:58:06 +00:00
2018-05-16 20:09:50 +00:00
if len ( num_string ) > 0 :
2018-05-02 20:45:20 +00:00
page_name + = ' ( ' + num_string + ' ) '
2017-08-16 21:58:06 +00:00
2020-04-22 21:00:35 +00:00
safe_page_name = ClientGUIFunctions . EscapeMnemonics ( page_name )
2018-02-07 23:40:33 +00:00
2020-05-13 19:03:16 +00:00
tab_bar = self . tabBar ( )
existing_page_name = tab_bar . tabText ( index )
2018-02-07 23:40:33 +00:00
if existing_page_name not in ( safe_page_name , page_name ) :
2017-08-16 21:58:06 +00:00
2020-05-13 19:03:16 +00:00
tab_bar . setTabText ( index , safe_page_name )
2017-08-16 21:58:06 +00:00
def _RenamePage ( self , index ) :
2019-11-14 03:56:30 +00:00
if index == - 1 or index > self . count ( ) - 1 :
2017-08-16 21:58:06 +00:00
return
2019-11-14 03:56:30 +00:00
page = self . widget ( index )
2017-08-16 21:58:06 +00:00
2019-04-10 22:50:53 +00:00
current_name = page . GetName ( )
2017-10-25 21:45:15 +00:00
2017-08-16 21:58:06 +00:00
with ClientGUIDialogs . DialogTextEntry ( self , ' Enter the new name. ' , default = current_name , allow_blank = False ) as dlg :
2019-11-14 03:56:30 +00:00
if dlg . exec ( ) == QW . QDialog . Accepted :
2017-08-16 21:58:06 +00:00
new_name = dlg . GetValue ( )
2019-04-10 22:50:53 +00:00
page . SetName ( new_name )
2017-08-16 21:58:06 +00:00
self . _controller . pub ( ' refresh_page_name ' , page . GetPageKey ( ) )
2017-10-04 17:51:58 +00:00
def _SendPageToNewNotebook ( self , index ) :
2019-11-14 03:56:30 +00:00
if 0 < = index and index < = self . count ( ) - 1 :
2018-04-25 22:07:52 +00:00
2019-11-14 03:56:30 +00:00
page = self . widget ( index )
2018-04-25 22:07:52 +00:00
dest_notebook = self . NewPagesNotebook ( forced_insertion_index = index , give_it_a_blank_page = False )
self . _MovePage ( page , dest_notebook , 0 )
2017-10-04 17:51:58 +00:00
def _SendRightPagesToNewNotebook ( self , from_index ) :
message = ' Send all pages to the right to a new page of pages? '
2019-09-05 00:05:32 +00:00
result = ClientGUIDialogsQuick . GetYesNo ( self , message )
2019-11-14 03:56:30 +00:00
if result == QW . QDialog . Accepted :
2017-10-04 17:51:58 +00:00
2019-11-14 03:56:30 +00:00
pages_index = self . count ( )
2019-09-05 00:05:32 +00:00
dest_notebook = self . NewPagesNotebook ( forced_insertion_index = pages_index , give_it_a_blank_page = False )
movees = list ( range ( from_index + 1 , pages_index ) )
movees . reverse ( )
for index in movees :
2017-10-04 17:51:58 +00:00
2019-11-14 03:56:30 +00:00
page = self . widget ( index )
2017-10-04 17:51:58 +00:00
2019-09-05 00:05:32 +00:00
self . _MovePage ( page , dest_notebook , 0 )
2017-10-04 17:51:58 +00:00
2019-07-10 22:38:30 +00:00
def _ShiftPage ( self , page_index , delta = None , new_index = None ) :
new_page_index = page_index
if delta is not None :
new_page_index = page_index + delta
if new_index is not None :
new_page_index = new_index
if new_page_index == page_index :
return
2019-11-14 03:56:30 +00:00
if 0 < = new_page_index and new_page_index < = self . count ( ) - 1 :
page_is_selected = self . currentIndex ( ) == page_index
2019-07-10 22:38:30 +00:00
2019-11-14 03:56:30 +00:00
page = self . widget ( page_index )
name = self . tabText ( page_index )
2019-07-10 22:38:30 +00:00
2019-11-14 03:56:30 +00:00
self . removeTab ( page_index )
2019-07-10 22:38:30 +00:00
2019-11-14 03:56:30 +00:00
self . _UpdatePreviousPageIndex ( )
2019-07-10 22:38:30 +00:00
2019-11-14 03:56:30 +00:00
self . insertTab ( new_page_index , page , name )
if page_is_selected : self . setCurrentIndex ( new_page_index )
2019-07-10 22:38:30 +00:00
2017-08-23 21:34:25 +00:00
def _ShowMenu ( self , screen_position ) :
2019-11-14 03:56:30 +00:00
tab_index = ClientGUIFunctions . NotebookScreenToHitTest ( self , screen_position )
2017-08-16 21:58:06 +00:00
2019-11-14 03:56:30 +00:00
num_pages = self . count ( )
2017-08-16 21:58:06 +00:00
2018-04-05 01:22:26 +00:00
end_index = num_pages - 1
2017-12-13 22:33:07 +00:00
more_than_one_tab = num_pages > 1
2017-08-16 21:58:06 +00:00
click_over_tab = tab_index != - 1
2021-08-18 21:10:01 +00:00
can_go_home = tab_index > 1
2018-04-05 01:22:26 +00:00
can_go_left = tab_index > 0
can_go_right = tab_index < end_index
2021-08-18 21:10:01 +00:00
can_go_end = tab_index < end_index - 1
2017-12-13 22:33:07 +00:00
2018-04-05 01:22:26 +00:00
click_over_page_of_pages = False
2017-08-16 21:58:06 +00:00
2019-11-14 03:56:30 +00:00
menu = QW . QMenu ( )
2017-08-16 21:58:06 +00:00
2017-10-04 17:51:58 +00:00
if click_over_tab :
2017-08-16 21:58:06 +00:00
2019-11-14 03:56:30 +00:00
page = self . widget ( tab_index )
2017-12-13 22:33:07 +00:00
click_over_page_of_pages = isinstance ( page , PagesNotebook )
2021-06-02 21:59:19 +00:00
if HG . client_controller . new_options . GetBoolean ( ' advanced_mode ' ) :
label = ' page weight: {} ' . format ( HydrusData . ToHumanInt ( page . GetTotalWeight ( ) ) )
ClientGUIMenus . AppendMenuLabel ( menu , label , label )
ClientGUIMenus . AppendSeparator ( menu )
2019-11-14 03:56:30 +00:00
ClientGUIMenus . AppendMenuItem ( menu , ' close page ' , ' Close this page. ' , self . _ClosePage , tab_index )
2017-08-16 21:58:06 +00:00
2021-08-18 21:10:01 +00:00
if more_than_one_tab :
if not can_go_left or not can_go_right :
if num_pages == 2 :
label = ' close other page '
description = ' Close the other page. '
else :
label = ' close other pages '
description = ' Close all pages but this one. '
ClientGUIMenus . AppendMenuItem ( menu , label , description , self . _CloseOtherPages , tab_index )
else :
close_menu = QW . QMenu ( menu )
ClientGUIMenus . AppendMenuItem ( close_menu , ' other pages ' , ' Close all pages but this one. ' , self . _CloseOtherPages , tab_index )
if can_go_left :
ClientGUIMenus . AppendMenuItem ( close_menu , ' pages to the left ' , ' Close all pages to the left of this one. ' , self . _CloseLeftPages , tab_index )
if can_go_right :
ClientGUIMenus . AppendMenuItem ( close_menu , ' pages to the right ' , ' Close all pages to the right of this one. ' , self . _CloseRightPages , tab_index )
ClientGUIMenus . AppendMenu ( menu , close_menu , ' close ' )
2022-02-02 22:14:01 +00:00
ClientGUIMenus . AppendSeparator ( menu )
#
if click_over_page_of_pages :
notebook_to_get_selectable_media_pages_from = self . widget ( tab_index )
else :
notebook_to_get_selectable_media_pages_from = self
selectable_media_pages = notebook_to_get_selectable_media_pages_from . GetMediaPages ( )
if len ( selectable_media_pages ) > 0 :
select_menu = QW . QMenu ( menu )
for selectable_media_page in selectable_media_pages :
2022-02-16 22:10:11 +00:00
label = selectable_media_page . GetNameForMenu ( )
2022-02-02 22:14:01 +00:00
ClientGUIMenus . AppendMenuItem ( select_menu , label , ' select this page ' , self . ShowPage , selectable_media_page )
ClientGUIMenus . AppendMenu ( menu , select_menu , ' pages ' )
#
if more_than_one_tab :
selection_index = self . currentIndex ( )
can_select_home = selection_index > 1
can_select_left = selection_index > 0
can_select_right = selection_index < end_index
can_select_end = selection_index < end_index - 1
navigate_menu = QW . QMenu ( menu )
if can_select_home :
ClientGUIMenus . AppendMenuItem ( navigate_menu , ' first page ' , ' Select the page at the start of these. ' , self . MoveSelectionEnd , - 1 )
if can_select_left :
ClientGUIMenus . AppendMenuItem ( navigate_menu , ' page to the left ' , ' Select the page to the left of this one. ' , self . MoveSelection , - 1 )
if can_select_right :
ClientGUIMenus . AppendMenuItem ( navigate_menu , ' page to the right ' , ' Select the page to the right of this one. ' , self . MoveSelection , 1 )
if can_select_end :
ClientGUIMenus . AppendMenuItem ( navigate_menu , ' last page ' , ' Select the page at the end of these. ' , self . MoveSelectionEnd , 1 )
ClientGUIMenus . AppendMenu ( menu , navigate_menu , ' select ' )
ClientGUIMenus . AppendSeparator ( menu )
ClientGUIMenus . AppendMenuItem ( menu , ' new page ' , ' Choose a new page. ' , self . _ChooseNewPage )
if click_over_tab :
ClientGUIMenus . AppendMenuItem ( menu , ' new page here ' , ' Choose a new page. ' , self . _ChooseNewPage , tab_index )
ClientGUIMenus . AppendSeparator ( menu )
if more_than_one_tab :
2017-08-16 21:58:06 +00:00
2021-08-18 21:10:01 +00:00
move_menu = QW . QMenu ( menu )
if can_go_home :
ClientGUIMenus . AppendMenuItem ( move_menu , ' to left end ' , ' Move this page all the way to the left. ' , self . _ShiftPage , tab_index , new_index = 0 )
2017-08-16 21:58:06 +00:00
2017-10-04 17:51:58 +00:00
if can_go_left :
2020-03-04 22:12:53 +00:00
2021-08-18 21:10:01 +00:00
ClientGUIMenus . AppendMenuItem ( move_menu , ' left ' , ' Move this page one to the left. ' , self . _ShiftPage , tab_index , delta = - 1 )
2017-08-16 21:58:06 +00:00
2017-10-04 17:51:58 +00:00
if can_go_right :
2020-03-04 22:12:53 +00:00
2021-08-18 21:10:01 +00:00
ClientGUIMenus . AppendMenuItem ( move_menu , ' right ' , ' Move this page one to the right. ' , self . _ShiftPage , tab_index , 1 )
if can_go_end :
ClientGUIMenus . AppendMenuItem ( move_menu , ' to right end ' , ' Move this page all the way to the right. ' , self . _ShiftPage , tab_index , new_index = end_index )
ClientGUIMenus . AppendMenu ( menu , move_menu , ' move page ' )
2017-08-16 21:58:06 +00:00
2019-11-14 03:56:30 +00:00
ClientGUIMenus . AppendMenuItem ( menu , ' rename page ' , ' Rename this page. ' , self . _RenamePage , tab_index )
2017-08-16 21:58:06 +00:00
2020-03-04 22:12:53 +00:00
ClientGUIMenus . AppendMenuItem ( menu , ' duplicate page ' , ' Duplicate this page. ' , self . _DuplicatePage , tab_index )
2017-08-16 21:58:06 +00:00
if more_than_one_tab :
2019-07-10 22:38:30 +00:00
ClientGUIMenus . AppendSeparator ( menu )
2020-12-23 23:07:58 +00:00
submenu = QW . QMenu ( menu )
2022-05-18 20:18:25 +00:00
ClientGUIMenus . AppendMenuItem ( submenu , ' by most files first ' , ' Sort these pages according to how many files they have. ' , self . _SortPagesByFileCount , ' desc ' )
ClientGUIMenus . AppendMenuItem ( submenu , ' by fewest files first ' , ' Sort these pages according to how few files they have. ' , self . _SortPagesByFileCount , ' asc ' )
ClientGUIMenus . AppendMenuItem ( submenu , ' by largest total file size first ' , ' Sort these pages according to how large their files are. ' , self . _SortPagesByFileSize , ' desc ' )
ClientGUIMenus . AppendMenuItem ( submenu , ' by smallest total file size first ' , ' Sort these pages according to how small their files are. ' , self . _SortPagesByFileSize , ' asc ' )
2022-02-02 22:14:01 +00:00
ClientGUIMenus . AppendMenuItem ( submenu , ' by name a-z ' , ' Sort these pages according to their names. ' , self . _SortPagesByName , ' asc ' )
ClientGUIMenus . AppendMenuItem ( submenu , ' by name z-a ' , ' Sort these pages according to their names. ' , self . _SortPagesByName , ' desc ' )
2020-12-23 23:07:58 +00:00
ClientGUIMenus . AppendMenu ( menu , submenu , ' sort pages ' )
2019-07-10 22:38:30 +00:00
2017-08-16 21:58:06 +00:00
2018-04-05 01:22:26 +00:00
ClientGUIMenus . AppendSeparator ( menu )
2019-11-14 03:56:30 +00:00
ClientGUIMenus . AppendMenuItem ( menu , ' send this page down to a new page of pages ' , ' Make a new page of pages and put this page in it. ' , self . _SendPageToNewNotebook , tab_index )
2018-04-05 01:22:26 +00:00
if can_go_right :
2019-12-11 23:18:37 +00:00
ClientGUIMenus . AppendMenuItem ( menu , ' send pages to the right to a new page of pages ' , ' Make a new page of pages and put all the pages to the right into it. ' , self . _SendRightPagesToNewNotebook , tab_index )
2018-04-05 01:22:26 +00:00
2020-04-08 21:10:11 +00:00
2019-11-14 03:56:30 +00:00
if click_over_page_of_pages and page . count ( ) > 0 :
2017-10-04 17:51:58 +00:00
ClientGUIMenus . AppendSeparator ( menu )
2019-11-14 03:56:30 +00:00
ClientGUIMenus . AppendMenuItem ( menu , ' refresh all this page \' s pages ' , ' Command every page below this one to refresh. ' , page . RefreshAllPages )
2017-10-04 17:51:58 +00:00
2017-08-16 21:58:06 +00:00
2021-06-02 21:59:19 +00:00
existing_session_names = self . _controller . Read ( ' serialisable_names ' , HydrusSerialisable . SERIALISABLE_TYPE_GUI_SESSION_CONTAINER )
2018-11-28 22:31:04 +00:00
2018-04-05 01:22:26 +00:00
if len ( existing_session_names ) > 0 or click_over_page_of_pages :
ClientGUIMenus . AppendSeparator ( menu )
if len ( existing_session_names ) > 0 :
2019-11-14 03:56:30 +00:00
submenu = QW . QMenu ( menu )
2018-04-05 01:22:26 +00:00
for name in existing_session_names :
2019-12-11 23:18:37 +00:00
2021-06-02 21:59:19 +00:00
ClientGUIMenus . AppendMenuItem ( submenu , name , ' Load this session here. ' , self . AppendGUISessionFreshest , name )
2018-04-05 01:22:26 +00:00
ClientGUIMenus . AppendMenu ( menu , submenu , ' append session ' )
if click_over_page_of_pages :
2019-11-14 03:56:30 +00:00
submenu = QW . QMenu ( menu )
2018-04-05 01:22:26 +00:00
for name in existing_session_names :
2021-06-02 21:59:19 +00:00
if name in ClientGUISession . RESERVED_SESSION_NAMES :
2018-04-05 01:22:26 +00:00
continue
2019-12-11 23:18:37 +00:00
ClientGUIMenus . AppendMenuItem ( submenu , name , ' Save this page of pages to the session. ' , self . _controller . gui . ProposeSaveGUISession , notebook = page , name = name )
ClientGUIMenus . AppendMenuItem ( submenu , ' create a new session ' , ' Save this page of pages to the session. ' , self . _controller . gui . ProposeSaveGUISession , notebook = page , suggested_name = page . GetName ( ) )
2018-04-05 01:22:26 +00:00
ClientGUIMenus . AppendMenu ( menu , submenu , ' save this page of pages to a session ' )
2020-03-04 22:12:53 +00:00
CGC . core ( ) . PopupMenu ( self , menu )
2017-08-16 21:58:06 +00:00
2019-07-10 22:38:30 +00:00
def _SortPagesByFileCount ( self , order ) :
def key ( page ) :
( total_num_files , ( total_num_value , total_num_range ) ) = page . GetNumFileSummary ( )
return ( total_num_files , total_num_range , total_num_value )
2020-12-23 23:07:58 +00:00
ordered_pages = sorted ( self . GetPages ( ) , key = key , reverse = order == ' desc ' )
2019-07-10 22:38:30 +00:00
2020-12-23 23:07:58 +00:00
self . _SortPagesSetPages ( ordered_pages )
2022-05-18 20:18:25 +00:00
def _SortPagesByFileSize ( self , order ) :
def key ( page ) :
total_file_size = page . GetTotalFileSize ( )
return total_file_size
ordered_pages = sorted ( self . GetPages ( ) , key = key , reverse = order == ' desc ' )
self . _SortPagesSetPages ( ordered_pages )
2020-12-23 23:07:58 +00:00
def _SortPagesByName ( self , order ) :
def file_count_secondary ( page ) :
2019-07-10 22:38:30 +00:00
2020-12-23 23:07:58 +00:00
( total_num_files , ( total_num_value , total_num_range ) ) = page . GetNumFileSummary ( )
2019-07-10 22:38:30 +00:00
2020-12-23 23:07:58 +00:00
return ( total_num_files , total_num_range , total_num_value )
ordered_pages = sorted ( self . GetPages ( ) , key = file_count_secondary , reverse = True )
ordered_pages = sorted ( ordered_pages , key = lambda page : page . GetName ( ) , reverse = order == ' desc ' )
self . _SortPagesSetPages ( ordered_pages )
def _SortPagesSetPages ( self , ordered_pages ) :
2019-07-10 22:38:30 +00:00
2019-11-14 03:56:30 +00:00
selected_page = self . currentWidget ( )
2019-07-10 22:38:30 +00:00
pages_to_names = { }
2019-11-14 03:56:30 +00:00
for i in range ( self . count ( ) ) :
2019-07-10 22:38:30 +00:00
2019-11-14 03:56:30 +00:00
page = self . widget ( 0 )
2019-07-10 22:38:30 +00:00
2019-11-14 03:56:30 +00:00
name = self . tabText ( 0 )
2019-07-10 22:38:30 +00:00
pages_to_names [ page ] = name
2019-11-14 03:56:30 +00:00
self . removeTab ( 0 )
self . _UpdatePreviousPageIndex ( )
2019-07-10 22:38:30 +00:00
for page in ordered_pages :
name = pages_to_names [ page ]
2019-11-14 03:56:30 +00:00
self . addTab ( page , name )
2020-12-23 23:07:58 +00:00
if page == selected_page :
self . setCurrentIndex ( self . count ( ) - 1 )
2019-07-10 22:38:30 +00:00
2021-06-02 21:59:19 +00:00
def AppendGUISession ( self , session : ClientGUISession . GUISessionContainer ) :
2017-08-16 21:58:06 +00:00
2021-06-02 21:59:19 +00:00
starting_index = self . _GetDefaultPageInsertionIndex ( )
2020-02-19 21:48:36 +00:00
2021-06-02 21:59:19 +00:00
forced_insertion_index = starting_index
2020-02-19 21:48:36 +00:00
2021-06-02 21:59:19 +00:00
self . InsertSession ( forced_insertion_index , session )
2020-02-19 21:48:36 +00:00
2021-06-02 21:59:19 +00:00
def AppendGUISessionBackup ( self , name , timestamp , load_in_a_page_of_pages = True ) :
2020-02-19 21:48:36 +00:00
2017-08-16 21:58:06 +00:00
try :
2021-06-02 21:59:19 +00:00
session = session = self . _controller . Read ( ' gui_session ' , name , timestamp )
2017-08-16 21:58:06 +00:00
except Exception as e :
2021-06-02 21:59:19 +00:00
HydrusData . ShowText ( ' While trying to load session " {} " (ts {} ), this error happened: ' . format ( name , timestamp ) )
2017-08-16 21:58:06 +00:00
HydrusData . ShowException ( e )
return
2017-12-13 22:33:07 +00:00
if load_in_a_page_of_pages :
2021-06-02 21:59:19 +00:00
destination = self . NewPagesNotebook ( name = name , give_it_a_blank_page = False )
2017-12-13 22:33:07 +00:00
else :
destination = self
2021-06-02 21:59:19 +00:00
destination . AppendGUISession ( session )
2017-08-16 21:58:06 +00:00
2021-06-02 21:59:19 +00:00
def AppendGUISessionFreshest ( self , name , load_in_a_page_of_pages = True ) :
2020-04-08 21:10:11 +00:00
2021-06-02 21:59:19 +00:00
job_key = ClientThreading . JobKey ( )
2017-08-16 21:58:06 +00:00
2021-06-02 21:59:19 +00:00
job_key . SetVariable ( ' popup_text_1 ' , ' loading session " {} " \u2026 ' . format ( name ) )
2020-02-19 21:48:36 +00:00
2021-06-02 21:59:19 +00:00
HG . client_controller . pub ( ' message ' , job_key )
# get that message showing before we do the work of loading session
HG . client_controller . app . processEvents ( )
2018-11-28 22:31:04 +00:00
try :
2021-06-02 21:59:19 +00:00
session = self . _controller . Read ( ' gui_session ' , name )
2018-11-28 22:31:04 +00:00
except Exception as e :
2021-06-02 21:59:19 +00:00
HydrusData . ShowText ( ' While trying to load session " {} " , this error happened: ' . format ( name ) )
2018-11-28 22:31:04 +00:00
HydrusData . ShowException ( e )
return
2021-06-02 21:59:19 +00:00
HG . client_controller . app . processEvents ( )
2018-11-28 22:31:04 +00:00
if load_in_a_page_of_pages :
2021-06-02 21:59:19 +00:00
destination = self . NewPagesNotebook ( name = name , give_it_a_blank_page = False )
2018-11-28 22:31:04 +00:00
else :
destination = self
2021-06-02 21:59:19 +00:00
HG . client_controller . app . processEvents ( )
2017-08-16 21:58:06 +00:00
2021-06-02 21:59:19 +00:00
destination . AppendGUISession ( session )
2017-08-16 21:58:06 +00:00
2021-09-22 21:12:34 +00:00
self . freshSessionLoaded . emit ( session )
2021-06-02 21:59:19 +00:00
job_key . Delete ( )
2017-08-16 21:58:06 +00:00
def ChooseNewPage ( self ) :
self . _ChooseNewPage ( )
def ChooseNewPageForDeepestNotebook ( self ) :
2019-11-14 03:56:30 +00:00
current_page = self . currentWidget ( )
2017-08-16 21:58:06 +00:00
if isinstance ( current_page , PagesNotebook ) :
current_page . ChooseNewPageForDeepestNotebook ( )
else :
self . _ChooseNewPage ( )
2019-06-19 22:08:48 +00:00
def CleanBeforeClose ( self ) :
for page in self . _GetPages ( ) :
page . CleanBeforeClose ( )
2017-08-16 21:58:06 +00:00
def CleanBeforeDestroy ( self ) :
for page in self . _GetPages ( ) :
page . CleanBeforeDestroy ( )
2018-05-23 21:05:06 +00:00
self . _controller . ReleasePageKey ( self . _page_key )
2017-08-16 21:58:06 +00:00
def CloseCurrentPage ( self , polite = True ) :
2019-11-14 03:56:30 +00:00
selection = self . currentIndex ( )
2017-08-16 21:58:06 +00:00
2019-11-14 03:56:30 +00:00
if selection != - 1 :
2017-08-16 21:58:06 +00:00
2019-11-14 03:56:30 +00:00
page = self . widget ( selection )
2017-08-16 21:58:06 +00:00
if isinstance ( page , PagesNotebook ) :
if page . GetNumPages ( ) > 0 :
page . CloseCurrentPage ( polite )
else :
self . _ClosePage ( selection , polite = polite )
else :
self . _ClosePage ( selection , polite = polite )
2021-03-17 21:59:28 +00:00
2017-08-23 21:34:25 +00:00
2021-03-17 21:59:28 +00:00
def eventFilter ( self , watched , event ) :
2019-12-11 23:18:37 +00:00
2021-03-17 21:59:28 +00:00
if event . type ( ) in ( QC . QEvent . MouseButtonDblClick , QC . QEvent . MouseButtonRelease ) :
2019-12-11 23:18:37 +00:00
2021-03-17 21:59:28 +00:00
screen_position = QG . QCursor . pos ( )
2019-12-11 23:18:37 +00:00
2021-03-17 21:59:28 +00:00
if watched == self . tabBar ( ) :
tab_pos = self . tabBar ( ) . mapFromGlobal ( screen_position )
over_a_tab = tab_pos != - 1
over_tab_greyspace = tab_pos == - 1
else :
over_a_tab = False
widget_under_mouse = QW . QApplication . instance ( ) . widgetAt ( screen_position )
if widget_under_mouse is None :
over_tab_greyspace = None
else :
if self . count ( ) == 0 and isinstance ( widget_under_mouse , QW . QStackedWidget ) :
over_tab_greyspace = True
else :
over_tab_greyspace = widget_under_mouse == self
if event . type ( ) == QC . QEvent . MouseButtonDblClick :
if event . button ( ) == QC . Qt . LeftButton and over_tab_greyspace and not over_a_tab :
self . EventNewPageFromScreenPosition ( screen_position )
return True
elif event . type ( ) == QC . QEvent . MouseButtonRelease :
if event . button ( ) == QC . Qt . RightButton and ( over_a_tab or over_tab_greyspace ) :
self . ShowMenuFromScreenPosition ( screen_position )
return True
elif event . button ( ) == QC . Qt . MiddleButton and over_tab_greyspace and not over_a_tab :
self . EventNewPageFromScreenPosition ( screen_position )
return True
2019-12-11 23:18:37 +00:00
2017-08-16 21:58:06 +00:00
2021-03-17 21:59:28 +00:00
return False
2017-08-16 21:58:06 +00:00
2019-12-11 23:18:37 +00:00
def ShowMenuFromScreenPosition ( self , position ) :
2017-08-16 21:58:06 +00:00
2017-08-23 21:34:25 +00:00
notebook = self . _GetNotebookFromScreenPosition ( position )
2017-08-16 21:58:06 +00:00
notebook . _ShowMenu ( position )
2017-08-23 21:34:25 +00:00
def EventNewPageFromScreenPosition ( self , position ) :
2017-08-16 21:58:06 +00:00
2017-08-23 21:34:25 +00:00
notebook = self . _GetNotebookFromScreenPosition ( position )
2017-08-16 21:58:06 +00:00
notebook . _ChooseNewPage ( )
2019-08-21 21:34:01 +00:00
def GetAPIInfoDict ( self , simple ) :
return { }
2021-09-22 21:12:34 +00:00
def GetCurrentGUISession ( self , name : str , only_changed_page_data : bool , about_to_save : bool ) :
2019-12-11 23:18:37 +00:00
2021-09-22 21:12:34 +00:00
( page_container , hashes_to_page_data , skipped_unchanged_page_hashes ) = self . GetSerialisablePage ( only_changed_page_data , about_to_save )
2019-12-11 23:18:37 +00:00
2021-09-22 21:12:34 +00:00
session = ClientGUISession . GUISessionContainer ( name , top_notebook_container = page_container , hashes_to_page_data = hashes_to_page_data , skipped_unchanged_page_hashes = skipped_unchanged_page_hashes )
2019-12-11 23:18:37 +00:00
return session
2017-08-16 21:58:06 +00:00
def GetCurrentMediaPage ( self ) :
2019-11-14 03:56:30 +00:00
page = self . currentWidget ( )
2017-08-16 21:58:06 +00:00
if isinstance ( page , PagesNotebook ) :
return page . GetCurrentMediaPage ( )
else :
return page # this can be None
def GetMediaPages ( self , only_my_level = False ) :
return self . _GetMediaPages ( only_my_level )
def GetName ( self ) :
return self . _name
2022-02-16 22:10:11 +00:00
def GetNameForMenu ( self ) - > str :
name_for_menu = self . GetName ( )
( num_files , ( num_value , num_range ) ) = self . GetNumFileSummary ( )
if num_files > 0 :
name_for_menu = ' {} - {} files ' . format ( name_for_menu , HydrusData . ToHumanInt ( num_files ) )
if num_value != num_range :
name_for_menu = ' {} - {} ' . format ( name_for_menu , HydrusData . ConvertValueRangeToPrettyString ( num_value , num_range ) )
return HydrusText . ElideText ( name_for_menu , 32 , elide_center = True )
2018-05-02 20:45:20 +00:00
def GetNumFileSummary ( self ) :
total_num_files = 0
total_num_value = 0
total_num_range = 0
for page in self . _GetPages ( ) :
( num_files , ( num_value , num_range ) ) = page . GetNumFileSummary ( )
total_num_files + = num_files
total_num_value + = num_value
total_num_range + = num_range
2017-08-16 21:58:06 +00:00
2018-05-02 20:45:20 +00:00
return ( total_num_files , ( total_num_value , total_num_range ) )
2017-08-16 21:58:06 +00:00
def GetNumPages ( self , only_my_level = False ) :
if only_my_level :
2019-11-14 03:56:30 +00:00
return self . count ( )
2017-08-16 21:58:06 +00:00
else :
total = 0
for page in self . _GetPages ( ) :
if isinstance ( page , PagesNotebook ) :
total + = page . GetNumPages ( False )
else :
total + = 1
return total
2021-06-09 20:28:09 +00:00
def GetOrMakeGalleryDownloaderPage ( self , desired_page_name = None , desired_page_key = None , select_page = True ) :
potential_gallery_downloader_pages = [ page for page in self . _GetMediaPages ( False ) if page . IsGalleryDownloaderPage ( ) ]
if desired_page_key is not None and desired_page_key in ( page . GetPageKey ( ) for page in potential_gallery_downloader_pages ) :
potential_gallery_downloader_pages = [ page for page in potential_gallery_downloader_pages if page . GetPageKey ( ) == desired_page_key ]
elif desired_page_name is not None :
potential_gallery_downloader_pages = [ page for page in potential_gallery_downloader_pages if page . GetName ( ) == desired_page_name ]
if len ( potential_gallery_downloader_pages ) > 0 :
# ok, we can use an existing one. should we use the current?
current_media_page = self . GetCurrentMediaPage ( )
if current_media_page is not None and current_media_page in potential_gallery_downloader_pages :
return current_media_page
else :
return potential_gallery_downloader_pages [ 0 ]
else :
return self . NewPageImportGallery ( page_name = desired_page_name , on_deepest_notebook = True , select_page = select_page )
2019-06-26 21:27:18 +00:00
def GetOrMakeMultipleWatcherPage ( self , desired_page_name = None , desired_page_key = None , select_page = True ) :
2018-05-16 20:09:50 +00:00
2019-03-20 21:22:10 +00:00
potential_watcher_pages = [ page for page in self . _GetMediaPages ( False ) if page . IsMultipleWatcherPage ( ) ]
2018-05-30 20:13:21 +00:00
2019-06-26 21:27:18 +00:00
if desired_page_key is not None and desired_page_key in ( page . GetPageKey ( ) for page in potential_watcher_pages ) :
potential_watcher_pages = [ page for page in potential_watcher_pages if page . GetPageKey ( ) == desired_page_key ]
elif desired_page_name is not None :
2018-05-30 20:13:21 +00:00
2019-04-10 22:50:53 +00:00
potential_watcher_pages = [ page for page in potential_watcher_pages if page . GetName ( ) == desired_page_name ]
2018-05-30 20:13:21 +00:00
2019-02-27 23:03:30 +00:00
2019-03-20 21:22:10 +00:00
if len ( potential_watcher_pages ) > 0 :
2019-02-27 23:03:30 +00:00
2019-03-20 21:22:10 +00:00
# ok, we can use an existing one. should we use the current?
2019-02-27 23:03:30 +00:00
2019-03-20 21:22:10 +00:00
current_media_page = self . GetCurrentMediaPage ( )
2018-05-16 20:09:50 +00:00
2019-03-20 21:22:10 +00:00
if current_media_page is not None and current_media_page in potential_watcher_pages :
2018-05-16 20:09:50 +00:00
2019-03-20 21:22:10 +00:00
return current_media_page
2018-05-16 20:09:50 +00:00
2019-03-20 21:22:10 +00:00
else :
2018-05-16 20:09:50 +00:00
2019-03-20 21:22:10 +00:00
return potential_watcher_pages [ 0 ]
2018-05-16 20:09:50 +00:00
2019-03-20 21:22:10 +00:00
else :
return self . NewPageImportMultipleWatcher ( page_name = desired_page_name , on_deepest_notebook = True , select_page = select_page )
2018-05-16 20:09:50 +00:00
2019-06-26 21:27:18 +00:00
def GetOrMakeURLImportPage ( self , desired_page_name = None , desired_page_key = None , select_page = True ) :
2019-02-27 23:03:30 +00:00
2019-03-20 21:22:10 +00:00
potential_url_import_pages = [ page for page in self . _GetMediaPages ( False ) if page . IsURLImportPage ( ) ]
2019-02-27 23:03:30 +00:00
2019-06-26 21:27:18 +00:00
if desired_page_key is not None and desired_page_key in ( page . GetPageKey ( ) for page in potential_url_import_pages ) :
potential_url_import_pages = [ page for page in potential_url_import_pages if page . GetPageKey ( ) == desired_page_key ]
elif desired_page_name is not None :
2019-02-27 23:03:30 +00:00
2019-04-10 22:50:53 +00:00
potential_url_import_pages = [ page for page in potential_url_import_pages if page . GetName ( ) == desired_page_name ]
2019-02-27 23:03:30 +00:00
2019-03-20 21:22:10 +00:00
if len ( potential_url_import_pages ) > 0 :
2019-02-27 23:03:30 +00:00
2019-03-20 21:22:10 +00:00
# ok, we can use an existing one. should we use the current?
2019-02-27 23:03:30 +00:00
2019-03-20 21:22:10 +00:00
current_media_page = self . GetCurrentMediaPage ( )
2017-08-16 21:58:06 +00:00
2019-03-20 21:22:10 +00:00
if current_media_page is not None and current_media_page in potential_url_import_pages :
2017-08-16 21:58:06 +00:00
2019-03-20 21:22:10 +00:00
return current_media_page
2017-08-16 21:58:06 +00:00
2019-03-20 21:22:10 +00:00
else :
2017-08-16 21:58:06 +00:00
2019-03-20 21:22:10 +00:00
return potential_url_import_pages [ 0 ]
2017-08-16 21:58:06 +00:00
2019-03-20 21:22:10 +00:00
else :
return self . NewPageImportURLs ( page_name = desired_page_name , on_deepest_notebook = True , select_page = select_page )
2017-08-16 21:58:06 +00:00
2019-07-17 22:10:19 +00:00
def GetPageFromPageKey ( self , page_key ) :
2019-08-21 21:34:01 +00:00
if self . _page_key == page_key :
return self
2019-07-17 22:10:19 +00:00
for page in self . _GetPages ( ) :
if page . GetPageKey ( ) == page_key :
return page
if isinstance ( page , PagesNotebook ) :
if page . HasPageKey ( page_key ) :
return page . GetPageFromPageKey ( page_key )
return None
2017-08-16 21:58:06 +00:00
def GetPageKey ( self ) :
return self . _page_key
2018-05-23 21:05:06 +00:00
def GetPageKeys ( self ) :
page_keys = { self . _page_key }
for page in self . _GetPages ( ) :
page_keys . update ( page . GetPageKeys ( ) )
return page_keys
2020-04-08 21:10:11 +00:00
def GetParentNotebook ( self ) :
return self . _parent_notebook
2022-02-16 22:10:11 +00:00
def GetPages ( self ) :
return self . _GetPages ( )
def GetPrettyStatusForStatusBar ( self ) :
( num_files , ( num_value , num_range ) ) = self . GetNumFileSummary ( )
num_string = HydrusData . ToHumanInt ( num_files )
if num_range > 0 and num_value != num_range :
num_string + = ' , ' + HydrusData . ConvertValueRangeToPrettyString ( num_value , num_range )
return HydrusData . ToHumanInt ( self . count ( ) ) + ' pages, ' + num_string + ' files '
2021-09-22 21:12:34 +00:00
def GetSerialisablePage ( self , only_changed_page_data , about_to_save ) :
2021-06-02 21:59:19 +00:00
page_containers = [ ]
hashes_to_page_data = { }
2021-09-22 21:12:34 +00:00
skipped_unchanged_page_hashes = set ( )
2021-06-02 21:59:19 +00:00
for page in self . _GetPages ( ) :
2021-09-22 21:12:34 +00:00
( sub_page_container , some_hashes_to_page_data , some_skipped_unchanged_page_hashes ) = page . GetSerialisablePage ( only_changed_page_data , about_to_save )
2021-06-02 21:59:19 +00:00
page_containers . append ( sub_page_container )
hashes_to_page_data . update ( some_hashes_to_page_data )
2021-09-22 21:12:34 +00:00
skipped_unchanged_page_hashes . update ( some_skipped_unchanged_page_hashes )
2021-06-02 21:59:19 +00:00
page_container = ClientGUISession . GUISessionContainerPageNotebook ( self . _name , page_containers = page_containers )
2021-09-22 21:12:34 +00:00
return ( page_container , hashes_to_page_data , skipped_unchanged_page_hashes )
2021-06-02 21:59:19 +00:00
2019-08-21 21:34:01 +00:00
def GetSessionAPIInfoDict ( self , is_selected = True ) :
2019-06-05 19:42:39 +00:00
2019-11-14 03:56:30 +00:00
current_page = self . currentWidget ( )
2019-06-05 19:42:39 +00:00
my_pages_list = [ ]
for page in self . _GetPages ( ) :
2021-09-01 21:09:01 +00:00
page_is_selected = is_selected and page == current_page
page_info_dict = page . GetSessionAPIInfoDict ( is_selected = page_is_selected )
2019-06-05 19:42:39 +00:00
my_pages_list . append ( page_info_dict )
root = { }
root [ ' name ' ] = self . GetName ( )
2019-06-26 21:27:18 +00:00
root [ ' page_key ' ] = self . _page_key . hex ( )
2019-06-05 19:42:39 +00:00
root [ ' page_type ' ] = ClientGUIManagement . MANAGEMENT_TYPE_PAGE_OF_PAGES
root [ ' selected ' ] = is_selected
root [ ' pages ' ] = my_pages_list
return root
2019-02-06 22:41:35 +00:00
def GetTestAbleToCloseStatement ( self ) :
count = collections . Counter ( )
for page in self . _GetMediaPages ( False ) :
try :
page . CheckAbleToClose ( )
except HydrusExceptions . VetoException as e :
reason = str ( e )
count [ reason ] + = 1
if len ( count ) > 0 :
message = ' '
for ( reason , c ) in list ( count . items ( ) ) :
if c == 1 :
message = ' 1 page says: ' + reason
else :
message = HydrusData . ToHumanInt ( c ) + ' pages say: ' + reason
message + = os . linesep
return message
else :
return None
2022-05-18 20:18:25 +00:00
def GetTotalFileSize ( self ) :
total_file_size = 0
for page in self . _GetPages ( ) :
total_file_size + = page . GetTotalFileSize ( )
return total_file_size
2021-10-06 20:59:30 +00:00
def GetTotalNumHashesAndSeeds ( self ) - > int :
total_num_hashes = 0
total_num_seeds = 0
for page in self . _GetPages ( ) :
( num_hashes , num_seeds ) = page . GetTotalNumHashesAndSeeds ( )
total_num_hashes + = num_hashes
total_num_seeds + = num_seeds
return ( total_num_hashes , total_num_seeds )
def GetTotalWeight ( self ) - > int :
2019-10-16 20:47:55 +00:00
total_weight = sum ( ( page . GetTotalWeight ( ) for page in self . _GetPages ( ) ) )
return total_weight
2018-05-16 20:09:50 +00:00
def HasMediaPageName ( self , page_name , only_my_level = False ) :
media_pages = self . _GetMediaPages ( only_my_level )
for page in media_pages :
if page . GetName ( ) == page_name :
return True
return False
2017-08-16 21:58:06 +00:00
def HasPage ( self , page ) :
return self . HasPageKey ( page . GetPageKey ( ) )
def HasPageKey ( self , page_key ) :
for page in self . _GetPages ( ) :
if page . GetPageKey ( ) == page_key :
return True
elif isinstance ( page , PagesNotebook ) and page . HasPageKey ( page_key ) :
return True
2018-05-16 20:09:50 +00:00
return False
def HasMultipleWatcherPage ( self ) :
for page in self . _GetPages ( ) :
if isinstance ( page , PagesNotebook ) :
if page . HasMultipleWatcherPage ( ) :
return True
else :
if page . IsMultipleWatcherPage ( ) :
return True
2017-08-16 21:58:06 +00:00
return False
def HasURLImportPage ( self ) :
for page in self . _GetPages ( ) :
if isinstance ( page , PagesNotebook ) :
if page . HasURLImportPage ( ) :
return True
else :
if page . IsURLImportPage ( ) :
return True
return False
2021-09-22 21:12:34 +00:00
def InsertSession ( self , forced_insertion_index : int , session : ClientGUISession . GUISessionContainer , session_is_clean = True ) :
2021-06-02 21:59:19 +00:00
# get the top notebook, then for every page in there...
top_notebook_container = session . GetTopNotebook ( )
page_containers = top_notebook_container . GetPageContainers ( )
select_first_page = True
2021-09-22 21:12:34 +00:00
self . InsertSessionNotebookPages ( forced_insertion_index , session , page_containers , select_first_page , session_is_clean = session_is_clean )
2021-06-02 21:59:19 +00:00
2021-09-22 21:12:34 +00:00
def InsertSessionNotebook ( self , forced_insertion_index : int , session : ClientGUISession . GUISessionContainer , notebook_page_container : ClientGUISession . GUISessionContainerPageNotebook , select_first_page : bool , session_is_clean = True ) :
2021-06-02 21:59:19 +00:00
name = notebook_page_container . GetName ( )
page = self . NewPagesNotebook ( name , forced_insertion_index = forced_insertion_index , give_it_a_blank_page = False , select_page = select_first_page )
page_containers = notebook_page_container . GetPageContainers ( )
2021-09-22 21:12:34 +00:00
page . InsertSessionNotebookPages ( 0 , session , page_containers , select_first_page , session_is_clean = session_is_clean )
2021-06-02 21:59:19 +00:00
2021-09-22 21:12:34 +00:00
def InsertSessionNotebookPages ( self , forced_insertion_index : int , session : ClientGUISession . GUISessionContainer , page_containers : typing . Collection [ ClientGUISession . GUISessionContainerPage ] , select_first_page : bool , session_is_clean = True ) :
2020-03-04 22:12:53 +00:00
done_first_page = False
2021-06-02 21:59:19 +00:00
for page_container in page_containers :
2020-05-13 19:03:16 +00:00
2021-06-02 21:59:19 +00:00
select_page = select_first_page and not done_first_page
2020-03-04 22:12:53 +00:00
2021-06-02 21:59:19 +00:00
try :
2020-03-04 22:12:53 +00:00
2021-06-02 21:59:19 +00:00
if isinstance ( page_container , ClientGUISession . GUISessionContainerPageNotebook ) :
2020-03-04 22:12:53 +00:00
2021-09-22 21:12:34 +00:00
self . InsertSessionNotebook ( forced_insertion_index , session , page_container , select_page , session_is_clean = session_is_clean )
2020-03-04 22:12:53 +00:00
2021-06-02 21:59:19 +00:00
else :
2020-03-04 22:12:53 +00:00
2021-09-22 21:12:34 +00:00
result = self . InsertSessionPage ( forced_insertion_index , session , page_container , select_page , session_is_clean = session_is_clean )
2020-03-04 22:12:53 +00:00
2021-06-02 21:59:19 +00:00
if result is None :
continue
2020-03-04 22:12:53 +00:00
2021-06-02 21:59:19 +00:00
except Exception as e :
2020-03-04 22:12:53 +00:00
2021-06-02 21:59:19 +00:00
HydrusData . ShowException ( e )
2020-03-04 22:12:53 +00:00
forced_insertion_index + = 1
2020-05-13 19:03:16 +00:00
done_first_page = True
2020-03-04 22:12:53 +00:00
2021-09-22 21:12:34 +00:00
def InsertSessionPage ( self , forced_insertion_index : int , session : ClientGUISession . GUISessionContainer , page_container : ClientGUISession . GUISessionContainerPageSingle , select_page : bool , session_is_clean = True ) :
2021-06-02 21:59:19 +00:00
try :
page_data_hash = page_container . GetPageDataHash ( )
page_data = session . GetPageData ( page_data_hash )
except HydrusExceptions . DataMissing as e :
HydrusData . ShowText ( ' The page with name " {} " and hash " {} " failed to load because its data was missing! ' . format ( page_container . GetName ( ) , page_data_hash . hex ( ) ) )
return None
management_controller = page_data . GetManagementController ( )
initial_hashes = page_data . GetHashes ( )
2021-09-22 21:12:34 +00:00
page = self . NewPage ( management_controller , initial_hashes = initial_hashes , forced_insertion_index = forced_insertion_index , select_page = select_page )
if session_is_clean and page is not None :
page . SetPageContainerClean ( page_container )
return page
2021-06-02 21:59:19 +00:00
2019-02-27 23:03:30 +00:00
def IsMultipleWatcherPage ( self ) :
return False
2018-12-05 22:35:30 +00:00
def IsImporter ( self ) :
return False
2019-02-27 23:03:30 +00:00
def IsURLImportPage ( self ) :
return False
2017-08-16 21:58:06 +00:00
def LoadGUISession ( self , name ) :
2019-11-14 03:56:30 +00:00
if self . count ( ) > 0 :
2017-08-16 21:58:06 +00:00
2019-09-05 00:05:32 +00:00
message = ' Close the current pages and load session " {} " ? ' . format ( name )
result = ClientGUIDialogsQuick . GetYesNo ( self , message , title = ' Clear and load session? ' )
2017-08-16 21:58:06 +00:00
2019-11-14 03:56:30 +00:00
if result != QW . QDialog . Accepted :
2017-12-13 22:33:07 +00:00
2019-09-05 00:05:32 +00:00
return
2017-12-13 22:33:07 +00:00
2017-08-16 21:58:06 +00:00
2017-12-13 22:33:07 +00:00
try :
self . TestAbleToClose ( )
2018-05-02 20:45:20 +00:00
except HydrusExceptions . VetoException :
2017-12-13 22:33:07 +00:00
return
2018-05-16 20:09:50 +00:00
self . _CloseAllPages ( polite = False , delete_pages = True )
2021-06-23 21:11:38 +00:00
self . _controller . CallLaterQtSafe ( self , 1.0 , ' append session ' , self . AppendGUISessionFreshest , name , load_in_a_page_of_pages = False )
2018-05-16 20:09:50 +00:00
else :
2021-06-02 21:59:19 +00:00
self . AppendGUISessionFreshest ( name , load_in_a_page_of_pages = False )
2017-08-16 21:58:06 +00:00
2017-12-20 22:55:48 +00:00
def MediaDragAndDropDropped ( self , source_page_key , hashes ) :
2019-07-17 22:10:19 +00:00
source_page = self . GetPageFromPageKey ( source_page_key )
2017-12-20 22:55:48 +00:00
if source_page is None :
return
2022-01-19 21:28:59 +00:00
source_management_controller = source_page . GetManagementController ( )
location_context = source_management_controller . GetVariable ( ' location_context ' )
2019-11-14 03:56:30 +00:00
screen_position = QG . QCursor . pos ( )
2017-12-20 22:55:48 +00:00
dest_notebook = self . _GetNotebookFromScreenPosition ( screen_position )
2019-11-14 03:56:30 +00:00
tab_index = ClientGUIFunctions . NotebookScreenToHitTest ( dest_notebook , screen_position )
2017-12-20 22:55:48 +00:00
do_add = True
# do chase - if we need to chase to an existing dest page on which we dropped files
# do return - if we need to return to source page if we created a new one
2021-12-15 22:16:22 +00:00
current_widget = dest_notebook . currentWidget ( )
if tab_index == - 1 and current_widget is not None and not isinstance ( current_widget , PagesNotebook ) and current_widget . rect ( ) . contains ( current_widget . mapFromGlobal ( screen_position ) ) :
2017-12-20 22:55:48 +00:00
2021-12-15 22:16:22 +00:00
dest_page = current_widget
2017-12-20 22:55:48 +00:00
2019-11-14 03:56:30 +00:00
elif tab_index == - 1 :
2017-12-20 22:55:48 +00:00
2022-01-19 21:28:59 +00:00
dest_page = dest_notebook . NewPageQuery ( location_context , initial_hashes = hashes )
2017-12-20 22:55:48 +00:00
do_add = False
else :
2019-11-14 03:56:30 +00:00
dest_page = dest_notebook . widget ( tab_index )
2017-12-20 22:55:48 +00:00
if isinstance ( dest_page , PagesNotebook ) :
result = dest_page . GetCurrentMediaPage ( )
if result is None :
2022-01-19 21:28:59 +00:00
dest_page = dest_page . NewPageQuery ( location_context , initial_hashes = hashes )
2017-12-20 22:55:48 +00:00
do_add = False
else :
dest_page = result
if dest_page is None :
return # we somehow dropped onto a new notebook that has no pages
2021-12-15 22:16:22 +00:00
if isinstance ( dest_page , PagesNotebook ) :
return # dropped on the edge of some notebook somehow
2017-12-20 22:55:48 +00:00
if dest_page . GetPageKey ( ) == source_page_key :
return # we dropped onto the same page we picked up on
if do_add :
2019-05-01 21:24:42 +00:00
media_results = self . _controller . Read ( ' media_results ' , hashes , sorted = True )
2017-12-20 22:55:48 +00:00
2020-11-11 22:20:16 +00:00
dest_page . AddMediaResults ( media_results )
2017-12-20 22:55:48 +00:00
else :
self . ShowPage ( source_page )
2019-11-14 03:56:30 +00:00
# queryKBM here for instant check, not waiting for event processing to catch up u wot mate
ctrl_down = QW . QApplication . queryKeyboardModifiers ( ) & QC . Qt . ControlModifier
2017-12-20 22:55:48 +00:00
if not ctrl_down :
source_page . GetMediaPanel ( ) . RemoveMedia ( source_page . GetPageKey ( ) , hashes )
2020-11-11 22:20:16 +00:00
def MoveSelection ( self , delta , just_do_test = False ) :
current_index = self . currentIndex ( )
current_page = self . currentWidget ( )
if current_page is None or current_index is None :
return False
elif isinstance ( current_page , PagesNotebook ) :
if current_page . MoveSelection ( delta , just_do_test = True ) :
return current_page . MoveSelection ( delta , just_do_test = just_do_test )
new_index = self . currentIndex ( ) + delta
if 0 < = new_index < = self . count ( ) - 1 :
if not just_do_test :
self . setCurrentIndex ( new_index )
return True
return False
def MoveSelectionEnd ( self , delta , just_do_test = False ) :
if self . count ( ) < = 1 : # 1 is a no-op
return False
current_page = self . currentWidget ( )
if isinstance ( current_page , PagesNotebook ) :
if current_page . MoveSelectionEnd ( delta , just_do_test = True ) :
return current_page . MoveSelectionEnd ( delta , just_do_test = just_do_test )
if delta < 0 :
new_index = 0
else :
new_index = self . count ( ) - 1
if not just_do_test :
self . setCurrentIndex ( new_index )
return True
2018-02-14 21:47:18 +00:00
def NewPage ( self , management_controller , initial_hashes = None , forced_insertion_index = None , on_deepest_notebook = False , select_page = True ) :
2017-08-16 21:58:06 +00:00
2019-11-14 03:56:30 +00:00
current_page = self . currentWidget ( )
2017-08-16 21:58:06 +00:00
2017-08-23 21:34:25 +00:00
if on_deepest_notebook and isinstance ( current_page , PagesNotebook ) :
2017-08-16 21:58:06 +00:00
2017-09-13 20:50:41 +00:00
return current_page . NewPage ( management_controller , initial_hashes = initial_hashes , forced_insertion_index = forced_insertion_index , on_deepest_notebook = on_deepest_notebook )
2017-08-16 21:58:06 +00:00
2017-12-13 22:33:07 +00:00
WARNING_TOTAL_PAGES = self . _controller . new_options . GetInteger ( ' total_pages_warning ' )
2021-11-24 21:59:58 +00:00
MAX_TOTAL_PAGES = max ( 500 , WARNING_TOTAL_PAGES * 2 )
2017-12-06 22:06:56 +00:00
2021-10-06 20:59:30 +00:00
(
total_active_page_count ,
total_active_num_hashes ,
total_active_num_seeds ,
total_closed_page_count ,
total_closed_num_hashes ,
total_closed_num_seeds
) = self . _controller . gui . GetTotalPageCounts ( )
2017-12-06 22:06:56 +00:00
if total_active_page_count + total_closed_page_count > = WARNING_TOTAL_PAGES :
2017-08-16 21:58:06 +00:00
2017-12-06 22:06:56 +00:00
self . _controller . gui . DeleteAllClosedPages ( )
2017-08-16 21:58:06 +00:00
2017-12-06 22:06:56 +00:00
if not HG . no_page_limit_mode :
2017-08-16 21:58:06 +00:00
2021-11-24 21:59:58 +00:00
if total_active_page_count > = MAX_TOTAL_PAGES and not ClientGUIFunctions . DialogIsOpen ( ) :
2017-08-23 21:34:25 +00:00
2017-12-06 22:06:56 +00:00
message = ' The client should not have more than ' + str ( MAX_TOTAL_PAGES ) + ' pages open, as it leads to program instability! Are you sure you want to open more pages? '
2017-08-23 21:34:25 +00:00
2019-09-05 00:05:32 +00:00
result = ClientGUIDialogsQuick . GetYesNo ( self , message , title = ' Too many pages! ' , yes_label = ' yes, and do not tell me again ' , no_label = ' no ' )
2019-11-14 03:56:30 +00:00
if result == QW . QDialog . Accepted :
2017-12-06 22:06:56 +00:00
2019-09-05 00:05:32 +00:00
HG . no_page_limit_mode = True
self . _controller . pub ( ' notify_new_options ' )
else :
return None
2017-12-06 22:06:56 +00:00
2017-08-23 21:34:25 +00:00
2017-12-06 22:06:56 +00:00
if total_active_page_count == WARNING_TOTAL_PAGES :
2017-08-23 21:34:25 +00:00
2017-12-13 22:33:07 +00:00
HydrusData . ShowText ( ' You have ' + str ( total_active_page_count ) + ' pages open! You can only open a few more before program stability is affected! Please close some now! ' )
2017-08-23 21:34:25 +00:00
2017-08-16 21:58:06 +00:00
self . _controller . ResetIdleTimer ( )
self . _controller . ResetPageChangeTimer ( )
if initial_hashes is None :
initial_hashes = [ ]
page = Page ( self , self . _controller , management_controller , initial_hashes )
if forced_insertion_index is None :
if self . _next_new_page_index is None :
insertion_index = self . _GetDefaultPageInsertionIndex ( )
else :
insertion_index = self . _next_new_page_index
self . _next_new_page_index = None
else :
insertion_index = forced_insertion_index
2019-04-10 22:50:53 +00:00
page_name = page . GetName ( )
2017-08-16 21:58:06 +00:00
2017-10-18 19:41:25 +00:00
# in some unusual circumstances, this gets out of whack
2019-11-14 03:56:30 +00:00
insertion_index = min ( insertion_index , self . count ( ) )
2022-03-09 22:18:23 +00:00
if self . _controller . new_options . GetBoolean ( ' force_hide_page_signal_on_new_page ' ) :
current_gui_page = self . _controller . gui . GetCurrentPage ( )
if current_gui_page is not None :
current_gui_page . PageHidden ( )
2019-11-14 03:56:30 +00:00
self . insertTab ( insertion_index , page , page_name )
2019-11-28 01:11:46 +00:00
if select_page :
self . setCurrentIndex ( insertion_index )
2017-10-18 19:41:25 +00:00
2017-08-16 21:58:06 +00:00
self . _controller . pub ( ' refresh_page_name ' , page . GetPageKey ( ) )
2017-10-25 21:45:15 +00:00
self . _controller . pub ( ' notify_new_pages ' )
2017-08-16 21:58:06 +00:00
2021-03-17 21:59:28 +00:00
page . Start ( )
2018-03-28 21:55:58 +00:00
if select_page :
2018-05-16 20:09:50 +00:00
page . SetSearchFocus ( )
# this is here for now due to the pagechooser having a double-layer dialog on a booru choice, which messes up some focus inheritance
2021-06-23 21:11:38 +00:00
self . _controller . CallLaterQtSafe ( self , 0.5 , ' set page focus ' , page . SetSearchFocus )
2018-03-28 21:55:58 +00:00
2017-08-16 21:58:06 +00:00
return page
2017-08-23 21:34:25 +00:00
def NewPageDuplicateFilter ( self , on_deepest_notebook = False ) :
2017-08-16 21:58:06 +00:00
management_controller = ClientGUIManagement . CreateManagementControllerDuplicateFilter ( )
2017-08-23 21:34:25 +00:00
return self . NewPage ( management_controller , on_deepest_notebook = on_deepest_notebook )
2017-08-16 21:58:06 +00:00
2021-06-09 20:28:09 +00:00
def NewPageImportGallery ( self , page_name = None , on_deepest_notebook = False , select_page = True ) :
2017-08-16 21:58:06 +00:00
2021-06-09 20:28:09 +00:00
management_controller = ClientGUIManagement . CreateManagementControllerImportGallery ( page_name = page_name )
2017-08-16 21:58:06 +00:00
2021-06-09 20:28:09 +00:00
return self . NewPage ( management_controller , on_deepest_notebook = on_deepest_notebook , select_page = select_page )
2017-08-16 21:58:06 +00:00
2018-04-05 01:22:26 +00:00
def NewPageImportSimpleDownloader ( self , on_deepest_notebook = False ) :
2017-08-16 21:58:06 +00:00
2018-04-05 01:22:26 +00:00
management_controller = ClientGUIManagement . CreateManagementControllerImportSimpleDownloader ( )
2017-08-16 21:58:06 +00:00
2017-08-23 21:34:25 +00:00
return self . NewPage ( management_controller , on_deepest_notebook = on_deepest_notebook )
2017-08-16 21:58:06 +00:00
2019-03-20 21:22:10 +00:00
def NewPageImportMultipleWatcher ( self , page_name = None , url = None , on_deepest_notebook = False , select_page = True ) :
2018-05-16 20:09:50 +00:00
2019-02-27 23:03:30 +00:00
management_controller = ClientGUIManagement . CreateManagementControllerImportMultipleWatcher ( page_name = page_name , url = url )
2018-05-16 20:09:50 +00:00
2019-03-20 21:22:10 +00:00
return self . NewPage ( management_controller , on_deepest_notebook = on_deepest_notebook , select_page = select_page )
2018-05-16 20:09:50 +00:00
2019-03-20 21:22:10 +00:00
def NewPageImportURLs ( self , page_name = None , on_deepest_notebook = False , select_page = True ) :
2017-08-16 21:58:06 +00:00
2019-02-27 23:03:30 +00:00
management_controller = ClientGUIManagement . CreateManagementControllerImportURLs ( page_name = page_name )
2017-08-16 21:58:06 +00:00
2019-03-20 21:22:10 +00:00
return self . NewPage ( management_controller , on_deepest_notebook = on_deepest_notebook , select_page = select_page )
2017-08-16 21:58:06 +00:00
2017-08-23 21:34:25 +00:00
def NewPagePetitions ( self , service_key , on_deepest_notebook = False ) :
2017-08-16 21:58:06 +00:00
management_controller = ClientGUIManagement . CreateManagementControllerPetitions ( service_key )
2017-08-23 21:34:25 +00:00
return self . NewPage ( management_controller , on_deepest_notebook = on_deepest_notebook )
2017-08-16 21:58:06 +00:00
2022-01-19 21:28:59 +00:00
def NewPageQuery ( self , location_context : ClientLocation . LocationContext , initial_hashes = None , initial_predicates = None , page_name = None , on_deepest_notebook = False , do_sort = False , select_page = True ) :
2017-08-16 21:58:06 +00:00
if initial_hashes is None :
initial_hashes = [ ]
if initial_predicates is None :
initial_predicates = [ ]
if page_name is None :
page_name = ' files '
search_enabled = len ( initial_hashes ) == 0
2017-12-06 22:06:56 +00:00
new_options = self . _controller . new_options
2017-08-16 21:58:06 +00:00
tag_service_key = new_options . GetKey ( ' default_tag_service_search_page ' )
if not self . _controller . services_manager . ServiceExists ( tag_service_key ) :
tag_service_key = CC . COMBINED_TAG_SERVICE_KEY
2022-01-19 21:28:59 +00:00
if location_context . IsAllKnownFiles ( ) and tag_service_key == CC . COMBINED_TAG_SERVICE_KEY :
2020-03-18 21:35:57 +00:00
2022-01-19 21:28:59 +00:00
location_context = location_context = ClientLocation . LocationContext . STATICCreateSimple ( CC . COMBINED_LOCAL_FILE_SERVICE_KEY )
2020-03-18 21:35:57 +00:00
2020-03-11 21:52:11 +00:00
tag_search_context = ClientSearch . TagSearchContext ( service_key = tag_service_key )
2022-01-19 21:28:59 +00:00
file_search_context = ClientSearch . FileSearchContext ( location_context = location_context , tag_search_context = tag_search_context , predicates = initial_predicates )
2017-08-16 21:58:06 +00:00
2020-04-01 21:51:42 +00:00
management_controller = ClientGUIManagement . CreateManagementControllerQuery ( page_name , file_search_context , search_enabled )
2017-08-16 21:58:06 +00:00
2018-02-14 21:47:18 +00:00
page = self . NewPage ( management_controller , initial_hashes = initial_hashes , on_deepest_notebook = on_deepest_notebook , select_page = select_page )
2017-10-18 19:41:25 +00:00
if do_sort :
HG . client_controller . pub ( ' do_page_sort ' , page . GetPageKey ( ) )
return page
2017-08-16 21:58:06 +00:00
2018-05-16 20:09:50 +00:00
def NewPagesNotebook ( self , name = ' pages ' , forced_insertion_index = None , on_deepest_notebook = False , give_it_a_blank_page = True , select_page = True ) :
2017-08-23 21:34:25 +00:00
2019-11-14 03:56:30 +00:00
current_page = self . currentWidget ( )
2017-08-23 21:34:25 +00:00
if on_deepest_notebook and isinstance ( current_page , PagesNotebook ) :
2019-02-13 22:26:43 +00:00
return current_page . NewPagesNotebook ( name = name , forced_insertion_index = forced_insertion_index , on_deepest_notebook = on_deepest_notebook , give_it_a_blank_page = give_it_a_blank_page )
2017-08-23 21:34:25 +00:00
2017-08-16 21:58:06 +00:00
self . _controller . ResetIdleTimer ( )
self . _controller . ResetPageChangeTimer ( )
page = PagesNotebook ( self , self . _controller , name )
if forced_insertion_index is None :
if self . _next_new_page_index is None :
insertion_index = self . _GetDefaultPageInsertionIndex ( )
else :
insertion_index = self . _next_new_page_index
self . _next_new_page_index = None
else :
insertion_index = forced_insertion_index
2019-04-10 22:50:53 +00:00
page_name = page . GetName ( )
2017-08-16 21:58:06 +00:00
2019-11-14 03:56:30 +00:00
self . insertTab ( insertion_index , page , page_name )
2020-05-13 19:03:16 +00:00
if select_page :
self . setCurrentIndex ( insertion_index )
2017-08-16 21:58:06 +00:00
self . _controller . pub ( ' refresh_page_name ' , page . GetPageKey ( ) )
2017-08-30 20:27:47 +00:00
if give_it_a_blank_page :
2022-03-23 20:57:10 +00:00
default_location_context = HG . client_controller . new_options . GetDefaultLocalLocationContext ( )
2022-01-19 21:28:59 +00:00
page . NewPageQuery ( default_location_context )
2017-08-30 20:27:47 +00:00
2017-08-16 21:58:06 +00:00
return page
def NotifyPageUnclosed ( self , page ) :
page_key = page . GetPageKey ( )
for ( index , closed_page_key ) in self . _closed_pages :
if page_key == closed_page_key :
2019-11-14 03:56:30 +00:00
page . show ( )
2017-08-16 21:58:06 +00:00
2019-11-14 03:56:30 +00:00
insert_index = min ( index , self . count ( ) )
2017-08-16 21:58:06 +00:00
2019-04-10 22:50:53 +00:00
name = page . GetName ( )
2017-08-16 21:58:06 +00:00
2019-11-14 03:56:30 +00:00
self . insertTab ( insert_index , page , name )
self . setCurrentIndex ( insert_index )
2017-08-16 21:58:06 +00:00
self . _controller . pub ( ' refresh_page_name ' , page . GetPageKey ( ) )
self . _closed_pages . remove ( ( index , closed_page_key ) )
break
def PageHidden ( self ) :
2019-11-14 03:56:30 +00:00
result = self . currentWidget ( )
2017-08-16 21:58:06 +00:00
if result is not None :
result . PageHidden ( )
2020-05-13 19:03:16 +00:00
def pageJustChanged ( self , index ) :
old_selection = self . _previous_page_index
selection = index
if old_selection != - 1 and old_selection < self . count ( ) :
self . widget ( old_selection ) . PageHidden ( )
if selection != - 1 :
new_page = self . widget ( selection )
new_page . PageShown ( )
self . _controller . gui . RefreshStatusBar ( )
self . _previous_page_index = index
self . _controller . pub ( ' notify_page_change ' )
2017-08-16 21:58:06 +00:00
def PageShown ( self ) :
2019-11-14 03:56:30 +00:00
result = self . currentWidget ( )
2017-08-16 21:58:06 +00:00
if result is not None :
result . PageShown ( )
2018-02-14 21:47:18 +00:00
def PresentImportedFilesToPage ( self , hashes , page_name ) :
2020-11-11 22:20:16 +00:00
hashes = list ( hashes )
2020-09-23 21:02:02 +00:00
page = self . _GetPageFromName ( page_name , only_media_pages = True )
2018-02-14 21:47:18 +00:00
if page is None :
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
page = self . NewPageQuery ( location_context , initial_hashes = hashes , page_name = page_name , on_deepest_notebook = True , select_page = False )
2018-02-14 21:47:18 +00:00
else :
2020-11-11 22:20:16 +00:00
def work_callable ( ) :
2019-10-16 20:47:55 +00:00
2020-11-11 22:20:16 +00:00
media_results = self . _controller . Read ( ' media_results ' , hashes , sorted = True )
2019-10-16 20:47:55 +00:00
2020-11-11 22:20:16 +00:00
return media_results
2019-10-16 20:47:55 +00:00
2020-11-11 22:20:16 +00:00
def publish_callable ( media_results ) :
2019-10-16 20:47:55 +00:00
2020-11-11 22:20:16 +00:00
page . AddMediaResults ( media_results )
2019-10-16 20:47:55 +00:00
2018-02-14 21:47:18 +00:00
2020-11-11 22:20:16 +00:00
job = ClientGUIAsync . AsyncQtJob ( page , work_callable , publish_callable )
job . start ( )
2018-02-14 21:47:18 +00:00
return page
2017-10-04 17:51:58 +00:00
def RefreshAllPages ( self ) :
2017-08-16 21:58:06 +00:00
for page in self . _GetPages ( ) :
2017-10-04 17:51:58 +00:00
if isinstance ( page , PagesNotebook ) :
page . RefreshAllPages ( )
else :
page . RefreshQuery ( )
2017-08-16 21:58:06 +00:00
def RefreshPageName ( self , page_key = None ) :
if page_key is None :
2019-11-14 03:56:30 +00:00
for index in range ( self . count ( ) ) :
2017-08-16 21:58:06 +00:00
self . _RefreshPageName ( index )
else :
for ( index , page ) in enumerate ( self . _GetPages ( ) ) :
do_it = False
if page . GetPageKey ( ) == page_key :
do_it = True
elif isinstance ( page , PagesNotebook ) and page . HasPageKey ( page_key ) :
do_it = True
if do_it :
self . _RefreshPageName ( index )
break
2019-04-10 22:50:53 +00:00
def SetName ( self , name ) :
2017-08-16 21:58:06 +00:00
self . _name = name
def ShowPage ( self , showee ) :
for ( i , page ) in enumerate ( self . _GetPages ( ) ) :
2019-11-14 03:56:30 +00:00
if isinstance ( page , QW . QTabWidget ) and page . HasPage ( showee ) :
2017-08-16 21:58:06 +00:00
2019-11-14 03:56:30 +00:00
self . setCurrentIndex ( i )
2017-08-16 21:58:06 +00:00
page . ShowPage ( showee )
break
elif page == showee :
2019-11-14 03:56:30 +00:00
self . setCurrentIndex ( i )
2017-08-16 21:58:06 +00:00
break
2019-02-13 22:26:43 +00:00
def TestAbleToClose ( self ) :
statement = self . GetTestAbleToCloseStatement ( )
if statement is not None :
message = ' Are you sure you want to close this page of pages? '
message + = os . linesep * 2
message + = statement
2019-09-05 00:05:32 +00:00
result = ClientGUIDialogsQuick . GetYesNo ( self , message )
2019-11-14 03:56:30 +00:00
if result == QW . QDialog . Rejected :
2019-02-13 22:26:43 +00:00
2019-09-05 00:05:32 +00:00
raise HydrusExceptions . VetoException ( )
2019-02-13 22:26:43 +00:00
2018-05-30 20:13:21 +00:00
def REPEATINGPageUpdate ( self ) :
2017-12-13 22:33:07 +00:00
pass