예제 #1
0
static void
query_finished_cb (GObject *source_object, GAsyncResult *result, QueryData *data)
{
	GtkWindow *window;
	GDataFeed *feed;
	GError *error = NULL;
	TotemYouTubePlugin *self = data->plugin;

	g_debug ("Search finished!");

	feed = gdata_service_query_finish (GDATA_SERVICE (self->service), result, &error);

	/* Stop the progress bar; a little hacky, but it works */
	self->progress_bar_increment[data->tree_view] = 1.0;
	increment_progress_bar_fraction (self, data->tree_view);

	if (feed != NULL) {
		/* Success! */
		g_object_unref (feed);
		query_data_free (data);

		return;
	}

	/* Bail out if the operation was cancelled */
	if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) == TRUE) {
		/* Cancel the t-param and thumbnail threads, if applicable */
		if (data->t_param_cancellable != NULL)
			g_cancellable_cancel (data->t_param_cancellable);
		if (data->thumbnail_cancellable != NULL)
			g_cancellable_cancel (data->thumbnail_cancellable);

		goto finish;
	}

	/* Error! */
	window = totem_get_main_window (data->plugin->totem);
	if (g_error_matches (error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_PROTOCOL_ERROR) == TRUE) {
		/* Hide the ugly technical message libgdata gives behind a nice one telling them it's out of date (which it likely is
		 * if we're receiving a protocol error). */
		totem_interface_error (_("Error Searching for Videos"),
				       _("The response from the server could not be understood. "
				         "Please check you are running the latest version of libgdata."), window);
	} else {
		/* Spew out the error message as provided */
		totem_interface_error (_("Error Searching for Videos"), error->message, window);
	}

	g_object_unref (window);

finish:
	g_error_free (error);
	query_data_free (data);

	return;
}
예제 #2
0
/**
 * totem_interface_load_with_full_path:
 * @filename: the #GtkBuilder UI file path to load
 * @fatal: %TRUE if errors loading the file should be fatal, %FALSE otherwise
 * @parent: (allow-none): the parent window to use when displaying error dialogues, or %NULL
 * @user_data: (allow-none): the user data to pass to gtk_builder_connect_signals(), or %NULL
 *
 * Load a #GtkBuilder UI file from the given path and return the #GtkBuilder instance for it. If loading the file fails, an error dialogue is shown.
 *
 * Return value: (transfer full): the loaded #GtkBuilder object, or %NULL
 */
GtkBuilder *
totem_interface_load_with_full_path (const char *filename, gboolean fatal, 
				     GtkWindow *parent, gpointer user_data)
{
	GtkBuilder *builder = NULL;
	GError *error = NULL;

	if (filename != NULL) {
		builder = gtk_builder_new ();
		gtk_builder_set_translation_domain (builder, GETTEXT_PACKAGE);
	}

	if (builder == NULL || gtk_builder_add_from_file (builder, filename, &error) == FALSE) {
		char *msg;

		msg = g_strdup_printf (_("Couldn't load the '%s' interface. %s"), filename, error->message);
		if (fatal == FALSE)
			totem_interface_error (msg, _("Make sure that Totem is properly installed."), parent);
		else
			totem_interface_error_blocking (msg, _("Make sure that Totem is properly installed."), parent);

		g_free (msg);
		g_error_free (error);

		return NULL;
	}

	gtk_builder_connect_signals (builder, user_data);

	return builder;
}
예제 #3
0
/**
 * totem_interface_load:
 * @name: the #GtkBuilder UI file to load
 * @fatal: %TRUE if errors loading the file should be fatal, %FALSE otherwise
 * @parent: (allow-none): the parent window to use when displaying error dialogues, or %NULL
 * @user_data: (allow-none): the user data to pass to gtk_builder_connect_signals(), or %NULL
 *
 * Load a #GtkBuilder UI file with the given name and return the #GtkBuilder instance for it. If loading the file fails, an error dialogue is shown.
 *
 * Return value: (transfer full): the loaded #GtkBuilder object, or %NULL
 */
