~wongchiachen/ubuntu/precise/totem/hey_about_dialog

« back to all changes in this revision

Viewing changes to src/plugins/mythtv/totem-mythtv.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2011-05-20 16:38:02 UTC
  • mfrom: (1.11.13 upstream) (2.1.17 experimental)
  • Revision ID: james.westby@ubuntu.com-20110520163802-p3lohdmfvws2jqeo
Tags: 3.0.1-0ubuntu1
* Resynchronize on Debian, remaining diffs:
* debian/control.in:
  - use suggests rather than recommends for universe gstreamer components
  - add totem-plugins-extra for the components which have depends in universe
  - add build-depends on gnome-common, dh-autoreconf, 
    liblaunchpad-intrgration-3.0-dev, hardening-wrapper
  - drop build-depends on libepc-ui-dev, python-feedparser, xulrunner-dev,
    libtracker-sparql-0.10-dev
  - add XB-Npp-Description and XB-Npp-Filename header to the 
    totem-mozilla package to improve ubufox/ubuntu plugin db integration 
  - change refences from Iceweasel to Firefox
  - recommends gnome-icon-theme-symbolic rather than depending on it
  - list firefox as a totem-mozilla recommends before epiphany-browser
  - libtotem replaces totem (<< 3.0.1-1) for ppa upgrades
* debian/totem-common.install:
  - Install apport hook
* debian/totem-plugins-extra.install:
  - Plugins split out ouf totem-plugins
* debian/totem-plugins.install:    
  - Move some plugins to totem-plugins-extra
* debian/totem.preinst:
  - No longer required as Lucid has been released
* debian/patches/01_fake_keypresses.patch:
  - dropped it's an old workaround and should not be required
* debian/patches/02_lpi.patch:
  - Launchpad integration
* debian/patches/03_default_options.patch: 
  - enable the youtube option by default
* debian/patches/70_bbc_plugin.patch:
  - bbc content viewer, needs to be fixed for the new version
* debian/source_totem.py:
  - ubuntu apport debugging
* debian/rules:
  - run autoreconf on build
* debian/watch:
  - Watch for unstable versions

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2
 
/* 
3
 
 * Copyright (C) 2007 Bastien Nocera <hadess@hadess.net>
4
 
 *
5
 
 * This program is free software; you can redistribute it and/or modify
6
 
 * it under the terms of the GNU General Public License as published by
7
 
 * the Free Software Foundation; either version 2 of the License, or
8
 
 * (at your option) any later version.
9
 
 *
10
 
 * This program is distributed in the hope that it will be useful,
11
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
 * GNU General Public License for more details.
14
 
 *
15
 
 * You should have received a copy of the GNU General Public License
16
 
 * along with this program; if not, write to the Free Software
17
 
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA.
18
 
 *
19
 
 * The Totem project hereby grant permission for non-gpl compatible GStreamer
20
 
 * plugins to be used and distributed together with GStreamer and Totem. This
21
 
 * permission are above and beyond the permissions granted by the GPL license
22
 
 * Totem is covered by.
23
 
 *
24
 
 * See license_change file for details.
25
 
 *
26
 
 */
27
 
 
28
 
#include "config.h"
29
 
 
30
 
#include <glib.h>
31
 
#include <glib-object.h>
32
 
#include <glib/gi18n-lib.h>
33
 
#include <gconf/gconf-client.h>
34
 
#include <gmodule.h>
35
 
#include <string.h>
36
 
 
37
 
#include "totem-video-list.h"
38
 
#include "totem-cell-renderer-video.h"
39
 
#include "video-utils.h"
40
 
#include "totem-plugin.h"
41
 
#include "totem.h"
42
 
 
43
 
#include <gdk-pixbuf/gdk-pixbuf.h>
44
 
 
45
 
#include <gmyth/gmyth_backendinfo.h>
46
 
#include <gmyth/gmyth_file_transfer.h>
47
 
#include <gmyth/gmyth_scheduler.h>
48
 
#include <gmyth/gmyth_epg.h>
49
 
#include <gmyth/gmyth_util.h>
50
 
#include <gmyth_upnp.h>
51
 
 
52
 
 
53
 
