diff --git a/client.pyw b/client.pyw
index f7ca18c6..7c77cb64 100755
--- a/client.pyw
+++ b/client.pyw
@@ -77,6 +77,7 @@ try:
except:
import traceback
+ import os
try:
diff --git a/help/changelog.html b/help/changelog.html
index 73537b5f..9993903a 100755
--- a/help/changelog.html
+++ b/help/changelog.html
@@ -8,6 +8,22 @@
changelog
+ version 218
+
+ - related tags control now updates on new media events (i.e. if the parent media viewer scrolls to different media)
+ - related tags also initialises with suggestions and refreshes the list on media change
+ - related tags now properly filter out dupe suggestions caused by siblings
+ - went over all the gui colours in the client, cleared some redundancies and replaced all the static whites and blacks with appropriate system defaults or chosen custom colours
+ - full size thumbnails can now also be stored in a different location, like resized thumbs, under options->file storage locations
+ - fixed false postiive shutdown maintenance checking due to vacuums projected to take longer than the given maintenance time
+ - fixed false postiive shutdown maintenance checking due to sqlite_stat1 creeping in
+ - pasting tags or otherwise editing many in at once in the manage tags frame will immediately commit all the changes in one db transaction, rather than one for each tag laggily in turn
+ - removed 'import tags' from file menu--this advanced stuff is now done in and better left to the advanced content update dialog
+ - restoring from an old db backup with a simpler db structure will no longer create conflicts
+ - deleting currently rendering files from the trash should be slightly more reliable
+ - fixed some crash error reporting
+ - misc cleanup
+
version 217
- fixed some high-res video streaming thread scheduling problems with the new video renderer
diff --git a/include/ClientCaches.py b/include/ClientCaches.py
index 9a0d45dc..c802a951 100644
--- a/include/ClientCaches.py
+++ b/include/ClientCaches.py
@@ -349,7 +349,7 @@ class ClientFilesManager( object ):
def _GetRebalanceTuple( self ):
- ( locations_to_ideal_weights, resized_thumbnail_override ) = self._controller.GetNewOptions().GetClientFilesLocationsToIdealWeights()
+ ( locations_to_ideal_weights, resized_thumbnail_override, full_size_thumbnail_override ) = self._controller.GetNewOptions().GetClientFilesLocationsToIdealWeights()
total_weight = sum( locations_to_ideal_weights.values() )
@@ -421,17 +421,34 @@ class ClientFilesManager( object ):
else:
- for hex_prefix in HydrusData.IterateHexPrefixes():
+ if full_size_thumbnail_override is None:
- full_size_prefix = 't' + hex_prefix
- file_prefix = 'f' + hex_prefix
-
- full_size_location = self._prefixes_to_locations[ full_size_prefix ]
- file_location = self._prefixes_to_locations[ file_prefix ]
-
- if full_size_location != file_location:
+ for hex_prefix in HydrusData.IterateHexPrefixes():
- return ( full_size_prefix, full_size_location, file_location )
+ full_size_prefix = 't' + hex_prefix
+ file_prefix = 'f' + hex_prefix
+
+ full_size_location = self._prefixes_to_locations[ full_size_prefix ]
+ file_location = self._prefixes_to_locations[ file_prefix ]
+
+ if full_size_location != file_location:
+
+ return ( full_size_prefix, full_size_location, file_location )
+
+
+
+ else:
+
+ for hex_prefix in HydrusData.IterateHexPrefixes():
+
+ full_size_prefix = 't' + hex_prefix
+
+ full_size_location = self._prefixes_to_locations[ full_size_prefix ]
+
+ if full_size_location != full_size_thumbnail_override:
+
+ return ( full_size_prefix, full_size_location, full_size_thumbnail_override )
+
diff --git a/include/ClientController.py b/include/ClientController.py
index 61c7c110..ffa56682 100755
--- a/include/ClientController.py
+++ b/include/ClientController.py
@@ -417,11 +417,15 @@ class Controller( HydrusController.HydrusController ):
if idle_shutdown_action in ( CC.IDLE_ON_SHUTDOWN, CC.IDLE_ON_SHUTDOWN_ASK_FIRST ):
- if self.ThereIsIdleShutdownWorkDue():
+ idle_shutdown_max_minutes = self._options[ 'idle_shutdown_max_minutes' ]
+
+ time_to_stop = HydrusData.GetNow() + ( idle_shutdown_max_minutes * 60 )
+
+ if self.ThereIsIdleShutdownWorkDue( time_to_stop ):
if idle_shutdown_action == CC.IDLE_ON_SHUTDOWN_ASK_FIRST:
- text = 'Is now a good time for the client to do up to ' + HydrusData.ConvertIntToPrettyString( self._options[ 'idle_shutdown_max_minutes' ] ) + ' minutes\' maintenance work?'
+ text = 'Is now a good time for the client to do up to ' + HydrusData.ConvertIntToPrettyString( idle_shutdown_max_minutes ) + ' minutes\' maintenance work?'
with ClientGUIDialogs.DialogYesNo( self._splash, text, title = 'Maintenance is due' ) as dlg_yn:
@@ -993,9 +997,9 @@ class Controller( HydrusController.HydrusController ):
return self._system_busy
- def ThereIsIdleShutdownWorkDue( self ):
+ def ThereIsIdleShutdownWorkDue( self, time_to_stop ):
- maintenance_due = self.Read( 'maintenance_due' )
+ maintenance_due = self.Read( 'maintenance_due', time_to_stop )
if maintenance_due:
diff --git a/include/ClientDB.py b/include/ClientDB.py
index 0708cbe3..d4ec5f60 100755
--- a/include/ClientDB.py
+++ b/include/ClientDB.py
@@ -2320,7 +2320,7 @@ class DB( HydrusDB.HydrusDB ):
file_hashes = self._GetHashes( deletable_file_hash_ids )
- client_files_manager.DeleteFiles( file_hashes )
+ wx.CallAfter( client_files_manager.DeleteFiles, file_hashes )
useful_thumbnail_hash_ids = { hash_id for ( hash_id, ) in self._c.execute( 'SELECT hash_id FROM current_files WHERE service_id != ? AND hash_id IN ' + HydrusData.SplayListForDB( hash_ids ) + ';', ( self._trash_service_id, ) ) }
@@ -2331,7 +2331,7 @@ class DB( HydrusDB.HydrusDB ):
thumbnail_hashes = self._GetHashes( deletable_thumbnail_hash_ids )
- client_files_manager.DeleteThumbnails( thumbnail_hashes )
+ wx.CallAfter( client_files_manager.DeleteThumbnails, thumbnail_hashes )
@@ -4299,6 +4299,10 @@ class DB( HydrusDB.HydrusDB ):
def _GetRelatedTags( self, service_key, skip_hash, search_tags, max_results, max_time_to_take ):
+ siblings_manager = HydrusGlobals.client_controller.GetManager( 'tag_siblings' )
+
+ search_tags = siblings_manager.CollapseTags( search_tags )
+
start = HydrusData.GetNowPrecise()
service_id = self._GetServiceId( service_key )
@@ -4307,9 +4311,9 @@ class DB( HydrusDB.HydrusDB ):
( current_mappings_table_name, deleted_mappings_table_name, pending_mappings_table_name, petitioned_mappings_table_name ) = GenerateMappingsTableNames( service_id )
- namespace_ids_to_tag_ids = HydrusData.BuildKeyToListDict( [ self._GetNamespaceIdTagId( tag ) for tag in search_tags ] )
+ search_namespace_ids_to_tag_ids = HydrusData.BuildKeyToListDict( [ self._GetNamespaceIdTagId( tag ) for tag in search_tags ] )
- namespace_ids = namespace_ids_to_tag_ids.keys()
+ namespace_ids = search_namespace_ids_to_tag_ids.keys()
if len( namespace_ids ) == 0:
@@ -4329,7 +4333,7 @@ class DB( HydrusDB.HydrusDB ):
namespace_start = HydrusData.GetNowPrecise()
- tag_ids = namespace_ids_to_tag_ids[ namespace_id ]
+ tag_ids = search_namespace_ids_to_tag_ids[ namespace_id ]
random.shuffle( tag_ids )
@@ -4398,7 +4402,7 @@ class DB( HydrusDB.HydrusDB ):
#
- for ( namespace_id, tag_ids ) in namespace_ids_to_tag_ids.items():
+ for ( namespace_id, tag_ids ) in search_namespace_ids_to_tag_ids.items():
for tag_id in tag_ids:
@@ -4411,9 +4415,13 @@ class DB( HydrusDB.HydrusDB ):
results = counter.most_common( max_results )
- tags_and_counts = [ ( self._GetNamespaceTag( namespace_id, tag_id ), count ) for ( ( namespace_id, tag_id ), count ) in results ]
+ tags_to_counts = { self._GetNamespaceTag( namespace_id, tag_id ) : count for ( ( namespace_id, tag_id ), count ) in results }
- tags_to_do = [ tag for ( tag, count ) in tags_and_counts ]
+ tags_to_counts = siblings_manager.CollapseTagsToCount( tags_to_counts )
+
+ tags_to_do = tags_to_counts.keys()
+
+ tags_to_do = { tag for tag in tags_to_counts if tag not in search_tags }
tag_censorship_manager = self._controller.GetManager( 'tag_censorship' )
@@ -4422,7 +4430,7 @@ class DB( HydrusDB.HydrusDB ):
inclusive = True
pending_count = 0
- predicates = [ ClientSearch.Predicate( HC.PREDICATE_TYPE_TAG, tag, inclusive, current_count, pending_count ) for ( tag, current_count ) in tags_and_counts if tag in filtered_tags ]
+ predicates = [ ClientSearch.Predicate( HC.PREDICATE_TYPE_TAG, tag, inclusive, tags_to_counts[ tag ], pending_count ) for tag in filtered_tags ]
return predicates
@@ -5258,7 +5266,7 @@ class DB( HydrusDB.HydrusDB ):
return True
- def _MaintenanceDue( self ):
+ def _MaintenanceDue( self, stop_time ):
# vacuum
@@ -5272,11 +5280,33 @@ class DB( HydrusDB.HydrusDB ):
due_names = { name for name in db_names if name not in existing_names_to_timestamps or HydrusData.TimeHasPassed( existing_names_to_timestamps[ name ] + stale_time_delta ) }
- due_names.discard( 'sqlite_stat1' )
+ possible_due_names = set()
if len( due_names ) > 0:
- return True
+ self._CloseDBCursor()
+
+ try:
+
+ for name in due_names:
+
+ db_path = os.path.join( self._db_dir, self._db_filenames[ name ] )
+
+ if HydrusDB.CanVacuum( db_path, stop_time = stop_time ):
+
+ possible_due_names.add( name )
+
+
+
+ if len( possible_due_names ) > 0:
+
+ return True
+
+
+ finally:
+
+ self._InitDBCursor()
+
@@ -5295,7 +5325,9 @@ class DB( HydrusDB.HydrusDB ):
all_names.update( ( name for ( name, ) in self._c.execute( 'SELECT name FROM ' + db_name + '.sqlite_master;' ) ) )
- names_to_analyze = [ name for name in all_names if name not in existing_names_to_timestamps or HydrusData.TimeHasPassed( existing_names_to_timestamps[ name ] + stale_time_delta ) ]
+ names_to_analyze = { name for name in all_names if name not in existing_names_to_timestamps or HydrusData.TimeHasPassed( existing_names_to_timestamps[ name ] + stale_time_delta ) }
+
+ names_to_analyze.discard( 'sqlite_stat1' )
if len( names_to_analyze ) > 0:
@@ -8738,7 +8770,17 @@ class DB( HydrusDB.HydrusDB ):
source = os.path.join( path, filename )
dest = os.path.join( self._db_dir, filename )
- HydrusPaths.MirrorFile( source, dest )
+ if os.path.exists( source ):
+
+ HydrusPaths.MirrorFile( source, dest )
+
+ else:
+
+ # if someone backs up with an older version that does not have as many db files as this version, we get conflict
+ # don't want to delete just in case, but we will move it out the way
+
+ shutil.move( dest, dest + '.old' )
+
client_files_default = os.path.join( self._db_dir, 'client_files' )
diff --git a/include/ClientData.py b/include/ClientData.py
index fdfaadbf..5b858944 100644
--- a/include/ClientData.py
+++ b/include/ClientData.py
@@ -516,6 +516,7 @@ class ClientOptions( HydrusSerialisable.SerialisableBase ):
self._dictionary[ 'client_files_locations_ideal_weights' ] = [ ( HydrusPaths.ConvertAbsPathToPortablePath( client_files_default ), 1.0 ) ]
self._dictionary[ 'client_files_locations_resized_thumbnail_override' ] = None
+ self._dictionary[ 'client_files_locations_full_size_thumbnail_override' ] = None
def _InitialiseFromSerialisableInfo( self, serialisable_info ):
@@ -571,7 +572,15 @@ class ClientOptions( HydrusSerialisable.SerialisableBase ):
resized_thumbnail_override = HydrusPaths.ConvertPortablePathToAbsPath( resized_thumbnail_override )
- return ( paths_to_weights, resized_thumbnail_override )
+
+ full_size_thumbnail_override = self._dictionary[ 'client_files_locations_full_size_thumbnail_override' ]
+
+ if full_size_thumbnail_override is not None:
+
+ full_size_thumbnail_override = HydrusPaths.ConvertPortablePathToAbsPath( full_size_thumbnail_override )
+
+
+ return ( paths_to_weights, resized_thumbnail_override, full_size_thumbnail_override )
@@ -704,7 +713,7 @@ class ClientOptions( HydrusSerialisable.SerialisableBase ):
- def SetClientFilesLocationsToIdealWeights( self, locations_to_weights, resized_thumbnail_override ):
+ def SetClientFilesLocationsToIdealWeights( self, locations_to_weights, resized_thumbnail_override, full_size_thumbnail_override ):
with self._lock:
@@ -718,6 +727,7 @@ class ClientOptions( HydrusSerialisable.SerialisableBase ):
self._dictionary[ 'client_files_locations_resized_thumbnail_override' ] = resized_thumbnail_override
+ self._dictionary[ 'client_files_locations_full_size_thumbnail_override' ] = full_size_thumbnail_override
diff --git a/include/ClientGUI.py b/include/ClientGUI.py
index cfc1040c..ec2c4c28 100755
--- a/include/ClientGUI.py
+++ b/include/ClientGUI.py
@@ -702,7 +702,6 @@ class FrameGUI( ClientGUITopLevelWindows.FrameThatResizes ):
def file():
menu.Append( ClientCaches.MENU_EVENT_ID_TO_ACTION_CACHE.GetPermanentId( 'import_files' ), p( '&Import Files' ), p( 'Add new files to the database.' ) )
- menu.Append( ClientCaches.MENU_EVENT_ID_TO_ACTION_CACHE.GetPermanentId( 'import_tags' ), p( '&Import Tag Archive' ), p( 'Add tags from a tag archive.' ) )
menu.AppendSeparator()
menu.Append( ClientCaches.MENU_EVENT_ID_TO_ACTION_CACHE.GetPermanentId( 'manage_import_folders' ), p( 'Manage Import Folders' ), p( 'Manage folders from which the client can automatically import.' ) )
menu.Append( ClientCaches.MENU_EVENT_ID_TO_ACTION_CACHE.GetPermanentId( 'manage_export_folders' ), p( 'Manage Export Folders' ), p( 'Manage folders to which the client can automatically export.' ) )
@@ -793,7 +792,7 @@ class FrameGUI( ClientGUITopLevelWindows.FrameThatResizes ):
def pages():
menu.Append( ClientCaches.MENU_EVENT_ID_TO_ACTION_CACHE.GetPermanentId( 'refresh' ), p( '&Refresh' ), p( 'Refresh the current view.' ) )
- menu.Append( ClientCaches.MENU_EVENT_ID_TO_ACTION_CACHE.GetPermanentId( 'show_hide_splitters' ), p( 'Show/Hide Splitters' ), p( 'Show or hide the current page\'s splitters.' ) )
+ menu.Append( ClientCaches.MENU_EVENT_ID_TO_ACTION_CACHE.GetPermanentId( 'show_hide_splitters' ), p( 'Show/Hide Management and Preview Panels' ), p( 'Show or hide the panels on the left.' ) )
menu.AppendSeparator()
@@ -1207,27 +1206,6 @@ class FrameGUI( ClientGUITopLevelWindows.FrameThatResizes ):
- def _ImportTags( self ):
-
- with wx.FileDialog( self, style = wx.FD_MULTIPLE ) as dlg:
-
- if dlg.ShowModal() == wx.ID_OK:
-
- paths = [ HydrusData.ToUnicode( path ) for path in dlg.GetPaths() ]
-
- services = self._controller.GetServicesManager().GetServices( HC.TAG_SERVICES )
-
- service_keys = [ service.GetServiceKey() for service in services ]
-
- service_key = ClientGUIDialogs.SelectServiceKey( service_keys = service_keys )
-
- for path in paths:
-
- ClientGUIDialogs.ImportFromHTA( self, path, service_key )
-
-
-
-
def _InitialiseMenubar( self ):
self._menubar = wx.MenuBar()
@@ -2377,7 +2355,6 @@ The password is cleartext here but obscured in the entry dialog. Enter a blank p
elif command == 'help_about': self._AboutWindow()
elif command == 'help_shortcuts': wx.MessageBox( CC.SHORTCUT_HELP )
elif command == 'import_files': self._ImportFiles()
- elif command == 'import_tags': self._ImportTags()
elif command == 'load_gui_session': self._LoadGUISession( data )
elif command == 'load_into_disk_cache':
@@ -2892,7 +2869,7 @@ class FrameSplash( wx.Frame ):
def _Redraw( self, dc ):
- dc.SetBackground( wx.Brush( wx.WHITE ) )
+ dc.SetBackground( wx.Brush( wx.SystemSettings.GetColour( wx.SYS_COLOUR_WINDOW ) ) )
dc.Clear()
diff --git a/include/ClientGUICanvas.py b/include/ClientGUICanvas.py
index 6a26b538..0188849d 100755
--- a/include/ClientGUICanvas.py
+++ b/include/ClientGUICanvas.py
@@ -624,8 +624,6 @@ class AnimationBar( wx.Window ):
dc.SetFont( wx.SystemSettings.GetFont( wx.SYS_DEFAULT_GUI_FONT ) )
- dc.SetTextForeground( wx.BLACK )
-
s = HydrusData.ConvertValueRangeToPrettyString( self._current_frame_index + 1, self._num_frames )
( x, y ) = dc.GetTextExtent( s )
diff --git a/include/ClientGUICommon.py b/include/ClientGUICommon.py
index 9d53b2f2..33e9de7d 100755
--- a/include/ClientGUICommon.py
+++ b/include/ClientGUICommon.py
@@ -199,7 +199,7 @@ class AutoCompleteDropdown( wx.Panel ):
self._dropdown_window = wx.Frame( self, style = wx.FRAME_TOOL_WINDOW | wx.FRAME_NO_TASKBAR | wx.FRAME_FLOAT_ON_PARENT | wx.BORDER_RAISED )
- self._dropdown_window.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_BTNFACE ) )
+ self._dropdown_window.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_FRAMEBK ) )
self._dropdown_window.SetSize( ( 0, 0 ) )
@@ -1829,7 +1829,7 @@ class ListBook( wx.Panel ):
wx.Panel.__init__( self, *args, **kwargs )
- self.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_BTNFACE ) )
+ self.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_FRAMEBK ) )
self._keys_to_active_pages = {}
self._keys_to_proto_pages = {}
@@ -1839,7 +1839,7 @@ class ListBook( wx.Panel ):
self._empty_panel = wx.Panel( self )
- self._empty_panel.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_BTNFACE ) )
+ self._empty_panel.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_FRAMEBK ) )
self._current_key = None
@@ -2514,7 +2514,7 @@ class ListBox( wx.ScrolledWindow ):
dc.DrawRectangle( 0, i * self._text_y, my_width, self._text_y )
- text_colour = wx.WHITE
+ text_colour = self._background_colour
dc.SetTextForeground( text_colour )
@@ -4779,7 +4779,7 @@ class PopupMessageManager( wx.Frame ):
wx.Frame.__init__( self, parent, style = wx.FRAME_TOOL_WINDOW | wx.FRAME_NO_TASKBAR | wx.FRAME_FLOAT_ON_PARENT | wx.BORDER_NONE )
- self.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_BTNFACE ) )
+ self.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_FRAMEBK ) )
self._max_messages_to_display = 10
@@ -6099,7 +6099,7 @@ class StaticBox( wx.Panel ):
wx.Panel.__init__( self, parent, style = wx.BORDER_DOUBLE )
- self.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_BTNFACE ) )
+ self.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_FRAMEBK ) )
self._sizer = wx.BoxSizer( wx.VERTICAL )
@@ -6503,7 +6503,7 @@ class WaitingPolitelyTrafficLight( BufferedWindow ):
def _Draw( self, dc ):
- dc.SetBackground( wx.Brush( wx.SystemSettings.GetColour( wx.SYS_COLOUR_BTNFACE ) ) )
+ dc.SetBackground( wx.Brush( wx.SystemSettings.GetColour( wx.SYS_COLOUR_FRAMEBK ) ) )
dc.Clear()
@@ -6516,7 +6516,7 @@ class WaitingPolitelyTrafficLight( BufferedWindow ):
dc.SetBrush( wx.Brush( wx.Colour( 77, 250, 144 ) ) )
- dc.SetPen( wx.BLACK_PEN )
+ dc.SetPen( wx.Pen( wx.SystemSettings.GetColour( wx.SYS_COLOUR_BTNSHADOW ) ) )
dc.DrawCircle( 9, 9, 7 )
diff --git a/include/ClientGUIDialogs.py b/include/ClientGUIDialogs.py
index ac820cde..8aaba1e8 100755
--- a/include/ClientGUIDialogs.py
+++ b/include/ClientGUIDialogs.py
@@ -285,9 +285,7 @@ class Dialog( wx.Dialog ):
self._new_options = HydrusGlobals.client_controller.GetNewOptions()
- #self.SetDoubleBuffered( True )
-
- self.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_BTNFACE ) )
+ self.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_FRAMEBK ) )
self.SetIcon( wx.Icon( os.path.join( HC.STATIC_DIR, 'hydrus.ico' ), wx.BITMAP_TYPE_ICO ) )
diff --git a/include/ClientGUIDialogsManage.py b/include/ClientGUIDialogsManage.py
index 77667f3b..c8dbd6c0 100644
--- a/include/ClientGUIDialogsManage.py
+++ b/include/ClientGUIDialogsManage.py
@@ -667,8 +667,6 @@ class DialogManageBoorus( ClientGUIDialogs.Dialog ):
#
- self.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_BTNFACE ) )
-
gridbox = wx.FlexGridSizer( 0, 2 )
gridbox.AddGrowableCol( 1, 1 )
@@ -1278,8 +1276,6 @@ class DialogManageContacts( ClientGUIDialogs.Dialog ):
def ArrangeControls():
- self.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_BTNFACE ) )
-
gridbox = wx.FlexGridSizer( 0, 2 )
gridbox.AddGrowableCol( 1, 1 )
@@ -2248,10 +2244,6 @@ class DialogManageImageboards( ClientGUIDialogs.Dialog ):
def ArrangeControls():
- self.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_BTNFACE ) )
-
- #
-
gridbox = wx.FlexGridSizer( 0, 2 )
gridbox.AddGrowableCol( 1, 1 )
@@ -3372,8 +3364,6 @@ class DialogManageRatings( ClientGUIDialogs.Dialog ):
wx.Panel.__init__( self, parent )
- self.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_BTNFACE ) )
-
self._services = services
self._media = media
@@ -3441,8 +3431,6 @@ class DialogManageRatings( ClientGUIDialogs.Dialog ):
wx.Panel.__init__( self, parent )
- self.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_BTNFACE ) )
-
self._services = services
self._media = media
@@ -3895,8 +3883,6 @@ class DialogManageServer( ClientGUIDialogs.Dialog ):
#
- self.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_BTNFACE ) )
-
vbox = wx.BoxSizer( wx.VERTICAL )
gridbox = wx.FlexGridSizer( 0, 2 )
@@ -4603,8 +4589,6 @@ class DialogManageServices( ClientGUIDialogs.Dialog ):
#
- self.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_BTNFACE ) )
-
vbox = wx.BoxSizer( wx.VERTICAL )
if service_type not in HC.NONEDITABLE_SERVICES:
@@ -5382,10 +5366,6 @@ class DialogManageSubscriptions( ClientGUIDialogs.Dialog ):
#
- self.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_BTNFACE ) )
-
- #
-
hbox = wx.BoxSizer( wx.HORIZONTAL )
hbox.AddF( wx.StaticText( self._query_panel, label = 'Check subscription every ' ), CC.FLAGS_MIXED )
diff --git a/include/ClientGUIHoverFrames.py b/include/ClientGUIHoverFrames.py
index c94daac5..a0e13efc 100644
--- a/include/ClientGUIHoverFrames.py
+++ b/include/ClientGUIHoverFrames.py
@@ -28,7 +28,7 @@ class FullscreenHoverFrame( wx.Frame ):
self._last_ideal_position = None
- self.SetBackgroundColour( wx.WHITE )
+ self.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_FRAMEBK ) )
self.SetCursor( wx.StockCursor( wx.CURSOR_ARROW ) )
self._timer_check_show = wx.Timer( self, id = ClientGUICanvas.ID_TIMER_HOVER_SHOW )
@@ -474,8 +474,6 @@ class FullscreenHoverFrameRatings( FullscreenHoverFrame ):
self._icon_panel = wx.Panel( self )
- self._icon_panel.SetBackgroundColour( wx.WHITE )
-
self._trash_icon = ClientGUICommon.BufferedWindowIcon( self._icon_panel, CC.GlobalBMPs.trash )
self._inbox_icon = ClientGUICommon.BufferedWindowIcon( self._icon_panel, CC.GlobalBMPs.inbox )
diff --git a/include/ClientGUIManagement.py b/include/ClientGUIManagement.py
index 731725ec..f2c52ca0 100755
--- a/include/ClientGUIManagement.py
+++ b/include/ClientGUIManagement.py
@@ -246,8 +246,6 @@ def GenerateDumpMultipartFormDataCTAndBody( fields ):
if self._captcha_challenge is None:
- dc.SetBackground( wx.Brush( wx.WHITE ) )
-
dc.Clear()
self._refresh_button.SetLabelText( '' )
@@ -257,8 +255,6 @@ def GenerateDumpMultipartFormDataCTAndBody( fields ):
elif self._captcha_challenge == '':
- dc.SetBackground( wx.Brush( wx.WHITE ) )
-
dc.Clear()
event = wx.NotifyEvent( CAPTCHA_FETCH_EVENT_TYPE )
@@ -627,7 +623,7 @@ class ManagementPanel( wx.lib.scrolledpanel.ScrolledPanel ):
self.SetupScrolling()
- self.SetBackgroundColour( wx.WHITE )
+ self.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_FRAMEBK ) )
self._controller = controller
self._management_controller = management_controller
diff --git a/include/ClientGUIMedia.py b/include/ClientGUIMedia.py
index ffeb2926..f6cb370b 100755
--- a/include/ClientGUIMedia.py
+++ b/include/ClientGUIMedia.py
@@ -74,7 +74,7 @@ class MediaPanel( ClientMedia.ListeningMediaList, wx.ScrolledWindow ):
self.SetDoubleBuffered( True ) # This seems to stop some bad scroll draw logic, where top/bottom row is auto-drawn undrawn and then paint event called
- self.SetBackgroundColour( wx.WHITE )
+ self.SetBackgroundColour( wx.Colour( *HC.options[ 'gui_colours' ][ 'thumbgrid_background' ] ) )
self.SetScrollRate( 0, 50 )
@@ -392,7 +392,9 @@ class MediaPanel( ClientMedia.ListeningMediaList, wx.ScrolledWindow ):
self._SetFocussedMedia( None )
- HydrusGlobals.client_controller.Write( 'content_updates', { file_service_key : [ HydrusData.ContentUpdate( HC.CONTENT_TYPE_FILES, HC.CONTENT_UPDATE_DELETE, hashes ) ] } )
+ # we want currently animating files (i.e. currently open files) to be unloaded before the delete call goes through
+
+ wx.CallAfter( HydrusGlobals.client_controller.Write, 'content_updates', { file_service_key : [ HydrusData.ContentUpdate( HC.CONTENT_TYPE_FILES, HC.CONTENT_UPDATE_DELETE, hashes ) ] } )
else:
diff --git a/include/ClientGUIMessages.py b/include/ClientGUIMessages.py
index 74634765..94377f19 100755
--- a/include/ClientGUIMessages.py
+++ b/include/ClientGUIMessages.py
@@ -306,8 +306,6 @@ class ConversationPanel( wx.Panel ):
wx.Panel.__init__( self, parent, style = wx.SIMPLE_BORDER )
- self.SetBackgroundColour( wx.WHITE )
-
self._identity = identity
self._page_key = page_key
self._conversation = conversation
@@ -568,8 +566,6 @@ class DestinationPanel( wx.Panel ):
status_text = wx.StaticText( self, label = self._status )
- status_text.SetForegroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_HIGHLIGHT ) )
-
status_text.SetCursor( wx.StockCursor( wx.CURSOR_HAND ) )
status_text.Bind( wx.EVT_LEFT_DOWN, self.EventReadMenu )
@@ -578,8 +574,6 @@ class DestinationPanel( wx.Panel ):
status_text = wx.StaticText( self, label = self._status )
- status_text.SetForegroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_HIGHLIGHT ) )
-
status_text.SetCursor( wx.StockCursor( wx.CURSOR_HAND ) )
status_text.Bind( wx.EVT_LEFT_DOWN, self.EventUnreadMenu )
@@ -588,8 +582,6 @@ class DestinationPanel( wx.Panel ):
status_text = wx.StaticText( self, label = self._status )
- status_text.SetForegroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_HIGHLIGHT ) )
-
return status_text
@@ -968,7 +960,6 @@ class DraftBodyPanel( wx.Panel ):
else: selection_range = wx.richtext.RichTextRange( ip, ip )
text_attribute.SetFlags( wx.TEXT_ATTR_TEXT_COLOUR )
- text_attribute.SetTextColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_HIGHLIGHT ) )
text_attribute.SetFontUnderlined( True )
@@ -986,7 +977,6 @@ class DraftBodyPanel( wx.Panel ):
text_attribute = wx.richtext.TextAttrEx()
text_attribute.SetFlags( wx.TEXT_ATTR_TEXT_COLOUR )
- text_attribute.SetTextColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_WINDOWTEXT ) )
text_attribute.SetFontUnderlined( False )
diff --git a/include/ClientGUIPanels.py b/include/ClientGUIPanels.py
index 7baed7c5..ecd40763 100644
--- a/include/ClientGUIPanels.py
+++ b/include/ClientGUIPanels.py
@@ -231,8 +231,6 @@ class ManageOptionsPanel( ManagePanel ):
wx.Panel.__init__( self, parent )
- self.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_BTNFACE ) )
-
self._client_files = ClientGUICommon.SaneListCtrl( self, 200, [ ( 'path', -1 ), ( 'weight', 80 ) ] )
self._add = wx.Button( self, label = 'add' )
@@ -246,11 +244,13 @@ class ManageOptionsPanel( ManagePanel ):
self._resized_thumbnails_override = wx.DirPickerCtrl( self, style = wx.DIRP_USE_TEXTCTRL )
+ self._full_size_thumbnails_override = wx.DirPickerCtrl( self, style = wx.DIRP_USE_TEXTCTRL )
+
#
self._new_options = HydrusGlobals.client_controller.GetNewOptions()
- ( locations_to_ideal_weights, resized_thumbnail_override ) = self._new_options.GetClientFilesLocationsToIdealWeights()
+ ( locations_to_ideal_weights, resized_thumbnail_override, full_size_thumbnail_override ) = self._new_options.GetClientFilesLocationsToIdealWeights()
for ( location, weight ) in locations_to_ideal_weights.items():
@@ -262,6 +262,11 @@ class ManageOptionsPanel( ManagePanel ):
self._resized_thumbnails_override.SetPath( resized_thumbnail_override )
+ if full_size_thumbnail_override is not None:
+
+ self._full_size_thumbnails_override.SetPath( full_size_thumbnail_override )
+
+
#
vbox = wx.BoxSizer( wx.VERTICAL )
@@ -286,9 +291,11 @@ class ManageOptionsPanel( ManagePanel ):
vbox.AddF( hbox, CC.FLAGS_BUTTON_SIZER )
- text = 'If you like, you can force all your resized thumbnails to be stored in a single location, for instance on a low-latency SSD.'
+ text = 'If you like, you can force your thumbnails to be stored elsewhere, for instance on a low-latency SSD.'
text += os.linesep * 2
- text += 'Leave it blank to store resized thumbnails with everything else.'
+ text += 'Normally, your full size thumbnails are rarely accessed--only to initially generate resized thumbnails--so you can store them somewhere slow, but if you set the thumbnail size to be the maximum of 200x200, these originals will be used instead of resized thumbs and are good in a fast location.'
+ text += os.linesep * 2
+ text += 'Leave either of these blank to store the thumbnails alongside the original files.'
st = wx.StaticText( self, label = text )
@@ -298,6 +305,13 @@ class ManageOptionsPanel( ManagePanel ):
hbox = wx.BoxSizer( wx.HORIZONTAL )
+ hbox.AddF( wx.StaticText( self, label = 'full size thumbnail override location: ' ), CC.FLAGS_MIXED )
+ hbox.AddF( self._full_size_thumbnails_override, CC.FLAGS_EXPAND_BOTH_WAYS )
+
+ vbox.AddF( hbox, CC.FLAGS_EXPAND_PERPENDICULAR )
+
+ hbox = wx.BoxSizer( wx.HORIZONTAL )
+
hbox.AddF( wx.StaticText( self, label = 'resized thumbnail override location: ' ), CC.FLAGS_MIXED )
hbox.AddF( self._resized_thumbnails_override, CC.FLAGS_EXPAND_BOTH_WAYS )
@@ -383,7 +397,14 @@ class ManageOptionsPanel( ManagePanel ):
resized_thumbnails_override = None
- self._new_options.SetClientFilesLocationsToIdealWeights( locations_to_weights, resized_thumbnails_override )
+ full_size_thumbnails_override = self._full_size_thumbnails_override.GetPath()
+
+ if full_size_thumbnails_override == '':
+
+ full_size_thumbnails_override = None
+
+
+ self._new_options.SetClientFilesLocationsToIdealWeights( locations_to_weights, resized_thumbnails_override, full_size_thumbnails_override )
@@ -393,8 +414,6 @@ class ManageOptionsPanel( ManagePanel ):
wx.Panel.__init__( self, parent )
- self.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_BTNFACE ) )
-
self._gui_colours = {}
for ( name, rgb ) in HC.options[ 'gui_colours' ].items():
@@ -531,8 +550,6 @@ class ManageOptionsPanel( ManagePanel ):
wx.Panel.__init__( self, parent )
- self.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_BTNFACE ) )
-
self._external_host = wx.TextCtrl( self )
self._external_host.SetToolTipString( 'If you have trouble parsing your external ip using UPnP, you can force it to be this.' )
@@ -667,8 +684,6 @@ class ManageOptionsPanel( ManagePanel ):
self._new_options = new_options
- self.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_BTNFACE ) )
-
general = ClientGUICommon.StaticBox( self, 'general' )
self._website_download_polite_wait = wx.SpinCtrl( general, min = 1, max = 30 )
@@ -761,8 +776,6 @@ class ManageOptionsPanel( ManagePanel ):
wx.Panel.__init__( self, parent )
- self.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_BTNFACE ) )
-
self._jobs_panel = ClientGUICommon.StaticBox( self, 'when to run high cpu jobs' )
self._maintenance_panel = ClientGUICommon.StaticBox( self, 'maintenance period' )
self._processing_panel = ClientGUICommon.StaticBox( self, 'processing' )
@@ -964,8 +977,6 @@ class ManageOptionsPanel( ManagePanel ):
wx.Panel.__init__( self, parent )
- self.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_BTNFACE ) )
-
self._new_options = new_options
self._filter_inbox_and_archive_predicates = wx.CheckBox( self, label = 'hide inbox and archive predicates if either has no files' )
@@ -1038,8 +1049,6 @@ class ManageOptionsPanel( ManagePanel ):
self._new_options = new_options
- self.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_BTNFACE ) )
-
self._import_tag_options = wx.ListBox( self )
self._import_tag_options.Bind( wx.EVT_LEFT_DCLICK, self.EventDelete )
@@ -1177,8 +1186,6 @@ class ManageOptionsPanel( ManagePanel ):
wx.Panel.__init__( self, parent )
- self.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_BTNFACE ) )
-
self._export_location = wx.DirPickerCtrl( self, style = wx.DIRP_USE_TEXTCTRL )
self._delete_to_recycle_bin = wx.CheckBox( self, label = '' )
@@ -1265,8 +1272,6 @@ class ManageOptionsPanel( ManagePanel ):
wx.Panel.__init__( self, parent )
- self.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_BTNFACE ) )
-
self._default_gui_session = wx.Choice( self )
self._confirm_client_exit = wx.CheckBox( self )
@@ -1446,8 +1451,6 @@ class ManageOptionsPanel( ManagePanel ):
wx.Panel.__init__( self, parent )
- self.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_BTNFACE ) )
-
self._new_options = HydrusGlobals.client_controller.GetNewOptions()
self._fit_to_canvas = wx.CheckBox( self, label = '' )
@@ -1542,8 +1545,6 @@ class ManageOptionsPanel( ManagePanel ):
wx.Panel.__init__( self, parent )
- self.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_BTNFACE ) )
-
self._local_port = ClientGUICommon.NoneableSpinCtrl( self, 'local server port', none_phrase = 'do not run local server', min = 1, max = 65535 )
#
@@ -1575,8 +1576,6 @@ class ManageOptionsPanel( ManagePanel ):
wx.Panel.__init__( self, parent )
- self.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_BTNFACE ) )
-
self._shortcuts = ClientGUICommon.SaneListCtrl( self, 480, [ ( 'modifier', 120 ), ( 'key', 120 ), ( 'action', -1 ) ], delete_key_callback = self.DeleteShortcuts )
self._shortcuts_add = wx.Button( self, label = 'add' )
@@ -1700,8 +1699,6 @@ class ManageOptionsPanel( ManagePanel ):
wx.Panel.__init__( self, parent )
- self.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_BTNFACE ) )
-
self._default_sort = ClientGUICommon.ChoiceSort( self )
self._sort_fallback = ClientGUICommon.ChoiceSort( self )
@@ -1819,8 +1816,6 @@ class ManageOptionsPanel( ManagePanel ):
wx.Panel.__init__( self, parent )
- self.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_BTNFACE ) )
-
self._play_dumper_noises = wx.CheckBox( self, label = 'play success/fail noises when dumping' )
#
@@ -1850,8 +1845,6 @@ class ManageOptionsPanel( ManagePanel ):
self._new_options = new_options
- self.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_BTNFACE ) )
-
self._disk_cache_init_period = ClientGUICommon.NoneableSpinCtrl( self, 'max disk cache init period', none_phrase = 'do not run', min = 1, max = 120 )
self._disk_cache_init_period.SetToolTipString( 'When the client boots, it can speed up operation by reading the front of the database into memory. This sets the max number of seconds it can spend doing that.' )
@@ -2137,8 +2130,6 @@ class ManageOptionsPanel( ManagePanel ):
self._new_options = new_options
- self.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_BTNFACE ) )
-
self._default_tag_sort = wx.Choice( self )
self._default_tag_sort.Append( 'lexicographic (a-z)', CC.SORT_BY_LEXICOGRAPHIC_ASC )
@@ -2258,13 +2249,13 @@ class ManageOptionsPanel( ManagePanel ):
related_gridbox.AddF( wx.StaticText( suggested_tags_related_panel, label = 'width of related tags list' ), CC.FLAGS_MIXED )
related_gridbox.AddF( self._related_tags_width, CC.FLAGS_MIXED )
- related_gridbox.AddF( wx.StaticText( suggested_tags_related_panel, label = 'search 1 duration (ms)' ), CC.FLAGS_MIXED )
+ related_gridbox.AddF( wx.StaticText( suggested_tags_related_panel, label = 'initial search duration (ms)' ), CC.FLAGS_MIXED )
related_gridbox.AddF( self._related_tags_search_1_duration_ms, CC.FLAGS_MIXED )
- related_gridbox.AddF( wx.StaticText( suggested_tags_related_panel, label = 'search 2 duration (ms)' ), CC.FLAGS_MIXED )
+ related_gridbox.AddF( wx.StaticText( suggested_tags_related_panel, label = 'medium search duration (ms)' ), CC.FLAGS_MIXED )
related_gridbox.AddF( self._related_tags_search_2_duration_ms, CC.FLAGS_MIXED )
- related_gridbox.AddF( wx.StaticText( suggested_tags_related_panel, label = 'search 3 duration (ms)' ), CC.FLAGS_MIXED )
+ related_gridbox.AddF( wx.StaticText( suggested_tags_related_panel, label = 'thorough search duration (ms)' ), CC.FLAGS_MIXED )
related_gridbox.AddF( self._related_tags_search_3_duration_ms, CC.FLAGS_MIXED )
suggested_tags_related_panel.AddF( related_gridbox, CC.FLAGS_EXPAND_PERPENDICULAR )
@@ -2396,7 +2387,7 @@ class ManageTagsPanel( ManagePanel ):
service_key = service.GetServiceKey()
name = service.GetName()
- page = self._Panel( self._tag_repositories, self._file_service_key, service.GetServiceKey(), self._current_media, self._immediate_commit )
+ page = self._Panel( self._tag_repositories, self._file_service_key, service.GetServiceKey(), self._current_media, self._immediate_commit, canvas_key = self._canvas_key )
self._tag_repositories.AddPage( name, service_key, page )
@@ -2543,13 +2534,14 @@ class ManageTagsPanel( ManagePanel ):
class _Panel( wx.Panel ):
- def __init__( self, parent, file_service_key, tag_service_key, media, immediate_commit ):
+ def __init__( self, parent, file_service_key, tag_service_key, media, immediate_commit, canvas_key = None ):
wx.Panel.__init__( self, parent )
self._file_service_key = file_service_key
self._tag_service_key = tag_service_key
self._immediate_commit = immediate_commit
+ self._canvas_key = canvas_key
self._content_updates = []
@@ -2613,9 +2605,7 @@ class ManageTagsPanel( ManagePanel ):
self.SetMedia( media )
- self._suggested_tags = ClientGUITagSuggestions.SuggestedTagsPanel( self, self._tag_service_key, self._media, self.AddTags )
-
- self.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_BTNFACE ) )
+ self._suggested_tags = ClientGUITagSuggestions.SuggestedTagsPanel( self, self._tag_service_key, self._media, self.AddTags, canvas_key = self._canvas_key )
if self._i_am_local_tag_service:
@@ -2775,6 +2765,8 @@ class ManageTagsPanel( ManagePanel ):
forced_choice_actions = []
+ immediate_content_updates = []
+
for choices in sets_of_choices:
always_do = False
@@ -2902,12 +2894,7 @@ class ManageTagsPanel( ManagePanel ):
if self._immediate_commit:
- if len( content_updates ) > 0:
-
- service_keys_to_content_updates = { self._tag_service_key : content_updates }
-
- HydrusGlobals.client_controller.WriteSynchronous( 'content_updates', service_keys_to_content_updates )
-
+ immediate_content_updates.extend( content_updates )
else:
@@ -2915,6 +2902,13 @@ class ManageTagsPanel( ManagePanel ):
+ if len( immediate_content_updates ) > 0:
+
+ service_keys_to_content_updates = { self._tag_service_key : immediate_content_updates }
+
+ HydrusGlobals.client_controller.WriteSynchronous( 'content_updates', service_keys_to_content_updates )
+
+
self._tags_box.SetTagsByMedia( self._media, force_reload = True )
@@ -3099,8 +3093,6 @@ class ReviewServices( ReviewPanel ):
self._InitialiseServices()
- self.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_BTNFACE ) )
-
self._notebook.AddPage( self._local_listbook, 'local' )
self._notebook.AddPage( self._remote_listbook, 'remote' )
@@ -3382,8 +3374,6 @@ class ReviewServices( ReviewPanel ):
#
- self.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_BTNFACE ) )
-
vbox = wx.BoxSizer( wx.VERTICAL )
if service_type in HC.REPOSITORIES + HC.LOCAL_SERVICES + [ HC.IPFS ]:
@@ -3692,7 +3682,7 @@ class ReviewServices( ReviewPanel ):
num_ratings = service_info[ HC.SERVICE_INFO_NUM_FILES ]
- self._ratings_text.SetLabelText( str( num_ratings ) + ' files rated' )
+ self._ratings_text.SetLabelText( HydrusData.ConvertIntToPrettyString( num_ratings ) + ' files rated' )
elif service_type == HC.LOCAL_BOORU:
diff --git a/include/ClientGUITagSuggestions.py b/include/ClientGUITagSuggestions.py
index 2787f7d4..9b57e670 100644
--- a/include/ClientGUITagSuggestions.py
+++ b/include/ClientGUITagSuggestions.py
@@ -94,26 +94,23 @@ class ListBoxTagsSuggestionsRelated( ClientGUICommon.ListBoxTags ):
class RelatedTagsPanel( wx.Panel ):
- def __init__( self, parent, service_key, media, activate_callable ):
+ def __init__( self, parent, service_key, media, activate_callable, canvas_key = None ):
wx.Panel.__init__( self, parent )
self._service_key = service_key
self._media = media
+ self._canvas_key = canvas_key
self._new_options = HydrusGlobals.client_controller.GetNewOptions()
vbox = wx.BoxSizer( wx.VERTICAL )
- button_1 = wx.Button( self, label = '1' )
- button_1.Bind( wx.EVT_BUTTON, self.EventSuggestedRelatedTags1 )
- button_1.SetMinSize( ( 30, -1 ) )
-
- button_2 = wx.Button( self, label = '2' )
+ button_2 = wx.Button( self, label = 'medium' )
button_2.Bind( wx.EVT_BUTTON, self.EventSuggestedRelatedTags2 )
button_2.SetMinSize( ( 30, -1 ) )
- button_3 = wx.Button( self, label = '3' )
+ button_3 = wx.Button( self, label = 'thorough' )
button_3.Bind( wx.EVT_BUTTON, self.EventSuggestedRelatedTags3 )
button_3.SetMinSize( ( 30, -1 ) )
@@ -121,7 +118,6 @@ class RelatedTagsPanel( wx.Panel ):
button_hbox = wx.BoxSizer( wx.HORIZONTAL )
- button_hbox.AddF( button_1, CC.FLAGS_EXPAND_SIZER_BOTH_WAYS )
button_hbox.AddF( button_2, CC.FLAGS_EXPAND_SIZER_BOTH_WAYS )
button_hbox.AddF( button_3, CC.FLAGS_EXPAND_SIZER_BOTH_WAYS )
@@ -130,6 +126,13 @@ class RelatedTagsPanel( wx.Panel ):
self.SetSizer( vbox )
+ if self._canvas_key is not None:
+
+ HydrusGlobals.client_controller.sub( self, 'CanvasHasNewMedia', 'canvas_new_display_media' )
+
+
+ self._QuickSuggestedRelatedTags()
+
def _FetchRelatedTags( self, max_time_to_take ):
@@ -150,22 +153,28 @@ class RelatedTagsPanel( wx.Panel ):
predicates = HydrusGlobals.client_controller.Read( 'related_tags', self._service_key, hash, search_tags, max_results, max_time_to_take )
- siblings_manager = HydrusGlobals.client_controller.GetManager( 'tag_siblings' )
-
- predicates = siblings_manager.CollapsePredicates( predicates )
-
predicates = ClientSearch.SortPredicates( predicates )
self._related_tags.SetPredicates( predicates )
- def EventSuggestedRelatedTags1( self, event ):
+ def _QuickSuggestedRelatedTags( self ):
max_time_to_take = self._new_options.GetInteger( 'related_tags_search_1_duration_ms' ) / 1000.0
self._FetchRelatedTags( max_time_to_take )
+ def CanvasHasNewMedia( self, canvas_key, new_media_singleton ):
+
+ if canvas_key == self._canvas_key:
+
+ self._media = ( new_media_singleton.Duplicate(), )
+
+ self._QuickSuggestedRelatedTags()
+
+
+
def EventSuggestedRelatedTags2( self, event ):
max_time_to_take = self._new_options.GetInteger( 'related_tags_search_2_duration_ms' ) / 1000.0
@@ -182,12 +191,13 @@ class RelatedTagsPanel( wx.Panel ):
class SuggestedTagsPanel( wx.Panel ):
- def __init__( self, parent, service_key, media, activate_callable ):
+ def __init__( self, parent, service_key, media, activate_callable, canvas_key = None ):
wx.Panel.__init__( self, parent )
self._service_key = service_key
self._media = media
+ self._canvas_key = canvas_key
self._new_options = HydrusGlobals.client_controller.GetNewOptions()
@@ -210,7 +220,7 @@ class SuggestedTagsPanel( wx.Panel ):
if self._new_options.GetBoolean( 'show_related_tags' ) and len( media ) == 1:
- related_tags = RelatedTagsPanel( self, service_key, media, activate_callable )
+ related_tags = RelatedTagsPanel( self, service_key, media, activate_callable, canvas_key = self._canvas_key )
hbox.AddF( related_tags, CC.FLAGS_EXPAND_BOTH_WAYS )
diff --git a/include/ClientGUITopLevelWindows.py b/include/ClientGUITopLevelWindows.py
index 62274e3b..eb41d00e 100644
--- a/include/ClientGUITopLevelWindows.py
+++ b/include/ClientGUITopLevelWindows.py
@@ -213,7 +213,7 @@ class NewDialog( wx.Dialog ):
self._new_options = HydrusGlobals.client_controller.GetNewOptions()
- self.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_BTNFACE ) )
+ self.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_FRAMEBK ) )
self.SetIcon( wx.Icon( os.path.join( HC.STATIC_DIR, 'hydrus.ico' ), wx.BITMAP_TYPE_ICO ) )
@@ -357,7 +357,7 @@ class Frame( wx.Frame ):
self._new_options = HydrusGlobals.client_controller.GetNewOptions()
- self.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_BTNFACE ) )
+ self.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_FRAMEBK ) )
self.SetIcon( wx.Icon( os.path.join( HC.STATIC_DIR, 'hydrus.ico' ), wx.BITMAP_TYPE_ICO ) )
diff --git a/include/HydrusConstants.py b/include/HydrusConstants.py
index 30b79df3..80fa8530 100755
--- a/include/HydrusConstants.py
+++ b/include/HydrusConstants.py
@@ -48,7 +48,7 @@ options = {}
# Misc
NETWORK_VERSION = 17
-SOFTWARE_VERSION = 217
+SOFTWARE_VERSION = 218
UNSCALED_THUMBNAIL_DIMENSIONS = ( 200, 200 )
diff --git a/server.py b/server.py
index 00a50323..ea46c75d 100644
--- a/server.py
+++ b/server.py
@@ -99,6 +99,7 @@ except HydrusExceptions.PermissionException as e:
except:
import traceback
+ import os
try: