summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Withnall <pwithnall@svn.gnome.org>2007-10-23 17:39:00 +0000
committerPhilip Withnall <pwithnall@src.gnome.org>2007-10-23 17:39:00 +0000
commit4b96127cdc0304ee693fb97a453b1da8b637ced2 (patch)
tree211ea7b093fad9627cd6d631e73d3683c4c419dd
parent573a541536f8a22e627c8908118ee96876500158 (diff)
Create a new TotemVideoList object, enabling tooltips on lists of videos
2007-10-23 Philip Withnall <pwithnall@svn.gnome.org> * src/Makefile.am: * src/plugins/youtube/youtube.py: * src/plugins/youtube/youtube.ui: * src/totem-cell-renderer-video.c: (totem_cell_renderer_video_class_init), (totem_cell_renderer_video_init), (totem_cell_renderer_video_set_property), (totem_cell_renderer_video_get_property), (get_size), (totem_cell_renderer_video_render): * src/totem-video-list.c: (totem_video_list_new), (totem_video_list_class_init), (totem_video_list_init), (totem_video_list_set_property), (totem_video_list_get_property), (query_tooltip_cb), (selection_changed_cb), (row_activated_cb): * src/totem-video-list.h: Create a new TotemVideoList object, enabling tooltips on lists of videos (as in the YouTube plugin), and moving other functionality -- such as play-on-cell-activation -- support out too (Closes: #488826) svn path=/trunk/; revision=4811
-rw-r--r--ChangeLog20
-rw-r--r--src/Makefile.am4
-rw-r--r--src/plugins/youtube/youtube.py46
-rw-r--r--src/plugins/youtube/youtube.ui17
-rw-r--r--src/totem-cell-renderer-video.c69
-rw-r--r--src/totem-video-list.c199
-rw-r--r--src/totem-video-list.h60
7 files changed, 368 insertions, 47 deletions
diff --git a/ChangeLog b/ChangeLog
index 4fc37f73..60bf127f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,23 @@
+2007-10-23 Philip Withnall <pwithnall@svn.gnome.org>
+
+ * src/Makefile.am:
+ * src/plugins/youtube/youtube.py:
+ * src/plugins/youtube/youtube.ui:
+ * src/totem-cell-renderer-video.c:
+ (totem_cell_renderer_video_class_init),
+ (totem_cell_renderer_video_init),
+ (totem_cell_renderer_video_set_property),
+ (totem_cell_renderer_video_get_property), (get_size),
+ (totem_cell_renderer_video_render):
+ * src/totem-video-list.c: (totem_video_list_new),
+ (totem_video_list_class_init), (totem_video_list_init),
+ (totem_video_list_set_property), (totem_video_list_get_property),
+ (query_tooltip_cb), (selection_changed_cb), (row_activated_cb):
+ * src/totem-video-list.h: Create a new TotemVideoList object,
+ enabling tooltips on lists of videos (as in the YouTube plugin),
+ and moving other functionality -- such as play-on-cell-activation
+ -- support out too (Closes: #488826)
+
2007-10-23 Bastien Nocera <hadess@hadess.net>
* src/plparse/plparser.symbols: export totem_pl_parser_parse_date
diff --git a/src/Makefile.am b/src/Makefile.am
index 2d6b7b05..2d5d88a7 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -106,7 +106,9 @@ totem_SOURCES = \
totem-subtitle-encoding.c \
totem-subtitle-encoding.h \
totem-cell-renderer-video.c \
- totem-cell-renderer-video.h
+ totem-cell-renderer-video.h \
+ totem-video-list.c \
+ totem-video-list.h
totem_CPPFLAGS = \
-I$(srcdir)/plparse \
diff --git a/src/plugins/youtube/youtube.py b/src/plugins/youtube/youtube.py
index 8107e757..17bd797e 100644
--- a/src/plugins/youtube/youtube.py
+++ b/src/plugins/youtube/youtube.py
@@ -37,9 +37,10 @@ class YouTube (totem.Plugin):
self.search_button.connect ("clicked", self.on_search_button_clicked)
self.status_label = self.builder.get_object ("yt_status_label")
- """This is created here rather than in the UI file, because UI files parsed in C and GObjects created in Python don't mix."""
+ """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.insert_column_with_attributes (0, _("Videos"), self.renderer, thumbnail=0, title=1)
@@ -49,8 +50,7 @@ class YouTube (totem.Plugin):
vscroll.connect ("button-press-event", self.on_button_press_event)
vscroll.connect ("button-release-event", self.on_button_release_event)
- self.liststore = gtk.ListStore (gobject.TYPE_OBJECT, gobject.TYPE_STRING, gobject.TYPE_STRING)
-
+ self.liststore = self.builder.get_object ("yt_liststore")
self.treeview.set_model (self.liststore)
vbox = self.builder.get_object ("yt_vbox")
@@ -64,23 +64,7 @@ class YouTube (totem.Plugin):
totem.remove_sidebar_page ("youtube")
def on_row_activated (self, treeview, path, column):
model, iter = treeview.get_selection ().get_selected ()
- youtube_id = model.get_value (iter, 2)
-
- """Play the video"""
- conn = httplib.HTTPConnection ("www.youtube.com")
- conn.request ("GET", "/v/" + urllib.quote (youtube_id))
- response = conn.getresponse ()
- if response.status == 303:
- location = response.getheader("location")
- url = "http://www.youtube.com/get_video?video_id=" + urllib.quote (youtube_id) + "&t=" + urllib.quote (re.match (".*[?&]t=([^&]+)", location).groups ()[0])
- else:
- url = "http://www.youtube.com/v/" + urllib.quote (youtube_id)
- conn.close ()
-
- if self.debug:
- print "Playing: " + url
- else:
- self.totem.action_set_mrl_and_play (url)
+ youtube_id = model.get_value (iter, 3)
"""Get related videos"""
self.search_mode = False
@@ -104,7 +88,8 @@ class YouTube (totem.Plugin):
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)
def convert_url_to_id (self, url):
- return url.rpartition ("/")[2]
+ """Find the last clause in the URL; after the last /"""
+ return url.split ("/").pop ()
def populate_list_from_results (self, status_text):
"""Wait until we have some results to display"""
if self.entry == None or len (self.entry) == 0:
@@ -114,6 +99,23 @@ class YouTube (totem.Plugin):
entry = self.entry.pop (0)
self.results += 1
self.start_index += 1
+ youtube_id = self.convert_url_to_id (entry.id.text)
+
+ """Get the video stream MRL"""
+ try:
+ conn = httplib.HTTPConnection ("www.youtube.com")
+ conn.request ("GET", "/v/" + urllib.quote (youtube_id))
+ response = conn.getresponse ()
+ except:
+ print "Could not resolve stream MRL for YouTube video \"" + youtube_id + "\"."
+ return True
+
+ if response.status == 303:
+ location = response.getheader("location")
+ mrl = "http://www.youtube.com/get_video?video_id=" + urllib.quote (youtube_id) + "&t=" + urllib.quote (re.match (".*[?&]t=([^&]+)", location).groups ()[0])
+ else:
+ mrl = "http://www.youtube.com/v/" + urllib.quote (youtube_id)
+ conn.close ()
"""Find the thumbnail tag"""
for _element in entry.extension_elements:
@@ -137,7 +139,7 @@ class YouTube (totem.Plugin):
"""Don't leak the temporary file"""
unlink (filename)
- self.liststore.append ([pixbuf, entry.title.text, self.convert_url_to_id (entry.id.text)])
+ self.liststore.append ([pixbuf, entry.title.text, mrl, youtube_id])
self.treeview.window.process_updates (True)
"""Have we finished?"""
diff --git a/src/plugins/youtube/youtube.ui b/src/plugins/youtube/youtube.ui
index 293ecea6..9026df97 100644
--- a/src/plugins/youtube/youtube.ui
+++ b/src/plugins/youtube/youtube.ui
@@ -2,6 +2,14 @@
<!--*- mode: xml -*--><!DOCTYPE glade-interface
SYSTEM 'http://glade.gnome.org/glade-2.0.dtd'>
<interface>
+<object class="GtkListStore" id="yt_liststore">
+ <columns>
+ <column type="GdkPixbuf"/><!--Thumbnail-->
+ <column type="gchararray"/><!--Title-->
+ <column type="gchararray"/><!--MRL-->
+ <column type="gchararray"/><!--YouTube ID-->
+ </columns>
+</object>
<object class="GtkVBox" id="yt_vbox">
<property name="border_width">5</property>
@@ -71,14 +79,11 @@
<property name="shadow_type">GTK_SHADOW_IN</property>
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
<child>
- <object class="GtkTreeView" id="yt_treeview">
+ <object class="TotemVideoList" id="yt_treeview">
<property name="headers-visible">False</property>
<property name="fixed-height-mode">False</property>
- <child>
- <!--<object class="GtkTreeViewColumn" id="yt_treeview_column">
- <property name="title">Videos</property>
- </object>-->
- </child>
+ <property name="tooltip-column">1</property>
+ <property name="mrl-column">2</property>
</object>
</child>
</object>
diff --git a/src/totem-cell-renderer-video.c b/src/totem-cell-renderer-video.c
index 0becf0ae..f60ecf63 100644
--- a/src/totem-cell-renderer-video.c
+++ b/src/totem-cell-renderer-video.c
@@ -39,13 +39,15 @@ struct _TotemCellRendererVideoPrivate {
gboolean dispose_has_run;
gchar *title;
GdkPixbuf *thumbnail;
+ PangoAlignment alignment;
};
#define TOTEM_CELL_RENDERER_VIDEO_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TOTEM_TYPE_CELL_RENDERER_VIDEO, TotemCellRendererVideoPrivate))
enum {
PROP_THUMBNAIL = 1,
- PROP_TITLE
+ PROP_TITLE,
+ PROP_ALIGNMENT
};
static void totem_cell_renderer_video_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec);
@@ -75,7 +77,6 @@ totem_cell_renderer_video_class_init (TotemCellRendererVideoClass *klass)
object_class->dispose = totem_cell_renderer_video_dispose;
renderer_class->get_size = totem_cell_renderer_video_get_size;
renderer_class->render = totem_cell_renderer_video_render;
- /*renderer_class->activate = totem_cell_renderer_video_activate;*/
g_object_class_install_property (object_class, PROP_THUMBNAIL,
g_param_spec_object ("thumbnail", NULL, NULL,
@@ -83,6 +84,11 @@ totem_cell_renderer_video_class_init (TotemCellRendererVideoClass *klass)
g_object_class_install_property (object_class, PROP_TITLE,
g_param_spec_string ("title", NULL, NULL,
_("Unknown video"), G_PARAM_READWRITE));
+ g_object_class_install_property (object_class, PROP_ALIGNMENT,
+ g_param_spec_enum ("alignment", NULL, NULL,
+ PANGO_TYPE_ALIGNMENT,
+ PANGO_ALIGN_CENTER,
+ G_PARAM_READWRITE));
}
static void
@@ -92,6 +98,7 @@ totem_cell_renderer_video_init (TotemCellRendererVideo *self)
self->priv->dispose_has_run = FALSE;
self->priv->title = NULL;
self->priv->thumbnail = NULL;
+ self->priv->alignment = PANGO_ALIGN_CENTER;
/* Make sure we're in the right mode */
g_object_set ((gpointer) self, "mode", GTK_CELL_RENDERER_MODE_ACTIVATABLE, NULL);
@@ -118,18 +125,21 @@ totem_cell_renderer_video_dispose (GObject *object)
static void
totem_cell_renderer_video_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
{
- TotemCellRendererVideo *self = TOTEM_CELL_RENDERER_VIDEO (object);
+ TotemCellRendererVideoPrivate *priv = TOTEM_CELL_RENDERER_VIDEO_GET_PRIVATE (object);
switch (property_id)
{
case PROP_THUMBNAIL:
- if (self->priv->thumbnail != NULL)
- g_object_unref (self->priv->thumbnail);
- self->priv->thumbnail = (GdkPixbuf*) g_value_dup_object (value);
+ if (priv->thumbnail != NULL)
+ g_object_unref (priv->thumbnail);
+ priv->thumbnail = (GdkPixbuf*) g_value_dup_object (value);
break;
case PROP_TITLE:
- g_free (self->priv->title);
- self->priv->title = g_strdup (g_value_get_string (value));
+ g_free (priv->title);
+ priv->title = g_strdup (g_value_get_string (value));
+ break;
+ case PROP_ALIGNMENT:
+ priv->alignment = g_value_get_enum (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -139,15 +149,18 @@ totem_cell_renderer_video_set_property (GObject *object, guint property_id, cons
static void
totem_cell_renderer_video_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
{
- TotemCellRendererVideo *self = TOTEM_CELL_RENDERER_VIDEO (object);
+ TotemCellRendererVideoPrivate *priv = TOTEM_CELL_RENDERER_VIDEO_GET_PRIVATE (object);
switch (property_id)
{
case PROP_THUMBNAIL:
- g_value_set_object (value, G_OBJECT (self->priv->thumbnail));
+ g_value_set_object (value, G_OBJECT (priv->thumbnail));
break;
case PROP_TITLE:
- g_value_set_string (value, self->priv->title);
+ g_value_set_string (value, priv->title);
+ break;
+ case PROP_ALIGNMENT:
+ g_value_set_enum (value, priv->alignment);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -165,12 +178,12 @@ get_size (GtkCellRenderer *cell,
TotemCellRendererVideoPrivate *priv = TOTEM_CELL_RENDERER_VIDEO_GET_PRIVATE (cell);
guint pixbuf_width = 0;
guint pixbuf_height = 0;
+ guint title_height;
guint calc_width;
guint calc_height;
PangoContext *context;
PangoFontMetrics *metrics;
PangoFontDescription *font_desc;
- guint title_height;
/* Calculate thumbnail dimensions */
if (priv->thumbnail != NULL) {
@@ -185,13 +198,14 @@ get_size (GtkCellRenderer *cell,
metrics = pango_context_get_metrics (context,
font_desc,
pango_context_get_language (context));
+
title_height = PANGO_PIXELS (pango_font_metrics_get_ascent (metrics) +
pango_font_metrics_get_descent (metrics));
pango_font_metrics_unref (metrics);
pango_font_description_free (font_desc);
- /* Calculate the final size */
+ /* Calculate the total final size */
calc_width = cell->xpad * 2 + pixbuf_width;
calc_height = cell->ypad * 3 + pixbuf_height + title_height;
@@ -211,19 +225,37 @@ get_size (GtkCellRenderer *cell,
draw_area->width = calc_width;
draw_area->height = calc_height;
+ /*if (cell_area) {
+ g_message ("Cell area: X: %i, Y: %i, W: %i, H: %i", cell_area->x, cell_area->y, cell_area->width, cell_area->height);
+ g_message ("X-align: %f, Y-align: %f", cell->xalign, cell->yalign);
+ }
+ g_message ("Draw area: X: %i, Y: %i, W: %i, H: %i", draw_area->x, draw_area->y, draw_area->width, draw_area->height);*/
+
if (title_area) {
- title_area->x = draw_area->x;
- title_area->y = draw_area->y;
- title_area->width = calc_width;
+ if (cell_area) {
+ title_area->width = cell_area->width;
+ title_area->x = (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) ? 1.0 : 0.0;
+ } else {
+ title_area->width = calc_width;
+ title_area->x = draw_area->x;
+ }
+
title_area->height = title_height;
+ title_area->y = draw_area->y;
+
+ /*g_message ("Title area: X: %i, Y: %i, W: %i, H: %i", title_area->x, title_area->y, title_area->width, title_area->height);*/
}
if (thumbnail_area) {
thumbnail_area->x = draw_area->x;
thumbnail_area->y = draw_area->y + title_height + cell->ypad;
- thumbnail_area->width = calc_width;
+ thumbnail_area->width = cell->xpad * 2 + pixbuf_width;
thumbnail_area->height = pixbuf_height;
+
+ /*g_message ("Thumbnail area: X: %i, Y: %i, W: %i, H: %i", thumbnail_area->x, thumbnail_area->y, thumbnail_area->width, thumbnail_area->height);*/
}
+
+ /*g_message ("---");*/
}
}
@@ -313,7 +345,8 @@ totem_cell_renderer_video_render (GtkCellRenderer *cell,
pango_layout_set_font_description (layout, desc);
pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END);
- pango_layout_set_width (layout, (cell_area->width - title_area.x - 2 * cell->xpad) * PANGO_SCALE);
+ pango_layout_set_width (layout, title_area.width * PANGO_SCALE);
+ pango_layout_set_alignment (layout, priv->alignment);
gtk_paint_layout (widget->style,
window,
diff --git a/src/totem-video-list.c b/src/totem-video-list.c
new file mode 100644
index 00000000..8328a4aa
--- /dev/null
+++ b/src/totem-video-list.c
@@ -0,0 +1,199 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2001-2007 Philip Withnall <philip@tecnocode.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Totem project hereby grant permission for non-gpl compatible GStreamer
+ * plugins to be used and distributed together with GStreamer and Totem. This
+ * permission are above and beyond the permissions granted by the GPL license
+ * Totem is covered by.
+ *
+ * Monday 7th February 2005: Christian Schaller: Add exception clause.
+ * See license_change file for details.
+ *
+ */
+
+#include "config.h"
+
+#include <glib.h>
+#include <glib/gi18n.h>
+
+#include "totem.h"
+#include "totem-video-list.h"
+#include "totem-private.h"
+#include "totem-playlist.h"
+
+struct _TotemVideoListPrivate {
+ gboolean dispose_has_run;
+ gint tooltip_column;
+ gint mrl_column;
+ Totem *totem;
+};
+
+#define TOTEM_VIDEO_LIST_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TOTEM_TYPE_VIDEO_LIST, TotemVideoListPrivate))
+
+enum {
+ PROP_TOOLTIP_COLUMN = 1,
+ PROP_MRL_COLUMN,
+ PROP_TOTEM
+};
+
+static void totem_video_list_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec);
+static void totem_video_list_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec);
+static gboolean query_tooltip_cb (GtkWidget *widget, gint x, gint y, gboolean keyboard_mode, GtkTooltip *tooltip, gpointer user_data);
+static void selection_changed_cb (GtkTreeSelection *selection, GtkWidget *tree_view);
+static void row_activated_cb (GtkTreeView *tree_view, GtkTreePath *path, GtkTreeViewColumn *column, gpointer user_data);
+
+G_DEFINE_TYPE (TotemVideoList, totem_video_list, GTK_TYPE_TREE_VIEW)
+
+TotemVideoList *
+totem_video_list_new (void)
+{
+ return g_object_new (TOTEM_TYPE_VIDEO_LIST, NULL);
+}
+
+static void
+totem_video_list_class_init (TotemVideoListClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof (TotemVideoListPrivate));
+
+ object_class->set_property = totem_video_list_set_property;
+ object_class->get_property = totem_video_list_get_property;
+
+ g_object_class_install_property (object_class, PROP_TOOLTIP_COLUMN,
+ g_param_spec_int ("tooltip-column", NULL, NULL,
+ -1, G_MAXINT, -1, G_PARAM_READWRITE));
+ g_object_class_install_property (object_class, PROP_MRL_COLUMN,
+ g_param_spec_int ("mrl-column", NULL, NULL,
+ -1, G_MAXINT, -1, G_PARAM_READWRITE));
+ g_object_class_install_property (object_class, PROP_TOTEM,
+ g_param_spec_object ("totem", NULL, NULL,
+ TOTEM_TYPE_OBJECT, G_PARAM_READWRITE));
+}
+
+static void
+totem_video_list_init (TotemVideoList *self)
+{
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, TOTEM_TYPE_VIDEO_LIST, TotemVideoListPrivate);
+ self->priv->dispose_has_run = FALSE;
+ self->priv->totem = NULL;
+ self->priv->tooltip_column = -1;
+ self->priv->mrl_column = -1;
+
+ /* Set up tooltips */
+ g_object_set (self, "has-tooltip", TRUE, NULL);
+ g_signal_connect (self, "row-activated", G_CALLBACK (row_activated_cb), NULL);
+ g_signal_connect (self, "query-tooltip", G_CALLBACK (query_tooltip_cb), NULL);
+ g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (self)),
+ "changed", G_CALLBACK (selection_changed_cb), GTK_TREE_VIEW (self));
+}
+
+static void
+totem_video_list_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
+{
+ TotemVideoListPrivate *priv = TOTEM_VIDEO_LIST_GET_PRIVATE (object);
+
+ switch (property_id)
+ {
+ case PROP_TOOLTIP_COLUMN:
+ priv->tooltip_column = g_value_get_int (value);
+ break;
+ case PROP_MRL_COLUMN:
+ priv->mrl_column = g_value_get_int (value);
+ break;
+ case PROP_TOTEM:
+ if (priv->totem != NULL)
+ g_object_unref (priv->totem);
+ priv->totem = (Totem*) g_value_dup_object (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ }
+}
+
+static void
+totem_video_list_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
+{
+ TotemVideoListPrivate *priv = TOTEM_VIDEO_LIST_GET_PRIVATE (object);
+
+ switch (property_id)
+ {
+ case PROP_TOOLTIP_COLUMN:
+ g_value_set_int (value, priv->tooltip_column);
+ break;
+ case PROP_MRL_COLUMN:
+ g_value_set_int (value, priv->mrl_column);
+ break;
+ case PROP_TOTEM:
+ g_value_set_object (value, G_OBJECT (priv->totem));
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ }
+}
+
+static gboolean
+query_tooltip_cb (GtkWidget *widget, gint x, gint y, gboolean keyboard_mode, GtkTooltip *tooltip, gpointer user_data)
+{
+ TotemVideoList *self = TOTEM_VIDEO_LIST (widget);
+ GtkTreeIter iter;
+ gchar *tooltip_text;
+ GtkTreeView *tree_view = GTK_TREE_VIEW (widget);
+ GtkTreeModel *model = gtk_tree_view_get_model (tree_view);
+ GtkTreePath *path = NULL;
+
+ if (self->priv->tooltip_column == -1)
+ return FALSE;
+
+ if (!gtk_tree_view_get_tooltip_context (tree_view, &x, &y,
+ keyboard_mode,
+ &model, &path, &iter))
+ return FALSE;
+
+ gtk_tree_model_get (model, &iter, self->priv->tooltip_column, &tooltip_text, -1);
+ gtk_tooltip_set_text (tooltip, tooltip_text);
+ gtk_tree_view_set_tooltip_row (tree_view, tooltip, path);
+
+ gtk_tree_path_free (path);
+ g_free (tooltip_text);
+
+ return TRUE;
+}
+
+static void
+selection_changed_cb (GtkTreeSelection *selection, GtkWidget *tree_view)
+{
+ gtk_widget_trigger_tooltip_query (tree_view);
+}
+
+static void
+row_activated_cb (GtkTreeView *tree_view, GtkTreePath *path, GtkTreeViewColumn *column, gpointer user_data)
+{
+ GtkTreeIter iter;
+ gchar *mrl;
+ TotemVideoList *self = TOTEM_VIDEO_LIST (tree_view);
+ GtkTreeModel *model = gtk_tree_view_get_model (tree_view);
+
+ if (self->priv->mrl_column == -1)
+ return;
+
+ gtk_tree_model_get_iter (model, &iter, path);
+ gtk_tree_model_get (model, &iter, self->priv->mrl_column, &mrl, -1);
+ totem_action_set_mrl_and_play (self->priv->totem, mrl);
+
+ g_free (mrl);
+}
diff --git a/src/totem-video-list.h b/src/totem-video-list.h
new file mode 100644
index 00000000..d5069b8a
--- /dev/null
+++ b/src/totem-video-list.h
@@ -0,0 +1,60 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2001-2007 Philip Withnall <philip@tecnocode.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Totem project hereby grant permission for non-gpl compatible GStreamer
+ * plugins to be used and distributed together with GStreamer and Totem. This
+ * permission are above and beyond the permissions granted by the GPL license
+ * Totem is covered by.
+ *
+ * Monday 7th February 2005: Christian Schaller: Add exception clause.
+ * See license_change file for details.
+ *
+ */
+
+#include <gtk/gtk.h>
+#include <glib.h>
+
+#ifndef TOTEM_VIDEOLIST_H
+#define TOTEM_VIDEOLIST_H
+
+G_BEGIN_DECLS
+
+#define TOTEM_TYPE_VIDEO_LIST (totem_video_list_get_type ())
+#define TOTEM_VIDEO_LIST(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), TOTEM_TYPE_VIDEO_LIST, TotemVideoList))
+#define TOTEM_VIDEO_LIST_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), TOTEM_TYPE_VIDEO_LIST, TotemVideoListClass))
+#define TOTEM_IS_VIDEO_LIST(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), TOTEM_TYPE_VIDEO_LIST))
+#define TOTEM_IS_VIDEO_LIST_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), TOTEM_TYPE_VIDEO_LIST))
+#define TOTEM_VIDEO_LIST_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TOTEM_TYPE_VIDEO_LIST, TotemVideoListClass))
+
+typedef struct _TotemVideoListPrivate TotemVideoListPrivate;
+
+typedef struct {
+ GtkTreeView parent;
+ TotemVideoListPrivate *priv;
+} TotemVideoList;
+
+typedef struct {
+ GtkTreeViewClass parent;
+} TotemVideoListClass;
+
+GType totem_video_list_get_type (void);
+TotemVideoList *totem_video_list_new (void);
+
+G_END_DECLS
+
+#endif /* TOTEM_VIDEOLIST_H */