new updating feed cache dialog following gnome hig guidelines

git-svn-id: svn://svn.berlios.de/gpodder/trunk@265 b0d088ad-0a06-0410-aad2-9ed5178a7e87
This commit is contained in:
Thomas Perl 2007-03-10 15:57:56 +00:00
parent d56aad02bf
commit f180ab24bb
4 changed files with 99 additions and 55 deletions

View File

@ -1,3 +1,18 @@
Sat, 10 Mar 2007 16:52:22 +0100 <thp@perli.net>
* src/gpodder/libpodcasts.py: Support cancelling downloading an RSS
file by supplying a callback_is_cancelled variable that should
return True when the download should be cancelled (and the old,
backed up cache file [if any] be used instead); additionally, get
rid of gtk events_pending code, as we call downloadRss only in
threads as of now
* src/gpodder/libgpodder.py: Support for cancelling the read()
operation of a gPodderChannelReader (uses old cache files instead)
* src/gpodder/gpodder.py: Re-design of the update feed cache dialog
following Gnome HIG guidelines for progress windows and making
use of the update_feed_cache() function (which now is threaded) in
every part of the gpodder window code; also provide the option of
cancelling a running update of the feed cache :)
Fri, 9 Mar 2007 20:05:20 +0100 <thp@perli.net>
* src/gpodder/libgpodder.py: Fix sanitize_feed_url() function
* src/gpodder/gpodder.py: Add support for dialogs to be centered on

View File

@ -153,15 +153,6 @@ class Gpodder(SimpleGladeApp):
self.download_status_manager = downloadStatusManager( main_window = self.gPodder, change_notification = self.updateTreeView)
self.treeDownloads.set_model( self.download_status_manager.getModel())
# read and display subscribed channels
self.active_channel = None
self.channels = []
reader = gPodderChannelReader()
self.channels = reader.read( False)
# update view
self.updateComboBox()
# tooltips :)
self.tooltips = gtk.Tooltips()
self.tooltips.set_tip( self.btnEditChannel, _("Channel Info"))
@ -176,9 +167,10 @@ class Gpodder(SimpleGladeApp):
gl = gPodderLib()
# Update the feed list if the user has set it up
if gl.update_on_startup:
self.update_feed_cache()
# Subscribed channels
self.active_channel = None
self.channels = gPodderChannelReader().read( force_update = False)
self.update_feed_cache( force_update = gl.update_on_startup)
# create a localDB object
self.ldb = localDB()
@ -293,16 +285,13 @@ class Gpodder(SimpleGladeApp):
channels_should_be = len( self.channels)
gPodderChannelWriter().write( self.channels)
self.channels = gPodderChannelReader().read( False)
self.update_feed_cache( force_update = False)
# check if gPodderChannelReader has successfully added the channel
if channels_should_be > len( self.channels):
self.showMessage( _("There has been an error adding the channel.\nMaybe the URL is wrong?"))
def add_new_channel( self, result = None):
# Treat "feed://" URLs like "http://" ones
gl = gPodderLib()
result = gl.sanitize_feed_url( result)
if result:
for old_channel in self.channels:
@ -314,7 +303,6 @@ class Gpodder(SimpleGladeApp):
self.comboAvailable.set_active( i)
return
log( 'Adding new channel: %s', result)
self.statusLabel.set_text( _("Fetching channel index..."))
channel = podcastChannel( url = result)
channel.remove_cache_file()
num_channels_before = len(self.channels)
@ -323,10 +311,6 @@ class Gpodder(SimpleGladeApp):
# download changed channels
self.refetch_channel_list()
# try to update combo box
self.updateComboBox()
self.statusLabel.set_text( "")
if num_channels_before < len(self.channels):
# ask user to download some new episodes
self.comboAvailable.set_active( len( self.channels)-1)
@ -395,39 +379,79 @@ class Gpodder(SimpleGladeApp):
sync.clean_playlist()
sync.close()
def update_feed_cache_callback( self, progressbar, position, count):
try:
progressbar.set_text( _("Updating: %s") % ( self.channels[position].title, ))
except:
progressbar.set_text( _("%d of %d") % ( position, count ))
def update_feed_cache_callback( self, label, progressbar, position, count):
title = _('Please wait...')
if len(self.channels) > position:
title = _('Updating %s') % self.channels[position].title
label.set_markup( '<i>%s</i>' % title)
progressbar.set_text( _('%d of %d channels updated') % ( position, count ))
progressbar.set_fraction( ((1.00*position) / (1.00*count)))
def update_feed_cache(self):
reader = gPodderChannelReader()
please_wait = gtk.Dialog( _("Updating feed cache"), self.gPodder)
please_wait.vbox.set_spacing( 5)
please_wait.set_border_width( 5)
def update_feed_cache_proc( self, reader, force_update, callback_proc, callback_error, finish_proc):
self.channels = reader.read( force_update, callback_proc = callback_proc, callback_error = callback_error)
finish_proc()
def update_feed_cache(self, force_update = True):
title = _('Downloading podcast feeds')
heading = _('Downloading feeds')
body = _('Podcast feeds contain channel metadata and information about current episodes.')
if not force_update:
title = _('Reading podcast feeds')
heading = _('Reading feeds')
please_wait = gtk.Dialog( title, self.gPodder, gtk.DIALOG_MODAL, ( gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, ))
please_wait.set_transient_for( self.gPodder)
please_wait.set_position( gtk.WIN_POS_CENTER_ON_PARENT)
please_wait.vbox.set_spacing( 5)
please_wait.set_border_width( 10)
please_wait.set_resizable( False)
label_heading = gtk.Label()
label_heading.set_alignment( 0.0, 0.5)
label_heading.set_markup( '<span weight="bold" size="larger">%s</span>' % heading)
label_body = gtk.Label()
label_body.set_text( body)
label_body.set_alignment( 0.0, 0.5)
label_body.set_line_wrap( True)
label = gtk.Label( _("Please wait - gPodder is updating its feed cache..."))
myprogressbar = gtk.ProgressBar()
mylabel = gtk.Label()
mylabel.set_alignment( 0.0, 0.5)
mylabel.set_ellipsize( pango.ELLIPSIZE_END)
# put it all together
please_wait.vbox.pack_start( label)
please_wait.vbox.pack_end( myprogressbar)
please_wait.vbox.pack_start( label_heading)
please_wait.vbox.pack_start( label_body)
please_wait.vbox.pack_start( myprogressbar)
please_wait.vbox.pack_end( mylabel)
please_wait.show_all()
# hide action anre and separator line
please_wait.action_area.hide()
# hide separator line
please_wait.set_has_separator( False)
# let's get down to business..
self.channels = reader.read( True, callback_proc = lambda pos, count: self.update_feed_cache_callback( myprogressbar, pos, count), callback_error = lambda x: self.showMessage( x, _('Channel update status')))
please_wait.destroy()
callback_proc = lambda pos, count: gobject.idle_add( self.update_feed_cache_callback, mylabel, myprogressbar, pos, count)
callback_error = lambda x: gobject.idle_add( self.showMessage( x))
finish_proc = lambda: gobject.idle_add( please_wait.destroy)
reader = gPodderChannelReader()
args = ( reader, force_update, callback_proc, callback_error, finish_proc, )
thread = Thread( target = self.update_feed_cache_proc, args = args)
thread.start()
if please_wait.run() == gtk.RESPONSE_CANCEL:
reader.cancel()
please_wait.destroy()
thread.join( 0.5)
self.updateComboBox()
# download all new?
if gPodderLib().download_after_update:
if force_update and gPodderLib().download_after_update:
self.on_itemDownloadAllNew_activate( self.gPodder)
def download_podcast_by_url( self, url, want_message_dialog = True, widget = None):
@ -594,15 +618,8 @@ class Gpodder(SimpleGladeApp):
active = self.comboAvailable.get_active()
if result != self.active_channel.url and result != None and result != "" and (result[:4] == "http" or result[:3] == "ftp"):
log( 'Changing channel #%d from "%s" to "%s"', active, self.active_channel.url, result)
self.statusLabel.set_text( _("Fetching channel index..."))
self.channels = self.channels[0:active] + [ podcastChannel( url = result) ] + self.channels[active+1:]
# fetch new channels
self.refetch_channel_list()
self.updateComboBox()
self.statusLabel.set_text( "")
#-- Gpodder.on_itemEditChannel_activate }
#-- Gpodder.on_itemRemoveChannel_activate {
@ -616,8 +633,7 @@ class Gpodder(SimpleGladeApp):
gPodderLib().clean_up_downloads( delete_partial)
self.channels.remove( self.active_channel)
gPodderChannelWriter().write( self.channels)
self.channels = gPodderChannelReader().read( False)
self.updateComboBox()
self.update_feed_cache( force_update = False)
except:
pass
#-- Gpodder.on_itemRemoveChannel_activate }