#define TOTEM_TYPE_MYTHTV_PLUGIN                (totem_mythtv_plugin_get_type ())
54
 
#define TOTEM_MYTHTV_PLUGIN(o)          (G_TYPE_CHECK_INSTANCE_CAST ((o), TOTEM_TYPE_MYTHTV_PLUGIN, TotemMythtvPlugin))
55
 
#define TOTEM_MYTHTV_PLUGIN_CLASS(k)    (G_TYPE_CHECK_CLASS_CAST((k), TOTEM_TYPE_MYTHTV_PLUGIN, TotemMythtvPluginClass))
56
 
#define TOTEM_IS_MYTHTV_PLUGIN(o)               (G_TYPE_CHECK_INSTANCE_TYPE ((o), TOTEM_TYPE_MYTHTV_PLUGIN))
57
 
#define TOTEM_IS_MYTHTV_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), TOTEM_TYPE_MYTHTV_PLUGIN))
58
 
#define TOTEM_MYTHTV_PLUGIN_GET_CLASS(o)        (G_TYPE_INSTANCE_GET_CLASS ((o), TOTEM_TYPE_MYTHTV_PLUGIN, TotemMythtvPluginClass))
59
 
 
60
 
#define MYTHTV_SIDEBAR_RECORDINGS "mythtv-recordings"
61
 
#define MYTHTV_SIDEBAR_LIVETV "mythtv-livetv"
62
 
 
63
 
enum {
64
 
        FILENAME_COL,
65
 
        URI_COL,
66
 
        THUMBNAIL_COL,
67
 
        NAME_COL,
68
 
        DESCRIPTION_COL,
69
 
        NUM_COLS
70
 
};
71
 
 
72
 
typedef struct
73
 
{
74
 
        TotemPlugin parent;
75
 
 
76
 
        GList *lst_b_info;
77
 
        GMythUPnP *upnp;
78
 
 
79
 
        TotemObject *totem;
80
 
        GConfClient *client;
81
 
 
82
 
        GtkWidget *sidebar_recordings;
83
 
        GtkWidget *sidebar_livetv;
84
 
} TotemMythtvPlugin;
85
 
 
86
 
typedef struct
87
 
{
88
 
        TotemPluginClass parent_class;
89
 
} TotemMythtvPluginClass;
90
 
 
91
 
 
92
 
G_MODULE_EXPORT GType register_totem_plugin     (GTypeModule *module);
93
 
GType   totem_mythtv_plugin_get_type            (void) G_GNUC_CONST;
94
 
static void totem_mythtv_plugin_finalize        (GObject *object);
95
 
static gboolean impl_activate                   (TotemPlugin *plugin, TotemObject *totem, GError **error);
96
 
static void impl_deactivate                     (TotemPlugin *plugin, TotemObject *totem);
97
 
 
98
 
TOTEM_PLUGIN_REGISTER(TotemMythtvPlugin, totem_mythtv_plugin)
99
 
 
100
 
#define MAX_THUMB_SIZE 500 * 1024 * 1024
101
 
#define THUMB_HEIGHT 32
102
 
 
103
 
static GdkPixbuf *
104
 
get_thumbnail (TotemMythtvPlugin *plugin, GMythBackendInfo *b_info, char *fname)
105
 
