Version 62

This commit is contained in:
Hydrus 2013-03-23 12:57:29 -05:00
parent 6e0d4594d3
commit 0d96611cff
13 changed files with 3608 additions and 3502 deletions

File diff suppressed because it is too large Load Diff

View File

@ -510,7 +510,7 @@ class AdvancedHTTPConnection():
except:
print( traceback.format_exc() )
raise Exception( 'Could not connect to server' )
raise
except:
print( traceback.format_exc() )
@ -1367,24 +1367,6 @@ class ConnectionToService():
def Post( self, request, **kwargs ): response = self._SendRequest( HC.POST, request, kwargs )
class ContentUpdate():
def __init__( self, action, service_identifier, hashes, info = None ):
self._action = action
self._service_identifier = service_identifier
self._hashes = set( hashes )
self._info = info
def GetAction( self ): return self._action
def GetHashes( self ): return self._hashes
def GetInfo( self ): return self._info
def GetServiceIdentifier( self ): return self._service_identifier
class CPRemoteRatingsServiceIdentifiers():
def __init__( self, service_identifiers_to_cp ):

View File

@ -51,6 +51,20 @@ class Controller( wx.App ):
else: wx.MessageBox( 'Could not get permission to access the clipboard!' )
elif type == 'text':
text = data
if wx.TheClipboard.Open():
data = wx.TextDataObject( text )
wx.TheClipboard.SetData( data )
wx.TheClipboard.Close()
else: wx.MessageBox( 'I could not get permission to access the clipboard.' )
def DeleteSessionKey( self, service_identifier ): self._session_manager.DeleteSessionKey( service_identifier )

View File

@ -1192,8 +1192,8 @@ class RatingDB():
c.executemany( 'INSERT INTO ratings ( service_id, hash_id, count, rating, score ) VALUES ( ?, ?, ?, ?, ? );', [ ( service_id, self._GetHashId( c, hash ), count, rating, HC.CalculateScoreFromRating( count, rating ) ) for ( hash, count, rating ) in ratings if count > 0 ] )
# these need count and score in
#self.pub( 'content_updates_data', [ CC.ContentUpdate( CC.CONTENT_UPDATE_RATING_REMOTE, service_identifier, ( hash, ), rating ) for ( hash, rating ) in ratings ] )
#self.pub( 'content_updates_gui', [ CC.ContentUpdate( CC.CONTENT_UPDATE_RATING_REMOTE, service_identifier, ( hash, ), rating ) for ( hash, rating ) in ratings ] )
#self.pub( 'content_updates_data', [ HC.ContentUpdate( CC.CONTENT_UPDATE_RATING_REMOTE, service_identifier, ( hash, ), rating ) for ( hash, rating ) in ratings ] )
#self.pub( 'content_updates_gui', [ HC.ContentUpdate( CC.CONTENT_UPDATE_RATING_REMOTE, service_identifier, ( hash, ), rating ) for ( hash, rating ) in ratings ] )
class TagDB():
@ -1298,8 +1298,8 @@ class ServiceDB( FileDB, MessageDB, TagDB, RatingDB ):
c.executemany( 'INSERT OR IGNORE INTO file_transfers ( service_id_from, service_id_to, hash_id ) VALUES ( ?, ?, ? );', [ ( service_id, self._local_file_service_id, hash_id ) for hash_id in hash_ids ] )
self.pub( 'notify_new_downloads' )
self.pub( 'content_updates_data', [ CC.ContentUpdate( CC.CONTENT_UPDATE_PENDING, CC.LOCAL_FILE_SERVICE_IDENTIFIER, hashes ) ] )
self.pub( 'content_updates_gui', [ CC.ContentUpdate( CC.CONTENT_UPDATE_PENDING, CC.LOCAL_FILE_SERVICE_IDENTIFIER, hashes ) ] )
self.pub( 'content_updates_data', [ HC.ContentUpdate( CC.CONTENT_UPDATE_PENDING, CC.LOCAL_FILE_SERVICE_IDENTIFIER, hashes ) ] )
self.pub( 'content_updates_gui', [ HC.ContentUpdate( CC.CONTENT_UPDATE_PENDING, CC.LOCAL_FILE_SERVICE_IDENTIFIER, hashes ) ] )
def _AddFiles( self, c, files_info_rows ):
@ -1379,14 +1379,14 @@ class ServiceDB( FileDB, MessageDB, TagDB, RatingDB ):
if len( new_hashes ) > 0:
self.pub( 'content_updates_data', [ CC.ContentUpdate( CC.CONTENT_UPDATE_ADD, service_identifier, new_hashes ) ] )
self.pub( 'content_updates_gui', [ CC.ContentUpdate( CC.CONTENT_UPDATE_ADD, service_identifier, new_hashes ) ] )
self.pub( 'content_updates_data', [ HC.ContentUpdate( CC.CONTENT_UPDATE_ADD, service_identifier, new_hashes ) ] )
self.pub( 'content_updates_gui', [ HC.ContentUpdate( CC.CONTENT_UPDATE_ADD, service_identifier, new_hashes ) ] )
if len( deleted_hashes ) > 0:
self.pub( 'content_updates_data', [ CC.ContentUpdate( CC.CONTENT_UPDATE_DELETE, service_identifier, deleted_hashes ) ] )
self.pub( 'content_updates_gui', [ CC.ContentUpdate( CC.CONTENT_UPDATE_DELETE, service_identifier, deleted_hashes ) ] )
self.pub( 'content_updates_data', [ HC.ContentUpdate( CC.CONTENT_UPDATE_DELETE, service_identifier, deleted_hashes ) ] )
self.pub( 'content_updates_gui', [ HC.ContentUpdate( CC.CONTENT_UPDATE_DELETE, service_identifier, deleted_hashes ) ] )
if len( new_hashes ) > 0 or len( deleted_hashes ) > 0: self.pub( 'notify_new_thumbnails' )
@ -1585,11 +1585,11 @@ class ServiceDB( FileDB, MessageDB, TagDB, RatingDB ):
deleted_mappings = [ deleted_mapping for deleted_mapping in update.GetDeletedMappings() ] # to clear generator
if len( mappings ) > 0:
self.pub( 'content_updates_data', [ CC.ContentUpdate( CC.CONTENT_UPDATE_ADD, service_identifier, hashes, info = tag ) for ( tag, hashes ) in mappings ] )
self.pub( 'content_updates_gui', [ CC.ContentUpdate( CC.CONTENT_UPDATE_ADD, service_identifier, hashes, info = tag ) for ( tag, hashes ) in mappings ] )
self.pub( 'content_updates_data', [ HC.ContentUpdate( CC.CONTENT_UPDATE_ADD, service_identifier, hashes, info = tag ) for ( tag, hashes ) in mappings ] )
self.pub( 'content_updates_gui', [ HC.ContentUpdate( CC.CONTENT_UPDATE_ADD, service_identifier, hashes, info = tag ) for ( tag, hashes ) in mappings ] )
if len( deleted_mappings ) > 0:
self.pub( 'content_updates_data', [ CC.ContentUpdate( CC.CONTENT_UPDATE_DELETE, service_identifier, hashes, info = tag ) for ( tag, hashes ) in deleted_mappings ] )
self.pub( 'content_updates_gui', [ CC.ContentUpdate( CC.CONTENT_UPDATE_DELETE, service_identifier, hashes, info = tag ) for ( tag, hashes ) in deleted_mappings ] )
self.pub( 'content_updates_data', [ HC.ContentUpdate( CC.CONTENT_UPDATE_DELETE, service_identifier, hashes, info = tag ) for ( tag, hashes ) in deleted_mappings ] )
self.pub( 'content_updates_gui', [ HC.ContentUpdate( CC.CONTENT_UPDATE_DELETE, service_identifier, hashes, info = tag ) for ( tag, hashes ) in deleted_mappings ] )
def _AddUpdate( self, c, service_identifier, update ):
@ -1624,8 +1624,8 @@ class ServiceDB( FileDB, MessageDB, TagDB, RatingDB ):
c.executemany( 'INSERT OR IGNORE INTO file_transfers ( service_id_from, service_id_to, hash_id ) VALUES ( ?, ?, ? );', [ ( self._local_file_service_id, service_id, hash_id ) for hash_id in hash_ids ] )
self.pub( 'notify_new_pending' )
self.pub( 'content_updates_data', [ CC.ContentUpdate( CC.CONTENT_UPDATE_PENDING, service_identifier, self._GetHashes( c, hash_ids ) ) ] )
self.pub( 'content_updates_gui', [ CC.ContentUpdate( CC.CONTENT_UPDATE_PENDING, service_identifier, self._GetHashes( c, hash_ids ) ) ] )
self.pub( 'content_updates_data', [ HC.ContentUpdate( CC.CONTENT_UPDATE_PENDING, service_identifier, self._GetHashes( c, hash_ids ) ) ] )
self.pub( 'content_updates_gui', [ HC.ContentUpdate( CC.CONTENT_UPDATE_PENDING, service_identifier, self._GetHashes( c, hash_ids ) ) ] )
def _ArchiveFiles( self, c, hash_ids ):
@ -3095,7 +3095,7 @@ class ServiceDB( FileDB, MessageDB, TagDB, RatingDB ):
return ( 'new', None )
def _ImportFile( self, c, file, advanced_import_options = {}, service_identifiers_to_tags = {}, generate_media_result = False, override_deleted = False ):
def _ImportFile( self, c, file, advanced_import_options = {}, service_identifiers_to_tags = {}, generate_media_result = False, override_deleted = False, url = None ):
result = 'successful'
@ -3122,6 +3122,8 @@ class ServiceDB( FileDB, MessageDB, TagDB, RatingDB ):
hash_id = self._GetHashId( c, hash )
if url is not None: c.execute( 'INSERT OR IGNORE INTO urls ( url, hash_id ) VALUES ( ?, ? );', ( url, hash_id ) )
already_in_db = c.execute( 'SELECT 1 FROM files_info WHERE service_id = ? AND hash_id = ?;', ( self._local_file_service_id, hash_id ) ).fetchone() is not None
if already_in_db:
@ -3132,8 +3134,8 @@ class ServiceDB( FileDB, MessageDB, TagDB, RatingDB ):
c.execute( 'DELETE FROM file_inbox WHERE hash_id = ?;', ( hash_id, ) )
self.pub( 'content_updates_data', [ CC.ContentUpdate( CC.CONTENT_UPDATE_ARCHIVE, CC.LOCAL_FILE_SERVICE_IDENTIFIER, set( ( hash, ) ) ) ] )
self.pub( 'content_updates_gui', [ CC.ContentUpdate( CC.CONTENT_UPDATE_ARCHIVE, CC.LOCAL_FILE_SERVICE_IDENTIFIER, set( ( hash, ) ) ) ] )
self.pub( 'content_updates_data', [ HC.ContentUpdate( CC.CONTENT_UPDATE_ARCHIVE, CC.LOCAL_FILE_SERVICE_IDENTIFIER, set( ( hash, ) ) ) ] )
self.pub( 'content_updates_gui', [ HC.ContentUpdate( CC.CONTENT_UPDATE_ARCHIVE, CC.LOCAL_FILE_SERVICE_IDENTIFIER, set( ( hash, ) ) ) ] )
can_add = False
@ -3249,7 +3251,7 @@ class ServiceDB( FileDB, MessageDB, TagDB, RatingDB ):
if service_identifier == CC.LOCAL_TAG_SERVICE_IDENTIFIER: edit_log = [ ( CC.CONTENT_UPDATE_ADD, tag ) for tag in tags ]
else: edit_log = [ ( CC.CONTENT_UPDATE_PENDING, tag ) for tag in tags ]
content_updates = [ CC.ContentUpdate( CC.CONTENT_UPDATE_EDIT_LOG, service_identifier, ( hash, ), edit_log ) ]
content_updates = [ HC.ContentUpdate( CC.CONTENT_UPDATE_EDIT_LOG, service_identifier, ( hash, ), edit_log ) ]
self._ProcessContentUpdates( c, content_updates )
@ -3274,20 +3276,13 @@ class ServiceDB( FileDB, MessageDB, TagDB, RatingDB ):
try:
( result, hash, media_result ) = self._ImportFile( c, file, advanced_import_options = advanced_import_options, service_identifiers_to_tags = service_identifiers_to_tags, generate_media_result = True )
if url is not None:
hash_id = self._GetHashId( c, hash )
c.execute( 'INSERT OR IGNORE INTO urls ( url, hash_id ) VALUES ( ?, ? );', ( url, hash_id ) )
( result, hash, media_result ) = self._ImportFile( c, file, advanced_import_options = advanced_import_options, service_identifiers_to_tags = service_identifiers_to_tags, generate_media_result = True, url = url )
if media_result is not None: self.pub( 'add_media_result', page_key, media_result )
if result == 'successful':
self.pub( 'content_updates_data', [ CC.ContentUpdate( CC.CONTENT_UPDATE_ADD, CC.LOCAL_FILE_SERVICE_IDENTIFIER, ( hash, ) ) ] )
self.pub( 'content_updates_gui', [ CC.ContentUpdate( CC.CONTENT_UPDATE_ADD, CC.LOCAL_FILE_SERVICE_IDENTIFIER, ( hash, ) ) ] )
self.pub( 'content_updates_data', [ HC.ContentUpdate( CC.CONTENT_UPDATE_ADD, CC.LOCAL_FILE_SERVICE_IDENTIFIER, ( hash, ) ) ] )
self.pub( 'content_updates_gui', [ HC.ContentUpdate( CC.CONTENT_UPDATE_ADD, CC.LOCAL_FILE_SERVICE_IDENTIFIER, ( hash, ) ) ] )
self.pub( 'import_done', page_key, result )
@ -3328,8 +3323,8 @@ class ServiceDB( FileDB, MessageDB, TagDB, RatingDB ):
c.executemany( 'INSERT OR IGNORE INTO file_petitions ( service_id, hash_id, reason_id ) VALUES ( ?, ?, ? );', [ ( service_id, hash_id, reason_id ) for hash_id in hash_ids ] )
self.pub( 'notify_new_pending' )
self.pub( 'content_updates_data', [ CC.ContentUpdate( CC.CONTENT_UPDATE_PETITION, service_identifier, hashes ) ] )
self.pub( 'content_updates_gui', [ CC.ContentUpdate( CC.CONTENT_UPDATE_PETITION, service_identifier, hashes ) ] )
self.pub( 'content_updates_data', [ HC.ContentUpdate( CC.CONTENT_UPDATE_PETITION, service_identifier, hashes ) ] )
self.pub( 'content_updates_gui', [ HC.ContentUpdate( CC.CONTENT_UPDATE_PETITION, service_identifier, hashes ) ] )
def _ProcessContentUpdates( self, c, content_updates ):
@ -4179,8 +4174,8 @@ class ServiceDB( FileDB, MessageDB, TagDB, RatingDB ):
content_updates = []
content_updates += [ CC.ContentUpdate( CC.CONTENT_UPDATE_ADD, service_identifier, self._GetHashes( c, hash_ids ), info = self._GetNamespaceTag( c, namespace_id, tag_id ) ) for ( namespace_id, tag_id, hash_ids ) in mappings_ids ]
content_updates += [ CC.ContentUpdate( CC.CONTENT_UPDATE_DELETE, service_identifier, self._GetHashes( c, hash_ids ), info = self._GetNamespaceTag( c, namespace_id, tag_id ) ) for ( namespace_id, tag_id, hash_ids ) in deleted_mappings_ids ]
content_updates += [ HC.ContentUpdate( CC.CONTENT_UPDATE_ADD, service_identifier, self._GetHashes( c, hash_ids ), info = self._GetNamespaceTag( c, namespace_id, tag_id ) ) for ( namespace_id, tag_id, hash_ids ) in mappings_ids ]
content_updates += [ HC.ContentUpdate( CC.CONTENT_UPDATE_DELETE, service_identifier, self._GetHashes( c, hash_ids ), info = self._GetNamespaceTag( c, namespace_id, tag_id ) ) for ( namespace_id, tag_id, hash_ids ) in deleted_mappings_ids ]
HC.pubsub.pub( 'progress_update', job_key, 6, 7, u'saving changes to gui' )
@ -4249,8 +4244,8 @@ class ServiceDB( FileDB, MessageDB, TagDB, RatingDB ):
HC.pubsub.pub( 'progress_update', job_key, num_uploads + 2, num_uploads + 4, u'saving changes to gui' )
if len( good_hash_ids ) > 0:
self.pub( 'content_updates_data', [ CC.ContentUpdate( CC.CONTENT_UPDATE_ADD, service_identifier, self._GetHashes( c, good_hash_ids ) ) ] )
self.pub( 'content_updates_gui', [ CC.ContentUpdate( CC.CONTENT_UPDATE_ADD, service_identifier, self._GetHashes( c, good_hash_ids ) ) ] )
self.pub( 'content_updates_data', [ HC.ContentUpdate( CC.CONTENT_UPDATE_ADD, service_identifier, self._GetHashes( c, good_hash_ids ) ) ] )
self.pub( 'content_updates_gui', [ HC.ContentUpdate( CC.CONTENT_UPDATE_ADD, service_identifier, self._GetHashes( c, good_hash_ids ) ) ] )
if num_petitions > 0:
@ -4267,8 +4262,8 @@ class ServiceDB( FileDB, MessageDB, TagDB, RatingDB ):
self._DeleteFiles( c, service_id, hash_ids )
self.pub( 'content_updates_data', [ CC.ContentUpdate( CC.CONTENT_UPDATE_DELETE, service_identifier, self._GetHashes( c, hash_ids ) ) ] )
self.pub( 'content_updates_gui', [ CC.ContentUpdate( CC.CONTENT_UPDATE_DELETE, service_identifier, self._GetHashes( c, hash_ids ) ) ] )
self.pub( 'content_updates_data', [ HC.ContentUpdate( CC.CONTENT_UPDATE_DELETE, service_identifier, self._GetHashes( c, hash_ids ) ) ] )
self.pub( 'content_updates_gui', [ HC.ContentUpdate( CC.CONTENT_UPDATE_DELETE, service_identifier, self._GetHashes( c, hash_ids ) ) ] )
except Exception as e: raise Exception( 'Encountered an error while trying to uploads petitions to '+ service_name + ':' + os.linesep + unicode( e ) )
@ -4316,6 +4311,12 @@ class DB( ServiceDB ):
if not os.path.exists( temp_dir ): os.mkdir( temp_dir )
except: pass
# clean up if last connection closed badly
( db, c ) = self._GetDBCursor()
db.close()
# ok should be fine
( db, c ) = self._GetDBCursor()
self._UpdateDB( c )
@ -6014,8 +6015,8 @@ class DB( ServiceDB ):
self.Write( 'import_file', HC.LOW_PRIORITY, file )
HC.pubsub.pub( 'content_updates_data', [ CC.ContentUpdate( CC.CONTENT_UPDATE_ADD, CC.LOCAL_FILE_SERVICE_IDENTIFIER, ( hash, ) ) ] )
HC.pubsub.pub( 'content_updates_gui', [ CC.ContentUpdate( CC.CONTENT_UPDATE_ADD, CC.LOCAL_FILE_SERVICE_IDENTIFIER, ( hash, ) ) ] )
HC.pubsub.pub( 'content_updates_data', [ HC.ContentUpdate( CC.CONTENT_UPDATE_ADD, CC.LOCAL_FILE_SERVICE_IDENTIFIER, ( hash, ) ) ] )
HC.pubsub.pub( 'content_updates_gui', [ HC.ContentUpdate( CC.CONTENT_UPDATE_ADD, CC.LOCAL_FILE_SERVICE_IDENTIFIER, ( hash, ) ) ] )
self.pub( 'log_message', 'download files daemon', 'downloaded ' + hash.encode( 'hex' ) + ' from ' + file_repository.GetServiceIdentifier().GetName() )

View File

