Version 75
This commit is contained in:
parent
9934544006
commit
62528976e3
|
@ -8,6 +8,27 @@
|
|||
<div class="content">
|
||||
<h3>changelog</h3>
|
||||
<ul>
|
||||
<li><h3>version 75</h3></li>
|
||||
<ul>
|
||||
<li>fullscreenpopup window added</li>
|
||||
<li>fullscreenpopup window can be dragged about</li>
|
||||
<li>fullscreenpopupfilterinbox</li>
|
||||
<li>fullscreenpopupfilterlike</li>
|
||||
<li>fullscreenpopupfilternumerical</li>
|
||||
<li>accuracy slider moved to popup</li>
|
||||
<li>compare same image until done added to popup</li>
|
||||
<li>keep on left/random/right added to popup</li>
|
||||
<li>'don't ratings filter this' added to popup</li>
|
||||
<li>that annoying as hell thumbnail selection drawing state bug is fixed</li>
|
||||
<li>display of flash with only one frame fixed</li>
|
||||
<li>downloaded tags now work again, sorry for the disruption!</li>
|
||||
<li>deleted tags will now always show in manage tags dialog</li>
|
||||
<li>fixed the various problems that were stopping DELETED->PENDING->CURRENT working for tags</li>
|
||||
<li>fixed the children can only have one parent bug</li>
|
||||
<li>a little counting logic improved in the special deleted_pending case</li>
|
||||
<li>fixed a typo re uploading file to a repo</li>
|
||||
<li>main guis statusbar now has a little 'db locked' indicator</li>
|
||||
</ul>
|
||||
<li><h3>version 74</h3></li>
|
||||
<ul>
|
||||
<li>flash scanbar added</li>
|
||||
|
|
|
@ -2192,40 +2192,6 @@ class ServiceLocalRatingNumerical( Service ):
|
|||
|
||||
def GetExtraInfo( self ): return ( self._lower, self._upper )
|
||||
|
||||
class ServiceManager():
|
||||
|
||||
def __init__( self ):
|
||||
|
||||
self._lock = threading.Lock()
|
||||
|
||||
services = wx.GetApp().Read( 'services' )
|
||||
|
||||
self._service_identifiers_to_services = { service.GetServiceIdentifier() : service for service in services }
|
||||
|
||||
# pubsub for services changing
|
||||
# maybe a variable that says services are not ready, so wait a second (for refresh)
|
||||
# maybe refresh should be synchro with db? nah, that makes locking issues
|
||||
|
||||
# need to protect the actual service objects with a lock too, although the subobjects make this delicate
|
||||
|
||||
|
||||
def GetService( self, service_identifier ):
|
||||
|
||||
with self._lock:
|
||||
|
||||
if service_identifier in self._service_identifiers_to_services: return self._service_identifiers_to_services[ service_identifier ]
|
||||
else: raise Exception( 'Could not find that service!' )
|
||||
|
||||
|
||||
|
||||
def GetServices( self, service_types ):
|
||||
|
||||
with self._lock:
|
||||
|
||||
return { service for ( service_identifier, service ) in self._service_identifiers_to_services.items() if service_idenifier.GetType() in service_types }
|
||||
|
||||
|
||||
|
||||
class ServiceRemote( Service ):
|
||||
|
||||
yaml_tag = u'!ServiceRemote'
|
||||
|
|
|
@ -22,7 +22,6 @@ class Controller( wx.App ):
|
|||
def _Read( self, action, *args, **kwargs ):
|
||||
|
||||
if action == 'options': return self._options
|
||||
elif action == 'tag_service_precedence': return self._tag_service_precedence
|
||||
elif action == 'file': return self._db.ReadFile( *args, **kwargs )
|
||||
elif action == 'thumbnail': return self._db.ReadThumbnail( *args, **kwargs )
|
||||
else: return self._db.Read( action, HC.HIGH_PRIORITY, *args, **kwargs )
|
||||
|
@ -196,8 +195,6 @@ class Controller( wx.App ):
|
|||
|
||||
self._options = self._db.Read( 'options', HC.HIGH_PRIORITY )
|
||||
|
||||
self._tag_service_precedence = self._db.Read( 'tag_service_precedence', HC.HIGH_PRIORITY )
|
||||
|
||||
self._session_manager = HydrusSessions.HydrusSessionManagerClient()
|
||||
self._web_session_manager = CC.WebSessionManagerClient()
|
||||
self._tag_parents_manager = CC.TagParentsManager()
|
||||
|
|
|
@ -575,8 +575,8 @@ class MessageDB():
|
|||
|
||||
num_inbox = len( convo_ids )
|
||||
|
||||
if num_inbox == 0: inbox_string = 'inbox empty'
|
||||
else: inbox_string = str( num_inbox ) + ' in inbox'
|
||||
if num_inbox == 0: inbox_string = 'message inbox empty'
|
||||
else: inbox_string = str( num_inbox ) + ' in message inbox'
|
||||
|
||||
self.pub( 'inbox_status', inbox_string )
|
||||
|
||||
|
@ -1407,7 +1407,7 @@ class ServiceDB( FileDB, MessageDB, TagDB, RatingDB ):
|
|||
|
||||
c.execute( 'INSERT INTO tag_service_precedence ( service_id, precedence ) SELECT ?, CASE WHEN MAX( precedence ) NOT NULL THEN MAX( precedence ) + 1 ELSE 0 END FROM tag_service_precedence;', ( service_id, ) )
|
||||
|
||||
self._RebuildTagServicePrecedence( c )
|
||||
self._RebuildTagServicePrecedenceCache( c )
|
||||
|
||||
#
|
||||
|
||||
|
@ -2547,7 +2547,7 @@ class ServiceDB( FileDB, MessageDB, TagDB, RatingDB ):
|
|||
|
||||
all_hash_ids = { hash_id for hash_id in itertools.chain.from_iterable( ( hash_ids for ( hash_ids, reason ) in petitioned ) ) }
|
||||
|
||||
hash_ids_to_hashes = self._GetHashIdsToHashes( c, hash_ids )
|
||||
hash_ids_to_hashes = self._GetHashIdsToHashes( c, all_hash_ids )
|
||||
|
||||
content_data[ HC.CONTENT_DATA_TYPE_FILES ][ HC.CONTENT_UPDATE_PETITION ] = petitioned
|
||||
|
||||
|
@ -3263,8 +3263,6 @@ class ServiceDB( FileDB, MessageDB, TagDB, RatingDB ):
|
|||
|
||||
service_id = self._GetServiceId( c, service_identifier )
|
||||
|
||||
hash_ids = self._GetHashIds( c, hashes )
|
||||
|
||||
c.executemany( 'INSERT OR IGNORE INTO file_transfers ( service_id, hash_id ) VALUES ( ?, ? );', [ ( service_id, hash_id ) for hash_id in hash_ids ] )
|
||||
|
||||
if service_identifier == HC.LOCAL_FILE_SERVICE_IDENTIFIER: notify_new_downloads = True
|
||||
|
@ -3385,8 +3383,8 @@ class ServiceDB( FileDB, MessageDB, TagDB, RatingDB ):
|
|||
|
||||
( parent_namespace_id, parent_tag_id ) = self._GetNamespaceIdTagId( c, parent_tag )
|
||||
|
||||
c.execute( 'DELETE FROM tag_parents WHERE service_id = ? AND child_namespace_id = ? AND child_tag_id = ?;', ( service_id, child_namespace_id, child_tag_id ) )
|
||||
c.execute( 'DELETE FROM tag_parent_petitions WHERE service_id = ? AND child_namespace_id = ? AND child_tag_id = ? AND status = ?;', ( service_id, child_namespace_id, child_tag_id, deletee_status ) )
|
||||
c.execute( 'DELETE FROM tag_parents WHERE service_id = ? AND child_namespace_id = ? AND child_tag_id = ? AND parent_namespace_id = ? AND parent_tag_id = ?;', ( service_id, child_namespace_id, child_tag_id, parent_namespace_id, parent_tag_id ) )
|
||||
c.execute( 'DELETE FROM tag_parent_petitions WHERE service_id = ? AND child_namespace_id = ? AND child_tag_id = ? AND parent_namespace_id = ? AND parent_tag_id = ? AND status = ?;', ( service_id, child_namespace_id, child_tag_id, parent_namespace_id, parent_tag_id, deletee_status ) )
|
||||
|
||||
c.execute( 'INSERT OR IGNORE INTO tag_parents ( service_id, child_namespace_id, child_tag_id, parent_namespace_id, parent_tag_id, status ) VALUES ( ?, ?, ?, ?, ?, ? );', ( service_id, child_namespace_id, child_tag_id, parent_namespace_id, parent_tag_id, new_status ) )
|
||||
|
||||
|
@ -3596,7 +3594,7 @@ class ServiceDB( FileDB, MessageDB, TagDB, RatingDB ):
|
|||
if do_new_permissions: self.pub( 'notify_new_permissions' )
|
||||
|
||||
|
||||
def _RebuildTagServicePrecedence( self, c ):
|
||||
def _RebuildTagServicePrecedenceCache( self, c ):
|
||||
|
||||
del self._tag_service_precedence[:]
|
||||
|
||||
|
@ -3665,7 +3663,7 @@ class ServiceDB( FileDB, MessageDB, TagDB, RatingDB ):
|
|||
|
||||
if service_type == HC.TAG_REPOSITORY:
|
||||
|
||||
self._RebuildTagServicePrecedence( c )
|
||||
self._RebuildTagServicePrecedenceCache( c )
|
||||
|
||||
self._RecalcCombinedMappings( c )
|
||||
|
||||
|
@ -3731,7 +3729,7 @@ class ServiceDB( FileDB, MessageDB, TagDB, RatingDB ):
|
|||
|
||||
c.executemany( 'INSERT INTO tag_service_precedence ( service_id, precedence ) VALUES ( ?, ? );', [ ( service_id, precedence ) for ( precedence, service_id ) in enumerate( service_ids ) ] )
|
||||
|
||||
self._RebuildTagServicePrecedence( c )
|
||||
self._RebuildTagServicePrecedenceCache( c )
|
||||
|
||||
self._RecalcCombinedMappings( c )
|
||||
|
||||
|
@ -3769,11 +3767,22 @@ class ServiceDB( FileDB, MessageDB, TagDB, RatingDB ):
|
|||
|
||||
def ChangeMappingStatus( namespace_id, tag_id, hash_ids, old_status, new_status ):
|
||||
|
||||
# when we have a tag both deleted and pending made current, we merge two statuses into one!
|
||||
# in this case, we have to be careful about the counts (decrement twice, but only increment once), hence why this returns two numbers
|
||||
|
||||
appropriate_hash_ids = [ id for ( id, ) in c.execute( 'SELECT hash_id FROM mappings WHERE service_id = ? AND namespace_id = ? AND tag_id = ? AND hash_id IN ' + HC.SplayListForDB( hash_ids ) + ' AND status = ?;', ( service_id, namespace_id, tag_id, old_status ) ) ]
|
||||
|
||||
existing_hash_ids = { id for ( id, ) in c.execute( 'SELECT hash_id FROM mappings WHERE service_id = ? AND namespace_id = ? AND tag_id = ? AND hash_id IN ' + HC.SplayListForDB( hash_ids ) + ' AND status = ?;', ( service_id, namespace_id, tag_id, new_status ) ) }
|
||||
|
||||
deletable_hash_ids = existing_hash_ids.intersection( appropriate_hash_ids )
|
||||
|
||||
c.execute( 'DELETE FROM mappings WHERE service_id = ? AND namespace_id = ? AND tag_id = ? AND hash_id IN ' + HC.SplayListForDB( deletable_hash_ids ) + ' AND status = ?;', ( service_id, namespace_id, tag_id, old_status ) )
|
||||
|
||||
num_old_deleted = self._GetRowCount( c )
|
||||
|
||||
c.execute( 'UPDATE mappings SET status = ? WHERE service_id = ? AND namespace_id = ? AND tag_id = ? AND hash_id IN ' + HC.SplayListForDB( appropriate_hash_ids ) + ' AND status = ?;', ( new_status, service_id, namespace_id, tag_id, old_status ) )
|
||||
|
||||
num_rows_changed = self._GetRowCount( c )
|
||||
num_old_made_new = self._GetRowCount( c )
|
||||
|
||||
if old_status != HC.PENDING and new_status == HC.PENDING:
|
||||
|
||||
|
@ -3803,7 +3812,7 @@ class ServiceDB( FileDB, MessageDB, TagDB, RatingDB ):
|
|||
CheckIfCombinedMappingsNeedDeleting( namespace_id, tag_id, appropriate_hash_ids )
|
||||
|
||||
|
||||
return num_rows_changed
|
||||
return ( num_old_deleted + num_old_made_new, num_old_made_new )
|
||||
|
||||
|
||||
def CheckIfCombinedMappingsNeedDeleting( namespace_id, tag_id, hash_ids ):
|
||||
|
@ -3904,7 +3913,8 @@ class ServiceDB( FileDB, MessageDB, TagDB, RatingDB ):
|
|||
|
||||
def InsertMappings( namespace_id, tag_id, hash_ids, status ):
|
||||
|
||||
existing_hash_ids = [ id for ( id, ) in c.execute( 'SELECT hash_id FROM mappings WHERE service_id = ? AND namespace_id = ? AND tag_id = ? AND hash_id IN ' + HC.SplayListForDB( hash_ids ) + ';', ( service_id, namespace_id, tag_id ) ) ]
|
||||
if status == HC.PENDING: existing_hash_ids = [ id for ( id, ) in c.execute( 'SELECT hash_id FROM mappings WHERE service_id = ? AND namespace_id = ? AND tag_id = ? AND hash_id IN ' + HC.SplayListForDB( hash_ids ) + ' AND status != ?;', ( service_id, namespace_id, tag_id, HC.DELETED ) ) ]
|
||||
else: existing_hash_ids = [ id for ( id, ) in c.execute( 'SELECT hash_id FROM mappings WHERE service_id = ? AND namespace_id = ? AND tag_id = ? AND hash_id IN ' + HC.SplayListForDB( hash_ids ) + ';', ( service_id, namespace_id, tag_id ) ) ]
|
||||
|
||||
new_hash_ids = set( hash_ids ).difference( existing_hash_ids )
|
||||
|
||||
|
@ -4020,23 +4030,23 @@ class ServiceDB( FileDB, MessageDB, TagDB, RatingDB ):
|
|||
|
||||
for ( namespace_id, tag_id, hash_ids ) in mappings_ids:
|
||||
|
||||
num_deleted_rescinded = ChangeMappingStatus( namespace_id, tag_id, hash_ids, HC.DELETED, HC.CURRENT )
|
||||
num_pending_committed = ChangeMappingStatus( namespace_id, tag_id, hash_ids, HC.PENDING, HC.CURRENT )
|
||||
( num_deleted_deleted, num_deleted_made_current ) = ChangeMappingStatus( namespace_id, tag_id, hash_ids, HC.DELETED, HC.CURRENT )
|
||||
( num_pending_deleted, num_pending_made_current ) = ChangeMappingStatus( namespace_id, tag_id, hash_ids, HC.PENDING, HC.CURRENT )
|
||||
num_raw_adds = InsertMappings( namespace_id, tag_id, hash_ids, HC.CURRENT )
|
||||
|
||||
change_in_num_mappings += num_deleted_rescinded + num_pending_committed + num_raw_adds
|
||||
change_in_num_deleted_mappings -= num_deleted_rescinded
|
||||
change_in_num_pending_mappings -= num_pending_committed
|
||||
change_in_num_mappings += num_deleted_made_current + num_pending_made_current + num_raw_adds
|
||||
change_in_num_deleted_mappings -= num_deleted_deleted
|
||||
change_in_num_pending_mappings -= num_pending_deleted
|
||||
|
||||
|
||||
for ( namespace_id, tag_id, hash_ids ) in deleted_mappings_ids:
|
||||
|
||||
num_current_deleted = ChangeMappingStatus( namespace_id, tag_id, hash_ids, HC.CURRENT, HC.DELETED )
|
||||
( num_current_deleted, num_current_made_deleted ) = ChangeMappingStatus( namespace_id, tag_id, hash_ids, HC.CURRENT, HC.DELETED )
|
||||
num_raw_adds = InsertMappings( namespace_id, tag_id, hash_ids, HC.DELETED )
|
||||
num_deleted_petitions = DeletePetitions( namespace_id, tag_id, hash_ids )
|
||||
|
||||
change_in_num_mappings -= num_current_deleted
|
||||
change_in_num_deleted_mappings += num_current_deleted + num_raw_adds
|
||||
change_in_num_deleted_mappings += num_current_made_deleted + num_raw_adds
|
||||
change_in_num_petitioned_mappings -= num_deleted_petitions
|
||||
|
||||
|
||||
|
@ -4170,7 +4180,7 @@ class ServiceDB( FileDB, MessageDB, TagDB, RatingDB ):
|
|||
|
||||
if recalc_combined_mappings:
|
||||
|
||||
self._RebuildTagServicePrecedence( c )
|
||||
self._RebuildTagServicePrecedenceCache( c )
|
||||
|
||||
self._RecalcCombinedMappings( c )
|
||||
|
||||
|
@ -4278,7 +4288,7 @@ class ServiceDB( FileDB, MessageDB, TagDB, RatingDB ):
|
|||
|
||||
if recalc_combined_mappings:
|
||||
|
||||
self._RebuildTagServicePrecedence( c )
|
||||
self._RebuildTagServicePrecedenceCache( c )
|
||||
|
||||
self._RecalcCombinedMappings( c )
|
||||
|
||||
|
@ -4360,7 +4370,9 @@ class DB( ServiceDB ):
|
|||
|
||||
( self._options, ) = c.execute( 'SELECT options FROM options;' ).fetchone()
|
||||
|
||||
self._tag_service_precedence = self._GetTagServicePrecedence( c )
|
||||
self._tag_service_precedence = []
|
||||
|
||||
self._RebuildTagServicePrecedenceCache( c )
|
||||
|
||||
if not self._CheckPassword(): raise HC.PermissionException( 'No password!' )
|
||||
|
||||
|
@ -7041,7 +7053,7 @@ class DB( ServiceDB ):
|
|||
|
||||
self.WaitUntilGoodTimeToUseDBThread()
|
||||
|
||||
time.sleep( 0.25 )
|
||||
time.sleep( 0.10 )
|
||||
|
||||
try: service = wx.GetApp().ReadDaemon( 'service', service_identifier )
|
||||
except: break
|
||||
|
@ -7364,6 +7376,8 @@ class DB( ServiceDB ):
|
|||
|
||||
def _MainLoop_JobInternal( self, c, job ):
|
||||
|
||||
HC.pubsub.pub( 'db_locked_status', 'db locked' )
|
||||
|
||||
action = job.GetAction()
|
||||
|
||||
job_type = job.GetType()
|
||||
|
@ -7442,6 +7456,8 @@ class DB( ServiceDB ):
|
|||
|
||||
|
||||
|
||||
HC.pubsub.pub( 'db_locked_status', '' )
|
||||
|
||||
|
||||
def _MainLoop_Read( self, c, action, args, kwargs ):
|
||||
|
||||
|
@ -7600,15 +7616,9 @@ class DB( ServiceDB ):
|
|||
if action != 'do_file_query': return job.GetResult()
|
||||
|
||||
|
||||
def ReadFile( self, hash ):
|
||||
|
||||
return self._GetFile( hash )
|
||||
|
||||
def ReadFile( self, hash ): return self._GetFile( hash )
|
||||
|
||||
def ReadThumbnail( self, hash, full_size = False ):
|
||||
|
||||
return self._GetThumbnail( hash, full_size )
|
||||
|
||||
def ReadThumbnail( self, hash, full_size = False ): return self._GetThumbnail( hash, full_size )
|
||||
|
||||
def WaitUntilGoodTimeToUseDBThread( self ):
|
||||
|
||||
|
|
|
@ -46,13 +46,14 @@ class FrameGUI( ClientGUICommon.Frame ):
|
|||
self.SetDropTarget( ClientGUICommon.FileDropTarget( self.ImportFiles ) )
|
||||
|
||||
self._statusbar = self.CreateStatusBar()
|
||||
self._statusbar.SetFieldsCount( 4 )
|
||||
self._statusbar.SetStatusWidths( [ -1, 400, 200, 200 ] )
|
||||
self._statusbar.SetFieldsCount( 5 )
|
||||
self._statusbar.SetStatusWidths( [ -1, -1, 100, 120, 50 ] )
|
||||
|
||||
self._statusbar_media = ''
|
||||
self._statusbar_service = ''
|
||||
self._statusbar_inbox = ''
|
||||
self._statusbar_downloads = ''
|
||||
self._statusbar_db_locked = ''
|
||||
|
||||
self.SetIcon( wx.Icon( HC.STATIC_DIR + os.path.sep + 'hydrus.ico', wx.BITMAP_TYPE_ICO ) )
|
||||
|
||||
|
@ -90,6 +91,7 @@ class FrameGUI( ClientGUICommon.Frame ):
|
|||
HC.pubsub.sub( self, 'RefreshMenuBar', 'notify_new_services' )
|
||||
HC.pubsub.sub( self, 'RefreshAcceleratorTable', 'options_updated' )
|
||||
HC.pubsub.sub( self, 'RefreshStatusBar', 'refresh_status' )
|
||||
HC.pubsub.sub( self, 'SetDBLockedStatus', 'db_locked_status' )
|
||||
HC.pubsub.sub( self, 'SetDownloadsStatus', 'downloads_status' )
|
||||
HC.pubsub.sub( self, 'SetInboxStatus', 'inbox_status' )
|
||||
HC.pubsub.sub( self, 'SetServiceStatus', 'service_status' )
|
||||
|
@ -349,7 +351,7 @@ class FrameGUI( ClientGUICommon.Frame ):
|
|||
subprocess.Popen( [ 'explorer', HC.BASE_DIR + os.path.sep + 'server.exe' ] )
|
||||
|
||||
|
||||
time.sleep( 5 ) # give it time to init its db
|
||||
time.sleep( 10 ) # give it time to init its db
|
||||
|
||||
except:
|
||||
|
||||
|
@ -901,6 +903,7 @@ class FrameGUI( ClientGUICommon.Frame ):
|
|||
self._statusbar.SetStatusText( self._statusbar_service, number = 1 )
|
||||
self._statusbar.SetStatusText( self._statusbar_inbox, number = 2 )
|
||||
self._statusbar.SetStatusText( self._statusbar_downloads, number = 3 )
|
||||
self._statusbar.SetStatusText( self._statusbar_db_locked, number = 4 )
|
||||
|
||||
|
||||
def _ReviewServices( self ):
|
||||
|
@ -1470,6 +1473,16 @@ The password is cleartext here but obscured in the entry dialog. Enter a blank p
|
|||
|
||||
def RefreshStatusBar( self ): self._RefreshStatusBar()
|
||||
|
||||
def SetDBLockedStatus( self, status ):
|
||||
|
||||
if self.IsShown():
|
||||
|
||||
self._statusbar_db_locked = status
|
||||
|
||||
self._RefreshStatusBar()
|
||||
|
||||
|
||||
|
||||
def SetDownloadsStatus( self, status ):
|
||||
|
||||
if self.IsShown():
|
||||
|
|
|
@ -1570,6 +1570,14 @@ class CanvasFullscreenMediaListFilter( CanvasFullscreenMediaList ):
|
|||
self.SetMedia( self._GetFirst() )
|
||||
|
||||
|
||||
def _Delete( self ):
|
||||
|
||||
self._deleted.add( self._current_media )
|
||||
|
||||
if self._current_media == self._GetLast(): self.EventClose( None )
|
||||
else: self._ShowNext()
|
||||
|
||||
|
||||
def _Keep( self ):
|
||||
|
||||
self._kept.add( self._current_media )
|
||||
|
@ -1594,6 +1602,12 @@ class CanvasFullscreenMediaListFilter( CanvasFullscreenMediaList ):
|
|||
|
||||
|
||||
|
||||
def EventButtonBack( self, event ): self.EventBack( event )
|
||||
def EventButtonDelete( self, event ): self._Delete()
|
||||
def EventButtonDone( self, event ): self.EventClose( event )
|
||||
def EventButtonKeep( self, event ): self._Keep()
|
||||
def EventButtonSkip( self, event ): self._ShowNext()
|
||||
|
||||
def EventClose( self, event ):
|
||||
|
||||
if self._ShouldSkipInputDueToFlash(): event.Skip()
|
||||
|
@ -1649,13 +1663,7 @@ class CanvasFullscreenMediaListFilter( CanvasFullscreenMediaList ):
|
|||
def EventDelete( self, event ):
|
||||
|
||||
if self._ShouldSkipInputDueToFlash(): event.Skip()
|
||||
else:
|
||||
|
||||
self._deleted.add( self._current_media )
|
||||
|
||||
if self._current_media == self._GetLast(): self.EventClose( event )
|
||||
else: self._ShowNext()
|
||||
|
||||
else: self._Delete()
|
||||
|
||||
|
||||
def EventKeyDown( self, event ):
|
||||
|
@ -1768,6 +1776,374 @@ class CanvasFullscreenMediaListFilter( CanvasFullscreenMediaList ):
|
|||
|
||||
|
||||
|
||||
class CanvasFullscreenMediaListFilterInbox( CanvasFullscreenMediaListFilter ):
|
||||
|
||||
def __init__( self, my_parent, page_key, file_service_identifier, predicates, media_results ):
|
||||
|
||||
CanvasFullscreenMediaListFilter.__init__( self, my_parent, page_key, file_service_identifier, predicates, media_results )
|
||||
|
||||
FullscreenPopoutFilterInbox( self )
|
||||
|
||||
|
||||
class FullscreenPopout( wx.Frame ):
|
||||
|
||||
def __init__( self, parent ):
|
||||
|
||||
wx.Frame.__init__( self, parent, style = wx.FRAME_TOOL_WINDOW | wx.FRAME_NO_TASKBAR | wx.FRAME_FLOAT_ON_PARENT | wx.BORDER_SIMPLE )
|
||||
|
||||
self._last_drag_coordinates = None
|
||||
self._total_drag_delta = ( 0, 0 )
|
||||
|
||||
self.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_BTNFACE ) )
|
||||
|
||||
self.SetCursor( wx.StockCursor( wx.CURSOR_ARROW ) )
|
||||
|
||||
hbox = wx.BoxSizer( wx.HORIZONTAL )
|
||||
|
||||
self._popout_window = self._InitialisePopoutWindow( hbox )
|
||||
|
||||
self._popout_window.Hide()
|
||||
|
||||
self._button_window = self._InitialiseButtonWindow( hbox )
|
||||
|
||||
hbox.AddF( self._popout_window, FLAGS_EXPAND_PERPENDICULAR )
|
||||
hbox.AddF( self._button_window, FLAGS_EXPAND_PERPENDICULAR )
|
||||
|
||||
self.SetSizer( hbox )
|
||||
|
||||
self._SizeAndPosition()
|
||||
|
||||
tlp = self.GetParent().GetTopLevelParent()
|
||||
|
||||
tlp.Bind( wx.EVT_SIZE, self.EventResize )
|
||||
tlp.Bind( wx.EVT_MOVE, self.EventMove )
|
||||
|
||||
self.Show()
|
||||
|
||||
|
||||
def _InitialiseButtonWindow( self, sizer ):
|
||||
|
||||
button_window = wx.Window( self )
|
||||
|
||||
self._move_button = wx.Button( button_window, label = u'\u2022', size = ( 20, 20 ) )
|
||||
self._move_button.SetCursor( wx.StockCursor( wx.CURSOR_SIZING ) )
|
||||
self._move_button.Bind( wx.EVT_MOTION, self.EventDrag )
|
||||
self._move_button.Bind( wx.EVT_LEFT_DOWN, self.EventDragBegin )
|
||||
self._move_button.Bind( wx.EVT_LEFT_UP, self.EventDragEnd )
|
||||
|
||||
self._arrow_button = wx.Button( button_window, label = '>', size = ( 20, 80 ) )
|
||||
self._arrow_button.Bind( wx.EVT_BUTTON, self.EventArrowClicked )
|
||||
|
||||
vbox = wx.BoxSizer( wx.VERTICAL )
|
||||
|
||||
vbox.AddF( self._move_button, FLAGS_MIXED )
|
||||
vbox.AddF( self._arrow_button, FLAGS_EXPAND_BOTH_WAYS )
|
||||
|
||||
button_window.SetSizer( vbox )
|
||||
|
||||
return button_window
|
||||
|
||||
|
||||
def _SizeAndPosition( self ):
|
||||
|
||||
self.Fit()
|
||||
|
||||
parent = self.GetParent()
|
||||
|
||||
( parent_width, parent_height ) = parent.GetClientSize()
|
||||
|
||||
( my_width, my_height ) = self.GetClientSize()
|
||||
|
||||
my_y = ( parent_height - my_height ) / 2
|
||||
|
||||
( offset_x, offset_y ) = self._total_drag_delta
|
||||
|
||||
self.SetPosition( parent.ClientToScreenXY( 0 + offset_x, my_y + offset_y ) )
|
||||
|
||||
|
||||
def EventArrowClicked( self, event ):
|
||||
|
||||
if self._popout_window.IsShown():
|
||||
|
||||
self._popout_window.Hide()
|
||||
self._arrow_button.SetLabel( '>' )
|
||||
|
||||
else:
|
||||
|
||||
self._popout_window.Show()
|
||||
self._arrow_button.SetLabel( '<' )
|
||||
|
||||
|
||||
self._SizeAndPosition()
|
||||
|
||||
self.Layout()
|
||||
|
||||
|
||||
def EventMove( self, event ):
|
||||
|
||||
self._SizeAndPosition()
|
||||
|
||||
event.Skip()
|
||||
|
||||
|
||||
def EventDrag( self, event ):
|
||||
|
||||
if event.Dragging() and self._last_drag_coordinates is not None:
|
||||
|
||||
( old_x, old_y ) = self._last_drag_coordinates
|
||||
|
||||
( x, y ) = event.GetPosition()
|
||||
|
||||
( delta_x, delta_y ) = ( x - old_x, y - old_y )
|
||||
|
||||
( old_delta_x, old_delta_y ) = self._total_drag_delta
|
||||
|
||||
self._total_drag_delta = ( old_delta_x + delta_x, old_delta_y + delta_y )
|
||||
|
||||
self._SizeAndPosition()
|
||||
|
||||
|
||||
|
||||
def EventDragBegin( self, event ):
|
||||
|
||||
self._last_drag_coordinates = event.GetPosition()
|
||||
|
||||
event.Skip()
|
||||
|
||||
|
||||
def EventDragEnd( self, event ):
|
||||
|
||||
self._last_drag_coordinates = None
|
||||
|
||||
event.Skip()
|
||||
|
||||
|
||||
def EventResize( self, event ):
|
||||
|
||||
self._SizeAndPosition()
|
||||
|
||||
event.Skip()
|
||||
|
||||
|
||||
class FullscreenPopoutFilterInbox( FullscreenPopout ):
|
||||
|
||||
def _InitialisePopoutWindow( self, sizer ):
|
||||
|
||||
window = wx.Window( self )
|
||||
|
||||
vbox = wx.BoxSizer( wx.VERTICAL )
|
||||
|
||||
parent = self.GetParent()
|
||||
|
||||
keep = wx.Button( window, label = 'archive' )
|
||||
keep.Bind( wx.EVT_BUTTON, parent.EventButtonKeep )
|
||||
|
||||
delete = wx.Button( window, label = 'delete' )
|
||||
delete.Bind( wx.EVT_BUTTON, parent.EventButtonDelete )
|
||||
|
||||
skip = wx.Button( window, label = 'skip' )
|
||||
skip.Bind( wx.EVT_BUTTON, parent.EventButtonSkip )
|
||||
|
||||
back = wx.Button( window, label = 'back' )
|
||||
back.Bind( wx.EVT_BUTTON, parent.EventButtonBack )
|
||||
|
||||
done = wx.Button( window, label = 'done' )
|
||||
done.Bind( wx.EVT_BUTTON, parent.EventButtonDone )
|
||||
|
||||
vbox.AddF( keep, FLAGS_EXPAND_PERPENDICULAR )
|
||||
vbox.AddF( delete, FLAGS_EXPAND_PERPENDICULAR )
|
||||
vbox.AddF( skip, FLAGS_EXPAND_PERPENDICULAR )
|
||||
vbox.AddF( back, FLAGS_EXPAND_PERPENDICULAR )
|
||||
vbox.AddF( done, FLAGS_EXPAND_PERPENDICULAR )
|
||||
|
||||
window.SetSizer( vbox )
|
||||
|
||||
return window
|
||||
|
||||
|
||||
class FullscreenPopoutFilterLike( FullscreenPopout ):
|
||||
|
||||
def _InitialisePopoutWindow( self, sizer ):
|
||||
|
||||
window = wx.Window( self )
|
||||
|
||||
vbox = wx.BoxSizer( wx.VERTICAL )
|
||||
|
||||
parent = self.GetParent()
|
||||
|
||||
like = wx.Button( window, label = 'like' )
|
||||
like.Bind( wx.EVT_BUTTON, parent.EventButtonKeep )
|
||||
|
||||
dislike = wx.Button( window, label = 'dislike' )
|
||||
dislike.Bind( wx.EVT_BUTTON, parent.EventButtonDelete )
|
||||
|
||||
skip = wx.Button( window, label = 'skip' )
|
||||
skip.Bind( wx.EVT_BUTTON, parent.EventButtonSkip )
|
||||
|
||||
back = wx.Button( window, label = 'back' )
|
||||
back.Bind( wx.EVT_BUTTON, parent.EventButtonBack )
|
||||
|
||||
done = wx.Button( window, label = 'done' )
|
||||
done.Bind( wx.EVT_BUTTON, parent.EventButtonDone )
|
||||
|
||||
vbox.AddF( like, FLAGS_EXPAND_PERPENDICULAR )
|
||||
vbox.AddF( dislike, FLAGS_EXPAND_PERPENDICULAR )
|
||||
vbox.AddF( skip, FLAGS_EXPAND_PERPENDICULAR )
|
||||
vbox.AddF( back, FLAGS_EXPAND_PERPENDICULAR )
|
||||
vbox.AddF( done, FLAGS_EXPAND_PERPENDICULAR )
|
||||
|
||||
window.SetSizer( vbox )
|
||||
|
||||
return window
|
||||
|
||||
|
||||
class FullscreenPopoutFilterNumerical( FullscreenPopout ):
|
||||
|
||||
def __init__( self, parent, callable_parent ):
|
||||
|
||||
self._callable_parent = callable_parent
|
||||
|
||||
FullscreenPopout.__init__( self, parent )
|
||||
|
||||
|
||||
def _InitialisePopoutWindow( self, sizer ):
|
||||
|
||||
window = wx.Window( self )
|
||||
|
||||
vbox = wx.BoxSizer( wx.VERTICAL )
|
||||
|
||||
parent = self.GetParent()
|
||||
|
||||
#
|
||||
|
||||
options = wx.GetApp().Read( 'options' )
|
||||
|
||||
accuracy_slider_hbox = wx.BoxSizer( wx.HORIZONTAL )
|
||||
|
||||
if 'ratings_filter_accuracy' not in options:
|
||||
|
||||
options[ 'ratings_filter_accuracy' ] = 1
|
||||
|
||||
wx.GetApp().Write( 'save_options' )
|
||||
|
||||
|
||||
value = options[ 'ratings_filter_accuracy' ]
|
||||
|
||||
self._accuracy_slider = wx.Slider( window, size = ( 50, -1 ), value = value, minValue = 0, maxValue = 4 )
|
||||
self._accuracy_slider.Bind( wx.EVT_SLIDER, self.EventAccuracySlider )
|
||||
|
||||
accuracy_slider_hbox.AddF( wx.StaticText( window, label = 'quick' ), FLAGS_MIXED )
|
||||
accuracy_slider_hbox.AddF( self._accuracy_slider, FLAGS_EXPAND_BOTH_WAYS )
|
||||
accuracy_slider_hbox.AddF( wx.StaticText( window, label = 'accurate' ), FLAGS_MIXED )
|
||||
|
||||
self.EventAccuracySlider( None )
|
||||
|
||||
#
|
||||
|
||||
if 'ratings_filter_compare_same' not in options:
|
||||
|
||||
options[ 'ratings_filter_compare_same' ] = False
|
||||
|
||||
wx.GetApp().Write( 'save_options' )
|
||||
|
||||
|
||||
compare_same = options[ 'ratings_filter_compare_same' ]
|
||||
|
||||
self._compare_same = wx.CheckBox( window, label = 'compare same image until rating is done' )
|
||||
self._compare_same.SetValue( compare_same )
|
||||
self._compare_same.Bind( wx.EVT_CHECKBOX, self.EventCompareSame )
|
||||
|
||||
self.EventCompareSame( None )
|
||||
|
||||
#
|
||||
|
||||
self._left_right_slider_sizer = wx.BoxSizer( wx.HORIZONTAL )
|
||||
|
||||
if 'ratings_filter_left_right' not in options:
|
||||
|
||||
options[ 'ratings_filter_left_right' ] = 'left'
|
||||
|
||||
wx.GetApp().Write( 'save_options' )
|
||||
|
||||
|
||||
left_right = options[ 'ratings_filter_left_right' ]
|
||||
|
||||
if left_right == 'left': left_right_value = 0
|
||||
elif left_right == 'random': left_right_value = 1
|
||||
else: left_right_value = 2
|
||||
|
||||
self._left_right_slider = wx.Slider( window, size = ( 30, -1 ), value = left_right_value, minValue = 0, maxValue = 2 )
|
||||
self._left_right_slider.Bind( wx.EVT_SLIDER, self.EventLeftRight )
|
||||
|
||||
self._left_right_slider_sizer.AddF( wx.StaticText( window, label = 'left' ), FLAGS_MIXED )
|
||||
self._left_right_slider_sizer.AddF( self._left_right_slider, FLAGS_EXPAND_BOTH_WAYS )
|
||||
self._left_right_slider_sizer.AddF( wx.StaticText( window, label = 'right' ), FLAGS_MIXED )
|
||||
|
||||
self.EventLeftRight( None )
|
||||
|
||||
#
|
||||
|
||||
left = wx.Button( window, label = 'left is better' )
|
||||
left.Bind( wx.EVT_BUTTON, self._callable_parent.EventButtonLeft )
|
||||
|
||||
right = wx.Button( window, label = 'right is better' )
|
||||
right.Bind( wx.EVT_BUTTON, self._callable_parent.EventButtonRight )
|
||||
|
||||
equal = wx.Button( window, label = 'they are about the same' )
|
||||
equal.Bind( wx.EVT_BUTTON, self._callable_parent.EventButtonEqual )
|
||||
|
||||
back = wx.Button( window, label = 'back' )
|
||||
back.Bind( wx.EVT_BUTTON, self._callable_parent.EventButtonBack )
|
||||
|
||||
dont_filter = wx.Button( window, label = 'don\'t filter this file' )
|
||||
dont_filter.Bind( wx.EVT_BUTTON, self._callable_parent.EventButtonDontFilter )
|
||||
|
||||
done = wx.Button( window, label = 'done' )
|
||||
done.Bind( wx.EVT_BUTTON, self._callable_parent.EventButtonDone )
|
||||
|
||||
vbox.AddF( accuracy_slider_hbox, FLAGS_EXPAND_PERPENDICULAR )
|
||||
vbox.AddF( self._compare_same, FLAGS_EXPAND_PERPENDICULAR )
|
||||
vbox.AddF( self._left_right_slider_sizer, FLAGS_EXPAND_PERPENDICULAR )
|
||||
|
||||
vbox.AddF( wx.StaticLine( window, style = wx.LI_HORIZONTAL ), FLAGS_EXPAND_PERPENDICULAR )
|
||||
|
||||
vbox.AddF( left, FLAGS_EXPAND_PERPENDICULAR )
|
||||
vbox.AddF( right, FLAGS_EXPAND_PERPENDICULAR )
|
||||
vbox.AddF( equal, FLAGS_EXPAND_PERPENDICULAR )
|
||||
vbox.AddF( back, FLAGS_EXPAND_PERPENDICULAR )
|
||||
vbox.AddF( dont_filter, FLAGS_EXPAND_PERPENDICULAR )
|
||||
vbox.AddF( done, FLAGS_EXPAND_PERPENDICULAR )
|
||||
|
||||
window.SetSizer( vbox )
|
||||
|
||||
return window
|
||||
|
||||
|
||||
def EventAccuracySlider( self, event ):
|
||||
|
||||
value = self._accuracy_slider.GetValue()
|
||||
|
||||
self._callable_parent.SetAccuracy( value )
|
||||
|
||||
|
||||
def EventCompareSame( self, event ):
|
||||
|
||||
compare_same = self._compare_same.GetValue()
|
||||
|
||||
self._callable_parent.SetCompareSame( compare_same )
|
||||
|
||||
|
||||
def EventLeftRight( self, event ):
|
||||
|
||||
value = self._left_right_slider.GetValue()
|
||||
|
||||
if value == 0: left_right = 'left'
|
||||
elif value == 1: left_right = 'random'
|
||||
else: left_right = 'right'
|
||||
|
||||
self._callable_parent.SetLeftRight( left_right )
|
||||
|
||||
|
||||
class RatingsFilterFrameLike( CanvasFullscreenMediaListFilter ):
|
||||
|
||||
def __init__( self, my_parent, page_key, service_identifier, media_results ):
|
||||
|
@ -1777,6 +2153,8 @@ class RatingsFilterFrameLike( CanvasFullscreenMediaListFilter ):
|
|||
self._rating_service_identifier = service_identifier
|
||||
self._service = wx.GetApp().Read( 'service', service_identifier )
|
||||
|
||||
FullscreenPopoutFilterLike( self )
|
||||
|
||||
|
||||
def EventClose( self, event ):
|
||||
|
||||
|
@ -1847,6 +2225,7 @@ class RatingsFilterFrameNumerical( ClientGUICommon.Frame ):
|
|||
self._page_key = page_key
|
||||
self._service_identifier = service_identifier
|
||||
self._media_still_to_rate = { ClientGUIMixins.MediaSingleton( media_result ) for media_result in media_results }
|
||||
self._current_media_to_rate = None
|
||||
|
||||
self._file_query_result = CC.FileQueryResult( HC.LOCAL_FILE_SERVICE_IDENTIFIER, [], media_results )
|
||||
|
||||
|
@ -1871,37 +2250,6 @@ class RatingsFilterFrameNumerical( ClientGUICommon.Frame ):
|
|||
self._inequal_accuracy = self.RATINGS_FILTER_INEQUALITY_FULL
|
||||
self._equal_accuracy = self.RATINGS_FILTER_EQUALITY_FULL
|
||||
|
||||
# panel
|
||||
|
||||
if service_identifier.GetType() == HC.LOCAL_RATING_NUMERICAL:
|
||||
|
||||
top_panel = wx.Panel( self )
|
||||
|
||||
hbox = wx.BoxSizer( wx.HORIZONTAL )
|
||||
|
||||
if 'ratings_filter_accuracy' not in self._options:
|
||||
|
||||
self._options[ 'ratings_filter_accuracy' ] = 1
|
||||
|
||||
wx.GetApp().Write( 'save_options' )
|
||||
|
||||
|
||||
value = self._options[ 'ratings_filter_accuracy' ]
|
||||
|
||||
self._accuracy_slider = wx.Slider( top_panel, value = value, minValue = 0, maxValue = 4 )
|
||||
self._accuracy_slider.Bind( wx.EVT_SLIDER, self.EventSlider )
|
||||
|
||||
self.EventSlider( None )
|
||||
|
||||
hbox.AddF( wx.StaticText( top_panel, label = 'quick' ), FLAGS_MIXED )
|
||||
hbox.AddF( self._accuracy_slider, FLAGS_EXPAND_BOTH_WAYS )
|
||||
hbox.AddF( wx.StaticText( top_panel, label = 'accurate' ), FLAGS_MIXED )
|
||||
|
||||
top_panel.SetSizer( hbox )
|
||||
|
||||
|
||||
# end panel
|
||||
|
||||
self._statusbar = self.CreateStatusBar()
|
||||
self._statusbar.SetFieldsCount( 3 )
|
||||
self._statusbar.SetStatusWidths( [ -1, 500, -1 ] )
|
||||
|
@ -1911,7 +2259,6 @@ class RatingsFilterFrameNumerical( ClientGUICommon.Frame ):
|
|||
|
||||
vbox = wx.BoxSizer( wx.VERTICAL )
|
||||
|
||||
if service_identifier.GetType() == HC.LOCAL_RATING_NUMERICAL: vbox.AddF( top_panel, FLAGS_EXPAND_PERPENDICULAR )
|
||||
vbox.AddF( self._splitter, FLAGS_EXPAND_BOTH_WAYS )
|
||||
|
||||
self.SetSizer( vbox )
|
||||
|
@ -1933,6 +2280,8 @@ class RatingsFilterFrameNumerical( ClientGUICommon.Frame ):
|
|||
wx.GetApp().SetTopWindow( self )
|
||||
|
||||
self._left_window = self._Panel( self._splitter )
|
||||
FullscreenPopoutFilterNumerical( self._left_window, self )
|
||||
|
||||
self._right_window = self._Panel( self._splitter )
|
||||
|
||||
( my_width, my_height ) = self.GetClientSize()
|
||||
|
@ -2110,7 +2459,10 @@ class RatingsFilterFrameNumerical( ClientGUICommon.Frame ):
|
|||
|
||||
def _ShowNewMedia( self ):
|
||||
|
||||
( self._current_media_to_rate, ) = random.sample( self._media_still_to_rate, 1 )
|
||||
if not ( self._compare_same and self._current_media_to_rate in self._media_still_to_rate ):
|
||||
|
||||
( self._current_media_to_rate, ) = random.sample( self._media_still_to_rate, 1 )
|
||||
|
||||
|
||||
( min, max ) = self._media_to_current_scores_dict[ self._current_media_to_rate ]
|
||||
|
||||
|
@ -2190,7 +2542,11 @@ class RatingsFilterFrameNumerical( ClientGUICommon.Frame ):
|
|||
|
||||
self._current_media_to_rate_against = media_to_rate_against
|
||||
|
||||
if random.randint( 0, 1 ) == 0:
|
||||
if self._left_right == 'left': position = 0
|
||||
elif self._left_right == 'random': position = random.randint( 0, 1 )
|
||||
else: position = 1
|
||||
|
||||
if position == 0:
|
||||
|
||||
self._unrated_is_on_the_left = True
|
||||
|
||||
|
@ -2384,6 +2740,19 @@ class RatingsFilterFrameNumerical( ClientGUICommon.Frame ):
|
|||
else: self._ShowNewMedia()
|
||||
|
||||
|
||||
def EventButtonBack( self, event ): self._GoBack()
|
||||
def EventButtonDone( self, event ): self.EventClose( event )
|
||||
def EventButtonDontFilter( self, event ):
|
||||
|
||||
self._media_still_to_rate.discard( self._current_media_to_rate )
|
||||
|
||||
if len( self._media_still_to_rate ) == 0: self.EventClose( None )
|
||||
else: self._ShowNewMedia()
|
||||
|
||||
def EventButtonEqual( self, event ): self._ProcessAction( 'equal' )
|
||||
def EventButtonLeft( self, event ): self._ProcessAction( 'right' )
|
||||
def EventButtonRight( self, event ): self._ProcessAction( 'left' )
|
||||
|
||||
def EventClose( self, event ):
|
||||
|
||||
if len( self._decision_log ) > 0:
|
||||
|
@ -2469,23 +2838,6 @@ class RatingsFilterFrameNumerical( ClientGUICommon.Frame ):
|
|||
elif event.ButtonDown( wx.MOUSE_BTN_MIDDLE ): self._ProcessAction( 'equal' )
|
||||
|
||||
|
||||
def EventSlider( self, event ):
|
||||
|
||||
value = self._accuracy_slider.GetValue()
|
||||
|
||||
if value == 0: self._equal_accuracy = self.RATINGS_FILTER_EQUALITY_FULL
|
||||
elif value <= 2: self._equal_accuracy = self.RATINGS_FILTER_EQUALITY_HALF
|
||||
else: self._equal_accuracy = self.RATINGS_FILTER_EQUALITY_QUARTER
|
||||
|
||||
if value <= 1: self._inequal_accuracy = self.RATINGS_FILTER_INEQUALITY_FULL
|
||||
elif value <= 3: self._inequal_accuracy = self.RATINGS_FILTER_INEQUALITY_HALF
|
||||
else: self._inequal_accuracy = self.RATINGS_FILTER_INEQUALITY_QUARTER
|
||||
|
||||
self._options[ 'ratings_filter_accuracy' ] = value
|
||||
|
||||
wx.GetApp().Write( 'save_options' )
|
||||
|
||||
|
||||
def ProcessContentUpdates( self, service_identifiers_to_content_updates ):
|
||||
|
||||
redraw = False
|
||||
|
@ -2520,6 +2872,39 @@ class RatingsFilterFrameNumerical( ClientGUICommon.Frame ):
|
|||
self._right_window.RefreshBackground()
|
||||
|
||||
|
||||
def SetAccuracy( self, accuracy ):
|
||||
|
||||
if accuracy == 0: self._equal_accuracy = self.RATINGS_FILTER_EQUALITY_FULL
|
||||
elif accuracy <= 2: self._equal_accuracy = self.RATINGS_FILTER_EQUALITY_HALF
|
||||
else: self._equal_accuracy = self.RATINGS_FILTER_EQUALITY_QUARTER
|
||||
|
||||
if accuracy <= 1: self._inequal_accuracy = self.RATINGS_FILTER_INEQUALITY_FULL
|
||||
elif accuracy <= 3: self._inequal_accuracy = self.RATINGS_FILTER_INEQUALITY_HALF
|
||||
else: self._inequal_accuracy = self.RATINGS_FILTER_INEQUALITY_QUARTER
|
||||
|
||||
self._options[ 'ratings_filter_accuracy' ] = accuracy
|
||||
|
||||
wx.GetApp().Write( 'save_options' )
|
||||
|
||||
|
||||
def SetCompareSame( self, compare_same ):
|
||||
|
||||
self._options[ 'ratings_filter_compare_same' ] = compare_same
|
||||
|
||||
wx.GetApp().Write( 'save_options' )
|
||||
|
||||
self._compare_same = compare_same
|
||||
|
||||
|
||||
def SetLeftRight( self, left_right ):
|
||||
|
||||
self._options[ 'ratings_filter_left_right' ] = left_right
|
||||
|
||||
wx.GetApp().Write( 'save_options' )
|
||||
|
||||
self._left_right = left_right
|
||||
|
||||
|
||||
class _Panel( Canvas, wx.Window ):
|
||||
|
||||
def __init__( self, parent ):
|
||||
|
|
|
@ -3169,8 +3169,6 @@ class TagsBoxManage( TagsBox ):
|
|||
|
||||
self._callable = callable
|
||||
|
||||
self._show_deleted_tags = False
|
||||
|
||||
self._current_tags = set( current_tags )
|
||||
self._deleted_tags = set( deleted_tags )
|
||||
self._pending_tags = set( pending_tags )
|
||||
|
@ -3185,8 +3183,7 @@ class TagsBoxManage( TagsBox ):
|
|||
|
||||
siblings_manager = wx.GetApp().GetTagSiblingsManager()
|
||||
|
||||
if self._show_deleted_tags: all_tags = self._current_tags | self._deleted_tags | self._pending_tags | self._petitioned_tags
|
||||
else: all_tags = self._current_tags | self._pending_tags | self._petitioned_tags
|
||||
all_tags = self._current_tags | self._deleted_tags | self._pending_tags | self._petitioned_tags
|
||||
|
||||
self._ordered_strings = []
|
||||
self._strings_to_terms = {}
|
||||
|
@ -3245,13 +3242,6 @@ class TagsBoxManage( TagsBox ):
|
|||
self._RebuildTagStrings()
|
||||
|
||||
|
||||
def SetShowDeletedTags( self, value ):
|
||||
|
||||
self._show_deleted_tags = value
|
||||
|
||||
self._RebuildTagStrings()
|
||||
|
||||
|
||||
class TagsBoxOptions( TagsBox ):
|
||||
|
||||
def __init__( self, parent, initial_namespace_colours ):
|
||||
|
|
|
@ -8463,9 +8463,6 @@ class DialogManageTags( Dialog ):
|
|||
|
||||
self._add_tag_box = ClientGUICommon.AutoCompleteDropdownTagsWrite( self, self.AddTag, self._file_service_identifier, self._tag_service_identifier )
|
||||
|
||||
self._show_deleted_tags = wx.CheckBox( self, label='Show deleted tags' )
|
||||
self._show_deleted_tags.Bind( wx.EVT_CHECKBOX, self.EventShowDeletedTags )
|
||||
|
||||
self._modify_mappers = wx.Button( self, label='Modify mappers' )
|
||||
self._modify_mappers.Bind( wx.EVT_BUTTON, self.EventModify )
|
||||
|
||||
|
@ -8475,11 +8472,7 @@ class DialogManageTags( Dialog ):
|
|||
self._paste_tags = wx.Button( self, label = 'paste tags' )
|
||||
self._paste_tags.Bind( wx.EVT_BUTTON, self.EventPasteTags )
|
||||
|
||||
if self._i_am_local_tag_service:
|
||||
|
||||
self._show_deleted_tags.Hide()
|
||||
self._modify_mappers.Hide()
|
||||
|
||||
if self._i_am_local_tag_service: self._modify_mappers.Hide()
|
||||
else:
|
||||
|
||||
if not self._account.HasPermission( HC.POST_DATA ): self._add_tag_box.Hide()
|
||||
|
@ -8491,11 +8484,6 @@ class DialogManageTags( Dialog ):
|
|||
|
||||
self.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_BTNFACE ) )
|
||||
|
||||
special_hbox = wx.BoxSizer( wx.HORIZONTAL )
|
||||
|
||||
special_hbox.AddF( self._show_deleted_tags, FLAGS_MIXED )
|
||||
special_hbox.AddF( self._modify_mappers, FLAGS_MIXED )
|
||||
|
||||
copy_paste_hbox = wx.BoxSizer( wx.HORIZONTAL )
|
||||
|
||||
copy_paste_hbox.AddF( self._copy_tags, FLAGS_MIXED )
|
||||
|
@ -8506,7 +8494,7 @@ class DialogManageTags( Dialog ):
|
|||
vbox.AddF( self._tags_box, FLAGS_EXPAND_BOTH_WAYS )
|
||||
vbox.AddF( self._add_tag_box, FLAGS_EXPAND_PERPENDICULAR )
|
||||
vbox.AddF( copy_paste_hbox, FLAGS_BUTTON_SIZERS )
|
||||
vbox.AddF( special_hbox, FLAGS_BUTTON_SIZERS )
|
||||
vbox.AddF( self._modify_mappers, FLAGS_BUTTON_SIZERS )
|
||||
|
||||
self.SetSizer( vbox )
|
||||
|
||||
|
@ -8628,17 +8616,6 @@ class DialogManageTags( Dialog ):
|
|||
|
||||
|
||||
|
||||
elif tag in self._deleted_tags:
|
||||
|
||||
if self._account.HasPermission( HC.RESOLVE_PETITIONS ):
|
||||
|
||||
self._content_updates.append( HC.ContentUpdate( HC.CONTENT_DATA_TYPE_MAPPINGS, HC.CONTENT_UPDATE_PENDING, ( tag, self._hashes ) ) )
|
||||
|
||||
self._pending_tags.append( tag )
|
||||
|
||||
self._tags_box.PendTag( tag )
|
||||
|
||||
|
||||
else:
|
||||
|
||||
self._content_updates.append( HC.ContentUpdate( HC.CONTENT_DATA_TYPE_MAPPINGS, HC.CONTENT_UPDATE_PENDING, ( tag, self._hashes ) ) )
|
||||
|
@ -8719,8 +8696,6 @@ class DialogManageTags( Dialog ):
|
|||
else: wx.MessageBox( 'I could not get permission to access the clipboard.' )
|
||||
|
||||
|
||||
def EventShowDeletedTags( self, event ): self._tags_box.SetShowDeletedTags( self._show_deleted_tags.GetValue() )
|
||||
|
||||
def EventTagsBoxAction( self, event ):
|
||||
|
||||
tag = self._tags_box.GetSelectedTag()
|
||||
|
|
|
@ -261,7 +261,7 @@ class MediaPanel( ClientGUIMixins.ListeningMediaList, wx.ScrolledWindow ):
|
|||
|
||||
if len( media_results ) > 0:
|
||||
|
||||
try: ClientGUICanvas.CanvasFullscreenMediaListFilter( self.GetTopLevelParent(), self._page_key, self._file_service_identifier, self._predicates, media_results )
|
||||
try: ClientGUICanvas.CanvasFullscreenMediaListFilterInbox( self.GetTopLevelParent(), self._page_key, self._file_service_identifier, self._predicates, media_results )
|
||||
except: wx.MessageBox( traceback.format_exc() )
|
||||
|
||||
|
||||
|
@ -807,7 +807,9 @@ class MediaPanelThumbnails( MediaPanel ):
|
|||
|
||||
bmp = thumbnail.GetBmp()
|
||||
|
||||
self._thumbnails_being_faded_in[ ( bmp, x, y ) ] = ( bmp, 0 )
|
||||
hash = thumbnail.GetDisplayMedia().GetHash()
|
||||
|
||||
self._thumbnails_being_faded_in[ hash ] = ( bmp, bmp, x, y, 0 )
|
||||
|
||||
if not self._timer_animation.IsRunning(): self._timer_animation.Start( 0, wx.TIMER_ONE_SHOT )
|
||||
|
||||
|
@ -1543,13 +1545,11 @@ class MediaPanelThumbnails( MediaPanel ):
|
|||
|
||||
all_info = self._thumbnails_being_faded_in.items()
|
||||
|
||||
for ( key, ( alpha_bmp, num_frames_rendered ) ) in all_info:
|
||||
|
||||
( bmp, x, y ) = key
|
||||
for ( hash, ( original_bmp, alpha_bmp, x, y, num_frames_rendered ) ) in all_info:
|
||||
|
||||
if num_frames_rendered == 0:
|
||||
|
||||
image = bmp.ConvertToImage()
|
||||
image = original_bmp.ConvertToImage()
|
||||
|
||||
image.InitAlpha()
|
||||
|
||||
|
@ -1560,13 +1560,13 @@ class MediaPanelThumbnails( MediaPanel ):
|
|||
|
||||
num_frames_rendered += 1
|
||||
|
||||
self._thumbnails_being_faded_in[ key ] = ( alpha_bmp, num_frames_rendered )
|
||||
self._thumbnails_being_faded_in[ hash ] = ( original_bmp, alpha_bmp, x, y, num_frames_rendered )
|
||||
|
||||
if y < min_y or y > max_y or num_frames_rendered == 9:
|
||||
|
||||
bmp_to_use = bmp
|
||||
bmp_to_use = original_bmp
|
||||
|
||||
del self._thumbnails_being_faded_in[ key ]
|
||||
del self._thumbnails_being_faded_in[ hash ]
|
||||
|
||||
else:
|
||||
|
||||
|
|
|
@ -676,7 +676,7 @@ class MediaSingleton( Media ):
|
|||
|
||||
def HasArchive( self ): return not self._media_result.GetInbox()
|
||||
|
||||
def HasDuration( self ): return self._media_result.GetDuration() is not None
|
||||
def HasDuration( self ): return self._media_result.GetDuration() is not None and self._media_result.GetNumFrames() > 1
|
||||
|
||||
def HasImages( self ): return self.IsImage()
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ TEMP_DIR = BASE_DIR + os.path.sep + 'temp'
|
|||
# Misc
|
||||
|
||||
NETWORK_VERSION = 10
|
||||
SOFTWARE_VERSION = 74
|
||||
SOFTWARE_VERSION = 75
|
||||
|
||||
UNSCALED_THUMBNAIL_DIMENSIONS = ( 200, 200 )
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ def ConvertTagsToServiceIdentifiersToTags( tags, advanced_tag_options ):
|
|||
|
||||
if len( tags_to_add_here ) > 0:
|
||||
|
||||
tags_to_add_here = siblings_manager.CollapseTagList( tags_to_add_here )
|
||||
tags_to_add_here = siblings_manager.CollapseTags( tags_to_add_here )
|
||||
tags_to_add_here = parents_manager.ExpandTags( service_identifier, tags_to_add_here )
|
||||
|
||||
service_identifiers_to_tags[ service_identifier ] = tags_to_add_here
|
||||
|
|
Loading…
Reference in New Issue