{
106
 
        GMythFileTransfer *transfer;
107
 
        GdkPixbufLoader *loader;
108
 
        GdkPixbuf *pixbuf;
109
 
        GMythFileReadResult res;
110
 
        guint64 to_read;
111
 
        GByteArray *data;
112
 
 
113
 
        if (gmyth_util_file_exists (b_info, fname) == FALSE)
114
 
                return NULL;
115
 
 
116
 
        transfer = gmyth_file_transfer_new (b_info);
117
 
        if (gmyth_file_transfer_open(transfer, fname) == FALSE)
118
 
                return NULL;
119
 
 
120
 
        to_read = gmyth_file_transfer_get_filesize (transfer);
121
 
        /* Leave if the thumbnail is just too big */
122
 
        if (to_read > MAX_THUMB_SIZE) {
123
 
                gmyth_file_transfer_close (transfer);
124
 
                return NULL;
125
 
        }
126
 
 
127
 
        loader = gdk_pixbuf_loader_new_with_type ("png", NULL);
128
 
        data = g_byte_array_sized_new (to_read);
129
 
 
130
 
        res = gmyth_file_transfer_read(transfer, data, to_read, FALSE);
131
 
        if (gdk_pixbuf_loader_write (loader, data->data, to_read, NULL) == FALSE) {
132
 
                res = GMYTH_FILE_READ_ERROR;
133
 
        }
134
 
 
135
 
        gmyth_file_transfer_close (transfer);
136
 
        g_object_unref (transfer);
137
 
        g_byte_array_free (data, TRUE);
138
 
 
139
 
        if (res != GMYTH_FILE_READ_OK && res != GMYTH_FILE_READ_EOF) {
140
 
                g_object_unref (loader);
141
 
                return NULL;
142
 
        }
143
 
 
144
 
        if (gdk_pixbuf_loader_close (loader, NULL) == FALSE) {
145
 
                g_object_unref (loader);
146
 
                return NULL;
147
 
        }
148
 
 
149
 
        pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
150
 
        if (pixbuf != NULL)
151
 
                g_object_ref (pixbuf);
152
 
        g_object_unref (loader);
153
 
 
154
 
        if (pixbuf == NULL)
155
 
                return NULL;
156
 
 
157
 
        if (gdk_pixbuf_get_height (pixbuf) != THUMB_HEIGHT) {
158
 
                GdkPixbuf *scaled;
159
 
                int height, width;
160
 
 
161
 
                height = THUMB_HEIGHT;
162
 
                width = gdk_pixbuf_get_width (pixbuf) * height / gdk_pixbuf_get_height (pixbuf);
163
 
                scaled = gdk_pixbuf_scale_simple (pixbuf, width, height, GDK_INTERP_BILINEAR);
164
 
                g_object_unref (pixbuf);
165
 
 
166
 
                return scaled;
167
 
        }
168
 
 
169
 
        return pixbuf;
170
 
}
171
 
 
172
 
static GtkWidget *
173
 
create_treeview (TotemMythtvPlugin *plugin)
174
 
{
175
 
        TotemCellRendererVideo *renderer;
176
 
        GtkWidget *treeview;
177
 
        GtkTreeModel *model;
178
 
 
179
 
        /* Treeview and model */
180
 
        model = GTK_TREE_MODEL (gtk_list_store_new (NUM_COLS,
181
 
                                                    G_TYPE_STRING,
182
 
                                                    G_TYPE_STRING,
183
 
                                                    G_TYPE_OBJECT,
184
 
                                                    G_TYPE_STRING,
185
 
                                                    G_TYPE_STRING));
186
 
 
187
 
        treeview = GTK_WIDGET (g_object_new (TOTEM_TYPE_VIDEO_LIST,
188
 
                                             "totem", plugin->totem,
189
 
                                             "mrl-column", URI_COL,
190
 
                                             "tooltip-column", DESCRIPTION_COL,
191
 
                                             NULL));
192
 
 
193
 
        gtk_tree_view_set_model (GTK_TREE_VIEW (treeview),
194
 
                                 GTK_TREE_MODEL (model));
195
 
 
196
 
        renderer = totem_cell_renderer_video_new (TRUE);
197
 
        gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview), 0,
198
 
                                                     _("Recordings"), GTK_CELL_RENDERER (renderer),
199
 
                                                     "thumbnail", THUMBNAIL_COL,
200
 
                                                     "title", NAME_COL,
201
 
                                                     NULL);
202
 
 
203
 
        gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview), FALSE);
204
 
 
205
 
        return treeview;
206
 
}
207
 
 
208
 
static void
209
 
totem_mythtv_list_recordings (TotemMythtvPlugin *tm,
210
 
                              GMythBackendInfo *b_info)
211
 
{
212
 
        GMythScheduler *scheduler;
213
 
        GtkTreeModel *model;
214
 
        GList *list, *l;
215
 
 
216
 
        if (b_info == NULL)
217
 
                return;
218
 
 
219
 
        scheduler = gmyth_scheduler_new();
220
 
        if (gmyth_scheduler_connect_with_timeout(scheduler,
221
 
                                                 b_info, 5) == FALSE) {
222
 
                g_message ("Couldn't connect to scheduler");
223
 
                g_object_unref (scheduler);
224
 
                return;
225
 
        }
226
 
 
227
 
        if (gmyth_scheduler_get_recorded_list(scheduler, &list) < 0) {
228
 
                g_message ("Couldn't get recordings list");
229
 
                gmyth_scheduler_disconnect (scheduler);
230
 
                g_object_unref (scheduler);
231
 
                return;
232
 
        }
233
 
 
234
 
        gmyth_scheduler_disconnect (scheduler);
235
 
        g_object_unref (scheduler);
236
 
 
237
 
        model = g_object_get_data (G_OBJECT (tm->sidebar_recordings), "model");
238
 
 
239
 
        for (l = list; l != NULL; l = l->next) {
240
 
                RecordedInfo *recorded_info = (RecordedInfo *) l->data;
241
 
 
242
 
                if (gmyth_util_file_exists
243
 
                    (b_info, recorded_info->basename->str)) {
244
 
                        GtkTreeIter iter;
245
 
                        GdkPixbuf *pixbuf;
246
 
                        char *full_name = NULL;
247
 
                        char *thumb_fname, *uri;
248
 
 
249
 
                        if (recorded_info->subtitle->str != NULL && recorded_info->subtitle->str[0] != '\0')
250
 
                                full_name = g_strdup_printf ("%s - %s",
251
 
                                                             recorded_info->title->str,
252
 
                                                             recorded_info->subtitle->str);
253
 
                        thumb_fname = g_strdup_printf ("%s.png", recorded_info->basename->str);
254
 
                        uri = g_strdup_printf ("myth://%s:%d/%s",
255
 
                                               b_info->hostname,
256
 
                                               b_info->port,
257
 
                                               recorded_info->basename->str);
258
 
                        pixbuf = get_thumbnail (tm, b_info, thumb_fname);
259
 
                        g_free (thumb_fname);
260
 
 
261
 
                        gtk_list_store_insert_with_values (GTK_LIST_STORE (model), &iter, G_MAXINT32,
262
 
                                                           FILENAME_COL, recorded_info->basename->str,
263
 
                                                           URI_COL, uri,
264
 
                                                           THUMBNAIL_COL, pixbuf,
265
 
                                                           NAME_COL, full_name ? full_name : recorded_info->title->str,
266
 
                                                           DESCRIPTION_COL, recorded_info->description->str,
267
 
                                                           -1);
268
 
                        g_free (full_name);
269
 
                        g_free (uri);
270
 
                }
271
 
                gmyth_recorded_info_free(recorded_info);
272
 
        }
273
 
 
274
 
        g_list_free (list);
275
 
}
276
 
 
277
 
static gint
278
 
sort_channels (GMythChannelInfo *a, GMythChannelInfo *b)
279
 
{
280
 
        int a_int, b_int;
281
 
 
282
 
        a_int = g_strtod (a->channel_num->str, NULL);
283
 
        b_int = g_strtod (b->channel_num->str, NULL);
284
 
 
285
 
        if (a_int < b_int)
286
 
                return -1;
287
 
        if (a_int > b_int)
288
 
                return 1;
289
 
        return 0;
290
 
}
291
 
 
292
 
static void
293
 
totem_mythtv_list_livetv (TotemMythtvPlugin *tm,
294
 
                          GMythBackendInfo *b_info)
295
 