View File

@ -473,6 +473,13 @@ class gPodderChannelReader( DefaultHandler):
self.channels = []
self.current_item = None
self.current_element_data = ''
self.is_cancelled = False
def cancel( self):
self.is_cancelled = True
def callback_is_cancelled( self):
return self.is_cancelled
def read( self, force_update = False, callback_proc = None, callback_url = None, callback_error = None):
"""Read channels from a file into gPodder's cache
@ -516,7 +523,7 @@ class gPodderChannelReader( DefaultHandler):
if callback_url:
callback_url( channel.url)
cachefile = channel.downloadRss( force_update, callback_error = callback_error)
cachefile = channel.downloadRss( force_update, callback_error = callback_error, callback_is_cancelled = self.callback_is_cancelled)
# check if download was a success
if cachefile != None:
reader.parseXML( channel.url, cachefile)

View File

@ -249,18 +249,24 @@ class podcastChannel(ListType):
return None
def downloadRss( self, force_update = True, callback_error = None):
def downloadRss( self, force_update = True, callback_error = None, callback_is_cancelled = None):
if callback_is_cancelled:
if callback_is_cancelled() == True:
return self.cache_file
if not exists( self.cache_file) or force_update:
# remove old cache file
self.remove_cache_file()
event = Event()
downloadThread( self.url, self.cache_file, event).download()
download_thread = downloadThread( self.url, self.cache_file, event)
download_thread.download()
while event.isSet() == False:
while not event.isSet():
if callback_is_cancelled:
if callback_is_cancelled() == True:
download_thread.cancel()
self.restore_cache_file()
event.wait( 0.2)
#FIXME: we do not want gtk code when not needed
while gtk.events_pending():
gtk.main_iteration( False)
# check if download was a success
if not exists( self.cache_file):