1 # -*- coding: utf-8 -*-
3 # gPodder - A media aggregator and podcast client
4 # Copyright (c) 2005-2010 Thomas Perl and the gPodder Team
6 # gPodder is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 3 of the License, or
9 # (at your option) any later version.
11 # gPodder is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
27 from gpodder
import util
29 from gpodder
.gtkui
.interface
.common
import BuilderWidget
30 from gpodder
.gtkui
.model
import EpisodeListModel
31 from gpodder
.gtkui
.model
import PodcastChannelProxy
33 from gpodder
.gtkui
.frmntl
.episodeactions
import gPodderEpisodeActions
35 class gPodderEpisodes(BuilderWidget
):
39 # Styling for the label that appears when the list is empty
40 hildon
.hildon_helper_set_logical_font(self
.empty_label
, \
42 hildon
.hildon_helper_set_logical_color(self
.empty_label
, \
43 gtk
.RC_FG
, gtk
.STATE_NORMAL
, 'SecondaryTextColor')
45 self
.episode_actions
= gPodderEpisodeActions(self
.main_window
, \
46 episode_list_status_changed
=self
.episode_list_status_changed
, \
47 episode_is_downloading
=self
.episode_is_downloading
, \
48 show_episode_shownotes
=self
.show_episode_shownotes
, \
49 playback_episodes
=self
.playback_episodes
, \
50 download_episode_list
=self
.download_episode_list
, \
51 show_episode_in_download_manager
=self
.show_episode_in_download_manager
, \
52 add_download_task_monitor
=self
.add_download_task_monitor
, \
53 remove_download_task_monitor
=self
.remove_download_task_monitor
, \
54 for_each_episode_set_task_status
=self
.for_each_episode_set_task_status
, \
55 delete_episode_list
=self
.delete_episode_list
)
57 # Tap-and-hold (aka "long press") context menu
58 self
.touched_episode
= None
59 self
.context_menu
= gtk
.Menu()
60 # "Emulate" hildon_gtk_menu_new
61 self
.context_menu
.set_name('hildon-context-sensitive-menu')
62 self
.context_menu
.append(self
.action_shownotes
.create_menu_item())
63 self
.context_menu
.append(self
.action_download
.create_menu_item())
64 self
.context_menu
.append(self
.action_delete
.create_menu_item())
65 self
.context_menu
.append(gtk
.SeparatorMenuItem())
66 self
.context_menu
.append(self
.action_keep
.create_menu_item())
67 self
.context_menu
.append(self
.action_mark_as_old
.create_menu_item())
68 self
.context_menu
.show_all()
69 self
.treeview
.tap_and_hold_setup(self
.context_menu
)
71 # Workaround for Maemo bug XXX
72 self
.button_search_episodes_clear
.set_name('HildonButton-thumb')
73 appmenu
= hildon
.AppMenu()
74 for action
in (self
.action_update
, \
77 self
.action_unsubscribe
, \
78 self
.action_check_for_new_episodes
, \
79 self
.action_delete_episodes
):
81 action
.connect_proxy(button
)
82 appmenu
.append(button
)
84 self
.pause_sub_button
= hildon
.CheckButton(gtk
.HILDON_SIZE_FINGER_HEIGHT
)
85 self
.pause_sub_button
.set_label(_('Pause subscription'))
86 self
.pause_sub_button
.connect('toggled', self
.on_pause_subscription_button_toggled
)
87 appmenu
.append(self
.pause_sub_button
)
89 for filter in (self
.item_view_episodes_all
, \
90 self
.item_view_episodes_undeleted
, \
91 self
.item_view_episodes_downloaded
):
92 button
= gtk
.ToggleButton()
93 filter.connect_proxy(button
)
94 appmenu
.add_filter(button
)
96 self
.main_window
.set_app_menu(appmenu
)
98 def on_pause_subscription_button_toggled(self
, widget
):
99 new_value
= not widget
.get_active()
100 print 'toggled with new value = ', new_value
101 if new_value
!= self
.channel
.feed_update_enabled
:
102 self
.channel
.feed_update_enabled
= new_value
103 self
.cover_downloader
.reload_cover_from_disk(self
.channel
)
105 self
.update_podcast_list_model(urls
=[self
.channel
.url
])
107 def on_rename_button_clicked(self
, widget
):
108 if self
.channel
is None:
111 new_title
= self
.show_text_edit_dialog(_('Rename podcast'), \
112 _('New name:'), self
.channel
.title
, \
113 affirmative_text
=_('Rename'))
114 if new_title
is not None and new_title
!= self
.channel
.title
:
115 self
.channel
.set_custom_title(new_title
)
116 self
.main_window
.set_title(self
.channel
.title
)
118 self
.show_message(_('Podcast renamed: %s') % new_title
)
119 self
.update_podcast_list_model(urls
=[self
.channel
.url
])
121 def on_login_button_clicked(self
, widget
):
122 accept
, auth_data
= self
.show_login_dialog(_('Login to %s') % \
123 self
.channel
.title
, '', \
124 self
.channel
.username
, \
125 self
.channel
.password
)
127 self
.channel
.username
, self
.channel
.password
= auth_data
130 def on_website_button_clicked(self
, widget
):
131 if self
.channel
is not None:
132 util
.open_website(self
.channel
.link
)
134 def on_update_button_clicked(self
, widget
):
135 self
.on_itemUpdateChannel_activate()
137 def on_unsubscribe_button_clicked(self
, widget
):
138 self
.on_delete_event(widget
, None)
139 self
.on_itemRemoveChannel_activate(widget
)
141 def on_episode_selected(self
, treeview
, path
, column
):
142 model
= treeview
.get_model()
143 episode
= model
.get_value(model
.get_iter(path
), \
144 EpisodeListModel
.C_EPISODE
)
145 self
.episode_actions
.show_episode(episode
)
147 def on_delete_event(self
, widget
, event
):
148 self
.main_window
.hide()
150 self
.hide_episode_search()
153 def on_treeview_button_press(self
, widget
, event
):
154 result
= self
.treeview
.get_path_at_pos(int(event
.x
), int(event
.y
))
155 if result
is not None:
156 path
, column
, x
, y
= result
157 model
= self
.treeview
.get_model()
158 episode
= model
.get_value(model
.get_iter(path
), \
159 EpisodeListModel
.C_EPISODE
)
161 self
.action_delete
.set_property('visible', not episode
.is_locked
)
163 if episode
.was_downloaded():
164 self
.action_keep
.set_property('visible', True)
165 self
.action_download
.set_property('visible', not episode
.was_downloaded(and_exists
=True))
167 self
.action_keep
.set_property('visible', False)
168 self
.action_download
.set_property('visible', not self
.episode_is_downloading(episode
))
170 self
.touched_episode
= None
172 self
.action_keep
.set_active(episode
.is_locked
)
173 self
.action_mark_as_old
.set_active(not episode
.is_played
)
175 self
.touched_episode
= episode
177 self
.touched_episode
= None
179 def on_shownotes_button_clicked(self
, widget
):
180 if self
.touched_episode
is not None:
181 self
.show_episode_shownotes(self
.touched_episode
)
183 def on_download_button_clicked(self
, widget
):
184 if self
.touched_episode
is not None:
185 self
.show_message(_('Downloading episode'))
186 self
.download_episode_list([self
.touched_episode
])
188 def on_delete_button_clicked(self
, widget
):
189 if self
.touched_episode
is not None:
190 self
.delete_episode_list([self
.touched_episode
])
192 def on_keep_button_clicked(self
, widget
):
193 if self
.touched_episode
is not None:
194 self
.touched_episode
.mark(is_locked
=not self
.touched_episode
.is_locked
)
195 self
.episode_list_status_changed([self
.touched_episode
])
197 def on_mark_as_old_button_clicked(self
, widget
):
198 if self
.touched_episode
is not None:
199 self
.touched_episode
.mark(is_played
=not self
.touched_episode
.is_played
)
200 self
.episode_list_status_changed([self
.touched_episode
])
202 def on_check_for_new_episodes_button_clicked(self
, widget
):
203 self
.show_message(_('Checking for new episodes...'))
204 self
.on_itemUpdate_activate(widget
)
206 def on_delete_episodes_button_clicked(self
, widget
):
207 all_episodes
= isinstance(self
.channel
, PodcastChannelProxy
)
209 self
.show_delete_episodes_window()
211 self
.show_delete_episodes_window(self
.channel
)
214 # Check if we are displaying the "all episodes" view
215 all_episodes
= isinstance(self
.channel
, PodcastChannelProxy
)
217 for action
in (self
.action_rename
, \
219 self
.action_unsubscribe
, \
221 action
.set_visible(not all_episodes
)
223 self
.action_check_for_new_episodes
.set_visible(all_episodes
)
224 self
.action_delete_episodes
.set_visible(True)
226 self
.pause_sub_button
.set_active(\
227 not self
.channel
.feed_update_enabled
)
229 self
.main_window
.set_title(self
.channel
.title
)
230 self
.main_window
.show()
231 self
.treeview
.grab_focus()