GtkBuilder *
totem_interface_load (const char *name, gboolean fatal, GtkWindow *parent, gpointer user_data)
{
	GtkBuilder *builder = NULL;
	char *filename;

	filename = totem_interface_get_full_path (name);
	if (filename == NULL) {
		char *msg;

		msg = g_strdup_printf (_("Couldn't load the '%s' interface. %s"), name, _("The file does not exist."));
		if (fatal == FALSE)
			totem_interface_error (msg, _("Make sure that Totem is properly installed."), parent);
		else
			totem_interface_error_blocking (msg, _("Make sure that Totem is properly installed."), parent);

		g_free (msg);
		return NULL;
	}

	builder = totem_interface_load_with_full_path (filename, fatal, parent,
						       user_data);
	g_free (filename);

	return builder;
}
static void
totem_disc_recorder_plugin_burn (GAction                 *action,
				 GVariant                *variant,
				 TotemDiscRecorderPlugin *pi)
{
	char *path;
	char *error = NULL;

	path = totem_disc_recorder_plugin_write_video_project (pi, &error);
	if (!path) {
		totem_interface_error (_("The movie could not be recorded."),
				       error,
				       totem_object_get_main_window (pi->priv->totem));
		g_free (error);
		return;
	}

	if (!totem_disc_recorder_plugin_start_burning (pi, path, FALSE))
		g_remove (path);

	g_free (path);
}
예제 #5
0
void
open_in_web_browser_activate_cb (GtkAction *action, TotemYouTubePlugin *self)
{
	GtkTreeSelection *selection;
	GtkTreeModel *model;
	GList *paths, *path;

	selection = gtk_tree_view_get_selection (self->tree_view[self->current_tree_view]);
	paths = gtk_tree_selection_get_selected_rows (selection, &model);

	for (path = paths; path != NULL; path = path->next) {
		GtkTreeIter iter;
		GDataYouTubeVideo *video;
		GDataLink *link;
		GError *error = NULL;

		if (gtk_tree_model_get_iter (model, &iter, (GtkTreePath*) (path->data)) == FALSE)
			continue;

		/* Get the HTML page for the video; its <link rel="alternate" ... /> */
		gtk_tree_model_get (model, &iter, 3, &video, -1);
		link = gdata_entry_look_up_link (GDATA_ENTRY (video), GDATA_LINK_ALTERNATE);
		g_object_unref (video);

		/* Display the page */
		if (gtk_show_uri (gtk_widget_get_screen (GTK_WIDGET (self->bvw)), gdata_link_get_uri (link), GDK_CURRENT_TIME, &error) == FALSE) {
			GtkWindow *window = totem_get_main_window (self->totem);
			totem_interface_error (_("Error Opening Video in Web Browser"), error->message, window);
			g_object_unref (window);
			g_error_free (error);
		}
	}

	g_list_foreach (paths, (GFunc) gtk_tree_path_free, NULL);
	g_list_free (paths);
}
static gboolean
totem_disc_recorder_plugin_start_burning (TotemDiscRecorderPlugin *pi,
					  const char *path,
					  gboolean copy)
{
	GtkWindow *main_window;
	GdkScreen *screen;
	GdkDisplay *display;
	gchar *command_line;
	GList *uris;
	GAppInfo *info;
	GdkAppLaunchContext *context;
	GError *error = NULL;
	char *xid_arg;

	main_window = totem_object_get_main_window (pi->priv->totem);
	screen = gtk_widget_get_screen (GTK_WIDGET (main_window));
	display = gdk_display_get_default ();

	/* Build a command line to use */
	xid_arg = NULL;
#ifdef GDK_WINDOWING_X11
	if (GDK_IS_X11_DISPLAY (display))
		xid_arg = g_strdup_printf ("-x %d", (int) gdk_x11_window_get_xid (gtk_widget_get_window (GTK_WIDGET (main_window))));
#endif /* GDK_WINDOWING_X11 */
	g_object_unref (main_window);

	if (copy != FALSE)
		command_line = g_strdup_printf ("brasero %s -c", xid_arg ? xid_arg : "");
	else
		command_line = g_strdup_printf ("brasero %s -r", xid_arg ? xid_arg : "");

	/* Build the app info */
	info = g_app_info_create_from_commandline (command_line, NULL,
	                                           G_APP_INFO_CREATE_SUPPORTS_URIS | G_APP_INFO_CREATE_SUPPORTS_STARTUP_NOTIFICATION, &error);
	g_free (command_line);

	if (error != NULL)
		goto error;

	/* Create a launch context and launch it */
	context = gdk_display_get_app_launch_context (gtk_widget_get_display (GTK_WIDGET (main_window)));
	gdk_app_launch_context_set_screen (context, screen);

	uris = g_list_prepend (NULL, (gpointer) path);
	g_app_info_launch_uris (info, uris, G_APP_LAUNCH_CONTEXT (context), &error);
	g_list_free (uris);

	g_object_unref (info);
	g_object_unref (context);

	if (error != NULL)
		goto error;

	return TRUE;

error:
	main_window = totem_object_get_main_window (pi->priv->totem);

	if (copy != FALSE)
		totem_interface_error (_("The video disc could not be duplicated."), error->message, main_window);
	else
		totem_interface_error (_("The movie could not be recorded."), error->message, main_window);

	g_error_free (error);
	g_object_unref (main_window);

	return FALSE;
}
예제 #7
0
static void
resolve_t_param_cb (SoupSession *session, SoupMessage *message, TParamData *data)
{
	gchar *video_uri = NULL;
	const gchar *video_id, *contents;
	gsize length;
	GMatchInfo *match_info;
	GtkTreeIter iter;
	TotemYouTubePlugin *self = data->plugin;

	/* Prevent cancellation */
	g_cancellable_disconnect (data->cancellable, data->cancelled_id);

	/* Finish loading the page */
	if (message->status_code != SOUP_STATUS_OK) {
		GtkWindow *window;

		/* Bail out if the operation was cancelled */
		if (message->status_code == SOUP_STATUS_CANCELLED)
			goto free_data;

		/* Couldn't load the page contents; error */
		window = totem_get_main_window (data->plugin->totem);
		totem_interface_error (_("Error Looking Up Video URI"), message->response_body->data, window);
		g_object_unref (window);
		goto free_data;
	}

	contents = message->response_body->data;
	length = message->response_body->length;

	video_id = gdata_youtube_video_get_video_id (GDATA_YOUTUBE_VIDEO (data->entry));

	/* Check for the fmt_url_map parameter */
	g_regex_match (self->regex, contents, 0, &match_info);
	if (g_match_info_matches (match_info) == TRUE) {
		gchar *fmt_url_map_escaped, *fmt_url_map;
		gchar **mappings, **i;
		GHashTable *fmt_table;
		gint connection_speed;

		/* We have a match */
		fmt_url_map_escaped = g_match_info_fetch (match_info, 1);
		fmt_url_map = g_uri_unescape_string (fmt_url_map_escaped, NULL);
		g_free (fmt_url_map_escaped);

		/* The fmt_url_map parameter is in the following format:
		 *   fmt1|uri1,fmt2|uri2,fmt3|uri3,...
		 * where fmtN is an identifier for the audio and video encoding and resolution as described here:
		 * (http://en.wikipedia.org/wiki/YouTube#Quality_and_codecs) and uriN is the playback URI for that format.
		 *
		 * We parse it into a hash table from format to URI, and use that against a ranked list of preferred formats (based on the user's
		 * connection speed) to determine the URI to use. */
		fmt_table = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free);
		mappings = g_strsplit (fmt_url_map, ",", 0);

		for (i = mappings; *i != NULL; i++) {
			/* For the moment we just take the first format we get */
			gchar **mapping;
			gint fmt;

			mapping = g_strsplit (*i, "|", 2);

			if (mapping[0] == NULL || mapping[1] == NULL) {
				g_warning ("Bad format-URI mapping: %s", *i);
				g_strfreev (mapping);
				continue;
			}

			fmt = atoi (mapping[0]);

			if (fmt < 1) {
				g_warning ("Badly-formed format: %s", mapping[0]);
				g_strfreev (mapping);
				continue;
			}

			g_hash_table_insert (fmt_table, GUINT_TO_POINTER ((guint) fmt), g_strdup (mapping[1]));
			g_strfreev (mapping);
		}

		g_strfreev (mappings);

		/* Starting with the highest connection speed we support, look for video URIs matching our connection speed. */
		connection_speed = MIN (bacon_video_widget_get_connection_speed (self->bvw), (gint) G_N_ELEMENTS (fmt_preferences) - 1);
		for (; connection_speed >= 0; connection_speed--) {
			guint idx = (guint) connection_speed;
			video_uri = g_strdup (g_hash_table_lookup (fmt_table, GUINT_TO_POINTER (fmt_preferences [idx])));

			/* Have we found a match yet? */
			if (video_uri != NULL) {
				g_debug ("Using video URI for format %u (connection speed %u)", fmt_preferences[idx], idx);
				break;
			}
		}

		g_hash_table_destroy (fmt_table);
	}

	/* Fallback */
	if (video_uri == NULL) {
		GDataMediaContent *content;

		/* We don't have a match, which is odd; fall back to the FLV URI as advertised by the YouTube API */
		content = GDATA_MEDIA_CONTENT (gdata_youtube_video_look_up_content (GDATA_YOUTUBE_VIDEO (data->entry),
										    "application/x-shockwave-flash"));
		if (content != NULL) {
			video_uri = g_strdup (gdata_media_content_get_uri (content));
			g_debug ("Couldn't find the t param of entry %s; falling back to its FLV URI (\"%s\")", video_id, video_uri);
		} else {
			/* Cop out */
			g_warning ("Couldn't find the t param of entry %s or its FLV URI.", video_uri);
			video_uri = NULL;
		}
	}

	g_match_info_free (match_info);

	/* Update the tree view with the new MRL */
	if (gtk_tree_model_get_iter (GTK_TREE_MODEL (self->list_store[data->tree_view]), &iter, data->path) == TRUE) {
		gtk_list_store_set (self->list_store[data->tree_view], &iter, 2, video_uri, -1);
		g_debug ("Updated list store with new video URI (\"%s\") for entry %s", video_uri, video_id);
	}

	g_free (video_uri);

free_data:
	/* Update the progress bar */
	increment_progress_bar_fraction (self, data->tree_view);

	g_object_unref (data->cancellable);
	g_object_unref (data->plugin);
	g_object_unref (data->entry);
	gtk_tree_path_free (data->path);
	g_slice_free (TParamData, data);
}