Version 218

This commit is contained in:
Hydrus Network Developer 2016-08-10 14:04:08 -05:00
parent 2aec39b034
commit 935f03e494
20 changed files with 211 additions and 181 deletions

View File

@ -77,6 +77,7 @@ try:
except:
import traceback
import os
try:

View File

@ -8,6 +8,22 @@
<div class="content">
<h3>changelog</h3>
<ul>
<li><h3>version 218</h3></li>
<ul>
<li>related tags control now updates on new media events (i.e. if the parent media viewer scrolls to different media)</li>
<li>related tags also initialises with suggestions and refreshes the list on media change</li>
<li>related tags now properly filter out dupe suggestions caused by siblings</li>
<li>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</li>
<li>full size thumbnails can now also be stored in a different location, like resized thumbs, under options->file storage locations</li>
<li>fixed false postiive shutdown maintenance checking due to vacuums projected to take longer than the given maintenance time</li>
<li>fixed false postiive shutdown maintenance checking due to sqlite_stat1 creeping in</li>
<li>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</li>
<li>removed 'import tags' from file menu--this advanced stuff is now done in and better left to the advanced content update dialog</li>
<li>restoring from an old db backup with a simpler db structure will no longer create conflicts</li>
<li>deleting currently rendering files from the trash should be slightly more reliable</li>
<li>fixed some crash error reporting</li>
<li>misc cleanup</li>
</ul>
<li><h3>version 217</h3></li>
<ul>
<li>fixed some high-res video streaming thread scheduling problems with the new video renderer</li>

View File

@ -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 )

View File

@ -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:

View File

@ -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' )

View File

@ -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

View File

@ -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()

View File

@ -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 )

View File

@ -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 )

View File

@ -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 ) )

View File

@ -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 )

View File

@ -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 )

View File

@ -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

View File

@ -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:

View File

@ -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 )

View File

@ -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:

View File

@ -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 )

View File

@ -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 ) )

View File

@ -48,7 +48,7 @@ options = {}
# Misc
NETWORK_VERSION = 17
SOFTWARE_VERSION = 217
SOFTWARE_VERSION = 218
UNSCALED_THUMBNAIL_DIMENSIONS = ( 200, 200 )

View File

@ -99,6 +99,7 @@ except HydrusExceptions.PermissionException as e:
except:
import traceback
import os
try: