Merge pull request #1242 from auouymous/pause-resume

Add pausing and resuming from Episodes and context menus, and toolbar.
This commit is contained in:
auouymous 2022-03-15 14:58:00 -07:00 committed by GitHub
commit 91829b82f6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 65 additions and 13 deletions

View File

@ -29,6 +29,21 @@
<object class="GtkToolbar" id="toolbar">
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
<object class="GtkToolButton" id="toolPlay">
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can-focus">False</property>
<property name="is-important">True</property>
<property name="label" translatable="yes">Play</property>
<property name="icon-name">media-playback-start</property>
<signal name="clicked" handler="on_playback_selected_episodes" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<object class="GtkToolButton" id="toolDownload">
<property name="visible">True</property>
@ -45,14 +60,14 @@
</packing>
</child>
<child>
<object class="GtkToolButton" id="toolPlay">
<object class="GtkToolButton" id="toolPause">
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can-focus">False</property>
<property name="is-important">True</property>
<property name="label" translatable="yes">Play</property>
<property name="icon-name">media-playback-start</property>
<signal name="clicked" handler="on_playback_selected_episodes" swapped="no"/>
<property name="label" translatable="yes">Pause</property>
<property name="icon-name">media-playback-pause</property>
<signal name="clicked" handler="on_pause_selected_episodes" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>

View File

@ -116,6 +116,10 @@
<attribute name="action">win.download</attribute>
<attribute name="label" translatable="yes">Download</attribute>
</item>
<item>
<attribute name="action">win.pause</attribute>
<attribute name="label" translatable="yes">Pause</attribute>
</item>
<item>
<attribute name="action">win.cancel</attribute>
<attribute name="label" translatable="yes">Cancel</attribute>

View File

@ -620,6 +620,13 @@ class DownloadTask(object):
# Request pause of a running download
elif self.status == self.DOWNLOADING:
self.status = self.PAUSING
# download rate limited tasks sleep and take longer to transition from the PAUSING state to the PAUSED state
def unpause(self):
with self:
# Resume a downloading task that was transitioning to paused
if self.status == self.PAUSING:
self.status = self.DOWNLOADING
def cancel(self):
with self:

View File

