hydrus/include/ClientGUIPages.py

353 lines
13 KiB
Python
Executable File

import HydrusConstants as HC
import ClientConstants as CC
import ClientGUICommon
import ClientGUIDialogs
import ClientGUIManagement
import ClientGUIMedia
import ClientGUIMessages
import ClientGUICanvas
import os
import time
import traceback
import wx
# Sizer Flags
FLAGS_NONE = wx.SizerFlags( 0 )
FLAGS_SMALL_INDENT = wx.SizerFlags( 0 ).Border( wx.ALL, 2 )
FLAGS_EXPAND_PERPENDICULAR = wx.SizerFlags( 0 ).Border( wx.ALL, 2 ).Expand()
FLAGS_EXPAND_BOTH_WAYS = wx.SizerFlags( 2 ).Border( wx.ALL, 2 ).Expand()
FLAGS_BUTTON_SIZERS = wx.SizerFlags( 0 ).Align( wx.ALIGN_RIGHT )
FLAGS_LONE_BUTTON = wx.SizerFlags( 0 ).Border( wx.ALL, 2 ).Align( wx.ALIGN_RIGHT )
FLAGS_MIXED = wx.SizerFlags( 0 ).Border( wx.ALL, 2 ).Align( wx.ALIGN_CENTER_VERTICAL )
class PageBase():
def __init__( self ):
self._page_key = os.urandom( 32 )
self._pretty_status = ''
self._options = wx.GetApp().Read( 'options' )
HC.pubsub.sub( self, 'SetPrettyStatus', 'new_page_status' )
def GetPrettyStatus( self ): return self._pretty_status
def GetSashPositions( self ):
x = self._options[ 'hpos' ]
y = self._options[ 'vpos' ]
return ( x, y )
def PageHidden( self ): HC.pubsub.pub( 'page_hidden', self._page_key )
def PageShown( self ): HC.pubsub.pub( 'page_shown', self._page_key )
def SetPrettyStatus( self, page_key, status ):
if page_key == self._page_key:
self._pretty_status = status
HC.pubsub.pub( 'refresh_status' )
def RefreshQuery( self ): HC.pubsub.pub( 'refresh_query', self._page_key )
def SetMediaFocus( self ): pass
def SetSearchFocus( self ): HC.pubsub.pub( 'set_search_focus', self._page_key )
def SetSynchronisedWait( self ): HC.pubsub.pub( 'synchronised_wait_switch', self._page_key )
def ShowHideSplit( self ): pass
def TryToClose( self ): pass
class PageLog( PageBase, wx.Panel ):
def __init__( self, parent ):
wx.Panel.__init__( self, parent )
PageBase.__init__( self )
log = wx.GetApp().GetLog()
self._log_list_ctrl = ClientGUICommon.SaneListCtrl( self, 480, [ ( 'type', 60 ), ( 'source', 180 ), ( 'message', -1 ), ( 'time', 120 ) ] )
for ( type, source, message, time ) in log: self._AddEntry( type, source, message, time )
vbox = wx.BoxSizer( wx.VERTICAL )
vbox.AddF( self._log_list_ctrl, FLAGS_EXPAND_BOTH_WAYS )
self.SetSizer( vbox )
HC.pubsub.sub( self, 'AddError', 'log_error' )
HC.pubsub.sub( self, 'AddMessage', 'log_message' )
def _AddEntry( self, type, source, message, time ): self._log_list_ctrl.Append( ( CC.log_string_lookup[ type ], source, message, HC.ConvertTimestampToPrettyTime( time ) ), ( CC.log_string_lookup[ type ], source, message, time ) )
def AddError( self, source, message ):
# assuming we want to show errors right now
self._AddEntry( CC.LOG_ERROR, source, message, time.time() )
def AddMessage( self, source, message ):
# assuming we want to show messages right now
self._AddEntry( CC.LOG_MESSAGE, source, message, time.time() )
class PageMessages( PageBase, wx.SplitterWindow ):
def __init__( self, parent, identity ):
wx.SplitterWindow.__init__( self, parent )
PageBase.__init__( self )
self.SetMinimumPaneSize( 120 )
self.SetSashGravity( 0.0 )
self._identity = identity
self._search_preview_split = wx.SplitterWindow( self, style=wx.SP_NOBORDER )
self._search_preview_split.SetMinimumPaneSize( 180 )
self._search_preview_split.SetSashGravity( 0.5 )
self._search_preview_split.Bind( wx.EVT_SPLITTER_DCLICK, self.EventPreviewUnsplit )
self._InitManagementPanel()
self._preview_panel = ClientGUICanvas.CanvasPanel( self._search_preview_split, self._page_key, CC.LOCAL_FILE_SERVICE_IDENTIFIER )
self._InitMessagesPanel()
self.SplitVertically( self._search_preview_split, self._messages_panel, self._options[ 'hpos' ] )
wx.CallAfter( self._search_preview_split.SplitHorizontally, self._management_panel, self._preview_panel, self._options[ 'vpos' ] )
def _InitManagementPanel( self ): self._management_panel = ClientGUIManagement.ManagementPanelMessages( self._search_preview_split, self._page_key, self._identity )
def _InitMessagesPanel( self ): self._messages_panel = ClientGUIMessages.ConversationSplitter( self, self._page_key, self._identity )
def EventPreviewUnsplit( self, event ): self._search_preview_split.Unsplit( self._preview_panel )
def GetSashPositions( self ):
if self.IsSplit(): x = self.GetSashPosition()
else: x = self._options[ 'hpos' ]
if self._search_preview_split.IsSplit(): y = -1 * self._preview_panel.GetSize()[1]
else: y = self._options[ 'vpos' ]
return ( x, y )
def ShowHideSplit( self ):
if self._search_preview_split.IsSplit(): self._search_preview_split.Unsplit( self._preview_panel )
else: self._search_preview_split.SplitHorizontally( self._management_panel, self._preview_panel, self._options[ 'vpos' ] )
def TryToClose( self ): self._management_panel.TryToClose()
class PageWithMedia( PageBase, wx.SplitterWindow ):
def __init__( self, parent, file_service_identifier = CC.LOCAL_FILE_SERVICE_IDENTIFIER ):
wx.SplitterWindow.__init__( self, parent )
PageBase.__init__( self )
self._file_service_identifier = file_service_identifier
self.SetMinimumPaneSize( 120 )
self.SetSashGravity( 0.0 )
self.Bind( wx.EVT_SPLITTER_DCLICK, self.EventUnsplit )
self._search_preview_split = wx.SplitterWindow( self, style=wx.SP_NOBORDER )
self._search_preview_split.SetMinimumPaneSize( 180 )
self._search_preview_split.SetSashGravity( 0.5 )
self._search_preview_split.Bind( wx.EVT_SPLITTER_DCLICK, self.EventPreviewUnsplit )
self._InitManagementPanel()
self._preview_panel = ClientGUICanvas.CanvasPanel( self._search_preview_split, self._page_key, self._file_service_identifier )
self._InitMediaPanel()
self.SplitVertically( self._search_preview_split, self._media_panel, self._options[ 'hpos' ] )
wx.CallAfter( self._search_preview_split.SplitHorizontally, self._management_panel, self._preview_panel, self._options[ 'vpos' ] )
HC.pubsub.sub( self, 'SwapMediaPanel', 'swap_media_panel' )
def EventPreviewUnsplit( self, event ): self._search_preview_split.Unsplit( self._preview_panel )
def EventUnsplit( self, event ): self.Unsplit( self._search_preview_split )
# used by autocomplete
def GetMedia( self ): return self._media_panel.GetSortedMedia()
def GetSashPositions( self ):
if self.IsSplit(): x = self.GetSashPosition()
else: x = self._options[ 'hpos' ]
if self._search_preview_split.IsSplit(): y = -1 * self._preview_panel.GetSize()[1]
else: y = self._options[ 'vpos' ]
return ( x, y )
def ShowHideSplit( self ):
if self.IsSplit():
self.Unsplit( self._search_preview_split )
else:
self.SplitVertically( self._search_preview_split, self._media_panel, self._options[ 'hpos' ] )
self._search_preview_split.SplitHorizontally( self._management_panel, self._preview_panel, self._options[ 'vpos' ] )
def SetMediaFocus( self ): self._media_panel.SetFocus()
def SwapMediaPanel( self, page_key, new_panel ):
if page_key == self._page_key:
self._preview_panel.SetMedia( None )
self.ReplaceWindow( self._media_panel, new_panel )
self._media_panel.Destroy()
self._media_panel = new_panel
def TryToClose( self ): self._management_panel.TryToClose()
class PageImport( PageWithMedia ):
def _InitMediaPanel( self ): self._media_panel = ClientGUIMedia.MediaPanelThumbnails( self, self._page_key, self._file_service_identifier, [], CC.FileQueryResult( self._file_service_identifier, [], [] ) )
class PageImportBooru( PageImport ):
def __init__( self, parent, booru ):
self._booru = booru
PageImport.__init__( self, parent )
def _InitManagementPanel( self ): self._management_panel = ClientGUIManagement.ManagementPanelImportWithQueueAdvancedBooru( self._search_preview_split, self, self._page_key, self._booru )
class PageImportDeviantArt( PageImport ):
def __init__( self, parent ):
PageImport.__init__( self, parent )
def _InitManagementPanel( self ): self._management_panel = ClientGUIManagement.ManagementPanelImportWithQueueAdvancedDeviantArt( self._search_preview_split, self, self._page_key )
class PageImportHDD( PageImport ):
def __init__( self, parent, paths, **kwargs ):
self._paths = paths
self._kwargs = kwargs
PageImport.__init__( self, parent )
def _InitManagementPanel( self ): self._management_panel = ClientGUIManagement.ManagementPanelImportHDD( self._search_preview_split, self, self._page_key, self._paths, **self._kwargs )
class PageImportHentaiFoundryArtist( PageImport ):
def __init__( self, parent ):
PageImport.__init__( self, parent )
def _InitManagementPanel( self ): self._management_panel = ClientGUIManagement.ManagementPanelImportWithQueueAdvancedHentaiFoundryArtist( self._search_preview_split, self, self._page_key )
class PageImportHentaiFoundryTags( PageImport ):
def __init__( self, parent ):
PageImport.__init__( self, parent )
def _InitManagementPanel( self ): self._management_panel = ClientGUIManagement.ManagementPanelImportWithQueueAdvancedHentaiFoundryTags( self._search_preview_split, self, self._page_key )
class PageImportThreadWatcher( PageImport ):
def _InitManagementPanel( self ): self._management_panel = ClientGUIManagement.ManagementPanelImportThreadWatcher( self._search_preview_split, self, self._page_key )
class PageImportURL( PageImport ):
def _InitManagementPanel( self ): self._management_panel = ClientGUIManagement.ManagementPanelImportWithQueueURL( self._search_preview_split, self, self._page_key )
class PagePetitions( PageWithMedia ):
def _InitManagementPanel( self ): self._management_panel = ClientGUIManagement.ManagementPanelPetitions( self._search_preview_split, self, self._page_key, self._file_service_identifier )
def _InitMediaPanel( self ): self._media_panel = ClientGUIMedia.MediaPanelNoQuery( self, self._page_key, self._file_service_identifier )
class PageQuery( PageWithMedia ):
def __init__( self, parent, file_service_identifier, initial_predicates = [] ):
self._initial_predicates = initial_predicates
PageWithMedia.__init__( self, parent, file_service_identifier )
def _InitManagementPanel( self ): self._management_panel = ClientGUIManagement.ManagementPanelQuery( self._search_preview_split, self, self._page_key, self._file_service_identifier, initial_predicates = self._initial_predicates )
def _InitMediaPanel( self ): self._media_panel = ClientGUIMedia.MediaPanelNoQuery( self, self._page_key, self._file_service_identifier )
class PageThreadDumper( PageWithMedia ):
def __init__( self, parent, imageboard, hashes ):
self._imageboard = imageboard
search_context = CC.FileSearchContext()
self._unsorted_file_query_result = wx.GetApp().Read( 'media_results', search_context, hashes )
hashes_to_media_results = { media_result.GetHash() : media_result for media_result in self._unsorted_file_query_result }
self._media_results = [ hashes_to_media_results[ hash ] for hash in hashes ]
self._media_results = filter( self._imageboard.IsOkToPost, self._media_results )
PageWithMedia.__init__( self, parent, CC.LOCAL_FILE_SERVICE_IDENTIFIER )
def _InitManagementPanel( self ): self._management_panel = ClientGUIManagement.ManagementPanelDumper( self._search_preview_split, self, self._page_key, self._imageboard, self._media_results )
def _InitMediaPanel( self ): self._media_panel = ClientGUIMedia.MediaPanelThumbnails( self, self._page_key, CC.LOCAL_FILE_SERVICE_IDENTIFIER, [], self._media_results )