{
296
 
        GMythEPG *epg;
297
 
        int length;
298
 
        GList *clist, *ch;
299
 
        GtkTreeModel *model;
300
 
 
301
 
        epg = gmyth_epg_new ();
302
 
        if (!gmyth_epg_connect (epg, b_info)) {
303
 
                g_object_unref (epg);
304
 
                return;
305
 
        }
306
 
 
307
 
        length = gmyth_epg_get_channel_list (epg, &clist);
308
 
        gmyth_epg_disconnect (epg);
309
 
        g_object_unref (epg);
310
 
 
311
 
        model = g_object_get_data (G_OBJECT (tm->sidebar_livetv), "model");
312
 
        clist = g_list_sort (clist, (GCompareFunc) sort_channels);
313
 
 
314
 
        for (ch = clist; ch != NULL; ch = ch->next) {
315
 
                GMythChannelInfo *info = (GMythChannelInfo *) ch->data;
316
 
                GtkTreeIter iter;
317
 
                char *uri;
318
 
                GdkPixbuf *pixbuf;
319
 
 
320
 
                if ((info->channel_name == NULL) || (info->channel_num == NULL))
321
 
                        continue;
322
 
 
323
 
                pixbuf = NULL;
324
 
                if (info->channel_icon != NULL && info->channel_icon->str[0] != '\0') {
325
 
                        pixbuf = get_thumbnail (tm, b_info, info->channel_icon->str);
326
 
                        g_message ("icon name: %s", info->channel_icon->str);
327
 
                }
328
 
 
329
 
                uri = g_strdup_printf ("myth://%s:%d/?channel=%s", b_info->hostname, b_info->port, info->channel_num->str);
330
 
 
331
 
                gtk_list_store_insert_with_values (GTK_LIST_STORE (model), &iter, G_MAXINT32,
332
 
                                                   URI_COL, uri,
333
 
                                                   THUMBNAIL_COL, pixbuf,
334
 
                                                   NAME_COL, info->channel_name->str,
335
 
                                                   -1);
336
 
        }
337
 
 
338
 
        gmyth_free_channel_list (clist);
339
 
}
340
 
 
341
 
static void
342
 
totem_mythtv_plugin_class_init (TotemMythtvPluginClass *klass)
343
 
{
344
 
        GObjectClass *object_class = G_OBJECT_CLASS (klass);
345
 
        TotemPluginClass *plugin_class = TOTEM_PLUGIN_CLASS (klass);
346
 
 
347
 
        object_class->finalize = totem_mythtv_plugin_finalize;
348
 
 
349
 
        plugin_class->activate = impl_activate;
350
 
        plugin_class->deactivate = impl_deactivate;
351
 
}
352
 
 
353
 
static void
354
 
device_found_cb (GMythUPnP *upnp,
355
 
                 GMythBackendInfo *b_info,
356
 
                 TotemMythtvPlugin *plugin)
357
 
{
358
 
        if (!g_list_find (plugin->lst_b_info, b_info)) {
359
 
                plugin->lst_b_info = g_list_append (plugin->lst_b_info,
360
 
                                g_object_ref (b_info));
361
 
                totem_mythtv_list_recordings (plugin, b_info);
362
 
                totem_mythtv_list_livetv (plugin, b_info);
363
 
        }
364
 
}
365
 
 
366
 
static void
367
 
device_lost_cb (GMythUPnP *upnp,
368
 
                                 GMythBackendInfo *info,
369
 
                                 TotemMythtvPlugin *plugin)
370
 
{
371
 
        GList *elem;
372
 
        GMythBackendInfo *b_info;
373
 
 
374
 
        elem = g_list_find (plugin->lst_b_info, info);
375
 
        if (elem && elem->data) {
376
 
                b_info = elem->data;
377
 
                plugin->lst_b_info = g_list_remove (plugin->lst_b_info,
378
 
                                b_info);
379
 
                g_object_unref (b_info);
380
 
        }
381
 
 
382
 
}
383
 
 
384
 
static void
385
 
totem_mythtv_update_binfo (TotemMythtvPlugin *plugin)
386
 
