diff options
author | Philip Withnall <pwithnall@svn.gnome.org> | 2007-10-27 21:03:00 +0000 |
---|---|---|
committer | Philip Withnall <pwithnall@src.gnome.org> | 2007-10-27 21:03:00 +0000 |
commit | 4873b8b3380636cb8087ac6ff7fd7fdc5b03cb46 (patch) | |
tree | 74196e7c109c673e08d6cee0b88af288c3c8c15c | |
parent | dc91677c8b26587bc4333306b5f53d25048254f6 (diff) | |
download | totem-4873b8b3380636cb8087ac6ff7fd7fdc5b03cb46.tar.gz |
Split videos out into two treeviews; one for search results and one for
2007-10-27 Philip Withnall <pwithnall@svn.gnome.org>
* src/plugins/youtube/youtube.py:
* src/plugins/youtube/youtube.ui: Split videos out into two
treeviews; one for search results and one for related videos,
meaning that search results are no longer lost (Closes: #487100)
svn path=/trunk/; revision=4824
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | src/plugins/youtube/youtube.py | 148 | ||||
-rw-r--r-- | src/plugins/youtube/youtube.ui | 82 |
3 files changed, 151 insertions, 86 deletions
@@ -1,3 +1,10 @@ +2007-10-27 Philip Withnall <pwithnall@svn.gnome.org> + + * src/plugins/youtube/youtube.py: + * src/plugins/youtube/youtube.ui: Split videos out into two + treeviews; one for search results and one for related videos, + meaning that search results are no longer lost (Closes: #487100) + 2007-10-25 Bastien Nocera <hadess@hadess.net> * data/mime-type-list.txt: add audio/x-xm (XM tracker files) diff --git a/src/plugins/youtube/youtube.py b/src/plugins/youtube/youtube.py index ce88c7019..982579477 100644 --- a/src/plugins/youtube/youtube.py +++ b/src/plugins/youtube/youtube.py @@ -9,50 +9,50 @@ import re from os import unlink class DownloadThread (threading.Thread): - def __init__ (self, youtube, url): + def __init__ (self, youtube, url, treeview_name): self.youtube = youtube self.url = url + self.treeview_name = treeview_name threading.Thread.__init__ (self) def run (self): - self.youtube.entry = self.youtube.service.Get (self.url).entry + self.youtube.entry[self.treeview_name] = self.youtube.service.Get (self.url).entry class YouTube (totem.Plugin): def __init__ (self): totem.Plugin.__init__(self) self.debug = False - self.search_mode = True - self.query = "" - self.start_index = 1 + self.max_results = 20 - """Note that this is just the number of results from the last pagination query""" - self.results = 0 - self.entry = None self.button_down = False + + self.search_terms = "" + self.youtube_id = "" + + self.start_index = {} + self.results = {} # This is just the number of results from the last pagination query + self.entry = {} + + self.current_treeview_name = "" + self.notebook_pages = [] + + self.vadjust = {} + self.liststore = {} def activate (self, totem_object): self.builder = self.load_interface ("youtube.ui", True, totem_object.get_main_window (), self) + self.totem = totem_object self.search_entry = self.builder.get_object ("yt_search_entry") self.search_entry.connect ("activate", self.on_search_entry_activated) self.search_button = self.builder.get_object ("yt_search_button") self.search_button.connect ("clicked", self.on_search_button_clicked) - self.status_label = self.builder.get_object ("yt_status_label") - """This is done here rather than in the UI file, because UI files parsed in C and GObjects created in Python apparently don't mix.""" - self.renderer = totem.CellRendererVideo () - self.treeview = self.builder.get_object ("yt_treeview") - self.treeview.set_property ("totem", totem_object) - self.treeview.connect ("row-activated", self.on_row_activated) - self.treeview.connect ("starting-video", self.on_starting_video) - self.treeview.insert_column_with_attributes (0, _("Videos"), self.renderer, thumbnail=0, title=1) - - self.vadjust = self.treeview.get_vadjustment () - self.vadjust.connect ("value-changed", self.on_value_changed) - vscroll = self.builder.get_object ("yt_scrolled_window").get_vscrollbar () - vscroll.connect ("button-press-event", self.on_button_press_event) - vscroll.connect ("button-release-event", self.on_button_release_event) + self.notebook = self.builder.get_object ("yt_notebook") + self.notebook.connect ("switch-page", self.on_notebook_page_changed) - self.liststore = self.builder.get_object ("yt_liststore") - self.treeview.set_model (self.liststore) + self.notebook_pages = ["search", "related"] + for page in self.notebook_pages: + self.setup_treeview (page) + self.current_treeview_name = "search" vbox = self.builder.get_object ("yt_vbox") vbox.show_all () @@ -60,19 +60,40 @@ class YouTube (totem.Plugin): """Set up the service""" self.service = gdata.service.GDataService (None, None, "HOSTED_OR_GOOGLE", None, None, "gdata.youtube.com") - self.totem = totem_object def deactivate (self, totem): totem.remove_sidebar_page ("youtube") + def setup_treeview (self, treeview_name): + self.start_index[treeview_name] = 1 + self.results[treeview_name] = 0 + self.entry[treeview_name] = None + + """This is done here rather than in the UI file, because UI files parsed in C and GObjects created in Python apparently don't mix.""" + renderer = totem.CellRendererVideo () + treeview = self.builder.get_object ("yt_treeview_" + treeview_name) + treeview.set_property ("totem", self.totem) + treeview.connect ("row-activated", self.on_row_activated) + treeview.connect ("starting-video", self.on_starting_video) + treeview.insert_column_with_attributes (0, _("Videos"), renderer, thumbnail=0, title=1) + + self.vadjust[treeview_name] = treeview.get_vadjustment () + self.vadjust[treeview_name].connect ("value-changed", self.on_value_changed) + vscroll = self.builder.get_object ("yt_scrolled_window_" + treeview_name).get_vscrollbar () + vscroll.connect ("button-press-event", self.on_button_press_event) + vscroll.connect ("button-release-event", self.on_button_release_event) + + self.liststore[treeview_name] = self.builder.get_object ("yt_liststore_" + treeview_name) + treeview.set_model (self.liststore[treeview_name]) + def on_notebook_page_changed (self, notebook, notebook_page, page_num): + self.current_treeview_name = self.notebook_pages[page_num] def on_row_activated (self, treeview, path, column): model, iter = treeview.get_selection ().get_selected () youtube_id = model.get_value (iter, 3) """Get related videos""" - self.search_mode = False - self.query = youtube_id - self.start_index = 1 - self.results = 0 - self.get_results ("/feeds/videos/" + urllib.quote (youtube_id) + "/related?max-results=" + str (self.max_results), _("Related Videos:")) + self.youtube_id = youtube_id + self.start_index["related"] = 1 + self.results["related"] = 0 + self.get_results ("/feeds/videos/" + urllib.quote (youtube_id) + "/related?max-results=" + str (self.max_results), "related") def on_starting_video (self, treeview, path, user_data): model, iter = treeview.get_selection ().get_selected () youtube_id = model.get_value (iter, 3) @@ -100,29 +121,30 @@ class YouTube (totem.Plugin): self.button_down = True def on_button_release_event (self, widget, event): self.button_down = False - self.on_value_changed (self.vadjust) + self.on_value_changed (self.vadjust[self.current_treeview_name]) def on_value_changed (self, adjustment): """Load more results when we get near the bottom of the treeview""" - if not self.button_down and (adjustment.get_value () + adjustment.page_size) / adjustment.upper > 0.8 and self.results >= self.max_results: - if self.debug: - print "Getting more results for query \"" + self.query + "\" from offset " + str (self.start_index) - self.results = 0 - if self.search_mode: - self.get_results ("/feeds/videos?vq=" + urllib.quote_plus (self.query) + "&max-results=" + str (self.max_results) + "&orderby=relevance&start-index=" + str (self.start_index), _("Search Results:"), False) - else: - self.get_results ("/feeds/videos/" + urllib.quote_plus (self.query) + "/related?max-results=" + str (self.max_results) + "&start-index=" + str (self.start_index), _("Related Videos:"), False) + if not self.button_down and (adjustment.get_value () + adjustment.page_size) / adjustment.upper > 0.8 and self.results[self.current_treeview_name] >= self.max_results: + self.results[self.current_treeview_name] = 0 + if self.current_treeview_name == "search": + self.get_results ("/feeds/videos?vq=" + urllib.quote_plus (self.search_terms) + "&max-results=" + str (self.max_results) + "&orderby=relevance&start-index=" + str (self.start_index["search"]), "search", False) + if self.debug: + print "Getting more results for search \"" + self.search_terms + "\" from offset " + str (self.start_index["search"]) + elif self.current_treeview_name == "related": + self.get_results ("/feeds/videos/" + urllib.quote_plus (self.youtube_id) + "/related?max-results=" + str (self.max_results) + "&start-index=" + str (self.start_index["related"]), "related", False) + if self.debug: + print "Getting more related videos for video \"" + self.youtube_id + "\" from offset " + str (self.start_index["related"]) def convert_url_to_id (self, url): """Find the last clause in the URL; after the last /""" return url.split ("/").pop () - def populate_list_from_results (self, status_text): + def populate_list_from_results (self, treeview_name): """Wait until we have some results to display""" - if self.entry == None or len (self.entry) == 0: + if self.entry[treeview_name] == None or len (self.entry[treeview_name]) == 0: return True - """Only do one result at a time, as the thumbnail has to be downloaded; give them a temporary MRL until the real one is resolved before playing""" - entry = self.entry.pop (0) - self.results += 1 - self.start_index += 1 + entry = self.entry[treeview_name].pop (0) + self.results[treeview_name] += 1 + self.start_index[treeview_name] += 1 youtube_id = self.convert_url_to_id (entry.id.text) mrl = "http://www.youtube.com/v/" + urllib.quote (youtube_id) @@ -148,13 +170,11 @@ class YouTube (totem.Plugin): """Don't leak the temporary file""" unlink (filename) - self.liststore.append ([pixbuf, entry.title.text, mrl, youtube_id]) - self.treeview.window.process_updates (True) + self.liststore[treeview_name].append ([pixbuf, entry.title.text, mrl, youtube_id]) """Have we finished?""" - if len (self.entry) == 0: - self.status_label.set_text (status_text) - self.entry = None + if len (self.entry[treeview_name]) == 0: + self.entry[treeview_name] = None return False return True @@ -164,25 +184,21 @@ class YouTube (totem.Plugin): if self.debug: print "Searching for \"" + search_terms + "\"" - self.search_mode = True - self.query = search_terms - self.start_index = 1 - self.results = 0 - self.get_results ("/feeds/videos?vq=" + urllib.quote_plus (search_terms) + "&orderby=relevance&max-results=" + str (self.max_results), _("Search Results:")) + """Focus the "Search" tab""" + self.notebook.set_current_page (self.notebook_pages.index ("search")) + + self.search_terms = search_terms + self.start_index["search"] = 1 + self.results["search"] = 0 + self.get_results ("/feeds/videos?vq=" + urllib.quote_plus (search_terms) + "&orderby=relevance&max-results=" + str (self.max_results), "search") def on_search_entry_activated (self, entry): self.search_button.clicked () - def get_results (self, url, status_text, clear = True): + def get_results (self, url, treeview_name, clear = True): if clear: - self.liststore.clear () - - self.status_label.set_text (_("Loading...")) - - """Make sure things are redrawn""" - self.status_label.window.process_updates (True) - self.treeview.window.process_updates (True) + self.liststore[treeview_name].clear () if self.debug: - print "Getting results from URL \"" + url + "\"" + print "Getting results from URL \"" + url + "\"" - DownloadThread (self, url).start () - gobject.idle_add (self.populate_list_from_results, status_text) + DownloadThread (self, url, treeview_name).start () + gobject.idle_add (self.populate_list_from_results, treeview_name) diff --git a/src/plugins/youtube/youtube.ui b/src/plugins/youtube/youtube.ui index 9026df975..3ca541bd6 100644 --- a/src/plugins/youtube/youtube.ui +++ b/src/plugins/youtube/youtube.ui @@ -2,7 +2,15 @@ <!--*- mode: xml -*--><!DOCTYPE glade-interface SYSTEM 'http://glade.gnome.org/glade-2.0.dtd'> <interface> -<object class="GtkListStore" id="yt_liststore"> +<object class="GtkListStore" id="yt_liststore_search"> + <columns> + <column type="GdkPixbuf"/><!--Thumbnail--> + <column type="gchararray"/><!--Title--> + <column type="gchararray"/><!--MRL--> + <column type="gchararray"/><!--YouTube ID--> + </columns> +</object> +<object class="GtkListStore" id="yt_liststore_related"> <columns> <column type="GdkPixbuf"/><!--Thumbnail--> <column type="gchararray"/><!--Title--> @@ -17,13 +25,9 @@ <property name="homogeneous">False</property> <property name="spacing">6</property> <child> - <object class="GtkLabel" id="yt_status_label"> - <property name="label" translatable="yes">Please enter a search.</property> - <property name="justify">GTK_JUSTIFY_LEFT</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> + <object class="GtkLabel" id="label0"> + <property name="label" translatable="yes">Search:</property> + <property name="xalign">0.0</property> </object> <packing> <property name="padding">0</property> @@ -71,20 +75,58 @@ </packing> </child> <child> - <object class="GtkScrolledWindow" id="yt_scrolled_window"> - <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> + <object class="GtkNotebook" id="yt_notebook"> + <child> + <object class="GtkScrolledWindow" id="yt_scrolled_window_search"> + <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> + <child> + <object class="TotemVideoList" id="yt_treeview_search"> + <property name="headers-visible">False</property> + <property name="fixed-height-mode">False</property> + <property name="tooltip-column">1</property> + <property name="mrl-column">2</property> + </object> + </child> + </object> + </child> + <child type="tab"> + <object class="GtkLabel" id="label1"> + <property name="label" translatable="yes">Search Results</property> + </object> + <packing> + <property name="tab-fill">False</property> + </packing> + </child> <child> - <object class="TotemVideoList" id="yt_treeview"> - <property name="headers-visible">False</property> - <property name="fixed-height-mode">False</property> - <property name="tooltip-column">1</property> - <property name="mrl-column">2</property> + <object class="GtkScrolledWindow" id="yt_scrolled_window_related"> + <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> + <child> + <object class="TotemVideoList" id="yt_treeview_related"> + <property name="headers-visible">False</property> + <property name="fixed-height-mode">False</property> + <property name="tooltip-column">1</property> + <property name="mrl-column">2</property> + </object> + </child> + </object> + </child> + <child type="tab"> + <object class="GtkLabel" id="label2"> + <property name="label" translatable="yes">Related Videos</property> </object> + <packing> + <property name="tab-fill">False</property> + </packing> </child> </object> <packing> |