Index: src/plugins/youtube/youtube.py
===================================================================
--- src/plugins/youtube/youtube.py	(revision 5874)
+++ src/plugins/youtube/youtube.py	(working copy)
@@ -125,6 +125,7 @@
 		self.vbox = self.builder.get_object ("yt_vbox")
 		self.vbox.show_all ()
 		totem_object.add_sidebar_page ("youtube", _("YouTube"), self.vbox)
+		self.save_as_path = self.gconf_client.get_string ("/apps/totem/open_path")
 
 		"""Set up the service"""
 		self.service = gdata.service.GDataService (account_type = "HOSTED_OR_GOOGLE", server = "gdata.youtube.com")
@@ -162,7 +163,20 @@
 				   False)
 		menu_item = ui_manager.get_action ("/ui/totem-video-list-popup/open-in-web-browser")
 		menu_item.connect ("activate", self.on_open_in_web_browser_activated)
+		"""Save as... menu"""
+		action = gtk.Action ("save-as", _("_Save as..."), _("Save the video locally"), "gtk-save-as")
+		action_group.add_action_with_accel (action, None)
 
+		ui_manager.insert_action_group (action_group, 2)
+		ui_manager.add_ui (ui_manager.new_merge_id (),
+				   "/ui/totem-video-list-popup/",
+				   "save-as",
+				   "save-as",
+				   gtk.UI_MANAGER_MENUITEM,
+				   False)
+		menu_item = ui_manager.get_action ("/ui/totem-video-list-popup/save-as")
+		menu_item.connect ("activate", self.on_save_as_activated)
+
 		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 ()
@@ -243,6 +257,64 @@
 		"""Open the video in the browser"""
 		os.spawnlp (os.P_NOWAIT, "xdg-open", "xdg-open", "http://www.youtube.com/watch?v=" + urllib.quote (youtube_id) + self.get_fmt_string ())
 
+ 	def on_save_as_activated(self, action):
+ 		model, rows = self.treeview[self.current_treeview_name].get_selection ().get_selected_rows ()
+ 		iter = model.get_iter (rows[0])
+ 		video_title = model.get_value (iter, 1)
+ 		video_url = model.get_value (iter, 2)
+ 
+ 		"""Open the save as dialog"""
+ 		dialog = gtk.FileChooserDialog(title=_("Save as"),
+					       action=gtk.FILE_CHOOSER_ACTION_SAVE,
+					       buttons=(gtk.STOCK_CANCEL,
+						        gtk.RESPONSE_CANCEL,
+							gtk.STOCK_SAVE,
+							gtk.RESPONSE_OK))
+ 		dialog.set_current_name(video_title + ".flv")
+ 		dialog.set_do_overwrite_confirmation(True)
+ 		dialog.set_current_folder_uri(self.save_as_path)
+ 
+ 		response = dialog.run()
+ 		if response == gtk.RESPONSE_OK:
+ 			filename = dialog.get_filename()
+ 			self.save_as_path = dialog.get_current_folder_uri()
+ 		else:
+ 			dialog.destroy()
+ 			return
+ 		dialog.destroy()
+ 
+ 		"""Download the video from the url"""
+		"""Doing this in a background thread would be better but thread management is a headacke with pyGtk"""
+		"""Once playbin2 is used in totem, it might be possible to directly dump the buffer to the disk"""
+		"""For now we disable the usage of the plugin's widgets while downloading."""
+		"""disable all"""
+		for page in self.notebook_pages:
+			self.treeview[page].set_sensitive(False)
+		self.search_button.set_sensitive(False)
+		self.search_entry.handler_block_by_func (self.on_search_entry_activated)
+
+ 		self.progress_bar.set_text (_("Saving video..."))
+ 		self.progress_bar.set_fraction (0.0)
+		try:
+			urllib.urlretrieve(video_url, filename, self.download_report_cb)
+		except:
+			pass
+ 		self.progress_bar.set_text ("")
+ 		self.progress_bar.set_fraction (0.0)
+
+		"""reenable all"""
+		for page in self.notebook_pages:
+			self.treeview[page].set_sensitive(True)
+		self.search_button.set_sensitive(True)
+		self.search_entry.handler_unblock_by_func (self.on_search_entry_activated)
+
+ 	def download_report_cb (self, blocks, blck_size, total):
+ 		fraction = float (blocks * blck_size) / float (total)
+ 		if fraction > 0.0 and fraction < 1.0:
+ 			self.progress_bar.set_fraction (fraction)
+ 		while gtk.events_pending():
+ 			gtk.main_iteration()
+
 	def on_button_press_event (self, widget, event):
 		self.button_down = True
 