@ -94,14 +94,14 @@ class FrameGUI( ClientGUICommon.Frame ):
HC.pubsub.sub( self, 'SetInboxStatus', 'inbox_status' )
HC.pubsub.sub( self, 'SetServiceStatus', 'service_status' )
self._NewPageQuery( CC.LOCAL_FILE_SERVICE_IDENTIFIER )
self.RefreshMenuBar()
self._RefreshStatusBar()
self.Show( True )
wx.CallAfter( self._NewPageQuery, CC.LOCAL_FILE_SERVICE_IDENTIFIER )
def _THREADUploadPending( self, service_identifier, job_key, cancel_event ):
@ -156,8 +156,8 @@ class FrameGUI( ClientGUICommon.Frame ):
content_updates = []
content_updates += [ CC.ContentUpdate( CC.CONTENT_UPDATE_ADD, service_identifier, hashes, info = tag ) for ( tag, hashes ) in mappings_object ]
content_updates += [ CC.ContentUpdate( CC.CONTENT_UPDATE_DELETE, service_identifier, hashes, info = tag ) for ( reason, tag, hashes ) in petitions_object ]
content_updates += [ HC.ContentUpdate( CC.CONTENT_UPDATE_ADD, service_identifier, hashes, info = tag ) for ( tag, hashes ) in mappings_object ]
content_updates += [ HC.ContentUpdate( CC.CONTENT_UPDATE_DELETE, service_identifier, hashes, info = tag ) for ( reason, tag, hashes ) in petitions_object ]
wx.GetApp().Write( 'content_updates', content_updates )
@ -224,8 +224,8 @@ class FrameGUI( ClientGUICommon.Frame ):
content_updates = []
content_updates.append( CC.ContentUpdate( CC.CONTENT_UPDATE_ADD, service_identifier, good_hashes ) )
content_updates.append( CC.ContentUpdate( CC.CONTENT_UPDATE_DELETE, service_identifier, petitions_object.GetHashes() ) )
content_updates.append( HC.ContentUpdate( CC.CONTENT_UPDATE_ADD, service_identifier, good_hashes ) )
content_updates.append( HC.ContentUpdate( CC.CONTENT_UPDATE_DELETE, service_identifier, petitions_object.GetHashes() ) )
wx.GetApp().Write( 'content_updates', content_updates )
@ -811,7 +811,7 @@ class FrameGUI( ClientGUICommon.Frame ):
self._notebook.AddPage( new_page, 'files', select = True )
new_page.SetSearchFocus()
wx.CallAfter( new_page.SetSearchFocus )

View File

