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 self
.episode_actions
= gPodderEpisodeActions(self
.main_window
, \
40 episode_list_status_changed
=self
.episode_list_status_changed
, \
41 episode_is_downloading
=self
.episode_is_downloading
, \
42 show_episode_shownotes
=self
.show_episode_shownotes
, \
43 playback_episodes
=self
.playback_episodes
, \
44 download_episode_list
=self
.download_episode_list
, \
45 show_episode_in_download_manager
=self
.show_episode_in_download_manager
, \
46 add_download_task_monitor
=self
.add_download_task_monitor
, \
47 remove_download_task_monitor
=self
.remove_download_task_monitor
, \
48 for_each_episode_set_task_status
=self
.for_each_episode_set_task_status
, \
49 delete_episode_list
=self
.delete_episode_list
)
51 # Tap-and-hold (aka "long press") context menu
52 self
.touched_episode
= None
53 self
.context_menu
= gtk
.Menu()
54 # "Emulate" hildon_gtk_menu_new
55 self
.context_menu
.set_name('hildon-context-sensitive-menu')
56 self
.context_menu
.append(self
.action_shownotes
.create_menu_item())
57 self
.context_menu
.append(self
.action_download
.create_menu_item())
58 self
.context_menu
.append(self
.action_delete
.create_menu_item())
59 self
.context_menu
.append(gtk
.SeparatorMenuItem())
60 self
.context_menu
.append(self
.action_keep
.create_menu_item())
61 self
.context_menu
.append(self
.action_mark_as_old
.create_menu_item())
62 self
.context_menu
.show_all()
63 self
.treeview
.tap_and_hold_setup(self
.context_menu
)
65 # Workaround for Maemo bug XXX
66 self
.button_search_episodes_clear
.set_name('HildonButton-thumb')
67 appmenu
= hildon
.AppMenu()
68 for action
in (self
.action_update
, \
70 self
.action_play_m3u
, \
72 self
.action_unsubscribe
, \
73 self
.action_check_for_new_episodes
, \
74 self
.action_delete_episodes
):
76 action
.connect_proxy(button
)
77 appmenu
.append(button
)
78 for filter in (self
.item_view_episodes_all
, \
79 self
.item_view_episodes_undeleted
, \
80 self
.item_view_episodes_downloaded
):
81 button
= gtk
.ToggleButton()
82 filter.connect_proxy(button
)
83 appmenu
.add_filter(button
)
85 self
.main_window
.set_app_menu(appmenu
)
87 def on_rename_button_clicked(self
, widget
):
88 if self
.channel
is None:
91 new_title
= self
.show_text_edit_dialog(_('Rename podcast'), \
92 _('New name:'), self
.channel
.title
, \
93 affirmative_text
=_('Rename'))
94 if new_title
is not None and new_title
!= self
.channel
.title
:
95 self
.channel
.set_custom_title(new_title
)
96 self
.main_window
.set_title(self
.channel
.title
)
98 self
.show_message(_('Podcast renamed: %s') % new_title
)
99 self
.update_podcast_list_model(urls
=[self
.channel
.url
])
101 def on_login_button_clicked(self
, widget
):
102 accept
, auth_data
= self
.show_login_dialog(_('Login to %s') % \
103 self
.channel
.title
, '', \
104 self
.channel
.username
, \
105 self
.channel
.password
)
107 self
.channel
.username
, self
.channel
.password
= auth_data
110 def on_play_m3u_button_clicked(self
, widget
):
111 if self
.channel
is not None:
112 util
.gui_open(self
.channel
.get_playlist_filename())
114 def on_website_button_clicked(self
, widget
):
115 if self
.channel
is not None:
116 util
.open_website(self
.channel
.link
)
118 def on_update_button_clicked(self
, widget
):
119 self
.on_itemUpdateChannel_activate()
121 def on_unsubscribe_button_clicked(self
, widget
):
122 self
.on_delete_event(widget
, None)
123 self
.on_itemRemoveChannel_activate(widget
)
125 def on_episode_selected(self
, treeview
, path
, column
):
126 model
= treeview
.get_model()
127 episode
= model
.get_value(model
.get_iter(path
), \
128 EpisodeListModel
.C_EPISODE
)
129 self
.episode_actions
.show_episode(episode
)
131 def on_delete_event(self
, widget
, event
):
132 self
.main_window
.hide()
134 self
.hide_episode_search()
137 def on_treeview_button_press(self
, widget
, event
):
138 result
= self
.treeview
.get_path_at_pos(int(event
.x
), int(event
.y
))
139 if result
is not None:
140 path
, column
, x
, y
= result
141 model
= self
.treeview
.get_model()
142 episode
= model
.get_value(model
.get_iter(path
), \
143 EpisodeListModel
.C_EPISODE
)
145 self
.action_delete
.set_property('visible', not episode
.is_locked
)
147 if episode
.was_downloaded():
148 self
.action_keep
.set_property('visible', True)
149 self
.action_download
.set_property('visible', not episode
.was_downloaded(and_exists
=True))
151 self
.action_keep
.set_property('visible', False)
152 self
.action_download
.set_property('visible', not self
.episode_is_downloading(episode
))
154 self
.touched_episode
= None
156 self
.action_keep
.set_active(episode
.is_locked
)
157 self
.action_mark_as_old
.set_active(not episode
.is_played
)
159 self
.touched_episode
= episode
161 self
.touched_episode
= None
163 def on_shownotes_button_clicked(self
, widget
):
164 if self
.touched_episode
is not None:
165 self
.show_episode_shownotes(self
.touched_episode
)
167 def on_download_button_clicked(self
, widget
):
168 if self
.touched_episode
is not None:
169 self
.show_message(_('Downloading episode'))
170 self
.download_episode_list([self
.touched_episode
])
172 def on_delete_button_clicked(self
, widget
):
173 if self
.touched_episode
is not None:
174 self
.delete_episode_list([self
.touched_episode
])
176 def on_keep_button_clicked(self
, widget
):
177 if self
.touched_episode
is not None:
178 self
.touched_episode
.mark(is_locked
=not self
.touched_episode
.is_locked
)
179 self
.episode_list_status_changed([self
.touched_episode
])
181 def on_mark_as_old_button_clicked(self
, widget
):
182 if self
.touched_episode
is not None:
183 self
.touched_episode
.mark(is_played
=not self
.touched_episode
.is_played
)
184 self
.episode_list_status_changed([self
.touched_episode
])
186 def on_check_for_new_episodes_button_clicked(self
, widget
):
187 self
.show_message(_('Checking for new episodes...'))
188 self
.on_itemUpdate_activate(widget
)
191 # Check if we are displaying the "all episodes" view
192 all_episodes
= isinstance(self
.channel
, PodcastChannelProxy
)
194 for action
in (self
.action_rename
, \
195 self
.action_play_m3u
, \
197 self
.action_unsubscribe
, \
199 action
.set_visible(not all_episodes
)
201 for action
in (self
.action_check_for_new_episodes
, \
202 self
.action_delete_episodes
):
203 action
.set_visible(all_episodes
)
205 self
.main_window
.set_title(self
.channel
.title
)
206 self
.main_window
.show()
207 self
.treeview
.grab_focus()