@ -311,6 +311,7 @@ class gPodder(BuilderWidget, dbus.service.Object):
('play', self.on_playback_selected_episodes),
('open', self.on_playback_selected_episodes),
('download', self.on_download_selected_episodes),
('pause', self.on_pause_selected_episodes),
('cancel', self.on_item_cancel_download_activate),
('delete', self.on_btnDownloadedDelete_clicked),
('toggleEpisodeNew', self.on_item_toggle_played_activate),
@ -332,6 +333,7 @@ class gPodder(BuilderWidget, dbus.service.Object):
self.play_action = g.lookup_action('play')
self.open_action = g.lookup_action('open')
self.download_action = g.lookup_action('download')
self.pause_action = g.lookup_action('pause')
self.cancel_action = g.lookup_action('cancel')
self.delete_action = g.lookup_action('delete')
self.toggle_episode_new_action = g.lookup_action('toggleEpisodeNew')
@ -1954,7 +1956,7 @@ class gPodder(BuilderWidget, dbus.service.Object):
menu = Gtk.Menu()
(can_play, can_download, can_cancel, can_delete, open_instead_of_play) = self.play_or_download()
(can_play, can_download, can_pause, can_cancel, can_delete, open_instead_of_play) = self.play_or_download()
if open_instead_of_play:
item = Gtk.ImageMenuItem(_('Open'))
@ -1978,7 +1980,12 @@ class gPodder(BuilderWidget, dbus.service.Object):
item.set_image(Gtk.Image.new_from_icon_name('document-save', Gtk.IconSize.MENU))
item.set_action_name('win.download')
menu.append(item)
elif can_cancel:
if can_pause:
item = Gtk.ImageMenuItem(_('Pause'))
item.set_image(Gtk.Image.new_from_icon_name('media-playback-pause', Gtk.IconSize.MENU))
item.set_action_name('win.pause')
menu.append(item)
if can_cancel:
item = Gtk.ImageMenuItem.new_with_mnemonic(_('_Cancel'))
item.set_action_name('win.cancel')
menu.append(item)
@ -2230,11 +2237,11 @@ class gPodder(BuilderWidget, dbus.service.Object):
current_page = self.wNotebook.get_current_page()
if current_page > 0:
self.toolCancel.set_sensitive(True)
return (False, False, False, False, False)
return (False,) * 6
(can_play, can_download, can_cancel, can_delete) = (False,) * 4
(can_play, can_download, can_pause, can_cancel, can_delete, open_instead_of_play) = (False,) * 6
open_instead_of_play = False
can_resume = False
selection = self.treeAvailable.get_selection()
if selection.count_selected_rows() > 0:
@ -2261,11 +2268,17 @@ class gPodder(BuilderWidget, dbus.service.Object):
else:
if episode.downloading:
can_cancel = True
if episode.download_task is not None:
if episode.download_task.status in (episode.download_task.PAUSING, episode.download_task.PAUSED):
can_resume = True
elif episode.download_task.status in (episode.download_task.QUEUED, episode.download_task.DOWNLOADING):
can_pause = True
else:
streaming_possible |= self.streaming_possible(episode)
can_download = True
can_download = can_download and not can_cancel
can_download = (can_download and not can_cancel) or can_resume
can_play = streaming_possible or (can_play and not can_cancel and not can_download)
can_delete = not can_cancel
@ -2275,17 +2288,19 @@ class gPodder(BuilderWidget, dbus.service.Object):
self.toolPlay.set_icon_name('media-playback-start')
self.toolPlay.set_sensitive(can_play)
self.toolDownload.set_sensitive(can_download)
self.toolPause.set_sensitive(can_pause)
self.toolCancel.set_sensitive(can_cancel)
self.cancel_action.set_enabled(can_cancel)
self.download_action.set_enabled(can_download)
self.pause_action.set_enabled(can_pause)
self.open_action.set_enabled(can_play and open_instead_of_play)
self.play_action.set_enabled(can_play and not open_instead_of_play)
self.delete_action.set_enabled(can_delete)
self.toggle_episode_new_action.set_enabled(can_play)
self.toggle_episode_lock_action.set_enabled(can_play)
return (can_play, can_download, can_cancel, can_delete, open_instead_of_play)
return (can_play, can_download, can_pause, can_cancel, can_delete, open_instead_of_play)
def on_cbMaxDownloads_toggled(self, widget, *args):
self.spinMaxDownloads.set_sensitive(self.cbMaxDownloads.get_active())
@ -3124,6 +3139,7 @@ class gPodder(BuilderWidget, dbus.service.Object):
for task in self.download_tasks_seen:
if episode.url == task.url:
task_exists = True
task.unpause()
task.reuse()
if task.status not in (task.DOWNLOADING, task.QUEUED):
if downloader:
@ -3536,8 +3552,9 @@ class gPodder(BuilderWidget, dbus.service.Object):
self.message_area.hide()
self.message_area = None
else:
self.toolDownload.set_sensitive(False)
self.toolPlay.set_sensitive(False)
self.toolDownload.set_sensitive(False)
self.toolPause.set_sensitive(False)
self.toolCancel.set_sensitive(False)
def on_treeChannels_row_activated(self, widget, path, *args):
@ -3604,8 +3621,17 @@ class gPodder(BuilderWidget, dbus.service.Object):
self.shownotes_object.toggle_pane_visibility(episodes)
def on_download_selected_episodes(self, action_or_widget, param=None):
episodes = self.get_selected_episodes()
episodes = [e for e in self.get_selected_episodes()
if not e.download_task or e.download_task.status in (e.download_task.PAUSING, e.download_task.PAUSED, e.download_task.FAILED)]
self.download_episode_list(episodes)
self.update_downloads_list()
def on_pause_selected_episodes(self, action_or_widget, param=None):
for episode in self.get_selected_episodes():
if episode.download_task is not None:
episode.download_task.pause()
self.update_downloads_list()
def on_treeAvailable_row_activated(self, widget, path, view_column):
"""Double-click/enter action handler for treeAvailable"""