{
387
 
        GList *lst;
388
 
        GList *w;
389
 
 
390
 
        /* Clear old b_info */
391
 
        if (plugin->lst_b_info != NULL) {
392
 
                g_list_foreach (plugin->lst_b_info, (GFunc) g_object_unref, NULL);
393
 
                g_list_free (plugin->lst_b_info);
394
 
                plugin->lst_b_info = NULL;
395
 
        }
396
 
 
397
 
 
398
 
        /* Using GMythUPnP to search for avaliable servers */
399
 
        if (plugin->upnp == NULL) {
400
 
                plugin->upnp = gmyth_upnp_get_instance ();
401
 
                g_signal_connect (G_OBJECT (plugin->upnp),
402
 
                                                  "device-found",
403
 
                                                  G_CALLBACK (device_found_cb),
404
 
                                                  plugin);
405
 
                plugin->upnp = gmyth_upnp_get_instance ();
406
 
                g_signal_connect (G_OBJECT (plugin->upnp),
407
 
                                                  "device-lost",
408
 
                                                  G_CALLBACK (device_lost_cb),
409
 
                                                  plugin);
410
 
        }
411
 
 
412
 
        /* Load current servers */
413
 
        lst = gmyth_upnp_get_devices (plugin->upnp);
414
 
        for (w = lst; w != NULL; w = w->next) {
415
 
                GMythBackendInfo *b_info;
416
 
 
417
 
                b_info = (GMythBackendInfo *) w->data;
418
 
                plugin->lst_b_info = g_list_append (plugin->lst_b_info,
419
 
                                b_info);
420
 
                totem_mythtv_list_recordings (plugin, b_info);
421
 
                totem_mythtv_list_livetv (plugin, b_info);
422
 
        }
423
 
        g_list_free (lst);
424
 
        gmyth_upnp_search (plugin->upnp);
425
 
}
426
 
 
427
 
static void
428
 
refresh_cb (GtkWidget *button, TotemMythtvPlugin *tm)
429
 
{
430
 
        GtkTreeModel *model;
431
 
 
432
 
        gtk_widget_set_sensitive (button, FALSE);
433
 
        totem_gdk_window_set_waiting_cursor (gtk_widget_get_window (tm->sidebar_recordings));
434
 
        totem_gdk_window_set_waiting_cursor (gtk_widget_get_window (tm->sidebar_livetv));
435
 
 
436
 
        model = g_object_get_data (G_OBJECT (tm->sidebar_recordings), "model");
437
 
        gtk_list_store_clear (GTK_LIST_STORE (model));
438
 
        model = g_object_get_data (G_OBJECT (tm->sidebar_livetv), "model");
439
 
        gtk_list_store_clear (GTK_LIST_STORE (model));
440
 
 
441
 
        totem_mythtv_update_binfo (tm);
442
 
 
443
 
        gdk_window_set_cursor (gtk_widget_get_window (tm->sidebar_recordings), NULL);
444
 
        gdk_window_set_cursor (gtk_widget_get_window (tm->sidebar_livetv), NULL);
445
 
        gtk_widget_set_sensitive (button, TRUE);
446
 
}
447
 
 
448
 
static void
449
 
totem_mythtv_plugin_init (TotemMythtvPlugin *plugin)
450
 
{
451
 
        totem_mythtv_update_binfo (plugin);
452
 
}
453
 
 
454
 
static void
455
 
totem_mythtv_plugin_finalize (GObject *object)
456
 
{
457
 
        TotemMythtvPlugin *tm = TOTEM_MYTHTV_PLUGIN(object);
458
 
 
459
 
        if (tm->lst_b_info != NULL) {
460
 
                g_list_foreach (tm->lst_b_info, (GFunc ) g_object_unref, NULL);
461
 
                g_list_free (tm->lst_b_info);
462
 
                tm->lst_b_info = NULL;
463
 
        }
464
 
        if (tm->client != NULL) {
465
 
                g_object_unref (tm->client);
466
 
                tm->client = NULL;
467
 
        }
468
 
        if (tm->upnp != NULL) {
469
 
                g_object_unref (tm->upnp);
470
 
                tm->upnp = NULL;
471
 
        }
472
 
        if (tm->sidebar_recordings != NULL) {
473
 
                gtk_widget_destroy (tm->sidebar_recordings);
474
 
                tm->sidebar_recordings = NULL;
475
 
        }
476
 
        if (tm->sidebar_livetv != NULL) {
477
 
                gtk_widget_destroy (tm->sidebar_livetv);
478
 
                tm->sidebar_livetv = NULL;
479
 
        }
480
 
 
481
 
        G_OBJECT_CLASS (totem_mythtv_plugin_parent_class)->finalize (object);
482
 
}
483
 
 
484
 
static GtkWidget *
485
 
add_sidebar (TotemMythtvPlugin *tm, const char *name, const char *label)
486
 
{
487
 
        GtkWidget *box, *scrolled, *treeview, *button;
488
 
 
489
 
        box = gtk_vbox_new (FALSE, 6);
490
 
        button = gtk_button_new_from_stock (GTK_STOCK_REFRESH);
491
 
        g_signal_connect (G_OBJECT (button), "clicked",
492
 
                          G_CALLBACK (refresh_cb), tm);
493
 
        scrolled = gtk_scrolled_window_new (NULL, NULL);
494
 
        gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled),
495
 
                                        GTK_POLICY_NEVER,
496
 
                                        GTK_POLICY_AUTOMATIC);
497
 
        treeview = create_treeview (tm);
498
 
        gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled),
499
 
                                               GTK_WIDGET (treeview));
500
 
        gtk_container_add (GTK_CONTAINER (box), scrolled);
501
 
        gtk_box_pack_end (GTK_BOX (box), button, FALSE, FALSE, 0);
502
 
        gtk_widget_show_all (box);
503
 
        totem_add_sidebar_page (tm->totem, name, label, box);
504
 
 
505
 
        g_object_set_data (G_OBJECT (box), "treeview", treeview);
506
 
        g_object_set_data (G_OBJECT (box), "model",
507
 
                           gtk_tree_view_get_model (GTK_TREE_VIEW (treeview)));
508
 
 
509
 
        return g_object_ref (box);
510
 
}
511
 
 
512
 
static gboolean
513
 
impl_activate (TotemPlugin *plugin,
514
 
               TotemObject *totem,
515
 
               GError **error)
516
 
{
517
 
        TotemMythtvPlugin *tm = TOTEM_MYTHTV_PLUGIN(plugin);
518
 
 
519
 
        tm->totem = g_object_ref (totem);
520
 
 
521
 
        tm->sidebar_recordings = add_sidebar (tm, "mythtv-recordings", _("MythTV Recordings"));
522
 
        tm->sidebar_livetv = add_sidebar (tm, "mythtv-livetv", _("MythTV LiveTV"));
523
 
 
524
 
        totem_mythtv_update_binfo (TOTEM_MYTHTV_PLUGIN(plugin));
525
 
 
526
 
        /* FIXME we should only do that if it will be done in the background */
527
 
#if 0
528
 
        totem_gdk_window_set_waiting_cursor (gtk_widget_get_window (box);
529
 
        totem_mythtv_list_recordings (TOTEM_MYTHTV_PLUGIN(plugin));
530
 
        totem_mythtv_list_livetv (TOTEM_MYTHTV_PLUGIN(plugin));
531
 
        gdk_window_set_cursor (gtk_widget_get_window (box), NULL);
532
 
#endif
533
 
        return TRUE;
534
 
}
535
 
 
536
 
static void
537
 
impl_deactivate (TotemPlugin *plugin,
538
 
                 TotemObject *totem)
539
 
{
540
 
        TotemMythtvPlugin *tm = TOTEM_MYTHTV_PLUGIN(plugin);
541
 
 
542
 
        totem_remove_sidebar_page (totem, MYTHTV_SIDEBAR_RECORDINGS);
543
 
        totem_remove_sidebar_page (totem, MYTHTV_SIDEBAR_LIVETV);
544
 
 
545
 
        if (tm->lst_b_info != NULL) {
546
 
                g_list_foreach (tm->lst_b_info, (GFunc ) g_object_unref, NULL);
547
 
                g_list_free (tm->lst_b_info);
548
 
                tm->lst_b_info = NULL;
549
 
        }
550
 
        if (tm->client != NULL) {
551
 
                g_object_unref (tm->client);
552
 
                tm->client = NULL;
553
 
        }
554
 
        if (tm->upnp != NULL) {
555
 
                g_object_unref (tm->upnp);
556
 
                tm->upnp = NULL;
557
 
        }
558
 
        if (tm->sidebar_recordings != NULL) {
559
 
                gtk_widget_destroy (tm->sidebar_recordings);
560
 
                tm->sidebar_recordings = NULL;
561
 
        }
562
 
        if (tm->sidebar_livetv != NULL) {
563
 
                gtk_widget_destroy (tm->sidebar_livetv);
564
 
                tm->sidebar_livetv = NULL;
565
 
        }
566
 
        g_object_unref (totem);
567
 
}
568