Merge branch 'master' into dev-adaptive
This commit is contained in:
commit
cab3629813
|
@ -3,7 +3,7 @@ version: 2
|
|||
jobs:
|
||||
release-from-macos:
|
||||
macos:
|
||||
xcode: "11.1.0"
|
||||
xcode: "11.4.1"
|
||||
shell: /bin/bash --login -o pipefail
|
||||
environment:
|
||||
- BUNDLE_TAG: 21.4.27
|
||||
|
|
1074
po/cs_CZ.po
1074
po/cs_CZ.po
File diff suppressed because it is too large
Load Diff
1082
po/es_ES.po
1082
po/es_ES.po
File diff suppressed because it is too large
Load Diff
1077
po/es_MX.po
1077
po/es_MX.po
File diff suppressed because it is too large
Load Diff
1041
po/fa_IR.po
1041
po/fa_IR.po
File diff suppressed because it is too large
Load Diff
1033
po/id_ID.po
1033
po/id_ID.po
File diff suppressed because it is too large
Load Diff
1187
po/ko_KR.po
1187
po/ko_KR.po
File diff suppressed because it is too large
Load Diff
1034
po/messages.pot
1034
po/messages.pot
File diff suppressed because it is too large
Load Diff
1075
po/pt_BR.po
1075
po/pt_BR.po
File diff suppressed because it is too large
Load Diff
1194
po/zh_CN.po
1194
po/zh_CN.po
File diff suppressed because it is too large
Load Diff
|
@ -38,8 +38,8 @@ class gPodderExtension:
|
|||
dlg = Gtk.FileChooserDialog(title=_('Save video'),
|
||||
parent=self.gpodder.get_dialog_parent(),
|
||||
action=Gtk.FileChooserAction.SAVE)
|
||||
dlg.add_button(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL)
|
||||
dlg.add_button(Gtk.STOCK_SAVE, Gtk.ResponseType.OK)
|
||||
dlg.add_button(_('_Cancel'), Gtk.ResponseType.CANCEL)
|
||||
dlg.add_button(_('_Save'), Gtk.ResponseType.OK)
|
||||
|
||||
if dlg.run() == Gtk.ResponseType.OK:
|
||||
filename = dlg.get_filename()
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
# Windows 7 taskbar progress
|
||||
# Sean Munkel; 2013-01-05
|
||||
|
||||
import ctypes
|
||||
import functools
|
||||
import logging
|
||||
from ctypes import (HRESULT, POINTER, Structure, alignment, c_int, c_uint,
|
||||
|
@ -161,7 +162,11 @@ class gPodderExtension:
|
|||
|
||||
def on_ui_object_available(self, name, ui_object):
|
||||
def callback(self, window, *args):
|
||||
self.window_handle = window.window.handle
|
||||
ctypes.pythonapi.PyCapsule_GetPointer.restype = ctypes.c_void_p
|
||||
ctypes.pythonapi.PyCapsule_GetPointer.argtypes = [ctypes.py_object]
|
||||
win_gpointer = ctypes.pythonapi.PyCapsule_GetPointer(window.get_window().__gpointer__, None)
|
||||
gdkdll = ctypes.CDLL("libgdk-3-0.dll")
|
||||
self.window_handle = gdkdll.gdk_win32_window_get_handle(win_gpointer)
|
||||
|
||||
if name == 'gpodder-gtk':
|
||||
ui_object.main_window.connect('realize',
|
||||
|
|
|
@ -86,14 +86,10 @@ class YoutubeCustomDownload(download.CustomDownload):
|
|||
"""
|
||||
self._reporthook = reporthook
|
||||
# outtmpl: use given tempname by DownloadTask
|
||||
# (escape % and $ because outtmpl used as a string template by youtube-dl)
|
||||
outtmpl = tempname.replace('%', '%%').replace('$', '$$')
|
||||
# (escape % because outtmpl used as a string template by youtube-dl)
|
||||
outtmpl = tempname.replace('%', '%%')
|
||||
res = self._ytdl.fetch_video(self._url, outtmpl, self._my_hook)
|
||||
if outtmpl != tempname:
|
||||
if 'ext' in res and os.path.isfile(outtmpl + '.{}'.format(res['ext'])):
|
||||
os.rename(outtmpl + '.{}'.format(res['ext']), tempname)
|
||||
else:
|
||||
os.rename(outtmpl, tempname)
|
||||
# Renaming is not required because the escaped percent is not escaped in the output file.
|
||||
if 'duration' in res and res['duration']:
|
||||
self._episode.total_time = res['duration']
|
||||
headers = {}
|
||||
|
@ -468,7 +464,8 @@ class gPodderExtension:
|
|||
|
||||
def on_episodes_context_menu(self, episodes):
|
||||
if not self.container.config.manage_downloads \
|
||||
and not all(e.was_downloaded(and_exists=True) for e in episodes):
|
||||
and not all(e.was_downloaded(and_exists=True) for e in episodes) \
|
||||
and not any(e.downloading for e in episodes):
|
||||
return [(_("Download with Youtube-DL"), self.download_episodes)]
|
||||
|
||||
def download_episodes(self, episodes):
|
||||
|
|
|
@ -1,54 +1,43 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.38.2 -->
|
||||
<!--*- mode: xml -*-->
|
||||
<interface>
|
||||
<!-- interface-requires gtk+ 3.10 -->
|
||||
<requires lib="gtk+" version="3.16"/>
|
||||
<object class="GtkAdjustment" id="adjustment1">
|
||||
<property name="upper">10240</property>
|
||||
<property name="lower">0.5</property>
|
||||
<property name="page_increment">0</property>
|
||||
<property name="step_increment">0.5</property>
|
||||
<property name="page_size">0</property>
|
||||
<property name="upper">10240</property>
|
||||
<property name="step-increment">0.5</property>
|
||||
</object>
|
||||
<object class="GtkAdjustment" id="adjustment2">
|
||||
<property name="upper">16</property>
|
||||
<property name="lower">1</property>
|
||||
<property name="page_increment">0</property>
|
||||
<property name="step_increment">1</property>
|
||||
<property name="page_size">0</property>
|
||||
<property name="upper">16</property>
|
||||
<property name="step-increment">1</property>
|
||||
</object>
|
||||
<object class="GtkApplicationWindow" id="gPodder">
|
||||
<property name="name">gPodder</property>
|
||||
<property name="application">app</property>
|
||||
<property name="visible">False</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="title">gPodder</property>
|
||||
<property name="window_position">GTK_WIN_POS_CENTER</property>
|
||||
<property name="modal">False</property>
|
||||
<property name="destroy_with_parent">False</property>
|
||||
<property name="skip_taskbar_hint">False</property>
|
||||
<property name="skip_pager_hint">False</property>
|
||||
<property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
|
||||
<property name="focus_on_map">True</property>
|
||||
<property name="urgency_hint">False</property>
|
||||
<signal handler="on_gPodder_delete_event" name="delete-event"/>
|
||||
<property name="window-position">center</property>
|
||||
<signal name="delete-event" handler="on_gPodder_delete_event" swapped="no"/>
|
||||
<child>
|
||||
<!-- n-columns=1 n-rows=2 -->
|
||||
<object class="GtkGrid" id="vMain">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkToolbar" id="toolbar">
|
||||
<property name="visible">True</property>
|
||||
<property name="show_arrow">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<child>
|
||||
<object class="GtkToolButton" id="toolDownload">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Download</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="stock_id">gtk-go-down</property>
|
||||
<property name="visible_horizontal">True</property>
|
||||
<property name="visible_vertical">True</property>
|
||||
<property name="is_important">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<signal handler="on_download_selected_episodes" name="clicked"/>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="is-important">True</property>
|
||||
<property name="label" translatable="yes">Download</property>
|
||||
<property name="icon-name">go-down</property>
|
||||
<signal name="clicked" handler="on_download_selected_episodes" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
|
@ -58,12 +47,12 @@
|
|||
<child>
|
||||
<object class="GtkToolButton" id="toolPlay">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock_id">gtk-media-play</property>
|
||||
<property name="visible_horizontal">True</property>
|
||||
<property name="visible_vertical">True</property>
|
||||
<property name="is_important">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<signal handler="on_playback_selected_episodes" name="clicked"/>
|
||||
<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>
|
||||
|
@ -73,14 +62,12 @@
|
|||
<child>
|
||||
<object class="GtkToolButton" id="toolCancel">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Cancel</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="stock_id">gtk-cancel</property>
|
||||
<property name="visible_horizontal">True</property>
|
||||
<property name="visible_vertical">True</property>
|
||||
<property name="is_important">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<signal handler="on_item_cancel_download_activate" name="clicked"/>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="is-important">True</property>
|
||||
<property name="label" translatable="yes">Cancel</property>
|
||||
<property name="icon-name">process-stop</property>
|
||||
<signal name="clicked" handler="on_item_cancel_download_activate" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
|
@ -90,8 +77,7 @@
|
|||
<child>
|
||||
<object class="GtkSeparatorToolItem" id="toolbutton3">
|
||||
<property name="visible">True</property>
|
||||
<property name="visible_horizontal">True</property>
|
||||
<property name="visible_vertical">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
|
@ -101,12 +87,10 @@
|
|||
<child>
|
||||
<object class="GtkToolButton" id="toolPreferences">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock_id">gtk-preferences</property>
|
||||
<property name="visible_horizontal">True</property>
|
||||
<property name="visible_vertical">True</property>
|
||||
<property name="is_important">False</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="action-name">app.preferences</property>
|
||||
<property name="label" translatable="yes">Preferences</property>
|
||||
<property name="icon-name">preferences-desktop</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
|
@ -116,8 +100,7 @@
|
|||
<child>
|
||||
<object class="GtkSeparatorToolItem" id="toolbutton2">
|
||||
<property name="visible">True</property>
|
||||
<property name="visible_horizontal">True</property>
|
||||
<property name="visible_vertical">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
|
@ -127,12 +110,10 @@
|
|||
<child>
|
||||
<object class="GtkToolButton" id="toolQuit">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock_id">gtk-quit</property>
|
||||
<property name="visible_horizontal">True</property>
|
||||
<property name="visible_vertical">True</property>
|
||||
<property name="is_important">False</property>
|
||||
<signal handler="on_gPodder_delete_event" name="clicked"/>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">Quit</property>
|
||||
<property name="icon-name">application-exit</property>
|
||||
<signal name="clicked" handler="on_gPodder_delete_event" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
|
@ -140,348 +121,430 @@
|
|||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<!-- n-columns=1 n-rows=1 -->
|
||||
<object class="GtkGrid" id="hboxContainer">
|
||||
<property name="border_width">5</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="orientation">horizontal</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="vexpand">True</property>
|
||||
<property name="border-width">5</property>
|
||||
<child>
|
||||
<object class="GtkNotebook" id="wNotebook">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="show_tabs">True</property>
|
||||
<property name="show_border">True</property>
|
||||
<property name="tab_pos">GTK_POS_TOP</property>
|
||||
<property name="scrollable">False</property>
|
||||
<property name="enable_popup">False</property>
|
||||
<signal handler="on_wNotebook_switch_page" name="switch_page"/>
|
||||
<property name="can-focus">True</property>
|
||||
<signal name="switch-page" handler="on_wNotebook_switch_page" swapped="no"/>
|
||||
<child>
|
||||
<object class="GtkPaned" id="channelPaned">
|
||||
<property name="border_width">5</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="orientation">horizontal</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="border-width">5</property>
|
||||
<child>
|
||||
<!-- n-columns=1 n-rows=3 -->
|
||||
<object class="GtkGrid" id="vboxChannelNavigator">
|
||||
<property name="visible">True</property>
|
||||
<property name="row_spacing">5</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="row-spacing">5</property>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="scrolledwindow6">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
|
||||
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
|
||||
<property name="vexpand">True</property>
|
||||
<property name="shadow_type">GTK_SHADOW_IN</property>
|
||||
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="vexpand">True</property>
|
||||
<property name="shadow-type">in</property>
|
||||
<child>
|
||||
<object class="GtkTreeView" id="treeChannels">
|
||||
<property name="name">treeChannels</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="headers_visible">False</property>
|
||||
<property name="rules_hint">False</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="has-tooltip">True</property>
|
||||
<property name="reorderable">False</property>
|
||||
<property name="enable_search">True</property>
|
||||
<property name="fixed_height_mode">False</property>
|
||||
<property name="hover_selection">False</property>
|
||||
<property name="hover_expand">False</property>
|
||||
<signal handler="on_treeChannels_row_activated" name="row_activated"/>
|
||||
<signal handler="on_treeChannels_cursor_changed" name="cursor_changed"/>
|
||||
<signal handler="on_treeview_query_tooltip" name="query-tooltip"/>
|
||||
<signal handler="on_treeview_expose_event" name="draw"/>
|
||||
<signal handler="on_treeview_button_pressed" name="button-press-event"/>
|
||||
<signal handler="on_treeview_podcasts_button_released" name="button-release-event"/>
|
||||
<property name="headers-visible">False</property>
|
||||
<signal name="button-press-event" handler="on_treeview_button_pressed" swapped="no"/>
|
||||
<signal name="button-release-event" handler="on_treeview_podcasts_button_released" swapped="no"/>
|
||||
<signal name="cursor-changed" handler="on_treeChannels_cursor_changed" swapped="no"/>
|
||||
<signal name="draw" handler="on_treeview_expose_event" swapped="no"/>
|
||||
<signal name="query-tooltip" handler="on_treeview_query_tooltip" swapped="no"/>
|
||||
<signal name="row-activated" handler="on_treeChannels_row_activated" swapped="no"/>
|
||||
<child internal-child="selection">
|
||||
<object class="GtkTreeSelection"/>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<!-- n-columns=1 n-rows=1 -->
|
||||
<object class="GtkGrid" id="hbox_search_podcasts">
|
||||
<property name="column_spacing">6</property>
|
||||
<property name="orientation">horizontal</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="column-spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkEntry" id="entry_search_podcasts">
|
||||
<property name="hexpand">True</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="secondary-icon-stock">gtk-close</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="secondary-icon-name">edit-clear</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<!-- n-columns=1 n-rows=2 -->
|
||||
<object class="GtkGrid" id="vbox42">
|
||||
<property name="visible">True</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="btnUpdateFeeds">
|
||||
<property name="label" translatable="yes">Check for new episodes</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
<property name="action-name">win.update</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="receives-default">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="action-name">win.update</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<!-- n-columns=2 n-rows=1 -->
|
||||
<object class="GtkGrid" id="hboxUpdateFeeds">
|
||||
<property name="column_spacing">6</property>
|
||||
<property name="orientation">horizontal</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="column-spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkProgressBar" id="pbFeedUpdate">
|
||||
<property name="can-focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="pulse_step">0.10000000149</property>
|
||||
<property name="pulse-step">0.10000000149</property>
|
||||
<property name="show-text">True</property>
|
||||
<property name="ellipsize">PANGO_ELLIPSIZE_MIDDLE</property>
|
||||
<property name="ellipsize">middle</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="btnCancelFeedUpdate">
|
||||
<property name="can_focus">True</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
<signal handler="on_btnCancelFeedUpdate_clicked" name="clicked"/>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="receives-default">False</property>
|
||||
<signal name="clicked" handler="on_btnCancelFeedUpdate_clicked" swapped="no"/>
|
||||
<child>
|
||||
<object class="GtkImage" id="image3209">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-cancel</property>
|
||||
<property name="icon_size">4</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="icon-name">process-stop</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="shrink">False</property>
|
||||
<property name="resize">False</property>
|
||||
<property name="shrink">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<!-- n-columns=1 n-rows=2 -->
|
||||
<object class="GtkGrid" id="vbox_episode_list">
|
||||
<property name="visible">True</property>
|
||||
<property name="row_spacing">6</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="row-spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="scrollAvailable">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
|
||||
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
|
||||
<property name="shadow_type">GTK_SHADOW_IN</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="vexpand">True</property>
|
||||
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="vexpand">True</property>
|
||||
<property name="shadow-type">in</property>
|
||||
<child>
|
||||
<object class="GtkTreeView" id="treeAvailable">
|
||||
<property name="name">treeAvailable</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="headers_visible">True</property>
|
||||
<property name="rules_hint">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="has-tooltip">True</property>
|
||||
<property name="enable-search">False</property>
|
||||
<property name="rubber-banding">True</property>
|
||||
<property name="reorderable">False</property>
|
||||
<property name="enable_search">False</property>
|
||||
<property name="fixed_height_mode">False</property>
|
||||
<property name="hover_selection">False</property>
|
||||
<property name="hover_expand">False</property>
|
||||
<signal handler="on_treeAvailable_row_activated" name="row_activated"/>
|
||||
<signal handler="on_treeview_query_tooltip" name="query-tooltip"/>
|
||||
<signal handler="on_treeview_expose_event" name="draw"/>
|
||||
<signal handler="on_treeview_button_pressed" name="button-press-event"/>
|
||||
<signal handler="on_treeview_episodes_button_released" name="button-release-event"/>
|
||||
<signal name="button-press-event" handler="on_treeview_button_pressed" swapped="no"/>
|
||||
<signal name="button-release-event" handler="on_treeview_episodes_button_released" swapped="no"/>
|
||||
<signal name="draw" handler="on_treeview_expose_event" swapped="no"/>
|
||||
<signal name="query-tooltip" handler="on_treeview_query_tooltip" swapped="no"/>
|
||||
<signal name="row-activated" handler="on_treeAvailable_row_activated" swapped="no"/>
|
||||
<child internal-child="selection">
|
||||
<object class="GtkTreeSelection"/>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<!-- n-columns=2 n-rows=1 -->
|
||||
<object class="GtkGrid" id="hbox_search_episodes">
|
||||
<property name="column_spacing">6</property>
|
||||
<property name="orientation">horizontal</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="column-spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label_search_episodes">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">Filter:</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="entry_search_episodes">
|
||||
<property name="hexpand">True</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="secondary-icon-stock">gtk-close</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="secondary-icon-name">edit-clear</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="resize">True</property>
|
||||
<property name="shrink">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="tab">
|
||||
<object class="GtkLabel" id="label2">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">Podcasts</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="tab-fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<!-- n-columns=1 n-rows=2 -->
|
||||
<object class="GtkGrid" id="vboxDownloadStatusWidgets">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="border-width">5</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="row-spacing">5</property>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="scrolledwindow1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="vexpand">True</property>
|
||||
<property name="shadow-type">in</property>
|
||||
<child>
|
||||
<object class="GtkTreeView" id="treeDownloads">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="headers-visible">False</property>
|
||||
<property name="reorderable">True</property>
|
||||
<property name="rubber-banding">True</property>
|
||||
<signal name="button-press-event" handler="on_treeview_button_pressed" swapped="no"/>
|
||||
<signal name="button-release-event" handler="on_treeview_downloads_button_released" swapped="no"/>
|
||||
<signal name="draw" handler="on_treeview_expose_event" swapped="no"/>
|
||||
<signal name="row-activated" handler="on_treeDownloads_row_activated" swapped="no"/>
|
||||
<child internal-child="selection">
|
||||
<object class="GtkTreeSelection"/>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="shrink">False</property>
|
||||
<property name="resize">True</property>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="tab_expand">False</property>
|
||||
<property name="tab_fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child type="tab">
|
||||
<object class="GtkLabel" id="label2">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Podcasts</property>
|
||||
<property name="use_underline">False</property>
|
||||
<property name="use_markup">False</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="width_chars">-1</property>
|
||||
<property name="single_line_mode">False</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkGrid" id="vboxDownloadStatusWidgets">
|
||||
<property name="border_width">5</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="row_spacing">5</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="scrolledwindow1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="vexpand">True</property>
|
||||
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
|
||||
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
|
||||
<property name="shadow_type">GTK_SHADOW_IN</property>
|
||||
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
|
||||
<child>
|
||||
<object class="GtkTreeView" id="treeDownloads">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="headers_visible">False</property>
|
||||
<property name="rules_hint">False</property>
|
||||
<property name="rubber-banding">True</property>
|
||||
<property name="reorderable">True</property>
|
||||
<property name="enable_search">True</property>
|
||||
<property name="fixed_height_mode">False</property>
|
||||
<property name="hover_selection">False</property>
|
||||
<property name="hover_expand">False</property>
|
||||
<signal handler="on_treeDownloads_row_activated" name="row_activated"/>
|
||||
<signal handler="on_treeview_expose_event" name="draw"/>
|
||||
<signal handler="on_treeview_button_pressed" name="button-press-event"/>
|
||||
<signal handler="on_treeview_downloads_button_released" name="button-release-event"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<!-- n-columns=3 n-rows=1 -->
|
||||
<object class="GtkGrid" id="hboxDownloadSettings">
|
||||
<property name="border_width">5</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="column_spacing">10</property>
|
||||
<property name="orientation">horizontal</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="border-width">5</property>
|
||||
<property name="column-spacing">10</property>
|
||||
<child>
|
||||
<!-- n-columns=3 n-rows=1 -->
|
||||
<object class="GtkGrid" id="hboxDownloadLimit">
|
||||
<property name="visible">True</property>
|
||||
<property name="column_spacing">5</property>
|
||||
<property name="orientation">horizontal</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="column-spacing">5</property>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="cbLimitDownloads">
|
||||
<property name="label" translatable="yes">Limit rate to</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<signal name="toggled" handler="on_cbLimitDownloads_toggled"/>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="receives-default">False</property>
|
||||
<property name="draw-indicator">True</property>
|
||||
<signal name="toggled" handler="on_cbLimitDownloads_toggled" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSpinButton" id="spinLimitDownloads">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="invisible_char">●</property>
|
||||
<property name="climb_rate">1</property>
|
||||
<property name="digits">1</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="invisible-char">●</property>
|
||||
<property name="adjustment">adjustment1</property>
|
||||
<property name="climb-rate">1</property>
|
||||
<property name="digits">1</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="labelLimitRate">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">KiB/s</property>
|
||||
<property name="xalign">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">2</property>
|
||||
<property name="top-attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="DownloadSettingsSpacer">
|
||||
<property name="visible">True</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<!-- n-columns=2 n-rows=1 -->
|
||||
<object class="GtkGrid" id="hboxDownloadRate">
|
||||
<property name="visible">True</property>
|
||||
<property name="column_spacing">5</property>
|
||||
<property name="orientation">horizontal</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="column-spacing">5</property>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="cbMaxDownloads">
|
||||
<property name="label" translatable="yes">Limit downloads to</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<signal name="toggled" handler="on_cbMaxDownloads_toggled"/>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="receives-default">False</property>
|
||||
<property name="draw-indicator">True</property>
|
||||
<signal name="toggled" handler="on_cbMaxDownloads_toggled" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSpinButton" id="spinMaxDownloads">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="invisible_char">●</property>
|
||||
<property name="climb_rate">1</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="invisible-char">●</property>
|
||||
<property name="adjustment">adjustment2</property>
|
||||
<property name="climb-rate">1</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">2</property>
|
||||
<property name="top-attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="tab_expand">False</property>
|
||||
<property name="tab_fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child type="tab">
|
||||
<object class="GtkLabel" id="labelDownloads">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">Progress</property>
|
||||
<property name="use_underline">False</property>
|
||||
<property name="use_markup">False</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="width_chars">-1</property>
|
||||
<property name="single_line_mode">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
<property name="tab-fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
|
|
|
@ -1,294 +1,241 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.38.2 -->
|
||||
<!--*- mode: xml -*-->
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.16"/>
|
||||
<object class="GtkDialog" id="gPodderEpisodeSelector">
|
||||
<property name="visible">False</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="title" translatable="yes">Select episodes</property>
|
||||
<property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
|
||||
<property name="modal">True</property>
|
||||
<property name="transient-for">parent_widget</property>
|
||||
<property name="destroy_with_parent">False</property>
|
||||
<property name="skip_taskbar_hint">False</property>
|
||||
<property name="skip_pager_hint">False</property>
|
||||
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
|
||||
<property name="focus_on_map">True</property>
|
||||
<property name="urgency_hint">False</property>
|
||||
<property name="window-position">center-on-parent</property>
|
||||
<property name="type-hint">dialog</property>
|
||||
<child internal-child="vbox">
|
||||
<object class="GtkBox" id="vbox10">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkBox" id="vbox_for_episode_selector">
|
||||
<property name="border_width">5</property>
|
||||
<child internal-child="action_area">
|
||||
<object class="GtkButtonBox" id="hbox35">
|
||||
<property name="visible">True</property>
|
||||
<property name="spacing">5</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="can-focus">False</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="labelInstructions">
|
||||
<property name="label">additional text</property>
|
||||
<property name="use_underline">False</property>
|
||||
<property name="use_markup">False</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="width_chars">-1</property>
|
||||
<property name="single_line_mode">False</property>
|
||||
<object class="GtkButton" id="btnRemoveAction">
|
||||
<property name="label" translatable="yes">_Remove</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="receives-default">False</property>
|
||||
<property name="use-underline">True</property>
|
||||
<signal name="clicked" handler="on_remove_action_activate" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="btnCancel">
|
||||
<property name="label" translatable="yes">_Cancel</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="receives-default">False</property>
|
||||
<property name="use-underline">True</property>
|
||||
<signal name="clicked" handler="on_btnCancel_clicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="btnOK">
|
||||
<property name="label" translatable="yes">_OK</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="can-default">True</property>
|
||||
<property name="has-default">True</property>
|
||||
<property name="receives-default">False</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="always-show-image">True</property>
|
||||
<signal name="clicked" handler="on_btnOK_clicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="vbox_for_episode_selector">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="border-width">5</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">5</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="labelInstructions">
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label">additional text</property>
|
||||
<property name="xalign">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="scrolledwindow7">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
|
||||
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
|
||||
<property name="shadow_type">GTK_SHADOW_IN</property>
|
||||
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="shadow-type">in</property>
|
||||
<child>
|
||||
<object class="GtkTreeView" id="treeviewEpisodes">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="has_focus">True</property>
|
||||
<property name="headers_visible">False</property>
|
||||
<property name="rules_hint">False</property>
|
||||
<property name="reorderable">False</property>
|
||||
<property name="enable_search">False</property>
|
||||
<property name="fixed_height_mode">False</property>
|
||||
<property name="hover_selection">False</property>
|
||||
<property name="hover_expand">False</property>
|
||||
<signal name="row_activated" handler="on_row_activated"/>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="has-focus">True</property>
|
||||
<property name="headers-visible">False</property>
|
||||
<property name="enable-search">False</property>
|
||||
<signal name="row-activated" handler="on_row_activated" swapped="no"/>
|
||||
<child internal-child="selection">
|
||||
<object class="GtkTreeSelection"/>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="hboxButtons">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="spacing">5</property>
|
||||
<property name="orientation">horizontal</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="btnCheckAll">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
<signal handler="on_btnCheckAll_clicked" name="clicked"/>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="receives-default">False</property>
|
||||
<signal name="clicked" handler="on_btnCheckAll_clicked" swapped="no"/>
|
||||
<child>
|
||||
<object class="GtkAlignment" id="alignment22">
|
||||
<object class="GtkBox" id="hbox34">
|
||||
<property name="visible">True</property>
|
||||
<property name="xscale">0</property>
|
||||
<property name="yscale">0</property>
|
||||
<property name="top_padding">0</property>
|
||||
<property name="bottom_padding">0</property>
|
||||
<property name="left_padding">0</property>
|
||||
<property name="right_padding">0</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="spacing">2</property>
|
||||
<child>
|
||||
<object class="GtkBox" id="hbox34">
|
||||
<object class="GtkImage" id="image2636">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">2</property>
|
||||
<property name="orientation">horizontal</property>
|
||||
<child>
|
||||
<object class="GtkImage" id="image2636">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-apply</property>
|
||||
<property name="icon_size">4</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label107">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Select all</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_markup">False</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="width_chars">-1</property>
|
||||
<property name="single_line_mode">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="icon-name">object-select</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label107">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">Select _all</property>
|
||||
<property name="use-underline">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="btnCheckNone">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
<signal handler="on_btnCheckNone_clicked" name="clicked"/>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="receives-default">False</property>
|
||||
<signal name="clicked" handler="on_btnCheckNone_clicked" swapped="no"/>
|
||||
<child>
|
||||
<object class="GtkAlignment" id="alignment21">
|
||||
<object class="GtkBox" id="hbox33">
|
||||
<property name="visible">True</property>
|
||||
<property name="xscale">0</property>
|
||||
<property name="yscale">0</property>
|
||||
<property name="top_padding">0</property>
|
||||
<property name="bottom_padding">0</property>
|
||||
<property name="left_padding">0</property>
|
||||
<property name="right_padding">0</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="spacing">2</property>
|
||||
<child>
|
||||
<object class="GtkBox" id="hbox33">
|
||||
<object class="GtkImage" id="image2635">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">2</property>
|
||||
<property name="orientation">horizontal</property>
|
||||
<child>
|
||||
<object class="GtkImage" id="image2635">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-revert-to-saved</property>
|
||||
<property name="icon_size">4</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label106">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Select none</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_markup">False</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="width_chars">-1</property>
|
||||
<property name="single_line_mode">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="icon-name">document-revert</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label106">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">Select _none</property>
|
||||
<property name="use-underline">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="labelTotalSize">
|
||||
<property name="visible">True</property>
|
||||
<property name="use_underline">False</property>
|
||||
<property name="use_markup">False</property>
|
||||
<property name="justify">GTK_JUSTIFY_RIGHT</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="justify">right</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="width_chars">-1</property>
|
||||
<property name="single_line_mode">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child internal-child="action_area">
|
||||
<object class="GtkBox" id="hbox35">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">5</property>
|
||||
<property name="orientation">horizontal</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="btnRemoveAction">
|
||||
<property name="visible">False</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label">Remove</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
<signal handler="on_remove_action_activate" name="clicked"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="btnCancel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label">gtk-cancel</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
<signal handler="on_btnCancel_clicked" name="clicked"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="btnOK">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="has_default">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label">gtk-ok</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
<signal handler="on_btnOK_clicked" name="clicked"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
|
|
|
@ -26,7 +26,7 @@ from gpodder.sync import (episode_filename_on_device,
|
|||
episode_foldername_on_device)
|
||||
|
||||
import gi # isort:skip
|
||||
gi.require_version('Gtk', '3.0') # isort:skip
|
||||
gi.require_version('Gio', '2.0') # isort:skip
|
||||
from gi.repository import Gio, GLib # isort:skip
|
||||
|
||||
_ = gpodder.gettext
|
||||
|
|
|
@ -624,10 +624,9 @@ class DownloadTask(object):
|
|||
with self:
|
||||
# Cancelling directly is allowed if the task isn't currently downloading
|
||||
if self.status in (self.QUEUED, self.PAUSED, self.FAILED):
|
||||
self.status = self.CANCELLED
|
||||
# Call run, so the partial file gets deleted
|
||||
self.status = self.CANCELLING
|
||||
# Call run, so the partial file gets deleted, and task recycled
|
||||
self.run()
|
||||
self.recycle()
|
||||
# Otherwise request cancellation
|
||||
elif self.status == self.DOWNLOADING:
|
||||
self.status = self.CANCELLING
|
||||
|
@ -954,10 +953,6 @@ class DownloadTask(object):
|
|||
self.status = DownloadTask.FAILED
|
||||
self.__episode._download_error = self.error_message
|
||||
|
||||
# Delete empty partial files, they prevent streaming after a download failure (live stream)
|
||||
if util.calculate_size(self.filename) == 0:
|
||||
util.delete_file(self.tempname)
|
||||
|
||||
# cancelled/paused -- update state to mark it as safe to manipulate this task again
|
||||
elif self.status == DownloadTask.PAUSING:
|
||||
self.status = DownloadTask.PAUSED
|
||||
|
|
|
@ -230,7 +230,7 @@ class gPodderApplication(Gtk.Application):
|
|||
def on_about(self, action, param):
|
||||
dlg = Gtk.Dialog(_('About gPodder'), self.window.gPodder,
|
||||
Gtk.DialogFlags.MODAL)
|
||||
dlg.add_button(Gtk.STOCK_CLOSE, Gtk.ResponseType.OK).show()
|
||||
dlg.add_button(_('_Close'), Gtk.ResponseType.OK).show()
|
||||
dlg.set_resizable(True)
|
||||
|
||||
bg = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6, margin=16)
|
||||
|
|
|
@ -50,9 +50,6 @@ class GtkBuilderWidget(object):
|
|||
if parent is not None:
|
||||
self.builder.expose_object('parent_widget', parent)
|
||||
self.builder.set_translation_domain(textdomain)
|
||||
if hasattr(self, '_builder_expose'):
|
||||
for (key, value) in list(self._builder_expose.items()):
|
||||
self.builder.expose_object(key, value)
|
||||
|
||||
# print >>sys.stderr, 'Creating new from file', self.__class__.__name__
|
||||
|
||||
|
@ -67,6 +64,9 @@ class GtkBuilderWidget(object):
|
|||
|
||||
self.builder.connect_signals(self)
|
||||
self.set_attributes()
|
||||
if hasattr(self, '_gtk_properties'):
|
||||
for ((gobj, prop), val) in self._gtk_properties.items():
|
||||
getattr(self, gobj).set_property(prop, val)
|
||||
|
||||
self.new()
|
||||
|
||||
|
|
|
@ -165,6 +165,12 @@ class UIConfig(config.Config):
|
|||
window.set_position(Gtk.WindowPosition.CENTER_ON_PARENT)
|
||||
else:
|
||||
window.move(cfg.x, cfg.y)
|
||||
# From Gtk docs: most window managers ignore requests for initial window
|
||||
# positions (instead using a user-defined placement algorithm) and honor
|
||||
# requests after the window has already been shown.
|
||||
# Move it a second time after the window has been shown.
|
||||
# The first move reduces chance of window jumping.
|
||||
util.idle_add(window.move, cfg.x, cfg.y)
|
||||
|
||||
# Ignore events while we're connecting to the window
|
||||
self.__ignore_window_events = True
|
||||
|
|
|
@ -112,7 +112,7 @@ class gPodderChannel(BuilderWidget):
|
|||
|
||||
def on_button_add_section_clicked(self, widget):
|
||||
text = self.show_text_edit_dialog(_('Add section'), _('New section:'),
|
||||
affirmative_text=Gtk.STOCK_ADD)
|
||||
affirmative_text=_('_Add'))
|
||||
|
||||
if text is not None:
|
||||
for index, (section,) in enumerate(self.section_list):
|
||||
|
@ -146,8 +146,8 @@ class gPodderChannel(BuilderWidget):
|
|||
title=_('Select new podcast cover artwork'),
|
||||
parent=self.gPodderChannel,
|
||||
action=Gtk.FileChooserAction.OPEN)
|
||||
dlg.add_button(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL)
|
||||
dlg.add_button(Gtk.STOCK_OPEN, Gtk.ResponseType.OK)
|
||||
dlg.add_button(_('_Cancel'), Gtk.ResponseType.CANCEL)
|
||||
dlg.add_button(_('_Open'), Gtk.ResponseType.OK)
|
||||
|
||||
if dlg.run() == Gtk.ResponseType.OK:
|
||||
url = dlg.get_uri()
|
||||
|
|
|
@ -59,12 +59,9 @@ class gPodderEpisodeSelector(BuilderWidget):
|
|||
- title: (optional) The title of the window + heading
|
||||
- instructions: (optional) A one-line text describing what the
|
||||
user should select / what the selection is for
|
||||
- stock_ok_button: (optional) Will replace the "OK" button with
|
||||
another GTK+ stock item to be used for the
|
||||
affirmative button of the dialog (e.g. can
|
||||
be Gtk.STOCK_DELETE when the episodes to be
|
||||
selected will be deleted after closing the
|
||||
dialog)
|
||||
- ok_button: (optional) Will replace the "OK" button label with this
|
||||
string (e.g. can be '_Delete' when the episodes to be
|
||||
selected will be deleted after closing the dialog)
|
||||
- selection_buttons: (optional) A dictionary with labels as
|
||||
keys and callbacks as values; for each
|
||||
key a button will be generated, and when
|
||||
|
@ -89,6 +86,7 @@ class gPodderEpisodeSelector(BuilderWidget):
|
|||
COLUMN_ADDITIONAL = 3
|
||||
|
||||
def new(self):
|
||||
self.gPodderEpisodeSelector.set_transient_for(self.parent_widget)
|
||||
if hasattr(self, 'title'):
|
||||
self.gPodderEpisodeSelector.set_title(self.title)
|
||||
|
||||
|
@ -134,13 +132,13 @@ class gPodderEpisodeSelector(BuilderWidget):
|
|||
self.labelInstructions.set_text(self.instructions)
|
||||
self.labelInstructions.show_all()
|
||||
|
||||
if hasattr(self, 'stock_ok_button'):
|
||||
if self.stock_ok_button == 'gpodder-download':
|
||||
if hasattr(self, 'ok_button'):
|
||||
if self.ok_button == 'gpodder-download':
|
||||
self.btnOK.set_image(Gtk.Image.new_from_icon_name('go-down', Gtk.IconSize.BUTTON))
|
||||
self.btnOK.set_label(_('Download'))
|
||||
self.btnOK.set_label(_('_Download'))
|
||||
else:
|
||||
self.btnOK.set_label(self.stock_ok_button)
|
||||
self.btnOK.set_use_stock(True)
|
||||
self.btnOK.set_image(None)
|
||||
self.btnOK.set_label(self.ok_button)
|
||||
|
||||
# check/uncheck column
|
||||
toggle_cell = Gtk.CellRendererToggle()
|
||||
|
@ -326,9 +324,9 @@ class gPodderEpisodeSelector(BuilderWidget):
|
|||
self.btnOK.set_sensitive(count > 0)
|
||||
self.btnRemoveAction.set_sensitive(count > 0)
|
||||
if count > 0:
|
||||
self.btnCancel.set_label(Gtk.STOCK_CANCEL)
|
||||
self.btnCancel.set_label(_('_Cancel'))
|
||||
else:
|
||||
self.btnCancel.set_label(Gtk.STOCK_CLOSE)
|
||||
self.btnCancel.set_label(_('_Close'))
|
||||
else:
|
||||
self.btnOK.set_sensitive(False)
|
||||
self.btnRemoveAction.set_sensitive(False)
|
||||
|
|
|
@ -671,8 +671,8 @@ class gPodderPreferences(BuilderWidget):
|
|||
fs = Gtk.FileChooserDialog(title=_('Select folder for mount point'),
|
||||
action=Gtk.FileChooserAction.SELECT_FOLDER)
|
||||
fs.set_local_only(False)
|
||||
fs.add_button(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL)
|
||||
fs.add_button(Gtk.STOCK_OPEN, Gtk.ResponseType.OK)
|
||||
fs.add_button(_('_Cancel'), Gtk.ResponseType.CANCEL)
|
||||
fs.add_button(_('_Open'), Gtk.ResponseType.OK)
|
||||
|
||||
fs.set_uri(self.btn_filesystemMountpoint.get_label() or "")
|
||||
if fs.run() == Gtk.ResponseType.OK:
|
||||
|
@ -689,8 +689,8 @@ class gPodderPreferences(BuilderWidget):
|
|||
fs = Gtk.FileChooserDialog(title=_('Select folder for playlists'),
|
||||
action=Gtk.FileChooserAction.SELECT_FOLDER)
|
||||
fs.set_local_only(False)
|
||||
fs.add_button(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL)
|
||||
fs.add_button(Gtk.STOCK_OPEN, Gtk.ResponseType.OK)
|
||||
fs.add_button(_('_Cancel'), Gtk.ResponseType.CANCEL)
|
||||
fs.add_button(_('_Open'), Gtk.ResponseType.OK)
|
||||
|
||||
device_folder = util.new_gio_file(self._config.device_sync.device_folder)
|
||||
playlists_folder = device_folder.resolve_relative_path(self._config.device_sync.playlists.folder)
|
||||
|
|
|
@ -155,7 +155,7 @@ class UserAppsReader(object):
|
|||
self.apps.append(UserApplication(
|
||||
_('Default application'), 'default',
|
||||
';'.join((mime + '/*' for mime in self.mimetypes)),
|
||||
Gtk.STOCK_OPEN))
|
||||
'document-open'))
|
||||
|
||||
def add_separator(self):
|
||||
self.apps.append(UserApplication(
|
||||
|
|
|
@ -65,7 +65,7 @@ class DownloadStatusModel(Gtk.ListStore):
|
|||
# Set up stock icon IDs for tasks
|
||||
self._status_ids = collections.defaultdict(lambda: None)
|
||||
self._status_ids[download.DownloadTask.DOWNLOADING] = 'go-down'
|
||||
self._status_ids[download.DownloadTask.DONE] = Gtk.STOCK_APPLY
|
||||
self._status_ids[download.DownloadTask.DONE] = 'object-select-symbolic'
|
||||
self._status_ids[download.DownloadTask.FAILED] = 'dialog-error'
|
||||
self._status_ids[download.DownloadTask.CANCELLING] = 'media-playback-stop'
|
||||
self._status_ids[download.DownloadTask.CANCELLED] = 'media-playback-stop'
|
||||
|
|
|
@ -403,8 +403,6 @@ def get_foreground_color(state=Gtk.StateFlags.NORMAL, widget=Gtk.TreeView()):
|
|||
"""
|
||||
p = widget
|
||||
color = Gdk.RGBA(0, 0, 0, 0)
|
||||
style_context = widget.get_style_context()
|
||||
foreground = style_context.get_color(state)
|
||||
while p is not None and color.alpha == 0:
|
||||
style_context = p.get_style_context()
|
||||
color = style_context.get_color(state)
|
||||
|
|
|
@ -130,11 +130,11 @@ class BuilderWidget(GtkBuilderWidget):
|
|||
return response == Gtk.ResponseType.YES
|
||||
|
||||
def show_text_edit_dialog(self, title, prompt, text=None, empty=False,
|
||||
is_url=False, affirmative_text=Gtk.STOCK_OK):
|
||||
is_url=False, affirmative_text=_('_OK')):
|
||||
dialog = Gtk.Dialog(title, self.get_dialog_parent(),
|
||||
Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT)
|
||||
|
||||
dialog.add_button(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL)
|
||||
dialog.add_button(_('_Cancel'), Gtk.ResponseType.CANCEL)
|
||||
dialog.add_button(affirmative_text, Gtk.ResponseType.OK)
|
||||
|
||||
dialog.set_default_size(300, -1)
|
||||
|
@ -270,8 +270,8 @@ class BuilderWidget(GtkBuilderWidget):
|
|||
initial_directory = os.path.expanduser('~')
|
||||
|
||||
dlg = Gtk.FileChooserDialog(title=title, parent=self.main_window, action=Gtk.FileChooserAction.SELECT_FOLDER)
|
||||
dlg.add_button(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL)
|
||||
dlg.add_button(Gtk.STOCK_SAVE, Gtk.ResponseType.OK)
|
||||
dlg.add_button(_('_Cancel'), Gtk.ResponseType.CANCEL)
|
||||
dlg.add_button(_('_Save'), Gtk.ResponseType.OK)
|
||||
|
||||
dlg.set_do_overwrite_confirmation(True)
|
||||
dlg.set_current_folder(initial_directory)
|
||||
|
|
|
@ -100,7 +100,8 @@ class gPodder(BuilderWidget, dbus.service.Object):
|
|||
self.extensions_actions = []
|
||||
self._search_podcasts = None
|
||||
self._search_episodes = None
|
||||
BuilderWidget.__init__(self, None, _builder_expose={'app': app}, **kwargs)
|
||||
BuilderWidget.__init__(self, None,
|
||||
_gtk_properties={('gPodder', 'application'): app}, **kwargs)
|
||||
|
||||
self.last_episode_date_refresh = None
|
||||
self.refresh_episode_dates()
|
||||
|
@ -659,7 +660,7 @@ class gPodder(BuilderWidget, dbus.service.Object):
|
|||
episodes=changes,
|
||||
columns=columns,
|
||||
size_attribute=None,
|
||||
stock_ok_button=Gtk.STOCK_APPLY,
|
||||
ok_button=_('A_pply'),
|
||||
callback=execute_podcast_actions,
|
||||
_config=self.config)
|
||||
|
||||
|
@ -1961,7 +1962,7 @@ class gPodder(BuilderWidget, dbus.service.Object):
|
|||
|
||||
def on_open_download_folder(self, item):
|
||||
assert self.active_channel is not None
|
||||
util.gui_open(self.active_channel.save_dir)
|
||||
util.gui_open(self.active_channel.save_dir, gui=self)
|
||||
|
||||
def treeview_channels_show_context_menu(self, treeview, event=None):
|
||||
model, paths = self.treeview_handle_context_menu_click(treeview, event)
|
||||
|
@ -2312,6 +2313,11 @@ class gPodder(BuilderWidget, dbus.service.Object):
|
|||
for episode in episodes:
|
||||
episode._download_error = None
|
||||
|
||||
if episode.download_task is not None and episode.download_task.status == episode.download_task.FAILED:
|
||||
# Cancel failed task and remove from progress list
|
||||
episode.download_task.cancel()
|
||||
self.cleanup_downloads()
|
||||
|
||||
player = self.episode_player(episode)
|
||||
|
||||
try:
|
||||
|
@ -2369,7 +2375,7 @@ class gPodder(BuilderWidget, dbus.service.Object):
|
|||
if 'default' in groups:
|
||||
for filename in groups['default']:
|
||||
logger.debug('Opening with system default: %s', filename)
|
||||
util.gui_open(filename)
|
||||
util.gui_open(filename, gui=self)
|
||||
del groups['default']
|
||||
|
||||
# For each type now, go and create play commands
|
||||
|
@ -3030,8 +3036,8 @@ class gPodder(BuilderWidget, dbus.service.Object):
|
|||
|
||||
if downloading:
|
||||
dialog = Gtk.MessageDialog(self.gPodder, Gtk.DialogFlags.MODAL, Gtk.MessageType.QUESTION, Gtk.ButtonsType.NONE)
|
||||
dialog.add_button(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL)
|
||||
quit_button = dialog.add_button(Gtk.STOCK_QUIT, Gtk.ResponseType.CLOSE)
|
||||
dialog.add_button(_('_Cancel'), Gtk.ResponseType.CANCEL)
|
||||
quit_button = dialog.add_button(_('_Quit'), Gtk.ResponseType.CLOSE)
|
||||
|
||||
title = _('Quit gPodder')
|
||||
message = _('You are downloading episodes. You can resume downloads the next time you start gPodder. Do you want to quit now?')
|
||||
|
@ -3182,7 +3188,7 @@ class gPodder(BuilderWidget, dbus.service.Object):
|
|||
ui_folder=os.path.join(gpodder.ui_folders[0], '..', 'adaptive'),
|
||||
instructions=instructions,
|
||||
episodes=episodes, selected=selected, columns=columns,
|
||||
stock_ok_button=_('Delete'), callback=self.delete_episode_list,
|
||||
ok_button=_('_Delete'), callback=self.delete_episode_list,
|
||||
selection_buttons=selection_buttons, _config=self.config)
|
||||
|
||||
def on_selected_episodes_status_changed(self):
|
||||
|
@ -3384,10 +3390,10 @@ class gPodder(BuilderWidget, dbus.service.Object):
|
|||
episodes=episodes,
|
||||
columns=columns,
|
||||
selected=selected,
|
||||
stock_ok_button='gpodder-download',
|
||||
ok_button='gpodder-download',
|
||||
callback=download_episodes_callback,
|
||||
remove_callback=lambda e: e.mark_old(),
|
||||
remove_action=_('Mark as old'),
|
||||
remove_action=_('_Mark as old'),
|
||||
remove_finished=self.episode_new_status_changed,
|
||||
_config=self.config,
|
||||
show_notification=False)
|
||||
|
@ -3535,7 +3541,7 @@ class gPodder(BuilderWidget, dbus.service.Object):
|
|||
episodes=self.channels,
|
||||
columns=columns,
|
||||
size_attribute=None,
|
||||
stock_ok_button=_('Delete'),
|
||||
ok_button=_('_Delete'),
|
||||
callback=self.remove_podcast_list,
|
||||
_config=self.config)
|
||||
|
||||
|
@ -3636,8 +3642,8 @@ class gPodder(BuilderWidget, dbus.service.Object):
|
|||
dlg = Gtk.FileChooserDialog(title=_('Import from OPML'),
|
||||
parent=self.main_window,
|
||||
action=Gtk.FileChooserAction.OPEN)
|
||||
dlg.add_button(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL)
|
||||
dlg.add_button(Gtk.STOCK_OPEN, Gtk.ResponseType.OK)
|
||||
dlg.add_button(_('_Cancel'), Gtk.ResponseType.CANCEL)
|
||||
dlg.add_button(_('_Open'), Gtk.ResponseType.OK)
|
||||
dlg.set_filter(self.get_opml_filter())
|
||||
response = dlg.run()
|
||||
filename = None
|
||||
|
@ -3665,8 +3671,8 @@ class gPodder(BuilderWidget, dbus.service.Object):
|
|||
dlg = Gtk.FileChooserDialog(title=_('Export to OPML'),
|
||||
parent=self.gPodder,
|
||||
action=Gtk.FileChooserAction.SAVE)
|
||||
dlg.add_button(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL)
|
||||
dlg.add_button(Gtk.STOCK_SAVE, Gtk.ResponseType.OK)
|
||||
dlg.add_button(_('_Cancel'), Gtk.ResponseType.CANCEL)
|
||||
dlg.add_button(_('_Save'), Gtk.ResponseType.OK)
|
||||
dlg.set_filter(self.get_opml_filter())
|
||||
response = dlg.run()
|
||||
if response == Gtk.ResponseType.OK:
|
||||
|
|
|
@ -198,7 +198,7 @@ class EpisodeListModel(Gtk.ListStore):
|
|||
self.ICON_VIDEO_FILE = 'video-x-generic'
|
||||
self.ICON_IMAGE_FILE = 'image-x-generic'
|
||||
self.ICON_GENERIC_FILE = 'text-x-generic'
|
||||
self.ICON_DOWNLOADING = Gtk.STOCK_GO_DOWN
|
||||
self.ICON_DOWNLOADING = 'go-down'
|
||||
self.ICON_DELETED = 'edit-delete'
|
||||
self.ICON_ERROR = 'dialog-error'
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ from gpodder.gtkui.draw import (draw_text_box_centered, get_background_color,
|
|||
import gi # isort:skip
|
||||
gi.require_version('Gdk', '3.0') # isort:skip
|
||||
gi.require_version('Gtk', '3.0') # isort:skip
|
||||
from gi.repository import Gdk, Gtk, Pango # isort:skip
|
||||
from gi.repository import Gdk, Gio, GLib, Gtk, Pango # isort:skip
|
||||
|
||||
|
||||
_ = gpodder.gettext
|
||||
|
@ -438,8 +438,8 @@ class gPodderShownotesHTML(gPodderShownotes):
|
|||
decision.use()
|
||||
return False
|
||||
|
||||
def on_open_in_browser(self, action):
|
||||
util.open_website(action.url)
|
||||
def on_open_in_browser(self, action, var):
|
||||
util.open_website(var.get_string())
|
||||
|
||||
def on_authenticate(self, view, request):
|
||||
if request.is_retry():
|
||||
|
@ -469,10 +469,10 @@ class gPodderShownotesHTML(gPodderShownotes):
|
|||
return False
|
||||
|
||||
def create_open_item(self, name, label, url):
|
||||
action = Gtk.Action.new(name, label, None, Gtk.STOCK_OPEN)
|
||||
action.url = url
|
||||
action = Gio.SimpleAction.new(name, GLib.VariantType.new('s'))
|
||||
action.connect('activate', self.on_open_in_browser)
|
||||
return WebKit2.ContextMenuItem.new(action)
|
||||
var = GLib.Variant.new_string(url)
|
||||
return WebKit2.ContextMenuItem.new_from_gaction(action, label, var)
|
||||
|
||||
def get_stylesheet(self):
|
||||
if self.stylesheet is None:
|
||||
|
|
|
@ -30,7 +30,6 @@ import os.path
|
|||
import threading
|
||||
import time
|
||||
from enum import Enum
|
||||
from os import sync
|
||||
from re import S
|
||||
from urllib.parse import urlparse
|
||||
|
||||
|
@ -38,8 +37,8 @@ import gpodder
|
|||
from gpodder import download, services, util
|
||||
|
||||
import gi # isort:skip
|
||||
gi.require_version('Gtk', '3.0') # isort:skip
|
||||
from gi.repository import GLib, Gio, Gtk # isort:skip
|
||||
gi.require_version('Gio', '2.0') # isort:skip
|
||||
from gi.repository import GLib, Gio # isort:skip
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
@ -727,7 +726,7 @@ class SyncTask(download.DownloadTask):
|
|||
# An object representing the synchronization task of an episode
|
||||
|
||||
# Possible states this sync task can be in
|
||||
STATUS_MESSAGE = (_('Queued'), _('Queued'), _('Downloading'),
|
||||
STATUS_MESSAGE = (_('Queued'), _('Queued'), _('Syncing'),
|
||||
_('Finished'), _('Failed'), _('Cancelling'), _('Cancelled'), _('Pausing'), _('Paused'))
|
||||
(NEW, QUEUED, DOWNLOADING, DONE, FAILED, CANCELLING, CANCELLED, PAUSING, PAUSED) = list(range(9))
|
||||
|
||||
|
|
|
@ -161,7 +161,8 @@ def is_absolute_url(url):
|
|||
"""
|
||||
try:
|
||||
parsed = urllib.parse.urlparse(url)
|
||||
return not not parsed.scheme
|
||||
# fix #1190: when parsing a windows path, scheme=drive_letter, path=\rest_of_path
|
||||
return parsed.scheme and not parsed.path.startswith("\\")
|
||||
except ValueError:
|
||||
return False
|
||||
|
||||
|
@ -775,6 +776,10 @@ class ExtractHyperlinkedText(object):
|
|||
return self.extracter.get_result()
|
||||
|
||||
def visit(self, element):
|
||||
# skip functions generated by html5lib for comments in the HTML
|
||||
if callable(element.tag):
|
||||
return
|
||||
|
||||
NS = '{http://www.w3.org/1999/xhtml}'
|
||||
tag_name = (element.tag[len(NS):] if element.tag.startswith(NS) else element.tag).lower()
|
||||
self.extracter.handle_starttag(tag_name, list(element.items()))
|
||||
|
@ -1465,7 +1470,7 @@ def http_request(url, method='HEAD'):
|
|||
return conn.getresponse()
|
||||
|
||||
|
||||
def gui_open(filename):
|
||||
def gui_open(filename, gui=None):
|
||||
"""
|
||||
Open a file or folder with the default application set
|
||||
by the Desktop environment. This uses "xdg-open" on all
|
||||
|
@ -1476,13 +1481,30 @@ def gui_open(filename):
|
|||
try:
|
||||
if gpodder.ui.win32:
|
||||
os.startfile(filename)
|
||||
opener = None
|
||||
elif gpodder.ui.osx:
|
||||
Popen(['open', filename], close_fds=True)
|
||||
opener = 'open'
|
||||
else:
|
||||
Popen(['xdg-open', filename], close_fds=True)
|
||||
opener = 'xdg-open'
|
||||
|
||||
if opener:
|
||||
opener_fullpath = shutil.which(opener)
|
||||
if opener_fullpath is None:
|
||||
raise Exception((_("System default program '%(opener)s' not found"))
|
||||
% {'opener': opener}
|
||||
)
|
||||
Popen([opener_fullpath, filename], close_fds=True)
|
||||
return True
|
||||
except:
|
||||
logger.error('Cannot open file/folder: "%s"', filename, exc_info=True)
|
||||
if gui is not None:
|
||||
if opener is None:
|
||||
message = _("Cannot open file/folder '%(filename)s' using default program") % {'filename': filename}
|
||||
else:
|
||||
message = _("Cannot open '%(filename)s' using '%(opener)s'") \
|
||||
% {'filename': filename, 'opener': opener}
|
||||
gui.show_message_details(_('Cannot open file/folder'),
|
||||
str(sys.exc_info()[1]), message)
|
||||
return False
|
||||
|
||||
|
||||
|
|
|
@ -147,8 +147,21 @@ hls_formats = [
|
|||
]
|
||||
hls_formats_dict = dict(hls_formats)
|
||||
|
||||
V3_API_ENDPOINT = 'https://www.googleapis.com/youtube/v3'
|
||||
CHANNEL_VIDEOS_XML = 'https://www.youtube.com/feeds/videos.xml'
|
||||
WATCH_ENDPOINT = 'https://www.youtube.com/watch?bpctr=9999999999&has_verified=1&v='
|
||||
|
||||
# The page may contain "};" sequences inside the initial player response.
|
||||
# Use a greedy match with script end tag, and fallback to a non-greedy match without.
|
||||
INITIAL_PLAYER_RESPONSE_RE1 = r'ytInitialPlayerResponse\s*=\s*({.+})\s*;\s*</script'
|
||||
INITIAL_PLAYER_RESPONSE_RE2 = r'ytInitialPlayerResponse\s*=\s*({.+?})\s*;'
|
||||
|
||||
|
||||
def get_ipr(page):
|
||||
for regex in (INITIAL_PLAYER_RESPONSE_RE1, INITIAL_PLAYER_RESPONSE_RE2):
|
||||
ipr = re.search(regex, page)
|
||||
if ipr is not None:
|
||||
return ipr
|
||||
return None
|
||||
|
||||
|
||||
class YouTubeError(Exception):
|
||||
|
@ -198,12 +211,12 @@ def youtube_get_old_endpoint(vid):
|
|||
|
||||
|
||||
def youtube_get_new_endpoint(vid):
|
||||
url = 'https://www.youtube.com/watch?bpctr=9999999999&has_verified=1&v=' + vid
|
||||
url = WATCH_ENDPOINT + vid
|
||||
r = util.urlopen(url)
|
||||
if not r.ok:
|
||||
raise YouTubeError('Youtube "%s": %d %s' % (url, r.status_code, r.reason))
|
||||
|
||||
ipr = re.search(r'ytInitialPlayerResponse\s*=\s*({.+?})\s*;', r.text)
|
||||
ipr = get_ipr(r.text)
|
||||
if ipr is None:
|
||||
try:
|
||||
url = get_gdpr_consent_url(r.text)
|
||||
|
@ -213,7 +226,7 @@ def youtube_get_new_endpoint(vid):
|
|||
if not r.ok:
|
||||
raise YouTubeError('Youtube "%s": %d %s' % (url, r.status_code, r.reason))
|
||||
|
||||
ipr = re.search(r'ytInitialPlayerResponse\s*=\s*({.+?})\s*;', r.text)
|
||||
ipr = get_ipr(r.text)
|
||||
if ipr is None:
|
||||
raise YouTubeError('Youtube "%s": No ytInitialPlayerResponse found' % url)
|
||||
|
||||
|
@ -226,19 +239,19 @@ def get_total_time(episode):
|
|||
if vid is None:
|
||||
return 0
|
||||
|
||||
url = 'https://www.youtube.com/watch?v=' + vid
|
||||
url = WATCH_ENDPOINT + vid
|
||||
r = util.urlopen(url)
|
||||
if not r.ok:
|
||||
return 0
|
||||
|
||||
ipr = re.search(r'ytInitialPlayerResponse\s*=\s*({.+?})\s*;', r.text)
|
||||
ipr = get_ipr(r.text)
|
||||
if ipr is None:
|
||||
url = get_gdpr_consent_url(r.text)
|
||||
r = util.urlopen(url)
|
||||
if not r.ok:
|
||||
return 0
|
||||
|
||||
ipr = re.search(r'ytInitialPlayerResponse\s*=\s*({.+?})\s*;', r.text)
|
||||
ipr = get_ipr(r.text)
|
||||
if ipr is None:
|
||||
return 0
|
||||
|
||||
|
@ -354,10 +367,6 @@ def get_real_download_url(url, allow_partial, preferred_fmt_ids=None):
|
|||
|
||||
|
||||
def get_youtube_id(url):
|
||||
r = re.compile(r'http[s]?://(?:[a-z]+\.)?youtube\.com/v/(.*)\.swf', re.IGNORECASE).match(url)
|
||||
if r is not None:
|
||||
return r.group(1)
|
||||
|
||||
r = re.compile(r'http[s]?://(?:[a-z]+\.)?youtube\.com/watch\?v=([^&]*)', re.IGNORECASE).match(url)
|
||||
if r is not None:
|
||||
return r.group(1)
|
||||
|
@ -366,6 +375,10 @@ def get_youtube_id(url):
|
|||
if r is not None:
|
||||
return r.group(1)
|
||||
|
||||
r = re.compile(r'http[s]?://(?:[a-z]+\.)?youtube\.com/v/(.*)\.swf', re.IGNORECASE).match(url)
|
||||
if r is not None:
|
||||
return r.group(1)
|
||||
|
||||
return for_each_feed_pattern(lambda url, channel: channel, url, None)
|
||||
|
||||
|
||||
|
@ -389,6 +402,7 @@ def for_each_feed_pattern(func, url, fallback_result):
|
|||
r'http[s]?://(?:[a-z]+\.)?youtube\.com/profile?user=([a-z0-9]+)',
|
||||
r'http[s]?://(?:[a-z]+\.)?youtube\.com/rss/user/([a-z0-9]+)/videos\.rss',
|
||||
r'http[s]?://(?:[a-z]+\.)?youtube\.com/channel/([-_a-z0-9]+)',
|
||||
r'http[s]?://(?:[a-z]+\.)?youtube\.com/feeds/videos.xml\?user=([a-z0-9]+)',
|
||||
r'http[s]?://(?:[a-z]+\.)?youtube\.com/feeds/videos.xml\?channel_id=([-_a-z0-9]+)',
|
||||
r'http[s]?://gdata.youtube.com/feeds/users/([^/]+)/uploads',
|
||||
r'http[s]?://gdata.youtube.com/feeds/base/users/([^/]+)/uploads',
|
||||
|
|
|
@ -97,6 +97,7 @@ urllib3==1.26.5
|
|||
chardet==4.0.0
|
||||
idna==3.2
|
||||
PySocks==1.7.1
|
||||
comtypes==1.1.10
|
||||
"
|
||||
|
||||
function install_deps {
|
||||
|
|
Loading…
Reference in New Issue