@ -457,287 +457,6 @@ class Canvas():
class CanvasRatingsFilterPanel( Canvas, wx.Window ):
def __init__( self, parent ):
wx.Window.__init__( self, parent, style = wx.SIMPLE_BORDER | wx.WANTS_CHARS )
Canvas.__init__( self, CC.LOCAL_FILE_SERVICE_IDENTIFIER, wx.GetApp().GetFullscreenImageCache() )
wx.CallAfter( self.Refresh )
self.Bind( wx.EVT_MOTION, self.EventDrag )
self.Bind( wx.EVT_LEFT_DOWN, self.EventDragBegin )
self.Bind( wx.EVT_RIGHT_DOWN, self.GetParent().GetParent().EventMouseDown )
self.Bind( wx.EVT_MIDDLE_DOWN, self.GetParent().GetParent().EventMouseDown )
self.Bind( wx.EVT_LEFT_UP, self.EventDragEnd )
self.Bind( wx.EVT_MOUSEWHEEL, self.EventMouseWheel )
self.Bind( wx.EVT_KEY_DOWN, self.EventKeyDown )
self._timer_media_info_display = wx.Timer( self, id = ID_TIMER_MEDIA_INFO_DISPLAY )
self.Bind( wx.EVT_TIMER, self.EventTimerMediaInfoDisplay, id = ID_TIMER_MEDIA_INFO_DISPLAY )
self.Bind( wx.EVT_MENU, self.EventMenu )
def _ZoomIn( self ):
if self._current_media is not None:
if self._current_media.GetMime() == HC.APPLICATION_PDF: return
for zoom in ZOOMINS:
if self._current_zoom < zoom:
if self._current_media.GetMime() in ( HC.APPLICATION_FLASH, HC.VIDEO_FLV ):
# because of the event passing under mouse, we want to preserve whitespace around flash
( original_width, original_height ) = self._current_display_media.GetResolution()
( my_width, my_height ) = self.GetClientSize()
new_media_width = int( round( original_width * zoom ) )
new_media_height = int( round( original_height * zoom ) )
if new_media_width >= my_width or new_media_height >= my_height: return
with wx.FrozenWindow( self ):
( drag_x, drag_y ) = self._total_drag_delta
zoom_ratio = zoom / self._current_zoom
self._total_drag_delta = ( int( drag_x * zoom_ratio ), int( drag_y * zoom_ratio ) )
self._current_zoom = zoom
self._DrawBackgroundBitmap()
self._DrawCurrentMedia()
break
def _ZoomOut( self ):
if self._current_media is not None:
for zoom in ZOOMOUTS:
if self._current_zoom > zoom:
with wx.FrozenWindow( self ):
( drag_x, drag_y ) = self._total_drag_delta
zoom_ratio = zoom / self._current_zoom
self._total_drag_delta = ( int( drag_x * zoom_ratio ), int( drag_y * zoom_ratio ) )
self._current_zoom = zoom
self._DrawBackgroundBitmap()
self._DrawCurrentMedia()
break
def _ZoomSwitch( self ):
( my_width, my_height ) = self.GetClientSize()
( media_width, media_height ) = self._current_display_media.GetResolution()
if self._current_media.GetMime() == HC.APPLICATION_PDF: return
if self._current_media.GetMime() not in ( HC.APPLICATION_FLASH, HC.VIDEO_FLV ) or self._current_zoom > 1.0 or ( media_width < my_width and media_height < my_height ):
new_zoom = self._current_zoom
if self._current_zoom == 1.0:
if media_width > my_width or media_height > my_height:
width_zoom = my_width / float( media_width )
height_zoom = my_height / float( media_height )
new_zoom = min( ( width_zoom, height_zoom ) )
else: new_zoom = 1.0
if new_zoom != self._current_zoom:
( drag_x, drag_y ) = self._total_drag_delta
zoom_ratio = new_zoom / self._current_zoom
self._total_drag_delta = ( int( drag_x * zoom_ratio ), int( drag_y * zoom_ratio ) )
self._current_zoom = new_zoom
self._DrawBackgroundBitmap()
self._DrawCurrentMedia()
def EventDrag( self, event ):
if wx.Window.FindFocus() != self: self.SetFocus()
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 )
try: self.WarpPointer( old_x, old_y )
except: self._last_drag_coordinates = ( x, 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._DrawCurrentMedia()
self.SetCursor( wx.StockCursor( wx.CURSOR_ARROW ) )
self._timer_media_info_display.Start( 800, wx.TIMER_ONE_SHOT )
def EventDragBegin( self, event ):
if event.ShiftDown():
( x, y ) = event.GetPosition()
( client_x, client_y ) = self.GetClientSize()
if x < 20 or x > client_x - 20 or y < 20 or y > client_y -20:
try:
better_x = x
better_y = y
if x < 20: better_x = 20
if y < 20: better_y = 20
if x > client_x - 20: better_x = client_x - 20
if y > client_y - 20: better_y = client_y - 20
self.WarpPointer( better_x, better_y )
x = better_x
y = better_y
except: pass
self._last_drag_coordinates = ( x, y )
else: self.GetParent().GetParent().ProcessEvent( event )
def EventDragEnd( self, event ):
self._last_drag_coordinates = None
event.Skip()
def EventKeyDown( self, event ):
if self._ShouldSkipInputDueToFlash(): event.Skip()
else:
keys_i_want_to_bump_up_regardless = [ wx.WXK_SPACE, wx.WXK_UP, wx.WXK_NUMPAD_UP, wx.WXK_DOWN, wx.WXK_NUMPAD_DOWN, wx.WXK_LEFT, wx.WXK_NUMPAD_LEFT, wx.WXK_RIGHT, wx.WXK_NUMPAD_RIGHT, wx.WXK_BACK, wx.WXK_RETURN, wx.WXK_NUMPAD_ENTER, wx.WXK_ESCAPE ]
( modifier, key ) = HC.GetShortcutFromEvent( event )
key_dict = self._options[ 'shortcuts' ][ modifier ]
if event.KeyCode not in keys_i_want_to_bump_up_regardless and key in key_dict:
action = key_dict[ key ]
self.ProcessEvent( wx.CommandEvent( commandType = wx.wxEVT_COMMAND_MENU_SELECTED, winid = CC.MENU_EVENT_ID_TO_ACTION_CACHE.GetId( action ) ) )
else:
if event.KeyCode in ( ord( '+' ), wx.WXK_ADD, wx.WXK_NUMPAD_ADD ): self._ZoomIn()
elif event.KeyCode in ( ord( '-' ), wx.WXK_SUBTRACT, wx.WXK_NUMPAD_SUBTRACT ): self._ZoomOut()
elif event.KeyCode == ord( 'Z' ): self._ZoomSwitch()
else: self.GetParent().ProcessEvent( event )
def EventMenu( self, event ):
if self._ShouldSkipInputDueToFlash(): event.Skip()
else:
action = CC.MENU_EVENT_ID_TO_ACTION_CACHE.GetAction( event.GetId() )
if action is not None:
try:
( command, data ) = action
if command == 'frame_back': self._ChangeFrame( -1 )
elif command == 'frame_next': self._ChangeFrame( 1 )
elif command == 'manage_ratings': self._ManageRatings()
elif command == 'manage_tags': self._ManageTags()
elif command == 'zoom_in': self._ZoomIn()
elif command == 'zoom_out': self._ZoomOut()
else: event.Skip()
except Exception as e:
wx.MessageBox( unicode( e ) )
def EventMouseWheel( self, event ):
if self._ShouldSkipInputDueToFlash(): event.Skip()
else:
if event.CmdDown():
if event.GetWheelRotation() > 0: self._ZoomIn()
else: self._ZoomOut()
def EventTimerMediaInfoDisplay( self, event ): self.SetCursor( wx.StockCursor( wx.CURSOR_BLANK ) )
def RefreshBackground( self ): self._DrawBackgroundBitmap()
class CanvasPanel( Canvas, wx.Window ):
def __init__( self, parent, page_key, file_service_identifier ):
@ -1233,7 +952,7 @@ class CanvasFullscreenMediaListBrowser( CanvasFullscreenMediaList ):
else: self.SetMedia( self._GetMedia( { first_hash } )[0] )
def _Archive( self ): wx.GetApp().Write( 'content_updates', [ CC.ContentUpdate( CC.CONTENT_UPDATE_ARCHIVE, CC.LOCAL_FILE_SERVICE_IDENTIFIER, ( self._current_media.GetHash(), ) ) ] )
def _Archive( self ): wx.GetApp().Write( 'content_updates', [ HC.ContentUpdate( CC.CONTENT_UPDATE_ARCHIVE, CC.LOCAL_FILE_SERVICE_IDENTIFIER, ( self._current_media.GetHash(), ) ) ] )
def _CopyLocalUrlToClipboard( self ):
@ -1265,13 +984,13 @@ class CanvasFullscreenMediaListBrowser( CanvasFullscreenMediaList ):
with ClientGUIDialogs.DialogYesNo( self, 'Delete this file from the database?' ) as dlg:
if dlg.ShowModal() == wx.ID_YES: wx.GetApp().Write( 'content_updates', [ CC.ContentUpdate( CC.CONTENT_UPDATE_DELETE, CC.LOCAL_FILE_SERVICE_IDENTIFIER, ( self._current_media.GetHash(), ) ) ] )
if dlg.ShowModal() == wx.ID_YES: wx.GetApp().Write( 'content_updates', [ HC.ContentUpdate( CC.CONTENT_UPDATE_DELETE, CC.LOCAL_FILE_SERVICE_IDENTIFIER, ( self._current_media.GetHash(), ) ) ] )
self.SetFocus() # annoying bug because of the modal dialog
def _Inbox( self ): wx.GetApp().Write( 'content_updates', [ CC.ContentUpdate( CC.CONTENT_UPDATE_INBOX, CC.LOCAL_FILE_SERVICE_IDENTIFIER, ( self._current_media.GetHash(), ) ) ] )
def _Inbox( self ): wx.GetApp().Write( 'content_updates', [ HC.ContentUpdate( CC.CONTENT_UPDATE_INBOX, CC.LOCAL_FILE_SERVICE_IDENTIFIER, ( self._current_media.GetHash(), ) ) ] )
def _PausePlaySlideshow( self ):
@ -1479,7 +1198,7 @@ class CanvasFullscreenMediaListCustomFilter( CanvasFullscreenMediaList ):
self.SetMedia( self._GetFirst() )
def _Archive( self ): wx.GetApp().Write( 'content_updates', [ CC.ContentUpdate( CC.CONTENT_UPDATE_ARCHIVE, CC.LOCAL_FILE_SERVICE_IDENTIFIER, ( self._current_media.GetHash(), ) ) ] )
def _Archive( self ): wx.GetApp().Write( 'content_updates', [ HC.ContentUpdate( CC.CONTENT_UPDATE_ARCHIVE, CC.LOCAL_FILE_SERVICE_IDENTIFIER, ( self._current_media.GetHash(), ) ) ] )
def _CopyLocalUrlToClipboard( self ):
@ -1511,13 +1230,13 @@ class CanvasFullscreenMediaListCustomFilter( CanvasFullscreenMediaList ):
with ClientGUIDialogs.DialogYesNo( self, 'Delete this file from the database?' ) as dlg:
if dlg.ShowModal() == wx.ID_YES: wx.GetApp().Write( 'content_updates', [ CC.ContentUpdate( CC.CONTENT_UPDATE_DELETE, CC.LOCAL_FILE_SERVICE_IDENTIFIER, ( self._current_media.GetHash(), ) ) ] )
if dlg.ShowModal() == wx.ID_YES: wx.GetApp().Write( 'content_updates', [ HC.ContentUpdate( CC.CONTENT_UPDATE_DELETE, CC.LOCAL_FILE_SERVICE_IDENTIFIER, ( self._current_media.GetHash(), ) ) ] )
self.SetFocus() # annoying bug because of the modal dialog
def _Inbox( self ): wx.GetApp().Write( 'content_updates', [ CC.ContentUpdate( CC.CONTENT_UPDATE_INBOX, CC.LOCAL_FILE_SERVICE_IDENTIFIER, ( self._current_media.GetHash(), ) ) ] )
def _Inbox( self ): wx.GetApp().Write( 'content_updates', [ HC.ContentUpdate( CC.CONTENT_UPDATE_INBOX, CC.LOCAL_FILE_SERVICE_IDENTIFIER, ( self._current_media.GetHash(), ) ) ] )
def EventKeyDown( self, event ):
@ -1584,11 +1303,11 @@ class CanvasFullscreenMediaListCustomFilter( CanvasFullscreenMediaList ):
content_update = CC.ContentUpdate( CC.CONTENT_UPDATE_EDIT_LOG, service_identifier, ( self._current_media.GetHash(), ), info = edit_log )
content_update = HC.ContentUpdate( CC.CONTENT_UPDATE_EDIT_LOG, service_identifier, ( self._current_media.GetHash(), ), info = edit_log )
elif service_type in ( HC.LOCAL_RATING_LIKE, HC.LOCAL_RATING_NUMERICAL ):
content_update = CC.ContentUpdate( CC.CONTENT_UPDATE_RATING, service_identifier, ( self._current_media.GetHash(), ), info = action )
content_update = HC.ContentUpdate( CC.CONTENT_UPDATE_RATING, service_identifier, ( self._current_media.GetHash(), ), info = action )
wx.GetApp().Write( 'content_updates', ( content_update, ) )
@ -1798,8 +1517,8 @@ class CanvasFullscreenMediaListFilter( CanvasFullscreenMediaList ):
content_updates = []
content_updates.append( CC.ContentUpdate( CC.CONTENT_UPDATE_DELETE, CC.LOCAL_FILE_SERVICE_IDENTIFIER, self._deleted_hashes ) )
content_updates.append( CC.ContentUpdate( CC.CONTENT_UPDATE_ARCHIVE, CC.LOCAL_FILE_SERVICE_IDENTIFIER, self._kept_hashes ) )
content_updates.append( HC.ContentUpdate( CC.CONTENT_UPDATE_DELETE, CC.LOCAL_FILE_SERVICE_IDENTIFIER, self._deleted_hashes ) )
content_updates.append( HC.ContentUpdate( CC.CONTENT_UPDATE_ARCHIVE, CC.LOCAL_FILE_SERVICE_IDENTIFIER, self._kept_hashes ) )
wx.GetApp().Write( 'content_updates', content_updates )
@ -2029,8 +1748,8 @@ class RatingsFilterFrame( ClientGUICommon.Frame ):
wx.GetApp().SetTopWindow( self )
self._left_window = CanvasRatingsFilterPanel( self._splitter )
self._right_window = CanvasRatingsFilterPanel( self._splitter )
self._left_window = self._Panel( self._splitter )
self._right_window = self._Panel( self._splitter )
( my_width, my_height ) = self.GetClientSize()
@ -2506,8 +2225,8 @@ class RatingsFilterFrame( ClientGUICommon.Frame ):
content_updates = []
content_updates.extend( [ CC.ContentUpdate( CC.CONTENT_UPDATE_RATING, self._service_identifier, ( hash, ), info = rating ) for ( hash, rating ) in certain_ratings ] )
content_updates.extend( [ CC.ContentUpdate( CC.CONTENT_UPDATE_RATINGS_FILTER, self._service_identifier, ( hash, ), info = ( min, max ) ) for ( hash, min, max ) in uncertain_ratings ] )
content_updates.extend( [ HC.ContentUpdate( CC.CONTENT_UPDATE_RATING, self._service_identifier, ( hash, ), info = rating ) for ( hash, rating ) in certain_ratings ] )
content_updates.extend( [ HC.ContentUpdate( CC.CONTENT_UPDATE_RATINGS_FILTER, self._service_identifier, ( hash, ), info = ( min, max ) ) for ( hash, min, max ) in uncertain_ratings ] )
wx.GetApp().Write( 'content_updates', content_updates )
@ -2607,6 +2326,287 @@ class RatingsFilterFrame( ClientGUICommon.Frame ):
self._right_window.RefreshBackground()
class _Panel( Canvas, wx.Window ):
def __init__( self, parent ):
wx.Window.__init__( self, parent, style = wx.SIMPLE_BORDER | wx.WANTS_CHARS )
Canvas.__init__( self, CC.LOCAL_FILE_SERVICE_IDENTIFIER, wx.GetApp().GetFullscreenImageCache() )
wx.CallAfter( self.Refresh )
self.Bind( wx.EVT_MOTION, self.EventDrag )
self.Bind( wx.EVT_LEFT_DOWN, self.EventDragBegin )
self.Bind( wx.EVT_RIGHT_DOWN, self.GetParent().GetParent().EventMouseDown )
self.Bind( wx.EVT_MIDDLE_DOWN, self.GetParent().GetParent().EventMouseDown )
self.Bind( wx.EVT_LEFT_UP, self.EventDragEnd )
self.Bind( wx.EVT_MOUSEWHEEL, self.EventMouseWheel )
self.Bind( wx.EVT_KEY_DOWN, self.EventKeyDown )
self._timer_media_info_display = wx.Timer( self, id = ID_TIMER_MEDIA_INFO_DISPLAY )
self.Bind( wx.EVT_TIMER, self.EventTimerMediaInfoDisplay, id = ID_TIMER_MEDIA_INFO_DISPLAY )
self.Bind( wx.EVT_MENU, self.EventMenu )
def _ZoomIn( self ):
if self._current_media is not None:
if self._current_media.GetMime() == HC.APPLICATION_PDF: return
for zoom in ZOOMINS:
if self._current_zoom < zoom:
if self._current_media.GetMime() in ( HC.APPLICATION_FLASH, HC.VIDEO_FLV ):
# because of the event passing under mouse, we want to preserve whitespace around flash
( original_width, original_height ) = self._current_display_media.GetResolution()
( my_width, my_height ) = self.GetClientSize()
new_media_width = int( round( original_width * zoom ) )
new_media_height = int( round( original_height * zoom ) )
if new_media_width >= my_width or new_media_height >= my_height: return
with wx.FrozenWindow( self ):
( drag_x, drag_y ) = self._total_drag_delta
zoom_ratio = zoom / self._current_zoom
self._total_drag_delta = ( int( drag_x * zoom_ratio ), int( drag_y * zoom_ratio ) )
self._current_zoom = zoom
self._DrawBackgroundBitmap()
self._DrawCurrentMedia()
break
def _ZoomOut( self ):
if self._current_media is not None:
for zoom in ZOOMOUTS:
if self._current_zoom > zoom:
with wx.FrozenWindow( self ):
( drag_x, drag_y ) = self._total_drag_delta
zoom_ratio = zoom / self._current_zoom
self._total_drag_delta = ( int( drag_x * zoom_ratio ), int( drag_y * zoom_ratio ) )
self._current_zoom = zoom
self._DrawBackgroundBitmap()
self._DrawCurrentMedia()
break
def _ZoomSwitch( self ):
( my_width, my_height ) = self.GetClientSize()
( media_width, media_height ) = self._current_display_media.GetResolution()
if self._current_media.GetMime() == HC.APPLICATION_PDF: return
if self._current_media.GetMime() not in ( HC.APPLICATION_FLASH, HC.VIDEO_FLV ) or self._current_zoom > 1.0 or ( media_width < my_width and media_height < my_height ):
new_zoom = self._current_zoom
if self._current_zoom == 1.0:
if media_width > my_width or media_height > my_height:
width_zoom = my_width / float( media_width )
height_zoom = my_height / float( media_height )
new_zoom = min( ( width_zoom, height_zoom ) )
else: new_zoom = 1.0
if new_zoom != self._current_zoom:
( drag_x, drag_y ) = self._total_drag_delta
zoom_ratio = new_zoom / self._current_zoom
self._total_drag_delta = ( int( drag_x * zoom_ratio ), int( drag_y * zoom_ratio ) )
self._current_zoom = new_zoom
self._DrawBackgroundBitmap()
self._DrawCurrentMedia()
def EventDrag( self, event ):
if wx.Window.FindFocus() != self: self.SetFocus()
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 )
try: self.WarpPointer( old_x, old_y )
except: self._last_drag_coordinates = ( x, 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._DrawCurrentMedia()
self.SetCursor( wx.StockCursor( wx.CURSOR_ARROW ) )
self._timer_media_info_display.Start( 800, wx.TIMER_ONE_SHOT )
def EventDragBegin( self, event ):
if event.ShiftDown():
( x, y ) = event.GetPosition()
( client_x, client_y ) = self.GetClientSize()
if x < 20 or x > client_x - 20 or y < 20 or y > client_y -20:
try:
better_x = x
better_y = y
if x < 20: better_x = 20
if y < 20: better_y = 20
if x > client_x - 20: better_x = client_x - 20
if y > client_y - 20: better_y = client_y - 20
self.WarpPointer( better_x, better_y )
x = better_x
y = better_y
except: pass
self._last_drag_coordinates = ( x, y )
else: self.GetParent().GetParent().ProcessEvent( event )
def EventDragEnd( self, event ):
self._last_drag_coordinates = None
event.Skip()
def EventKeyDown( self, event ):
if self._ShouldSkipInputDueToFlash(): event.Skip()
else:
keys_i_want_to_bump_up_regardless = [ wx.WXK_SPACE, wx.WXK_UP, wx.WXK_NUMPAD_UP, wx.WXK_DOWN, wx.WXK_NUMPAD_DOWN, wx.WXK_LEFT, wx.WXK_NUMPAD_LEFT, wx.WXK_RIGHT, wx.WXK_NUMPAD_RIGHT, wx.WXK_BACK, wx.WXK_RETURN, wx.WXK_NUMPAD_ENTER, wx.WXK_ESCAPE ]
( modifier, key ) = HC.GetShortcutFromEvent( event )
key_dict = self._options[ 'shortcuts' ][ modifier ]
if event.KeyCode not in keys_i_want_to_bump_up_regardless and key in key_dict:
action = key_dict[ key ]
self.ProcessEvent( wx.CommandEvent( commandType = wx.wxEVT_COMMAND_MENU_SELECTED, winid = CC.MENU_EVENT_ID_TO_ACTION_CACHE.GetId( action ) ) )
else:
if event.KeyCode in ( ord( '+' ), wx.WXK_ADD, wx.WXK_NUMPAD_ADD ): self._ZoomIn()
elif event.KeyCode in ( ord( '-' ), wx.WXK_SUBTRACT, wx.WXK_NUMPAD_SUBTRACT ): self._ZoomOut()
elif event.KeyCode == ord( 'Z' ): self._ZoomSwitch()
else: self.GetParent().ProcessEvent( event )
def EventMenu( self, event ):
if self._ShouldSkipInputDueToFlash(): event.Skip()
else:
action = CC.MENU_EVENT_ID_TO_ACTION_CACHE.GetAction( event.GetId() )
if action is not None:
try:
( command, data ) = action
if command == 'frame_back': self._ChangeFrame( -1 )
elif command == 'frame_next': self._ChangeFrame( 1 )
elif command == 'manage_ratings': self._ManageRatings()
elif command == 'manage_tags': self._ManageTags()
elif command == 'zoom_in': self._ZoomIn()
elif command == 'zoom_out': self._ZoomOut()
else: event.Skip()
except Exception as e:
wx.MessageBox( unicode( e ) )
def EventMouseWheel( self, event ):
if self._ShouldSkipInputDueToFlash(): event.Skip()
else:
if event.CmdDown():
if event.GetWheelRotation() > 0: self._ZoomIn()
else: self._ZoomOut()
def EventTimerMediaInfoDisplay( self, event ): self.SetCursor( wx.StockCursor( wx.CURSOR_BLANK ) )
def RefreshBackground( self ): self._DrawBackgroundBitmap()
class Image( wx.Window ):
def __init__( self, parent, media, image_cache, initial_size, initial_position ):

View File

@ -83,14 +83,21 @@ class AutoCompleteDropdown( wx.TextCtrl ):
wx.TextCtrl.__init__( self, parent, style=wx.TE_PROCESS_ENTER )
self._dropdown_window = wx.PopupWindow( self, flags = wx.BORDER_RAISED )
#self._dropdown_window = wx.PopupWindow( self, flags = wx.BORDER_RAISED )
#self._dropdown_window = wx.PopupTransientWindow( self, style = wx.BORDER_RAISED )
#self._dropdown_window = wx.Window( self, style = wx.BORDER_RAISED )
#self._dropdown_window = wx.Panel( self )
self._dropdown_window = wx.Frame( self.GetTopLevelParent(), 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_list = self._InitDropDownList()
self._first_letters = ''
self._cached_results = self._InitCachedResults()
self._dropdown_list = self._InitDropDownList()
self.Bind( wx.EVT_SET_FOCUS, self.EventSetFocus )
self.Bind( wx.EVT_KILL_FOCUS, self.EventKillFocus )
@ -112,7 +119,7 @@ class AutoCompleteDropdown( wx.TextCtrl ):
tlp.Bind( wx.EVT_MOVE, self.EventMove )
wx.CallAfter( self._UpdateList )
self._initialised = False
def _BroadcastChoice( self, predicate ): pass
@ -130,12 +137,10 @@ class AutoCompleteDropdown( wx.TextCtrl ):
def _ShowDropdownIfFocussed( self ):
if self.GetTopLevelParent().IsActive() and wx.Window.FindFocus() == self and len( self._dropdown_list ) > 0:
if not self._dropdown_window.IsShown() and self.GetTopLevelParent().IsActive() and wx.Window.FindFocus() == self:
( my_width, my_height ) = self.GetSize()
#self._dropdown_list.Show()
self._dropdown_window.Fit()
self._dropdown_window.SetSize( ( my_width, -1 ) )
@ -174,7 +179,10 @@ class AutoCompleteDropdown( wx.TextCtrl ):
def EventKillFocus( self, event ):
self._HideDropdown()
new_window = event.GetWindow()
if new_window == self._dropdown_window or new_window in self._dropdown_window.GetChildren(): pass
else: self._HideDropdown()
event.Skip()
@ -220,14 +228,10 @@ class AutoCompleteDropdown( wx.TextCtrl ):
try:
self._HideDropdown()
try: self._HideDropdown()
except: pass
num_chars = len( self.GetValue() )
if num_chars == 0: lag = 0
elif num_chars == 1: lag = 400
elif num_chars == 2: lag = 250
else: lag = 100
lag = 100
self._move_hide_timer.Start( lag, wx.TIMER_ONE_SHOT )
@ -238,6 +242,13 @@ class AutoCompleteDropdown( wx.TextCtrl ):
def EventSetFocus( self, event ):
if not self._initialised:
self._UpdateList()
self._initialised = True
self._ShowDropdownIfFocussed()
event.Skip()
@ -390,29 +401,6 @@ class AutoCompleteDropdownTags( AutoCompleteDropdown ):
def _InitDropDownList( self ): return TagsBoxActiveOnly( self._dropdown_window, self.BroadcastChoice )
def _ShowDropdownIfFocussed( self ):
# don't know why I have to do this fit and layout rubbish manually here; I guess it is popupwindow screwing up as usual
if wx.Window.FindFocus() == self:
( my_width, my_height ) = self.GetSize()
#if len( self._dropdown_list ) > 0: self._dropdown_list.Show()
#else: self._dropdown_list.Hide()
self._dropdown_window.Fit()
self._dropdown_window.SetSize( ( my_width, -1 ) )
self._dropdown_window.Layout()
self._dropdown_window.SetPosition( self.ClientToScreenXY( -2, my_height - 2 ) )
self._dropdown_window.Show()
def _UpdateList( self ):
matches = self._GenerateMatches()
@ -435,6 +423,8 @@ class AutoCompleteDropdownTags( AutoCompleteDropdown ):
self.PopupMenu( menu )
menu.Destroy()
def EventMenu( self, event ):
@ -505,6 +495,8 @@ class AutoCompleteDropdownTags( AutoCompleteDropdown ):
self.PopupMenu( menu )
menu.Destroy()
class AutoCompleteDropdownTagsRead( AutoCompleteDropdownTags ):
@ -830,7 +822,7 @@ class CheckboxCollect( wx.combo.ComboCtrl ):
all_namespaces = list( all_namespaces )
all_namespaces.sort()
popup = CheckboxCollectDropdown( all_namespaces )
popup = self._Popup( all_namespaces )
#self.UseAltPopupWindow( True )
@ -861,72 +853,74 @@ class CheckboxCollect( wx.combo.ComboCtrl ):
HC.pubsub.pub( 'collect_media', self._page_key, self._collect_by )
class CheckboxCollectDropdown( wx.combo.ComboPopup ):
def __init__( self, namespaces ):
class _Popup( wx.combo.ComboPopup ):
wx.combo.ComboPopup.__init__( self )
self._namespaces = namespaces
def Create( self, parent ):
self._control = CheckboxCollectDropdownCheckListBox( parent, self.GetCombo(), self._namespaces )
return True
def GetAdjustedSize( self, preferred_width, preferred_height, max_height ):
return( ( preferred_width, -1 ) )
def GetControl( self ): return self._control
class CheckboxCollectDropdownCheckListBox( wx.CheckListBox ):
def __init__( self, parent, special_parent, namespaces ):
wx.CheckListBox.__init__( self, parent, choices = namespaces )
self._special_parent = special_parent
options = wx.GetApp().Read( 'options' )
default = options[ 'default_collect' ] # need to reset this to a list of a set in options!
if default is not None: self.SetCheckedStrings( default )
self.Bind( wx.EVT_CHECKLISTBOX, self.EventChanged )
self.Bind( wx.EVT_LEFT_DOWN, self.EventLeftDown )
self.EventChanged( None )
# as inspired by http://trac.wxwidgets.org/attachment/ticket/14413/test_clb_workaround.py
# what a clusterfuck
def EventLeftDown( self, event ):
index = self.HitTest( event.GetPosition() )
if index != wx.NOT_FOUND:
def __init__( self, namespaces ):
self.Check( index, not self.IsChecked( index ) )
wx.combo.ComboPopup.__init__( self )
self.EventChanged( event )
self._namespaces = namespaces
event.Skip()
def Create( self, parent ):
self._control = self._Control( parent, self.GetCombo(), self._namespaces )
return True
def EventChanged( self, event ):
def GetAdjustedSize( self, preferred_width, preferred_height, max_height ):
return( ( preferred_width, -1 ) )
namespaces = self.GetCheckedStrings()
def GetControl( self ): return self._control
self._special_parent.SetNamespaces( namespaces )
class _Control( wx.CheckListBox ):
def __init__( self, parent, special_parent, namespaces ):
wx.CheckListBox.__init__( self, parent, choices = namespaces )
self._special_parent = special_parent
options = wx.GetApp().Read( 'options' )
default = options[ 'default_collect' ] # need to reset this to a list of a set in options!
if default is not None: self.SetCheckedStrings( default )
self.Bind( wx.EVT_CHECKLISTBOX, self.EventChanged )
self.Bind( wx.EVT_LEFT_DOWN, self.EventLeftDown )
self.EventChanged( None )
# as inspired by http://trac.wxwidgets.org/attachment/ticket/14413/test_clb_workaround.py
# what a clusterfuck
def EventLeftDown( self, event ):
index = self.HitTest( event.GetPosition() )
if index != wx.NOT_FOUND:
self.Check( index, not self.IsChecked( index ) )
self.EventChanged( event )
event.Skip()
def EventChanged( self, event ):
namespaces = self.GetCheckedStrings()
self._special_parent.SetNamespaces( namespaces )
class ChoiceCollect( BetterChoice ):
@ -1118,37 +1112,34 @@ class ListBook( wx.Panel ):
def _Select( self, selection ):
with wx.FrozenWindow( self ):
if selection == wx.NOT_FOUND: self._current_name = None
else: self._current_name = self._list_box.GetString( selection )
self._current_panel.Hide()
self._list_box.SetSelection( selection )
if selection == wx.NOT_FOUND: self._current_panel = self._empty_panel
else:
if selection == wx.NOT_FOUND: self._current_name = None
else: self._current_name = self._list_box.GetString( selection )
panel_info = self._list_box.GetClientData( selection )
self._current_panel.Hide()
if type( panel_info ) == tuple:
( classname, args, kwargs ) = panel_info
page = classname( *args, **kwargs )
page.Hide()
self._panel_sizer.AddF( page, FLAGS_EXPAND_SIZER_BOTH_WAYS )
self._list_box.SetClientData( selection, page )
self._RecalcListBoxWidth()
self._list_box.SetSelection( selection )
if selection == wx.NOT_FOUND: self._current_panel = self._empty_panel
else:
panel_info = self._list_box.GetClientData( selection )
if type( panel_info ) == tuple:
( classname, args, kwargs ) = panel_info
page = classname( *args, **kwargs )
page.Hide()
self._panel_sizer.AddF( page, FLAGS_EXPAND_SIZER_BOTH_WAYS )
self._list_box.SetClientData( selection, page )
self._RecalcListBoxWidth()
self._current_panel = self._list_box.GetClientData( selection )
self._current_panel = self._list_box.GetClientData( selection )
self._current_panel.Show()
@ -1363,165 +1354,6 @@ class ListCtrlAutoWidth( wx.ListCtrl, ListCtrlAutoWidthMixin ):
for index in indices: self.DeleteItem( index )
class OnOffButton( wx.Button ):
def __init__( self, parent, page_key, topic, on_label, off_label = None, start_on = True ):
if start_on: label = on_label
else: label = off_label
wx.Button.__init__( self, parent, label = label )
self._page_key = page_key
self._topic = topic
self._on_label = on_label
if off_label is None: self._off_label = on_label
else: self._off_label = off_label
self._on = start_on
if self._on: self.SetForegroundColour( ( 0, 128, 0 ) )
else: self.SetForegroundColour( ( 128, 0, 0 ) )
self.Bind( wx.EVT_BUTTON, self.EventButton )
HC.pubsub.sub( self, 'HitButton', 'hit_on_off_button' )
def EventButton( self, event ):
if self._on:
self._on = False
self.SetLabel( self._off_label )
self.SetForegroundColour( ( 128, 0, 0 ) )
HC.pubsub.pub( self._topic, self._page_key, False )
else:
self._on = True
self.SetLabel( self._on_label )
self.SetForegroundColour( ( 0, 128, 0 ) )
HC.pubsub.pub( self._topic, self._page_key, True )
def IsOn( self ): return self._on
class NoneableSpinCtrl( wx.Panel ):
def __init__( self, parent, message, value, none_phrase = 'no limit', max = 1000000, multiplier = 1, num_dimensions = 1 ):
wx.Panel.__init__( self, parent )
self._num_dimensions = num_dimensions
self._multiplier = multiplier
self._checkbox = wx.CheckBox( self, label = none_phrase )
self._checkbox.Bind( wx.EVT_CHECKBOX, self.EventCheckBox )
if value is None:
self._one = wx.SpinCtrl( self, initial = 0, max = max, size = ( 80, -1 ) )
self._one.Disable()
if num_dimensions == 2:
self._two = wx.SpinCtrl( self, initial = 0, max = max, size = ( 80, -1 ) )
self._two.Disable()
self._checkbox.SetValue( True )
else:
if num_dimensions == 2:
( value, value_2 ) = value
self._two = wx.SpinCtrl( self, max = max, size = ( 80, -1 ) )
self._two.SetValue( value_2 / multiplier )
self._one = wx.SpinCtrl( self, max = max, size = ( 80, -1 ) )
self._one.SetValue( value / multiplier )
self._checkbox.SetValue( False )
hbox = wx.BoxSizer( wx.HORIZONTAL )
hbox.AddF( wx.StaticText( self, label=message + ': ' ), FLAGS_MIXED )
hbox.AddF( self._one, FLAGS_MIXED )
if self._num_dimensions == 2:
hbox.AddF( wx.StaticText( self, label = 'x' ), FLAGS_MIXED )
hbox.AddF( self._two, FLAGS_MIXED )
hbox.AddF( self._checkbox, FLAGS_MIXED )
self.SetSizer( hbox )
def EventCheckBox( self, event ):
if self._checkbox.GetValue():
self._one.Disable()
if self._num_dimensions == 2: self._two.Disable()
else:
self._one.Enable()
if self._num_dimensions == 2: self._two.Enable()
def GetValue( self ):
if self._checkbox.GetValue(): return None
else:
if self._num_dimensions == 2: return ( self._one.GetValue() * self._multiplier, self._two.GetValue() * self._multiplier )
else: return self._one.GetValue() * self._multiplier
def SetValue( self, value ):
if value is None:
self._checkbox.SetValue( True )
self._one.Disable()
if self._num_dimensions == 2: self._two.Disable()
else:
self._checkbox.SetValue( False )
self._one.Enable()
if self._num_dimensions == 2: self._two.Enable()
if self._num_dimensions == 2:
( value, y ) = value
self._two.SetValue( y / self._multiplier )
self._one.SetValue( value / self._multiplier )
class ListBox( wx.ScrolledWindow ):
def __init__( self, parent, min_height = 250 ):
@ -1554,9 +1386,12 @@ class ListBox( wx.ScrolledWindow ):
self.Bind( wx.EVT_LEFT_DOWN, self.EventMouseSelect )
self.Bind( wx.EVT_LEFT_DCLICK, self.EventDClick )
self.Bind( wx.EVT_RIGHT_DOWN, self.EventMouseRightClick )
self.Bind( wx.EVT_KEY_DOWN, self.EventKeyDown )
self.Bind( wx.EVT_MENU, self.EventMenu )
def __len__( self ): return len( self._ordered_strings )
@ -1707,6 +1542,61 @@ class ListBox( wx.ScrolledWindow ):
else: event.Skip()
def EventMenu( self, event ):
action = CC.MENU_EVENT_ID_TO_ACTION_CACHE.GetAction( event.GetId() )
if action is not None:
try:
( command, data ) = action
if command == 'copy': HC.pubsub.pub( 'clipboard', 'text', data )
else:
event.Skip()
return # this is about select_up and select_down
except Exception as e:
wx.MessageBox( unicode( e ) )
wx.MessageBox( traceback.format_exc() )
def EventMouseRightClick( self, event ):
index = self._GetIndexUnderMouse( event )
self._Select( index )
if self._current_selected_index is not None:
menu = wx.Menu()
term = self._strings_to_terms[ self._ordered_strings[ self._current_selected_index ] ]
menu.Append( CC.MENU_EVENT_ID_TO_ACTION_CACHE.GetId( 'copy', term ), 'copy ' + term )
if ':' in term:
sub_term = term.split( ':', 1 )[1]
menu.Append( CC.MENU_EVENT_ID_TO_ACTION_CACHE.GetId( 'copy', sub_term ), 'copy ' + sub_term )
self.PopupMenu( menu )
menu.Destroy()
event.Skip()
def EventMouseSelect( self, event ):
index = self._GetIndexUnderMouse( event )
@ -1865,6 +1755,165 @@ class ListBoxMessagesPredicates( ListBoxMessages ):
self._TextsHaveChanged()
class NoneableSpinCtrl( wx.Panel ):
def __init__( self, parent, message, value, none_phrase = 'no limit', max = 1000000, multiplier = 1, num_dimensions = 1 ):
wx.Panel.__init__( self, parent )
self._num_dimensions = num_dimensions
self._multiplier = multiplier
self._checkbox = wx.CheckBox( self, label = none_phrase )
self._checkbox.Bind( wx.EVT_CHECKBOX, self.EventCheckBox )
if value is None:
self._one = wx.SpinCtrl( self, initial = 0, max = max, size = ( 80, -1 ) )
self._one.Disable()
if num_dimensions == 2:
self._two = wx.SpinCtrl( self, initial = 0, max = max, size = ( 80, -1 ) )
self._two.Disable()
self._checkbox.SetValue( True )
else:
if num_dimensions == 2:
( value, value_2 ) = value
self._two = wx.SpinCtrl( self, max = max, size = ( 80, -1 ) )
self._two.SetValue( value_2 / multiplier )
self._one = wx.SpinCtrl( self, max = max, size = ( 80, -1 ) )
self._one.SetValue( value / multiplier )
self._checkbox.SetValue( False )
hbox = wx.BoxSizer( wx.HORIZONTAL )
hbox.AddF( wx.StaticText( self, label=message + ': ' ), FLAGS_MIXED )
hbox.AddF( self._one, FLAGS_MIXED )
if self._num_dimensions == 2:
hbox.AddF( wx.StaticText( self, label = 'x' ), FLAGS_MIXED )
hbox.AddF( self._two, FLAGS_MIXED )
hbox.AddF( self._checkbox, FLAGS_MIXED )
self.SetSizer( hbox )
def EventCheckBox( self, event ):
if self._checkbox.GetValue():
self._one.Disable()
if self._num_dimensions == 2: self._two.Disable()
else:
self._one.Enable()
if self._num_dimensions == 2: self._two.Enable()
def GetValue( self ):
if self._checkbox.GetValue(): return None
else:
if self._num_dimensions == 2: return ( self._one.GetValue() * self._multiplier, self._two.GetValue() * self._multiplier )
else: return self._one.GetValue() * self._multiplier
def SetValue( self, value ):
if value is None:
self._checkbox.SetValue( True )
self._one.Disable()
if self._num_dimensions == 2: self._two.Disable()
else:
self._checkbox.SetValue( False )
self._one.Enable()
if self._num_dimensions == 2: self._two.Enable()
if self._num_dimensions == 2:
( value, y ) = value
self._two.SetValue( y / self._multiplier )
self._one.SetValue( value / self._multiplier )
class OnOffButton( wx.Button ):
def __init__( self, parent, page_key, topic, on_label, off_label = None, start_on = True ):
if start_on: label = on_label
else: label = off_label
wx.Button.__init__( self, parent, label = label )
self._page_key = page_key
self._topic = topic
self._on_label = on_label
if off_label is None: self._off_label = on_label
else: self._off_label = off_label
self._on = start_on
if self._on: self.SetForegroundColour( ( 0, 128, 0 ) )
else: self.SetForegroundColour( ( 128, 0, 0 ) )
self.Bind( wx.EVT_BUTTON, self.EventButton )
HC.pubsub.sub( self, 'HitButton', 'hit_on_off_button' )
def EventButton( self, event ):
if self._on:
self._on = False
self.SetLabel( self._off_label )
self.SetForegroundColour( ( 128, 0, 0 ) )
HC.pubsub.pub( self._topic, self._page_key, False )
else:
self._on = True
self.SetLabel( self._on_label )
self.SetForegroundColour( ( 0, 128, 0 ) )
HC.pubsub.pub( self._topic, self._page_key, True )
def IsOn( self ): return self._on
class SaneListCtrl( wx.ListCtrl, ListCtrlAutoWidthMixin, ColumnSorterMixin ):
def __init__( self, parent, height, columns ):

File diff suppressed because it is too large Load Diff

View File

@ -1061,6 +1061,17 @@ class ManagementPanelDumper( ManagementPanel ):
def TryToClose( self ):
if self._dumping:
with ClientGUIDialogs.DialogYesNo( self, 'This page is still dumping. Are you sure you want to close it?' ) as dlg:
if dlg.ShowModal() == wx.ID_NO: raise Exception()
class ManagementPanelImport( ManagementPanel ):
def __init__( self, parent, page, page_key ):
@ -1280,7 +1291,7 @@ class ManagementPanelImport( ManagementPanel ):
def TryToClose( self ):
if self._currently_processing_import_queue:
if self._currently_processing_import_queue and not self._pause_import:
with ClientGUIDialogs.DialogYesNo( self, 'This page is still importing. Are you sure you want to close it?' ) as dlg:
@ -1604,7 +1615,7 @@ class ManagementPanelImportWithQueueAdvanced( ManagementPanelImportWithQueue ):
edit_log = [ ( action, tag ) for tag in tags_to_add_here ]
content_updates.append( CC.ContentUpdate( CC.CONTENT_UPDATE_EDIT_LOG, service_identifier, ( hash, ), info = edit_log ) )
content_updates.append( HC.ContentUpdate( CC.CONTENT_UPDATE_EDIT_LOG, service_identifier, ( hash, ), info = edit_log ) )
@ -3132,7 +3143,7 @@ class ManagementPanelImportThreadWatcher( ManagementPanelImport ):
def _GetPreprocessStatus( self ):
status = 'reading ' + str( self._import_queue_position + 1 ) + '/' + str( len( self._import_queue ) )
status = 'checking url/hash status ' + str( self._import_queue_position + 1 ) + '/' + str( len( self._import_queue ) )
return status
@ -3364,13 +3375,13 @@ class ManagementPanelPetitions( ManagementPanel ):
hashes = self._current_petition.GetPetitionHashes()
content_updates = [ CC.ContentUpdate( CC.CONTENT_UPDATE_DELETE, self._file_service_identifier, hashes ) ]
content_updates = [ HC.ContentUpdate( CC.CONTENT_UPDATE_DELETE, self._file_service_identifier, hashes ) ]
elif isinstance( self._current_petition, HC.ServerMappingPetition ):
( reason, tag, hashes ) = self._current_petition.GetPetitionInfo()
content_updates = [ CC.ContentUpdate( CC.CONTENT_UPDATE_DELETE, self._file_service_identifier, hashes, tag ) ]
content_updates = [ HC.ContentUpdate( CC.CONTENT_UPDATE_DELETE, self._file_service_identifier, hashes, tag ) ]
wx.GetApp().Write( 'content_updates', content_updates )

View File

@ -97,7 +97,7 @@ class MediaPanel( ClientGUIMixins.ListeningMediaList, wx.ScrolledWindow ):
hashes = self._GetSelectedHashes( CC.DISCRIMINANT_INBOX )
if len( hashes ) > 0: wx.GetApp().Write( 'content_updates', [ CC.ContentUpdate( CC.CONTENT_UPDATE_ARCHIVE, CC.LOCAL_FILE_SERVICE_IDENTIFIER, hashes ) ] )
if len( hashes ) > 0: wx.GetApp().Write( 'content_updates', [ HC.ContentUpdate( CC.CONTENT_UPDATE_ARCHIVE, CC.LOCAL_FILE_SERVICE_IDENTIFIER, hashes ) ] )
def _CopyHashToClipboard( self ):
@ -188,7 +188,7 @@ class MediaPanel( ClientGUIMixins.ListeningMediaList, wx.ScrolledWindow ):
if dlg.ShowModal() == wx.ID_YES:
try: wx.GetApp().Write( 'content_updates', [ CC.ContentUpdate( CC.CONTENT_UPDATE_DELETE, file_service_identifier, hashes ) ] )
try: wx.GetApp().Write( 'content_updates', [ HC.ContentUpdate( CC.CONTENT_UPDATE_DELETE, file_service_identifier, hashes ) ] )
except: wx.MessageBox( traceback.format_exc() )
@ -215,7 +215,7 @@ class MediaPanel( ClientGUIMixins.ListeningMediaList, wx.ScrolledWindow ):
self._SetFocussedMedia( None )
self._shift_focussed_media = None
with wx.FrozenWindow( self ): self._ReblitCanvas()
self._ReblitCanvas()
self._PublishSelectionChange()
@ -376,7 +376,7 @@ class MediaPanel( ClientGUIMixins.ListeningMediaList, wx.ScrolledWindow ):
hashes = self._GetSelectedHashes( CC.DISCRIMINANT_ARCHIVE )
if len( hashes ) > 0: wx.GetApp().Write( 'content_updates', [ CC.ContentUpdate( CC.CONTENT_UPDATE_INBOX, CC.LOCAL_FILE_SERVICE_IDENTIFIER, hashes ) ] )
if len( hashes ) > 0: wx.GetApp().Write( 'content_updates', [ HC.ContentUpdate( CC.CONTENT_UPDATE_INBOX, CC.LOCAL_FILE_SERVICE_IDENTIFIER, hashes ) ] )
def _ManageRatings( self ):
@ -514,12 +514,9 @@ class MediaPanel( ClientGUIMixins.ListeningMediaList, wx.ScrolledWindow ):
self._shift_focussed_media = None
with wx.FrozenWindow( self ):
self._RefitCanvas()
self._ReblitCanvas()
self._RefitCanvas()
self._ReblitCanvas()
self._PublishSelectionChange()
@ -556,7 +553,7 @@ class MediaPanel( ClientGUIMixins.ListeningMediaList, wx.ScrolledWindow ):
self._selected_media = set( self._sorted_media )
with wx.FrozenWindow( self ): self._ReblitCanvas()
self._ReblitCanvas()
self._PublishSelectionChange()
@ -605,7 +602,7 @@ class MediaPanel( ClientGUIMixins.ListeningMediaList, wx.ScrolledWindow ):
self._DeselectAll()
with wx.FrozenWindow( self ): self._RefitCanvas()
self._RefitCanvas()
# no refresh needed since the sort call that always comes after will do it
@ -674,12 +671,9 @@ class MediaPanel( ClientGUIMixins.ListeningMediaList, wx.ScrolledWindow ):
if action in ( CC.SERVICE_UPDATE_DELETE_PENDING, CC.SERVICE_UPDATE_RESET ):
with wx.FrozenWindow( self ):
self._RefitCanvas()
self._ReblitCanvas()
self._RefitCanvas()
self._ReblitCanvas()
self._PublishSelectionChange()
@ -711,7 +705,7 @@ class MediaPanel( ClientGUIMixins.ListeningMediaList, wx.ScrolledWindow ):
ClientGUIMixins.ListeningMediaList.Sort( self, sort_by )
with wx.FrozenWindow( self ): self._ReblitCanvas()
self._ReblitCanvas()
HC.pubsub.pub( 'sorted_media_pulse', self._page_key, self.GenerateMediaResults() )
@ -1043,12 +1037,9 @@ class MediaPanelThumbnails( MediaPanel ):
if old_num_rows != num_rows:
with wx.FrozenWindow( self ):
self._RefitCanvas()
self._ReblitCanvas()
self._RefitCanvas()
self._ReblitCanvas()
self._BlitThumbnail( media )
@ -1157,12 +1148,9 @@ class MediaPanelThumbnails( MediaPanel ):
if self._num_columns != old_numcols:
with wx.FrozenWindow( self ):
self._RefitCanvas()
self._ReblitCanvas()
self._RefitCanvas()
self._ReblitCanvas()
else:
@ -1174,7 +1162,7 @@ class MediaPanelThumbnails( MediaPanel ):
if self._num_rows_in_client_height > old_numclientrows:
with wx.FrozenWindow( self ): self._ReblitCanvas()
self._ReblitCanvas()
@ -1403,20 +1391,23 @@ class MediaPanelThumbnails( MediaPanel ):
if selection_has_local:
if multiple_selected: menu.Append( CC.MENU_EVENT_ID_TO_ACTION_CACHE.GetId( 'filter' ), 'filter' )
if i_can_post_ratings:
if multiple_selected or i_can_post_ratings:
ratings_filter_menu = wx.Menu()
if multiple_selected: menu.Append( CC.MENU_EVENT_ID_TO_ACTION_CACHE.GetId( 'filter' ), 'filter' )
for service in local_ratings_services: ratings_filter_menu.Append( CC.MENU_EVENT_ID_TO_ACTION_CACHE.GetId( 'ratings_filter', service.GetServiceIdentifier() ), service.GetServiceIdentifier().GetName() )
if i_can_post_ratings:
ratings_filter_menu = wx.Menu()
for service in local_ratings_services: ratings_filter_menu.Append( CC.MENU_EVENT_ID_TO_ACTION_CACHE.GetId( 'ratings_filter', service.GetServiceIdentifier() ), service.GetServiceIdentifier().GetName() )
menu.AppendMenu( CC.MENU_EVENT_ID_TO_ACTION_CACHE.GetId( 'ratings_filter' ), 'ratings filter', ratings_filter_menu )
menu.AppendMenu( CC.MENU_EVENT_ID_TO_ACTION_CACHE.GetId( 'ratings_filter' ), 'ratings filter', ratings_filter_menu )
if multiple_selected: menu.Append( CC.MENU_EVENT_ID_TO_ACTION_CACHE.GetId( 'custom_filter' ), 'custom filter' )
menu.AppendSeparator()
if multiple_selected: menu.Append( CC.MENU_EVENT_ID_TO_ACTION_CACHE.GetId( 'custom_filter' ), 'custom filter' )
if multiple_selected or i_can_post_ratings: menu.AppendSeparator()
if selection_has_inbox: menu.Append( CC.MENU_EVENT_ID_TO_ACTION_CACHE.GetId( 'archive' ), archive_phrase )
if selection_has_archive: menu.Append( CC.MENU_EVENT_ID_TO_ACTION_CACHE.GetId( 'inbox' ), inbox_phrase )
@ -1468,12 +1459,9 @@ class MediaPanelThumbnails( MediaPanel ):
if self._last_visible_row < num_rows and current_last_visible_row > int( self._last_visible_row * 0.75 ):
with wx.FrozenWindow( self ):
self._RefitCanvas()
self._ReblitCanvas()
self._RefitCanvas()
self._ReblitCanvas()
event.Skip()
@ -1620,12 +1608,9 @@ class MediaPanelThumbnails( MediaPanel ):
for t in self._sorted_media: t.ReloadFromDBLater()
with wx.FrozenWindow( self ):
self._RefitCanvas()
self._ReblitCanvas()
self._RefitCanvas()
self._ReblitCanvas()
class Selectable():

View File

@ -491,6 +491,8 @@ class MediaCollection( MediaList, Media ):
def GetNumFrames( self ): return sum( [ media.GetNumFrames() for media in self._sorted_media ] )
def GetNumWords( self ): return sum( [ media.GetNumWords() for media in self._sorted_media ] )
def GetPrettyAge( self ): return HC.ConvertTimestampToPrettyAge( self._timestamp )
def GetPrettyInfo( self ):
@ -594,6 +596,8 @@ class MediaSingleton( Media ):
def GetNumFrames( self ): return self._media_result.GetNumFrames()
def GetNumWords( self ): return self._media_result.GetNumWords()
def GetTimestamp( self ):
timestamp = self._media_result.GetTimestamp()
@ -616,6 +620,8 @@ class MediaSingleton( Media ):
if num_frames is not None: info_string += ' (' + HC.ConvertIntToPrettyString( num_frames ) + ' frames)'
if num_words is not None: info_string += ' (' + HC.ConvertIntToPrettyString( num_words ) + ' words)'
return info_string

View File

@ -30,7 +30,7 @@ TEMP_DIR = BASE_DIR + os.path.sep + 'temp'
# Misc
NETWORK_VERSION = 9
SOFTWARE_VERSION = 61
SOFTWARE_VERSION = 62
UNSCALED_THUMBNAIL_DIMENSIONS = ( 200, 200 )
@ -1253,6 +1253,24 @@ class ClientServiceIdentifier( HydrusYAMLBase ):
def GetType( self ): return self._type
class ContentUpdate():
def __init__( self, action, service_identifier, hashes, info = None ):
self._action = action
self._service_identifier = service_identifier
self._hashes = set( hashes )
self._info = info
def GetAction( self ): return self._action
def GetHashes( self ): return self._hashes
def GetInfo( self ): return self._info
def GetServiceIdentifier( self ): return self._service_identifier
class DAEMON( threading.Thread ):
def __init__( self, name, callable, period = 1200 ):

View File

@ -425,7 +425,8 @@ class HydrusHTTPRequestHandler( BaseHTTPServer.BaseHTTPRequestHandler ):
try:
hydrus_client = False
default_mime = HC.TEXT_HTML
default_encoding = lambda x: unicode( x )
user_agent_text = self.headers.getheader( 'User-Agent' )
@ -441,24 +442,23 @@ class HydrusHTTPRequestHandler( BaseHTTPServer.BaseHTTPRequestHandler ):
if client == 'hydrus':
if int( network_version ) == HC.NETWORK_VERSION: hydrus_client = True
else: raise HC.NetworkVersionException( 'Network version mismatch! This repository\'s network version is ' + str( HC.NETWORK_VERSION ) + ' whereas yours is ' + network_version + '! Please download the latest release.' )
default_mime = HC.APPLICATION_YAML
default_encoding = lambda x: yaml.safe_dump( unicode( x ) )
network_version = int( network_version )
if network_version != HC.NETWORK_VERSION:
if network_version < HC.NETWORK_VERSION: message = 'Please download the latest release.'
else: message = 'Please ask this server\'s admin to update to the latest release.'
raise HC.NetworkVersionException( 'Network version mismatch! This server\'s network version is ' + str( HC.NETWORK_VERSION ) + ', whereas your client\'s is ' + str( network_version ) + '! ' + message )
if hydrus_client:
default_mime = HC.APPLICATION_YAML
default_encoding = lambda x: yaml.safe_dump( unicode( x ) )
else:
default_mime = HC.TEXT_HTML
default_encoding = lambda x: unicode( x )
( ip, port ) = self.client_address
service_type = self._service_identifier.GetType()
@ -517,7 +517,7 @@ class HydrusHTTPRequestHandler( BaseHTTPServer.BaseHTTPRequestHandler ):
except KeyError: response_context = HC.ResponseContext( 403, mime = default_mime, body = default_encoding( 'It appears one or more parameters required for that request were missing.' ) )
except HC.PermissionException as e: response_context = HC.ResponseContext( 401, mime = default_mime, body = default_encoding( e ) )
except HC.ForbiddenException as e: response_context = HC.ResponseContext( 403, mime = default_mime, body = default_encoding( e ) )
except HC.NotFoundException as e: response_context = HC.ResponseContext( 404, mime = default_mime, body = default_encoding( e ) )
except HC.NotFoundException as e:response_context = HC.ResponseContext( 404, mime = default_mime, body = default_encoding( e ) )
except HC.NetworkVersionException as e: response_context = HC.ResponseContext( 426, mime = default_mime, body = default_encoding( e ) )
except HC.SessionException as e: response_context = HC.ResponseContext( 403, mime = default_mime, body = default_encoding( 'Session not found!' ) )
except Exception as e: