~ubuntu-branches/debian/experimental/brasero/experimental

« back to all changes in this revision

Viewing changes to src/brasero-playlist.c

  • Committer: Bazaar Package Importer
  • Author(s): Josselin Mouette
  • Date: 2011-03-29 16:33:51 UTC
  • mfrom: (1.3.18 upstream) (5.2.8 sid)
  • Revision ID: james.westby@ubuntu.com-20110329163351-ac3wgbh4mplmhnht
Tags: 2.91.93-1
* Only depend on growisofs instead of dvd+rw-tools.
* New upstream pre-release.
* Update build-dependencies, package names, and paths.
* Require totem-plparser 2.32 since its soname changed.
* Do not include GIR package for now, since the versioning is broken 
  (see Bugzilla #646069).
* 01_pkglibdir.patch: dropped, upstream now has a variable we can use 
  for that effect.
* 11_nautilus_menu_no_display.patch, 31_link_libice.patch, 
  50_checksum.patch: dropped, merged upstream.
* 90_relibtoolize.patch: dropped, unnecessary.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
1
2
/***************************************************************************
2
3
*            play-list.c
3
4
*
29
30
#  include <config.h>
30
31
#endif
31
32
 
32
 
#ifdef BUILD_PLAYLIST
33
 
 
34
33
#include <string.h>
35
34
 
36
35
#include <glib.h>
41
40
 
42
41
#include <gtk/gtk.h>
43
42
 
44
 
#ifdef BUILD_SEARCH
45
 
#include <beagle/beagle.h>
46
 
#endif
47
 
 
48
43
#include <totem-pl-parser.h>
49
44
 
50
45
#include "brasero-misc.h"
53
48
 
54
49
#include "brasero-app.h"
55
50
#include "brasero-playlist.h"
 
51
#include "brasero-search-engine.h"
56
52
#include "brasero-utils.h"
57
53
#include "brasero-metadata.h"
58
54
#include "brasero-io.h"
61
57
#include "brasero-uri-container.h"
62
58
#include "brasero-layout-object.h"
63
59
 
64
 
static void brasero_playlist_class_init (BraseroPlaylistClass *klass);
65
 
static void brasero_playlist_init (BraseroPlaylist *sp);
66
 
static void brasero_playlist_iface_uri_container_init (BraseroURIContainerIFace *iface);
67
 
static void brasero_playlist_iface_layout_object_init (BraseroLayoutObjectIFace *iface);
68
 
static void brasero_playlist_finalize (GObject *object);
69
 
static void brasero_playlist_destroy (GtkObject *object);
70
60
 
71
61
struct BraseroPlaylistPrivate {
72
 
 
73
 
#ifdef BUILD_SEARCH
74
 
        BeagleClient *client;
75
 
        BeagleQuery *query;
 
62
        BraseroSearchEngine *engine;
76
63
        int id;
77
 
#endif
78
64
 
79
65
        GtkWidget *tree;
80
66
        GtkWidget *button_add;
96
82
        BRASERO_PLAYLIST_NB_COL,
97
83
};
98
84
 
99
 
#ifdef BUILD_SEARCH
100
 
 
101
 
static void brasero_playlist_beagle_hit_added_cb (BeagleQuery *query,
102
 
                                                  BeagleHitsAddedResponse *response,
103
 
                                                  BraseroPlaylist *playlist);
104
 
static void brasero_playlist_beagle_hit_substracted_cb (BeagleQuery *query,
105
 
                                                        BeagleHitsSubtractedResponse *response,
106
 
                                                        BraseroPlaylist *playlist);
107
 
static void brasero_playlist_beagle_finished_cb (BeagleQuery *query,
108
 
                                                 BeagleFinishedResponse *response,
109
 
                                                 BraseroPlaylist *playlist);
110
 
#endif
111
 
 
112
 
static void brasero_playlist_drag_data_get_cb (GtkTreeView *tree,
113
 
                                               GdkDragContext *drag_context,
114
 
                                               GtkSelectionData *selection_data,
115
 
                                               guint info,
116
 
                                               guint time,
117
 
                                               BraseroPlaylist *playlist);
118
 
static void brasero_playlist_add_cb (GtkButton *button,
119
 
                                     BraseroPlaylist *playlist);
120
 
static void brasero_playlist_remove_cb (GtkButton *button,
121
 
                                        BraseroPlaylist *playlist);
122
 
static void brasero_playlist_add_uri_playlist (BraseroPlaylist *playlist,
123
 
                                               const char *uri,
124
 
                                               gboolean quiet);
125
 
static void brasero_playlist_search_playlists_rhythmbox (BraseroPlaylist *playlist);
126
 
static void brasero_playlist_increase_activity_counter (BraseroPlaylist *playlist);
127
 
static void brasero_playlist_decrease_activity_counter (BraseroPlaylist *playlist);
128
 
static void brasero_playlist_row_activated_cb (GtkTreeView *tree,
129
 
                                               GtkTreeIter *row,
130
 
                                               GtkTreeViewColumn *column,
131
 
                                               BraseroPlaylist *playlist);
132
 
static void brasero_playlist_selection_changed_cb (GtkTreeSelection *
133
 
                                                   selection,
134
 
                                                   BraseroPlaylist *
135
 
                                                   playlist);
136
 
static gchar **brasero_playlist_get_selected_uris_real (BraseroPlaylist *playlist);
137
 
 
138
 
static gchar **
139
 
brasero_playlist_get_selected_uris (BraseroURIContainer *container);
140
 
static gchar *
141
 
brasero_playlist_get_selected_uri (BraseroURIContainer *container);
142
 
 
143
 
static void
144
 
brasero_playlist_get_proportion (BraseroLayoutObject *object,
145
 
                                 gint *header,
146
 
                                 gint *center,
147
 
                                 gint *footer);
148
 
 
149
85
enum {
150
86
        TARGET_URIS_LIST,
151
87
};
155
91
};
156
92
static guint nb_ntables = sizeof (ntables) / sizeof (ntables[0]);
157
93
 
158
 
static GObjectClass *parent_class = NULL;
 
94
static void brasero_playlist_iface_uri_container_init (BraseroURIContainerIFace *iface);
 
95
static void brasero_playlist_iface_layout_object_init (BraseroLayoutObjectIFace *iface);
 
96
 
 
97
G_DEFINE_TYPE_WITH_CODE (BraseroPlaylist,
 
98
                         brasero_playlist,
 
99
                         GTK_TYPE_VBOX,
 
100
                         G_IMPLEMENT_INTERFACE (BRASERO_TYPE_URI_CONTAINER,
 
101
                                                brasero_playlist_iface_uri_container_init)
 
102
                         G_IMPLEMENT_INTERFACE (BRASERO_TYPE_LAYOUT_OBJECT,
 
103
                                                brasero_playlist_iface_layout_object_init));
159
104
 
160
105
#define BRASERO_PLAYLIST_SPACING 6
161
106
 
162
 
GType
163
 
brasero_playlist_get_type ()
164
 
{
165
 
        static GType type = 0;
166
 
 
167
 
        if (type == 0) {
168
 
                static const GTypeInfo our_info = {
169
 
                        sizeof (BraseroPlaylistClass),
170
 
                        NULL,
171
 
                        NULL,
172
 
                        (GClassInitFunc) brasero_playlist_class_init,
173
 
                        NULL,
174
 
                        NULL,
175
 
                        sizeof (BraseroPlaylist),
176
 
                        0,
177
 
                        (GInstanceInitFunc) brasero_playlist_init,
178
 
                };
179
 
 
180
 
                static const GInterfaceInfo uri_container_info =
181
 
                {
182
 
                        (GInterfaceInitFunc) brasero_playlist_iface_uri_container_init,
183
 
                        NULL,
184
 
                        NULL
185
 
                };
186
 
                static const GInterfaceInfo layout_object_info =
187
 
                {
188
 
                        (GInterfaceInitFunc) brasero_playlist_iface_layout_object_init,
189
 
                        NULL,
190
 
                        NULL
191
 
                };
192
 
 
193
 
                type = g_type_register_static (GTK_TYPE_VBOX,
194
 
                                               "BraseroPlaylist",
195
 
                                               &our_info, 0);
196
 
 
197
 
                g_type_add_interface_static (type,
198
 
                                             BRASERO_TYPE_URI_CONTAINER,
199
 
                                             &uri_container_info);
200
 
                g_type_add_interface_static (type,
201
 
                                             BRASERO_TYPE_LAYOUT_OBJECT,
202
 
                                             &layout_object_info);
203
 
        }
204
 
 
205
 
        return type;
206
 
}
207
 
 
208
 
static void
209
 
brasero_playlist_class_init (BraseroPlaylistClass *klass)
210
 
{
211
 
        GObjectClass *object_class = G_OBJECT_CLASS (klass);
212
 
        GtkObjectClass *gtkobject_class = GTK_OBJECT_CLASS (klass);
213
 
 
214
 
        parent_class = g_type_class_peek_parent (klass);
215
 
        object_class->finalize = brasero_playlist_finalize;
216
 
        gtkobject_class->destroy = brasero_playlist_destroy;
217
 
}
218
 
 
219
 
static void
220
 
brasero_playlist_iface_uri_container_init (BraseroURIContainerIFace *iface)
221
 
{
222
 
        iface->get_selected_uri = brasero_playlist_get_selected_uri;
223
 
        iface->get_selected_uris = brasero_playlist_get_selected_uris;
224
 
}
225
 
 
226
 
static void
227
 
brasero_playlist_iface_layout_object_init (BraseroLayoutObjectIFace *iface)
228
 
{
229
 
        iface->get_proportion = brasero_playlist_get_proportion;
230
 
}
231
 
 
232
107
static void
233
108
brasero_playlist_get_proportion (BraseroLayoutObject *object,
234
109
                                 gint *header,
237
112
{
238
113
        GtkRequisition requisition;
239
114
 
240
 
        gtk_widget_size_request (BRASERO_PLAYLIST (object)->priv->button_add->parent,
241
 
                                 &requisition);
 
115
        gtk_widget_get_preferred_size (gtk_widget_get_parent (BRASERO_PLAYLIST (object)->priv->button_add),
 
116
                                 &requisition, NULL);
242
117
        (*footer) = requisition.height + BRASERO_PLAYLIST_SPACING;
243
118
}
244
119
 
245
120
static void
246
 
brasero_playlist_init (BraseroPlaylist *obj)
247
 
{
248
 
        GtkWidget *hbox, *scroll;
249
 
        GtkTreeStore *store = NULL;
250
 
        GtkCellRenderer *renderer;
251
 
        GtkTreeViewColumn *column;
252
 
 
253
 
        obj->priv = g_new0 (BraseroPlaylistPrivate, 1);
254
 
        gtk_box_set_spacing (GTK_BOX (obj), BRASERO_PLAYLIST_SPACING);
255
 
 
256
 
        hbox = gtk_hbox_new (FALSE, 8);
257
 
        gtk_widget_show (hbox);
258
 
 
259
 
        obj->priv->button_add = gtk_button_new_from_stock (GTK_STOCK_ADD);
260
 
        gtk_widget_show (obj->priv->button_add);
261
 
        gtk_box_pack_end (GTK_BOX (hbox),
262
 
                          obj->priv->button_add,
263
 
                          FALSE,
264
 
                          FALSE,
265
 
                          0);
266
 
        g_signal_connect (G_OBJECT (obj->priv->button_add),
267
 
                          "clicked",
268
 
                          G_CALLBACK (brasero_playlist_add_cb),
269
 
                          obj);
270
 
 
271
 
        obj->priv->button_remove = gtk_button_new_from_stock (GTK_STOCK_REMOVE);
272
 
        gtk_widget_show (obj->priv->button_remove);
273
 
        gtk_box_pack_end (GTK_BOX (hbox),
274
 
                          obj->priv->button_remove,
275
 
                          FALSE,
276
 
                          FALSE,
277
 
                          0);
278
 
        g_signal_connect (G_OBJECT (obj->priv->button_remove),
279
 
                          "clicked",
280
 
                          G_CALLBACK (brasero_playlist_remove_cb),
281
 
                          obj);
282
 
 
283
 
        gtk_box_pack_end (GTK_BOX (obj), hbox, FALSE, FALSE, 0);
284
 
 
285
 
        store = gtk_tree_store_new (BRASERO_PLAYLIST_NB_COL,
286
 
                                    G_TYPE_STRING,
287
 
                                    G_TYPE_STRING,
288
 
                                    G_TYPE_STRING,
289
 
                                    G_TYPE_STRING, 
290
 
                                    G_TYPE_STRING,
291
 
                                    G_TYPE_INT64);
292
 
 
293
 
        obj->priv->tree = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
294
 
        egg_tree_multi_drag_add_drag_support (GTK_TREE_VIEW (obj->priv->tree));
295
 
 
296
 
        gtk_tree_view_set_enable_tree_lines (GTK_TREE_VIEW (obj->priv->tree), TRUE);
297
 
        gtk_tree_view_set_rubber_banding (GTK_TREE_VIEW (obj->priv->tree), TRUE);
298
 
        gtk_tree_view_set_headers_clickable (GTK_TREE_VIEW (obj->priv->tree), TRUE);
299
 
        gtk_tree_view_set_enable_search (GTK_TREE_VIEW (obj->priv->tree), TRUE);
300
 
        gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (obj->priv->tree), TRUE);
301
 
        gtk_tree_view_set_expander_column (GTK_TREE_VIEW (obj->priv->tree),
302
 
                                           BRASERO_PLAYLIST_DISPLAY_COL);
303
 
 
304
 
        renderer = gtk_cell_renderer_text_new ();
305
 
        column = gtk_tree_view_column_new_with_attributes (_("Playlists"),
306
 
                                                           renderer, "text",
307
 
                                                           BRASERO_PLAYLIST_DISPLAY_COL,
308
 
                                                           NULL);
309
 
        gtk_tree_view_column_set_sort_column_id (column,
310
 
                                                 BRASERO_PLAYLIST_DISPLAY_COL);
311
 
        gtk_tree_view_append_column (GTK_TREE_VIEW (obj->priv->tree),
312
 
                                     column);
313
 
        gtk_tree_view_column_set_expand (column, TRUE);
314
 
 
315
 
        renderer = gtk_cell_renderer_text_new ();
316
 
        column = gtk_tree_view_column_new_with_attributes (_("Number of Songs"),
317
 
                                                           renderer, "text",
318
 
                                                           BRASERO_PLAYLIST_NB_SONGS_COL,
319
 
                                                           NULL);
320
 
        gtk_tree_view_column_set_sort_column_id (column,
321
 
                                                 BRASERO_PLAYLIST_NB_SONGS_COL);
322
 
        gtk_tree_view_append_column (GTK_TREE_VIEW (obj->priv->tree),
323
 
                                     column);
324
 
 
325
 
        renderer = gtk_cell_renderer_text_new ();
326
 
        column = gtk_tree_view_column_new_with_attributes (_("Length"),
327
 
                                                           renderer, "text",
328
 
                                                           BRASERO_PLAYLIST_LEN_COL,
329
 
                                                           NULL);
330
 
        gtk_tree_view_column_set_sort_column_id (column,
331
 
                                                 BRASERO_PLAYLIST_LEN_COL);
332
 
        gtk_tree_view_append_column (GTK_TREE_VIEW (obj->priv->tree),
333
 
                                     column);
334
 
 
335
 
        renderer = gtk_cell_renderer_text_new ();
336
 
        column = gtk_tree_view_column_new_with_attributes (_("Genre"), renderer,
337
 
                                                           "text",
338
 
                                                           BRASERO_PLAYLIST_GENRE_COL,
339
 
                                                           NULL);
340
 
        gtk_tree_view_column_set_sort_column_id (column,
341
 
                                                 BRASERO_PLAYLIST_GENRE_COL);
342
 
        gtk_tree_view_append_column (GTK_TREE_VIEW (obj->priv->tree),
343
 
                                     column);
344
 
 
345
 
        gtk_tree_view_set_search_column (GTK_TREE_VIEW (obj->priv->tree),
346
 
                                         BRASERO_PLAYLIST_DISPLAY_COL);
347
 
        gtk_tree_view_enable_model_drag_source (GTK_TREE_VIEW (obj->priv->tree),
348
 
                                                GDK_BUTTON1_MASK, ntables,
349
 
                                                nb_ntables,
350
 
                                                GDK_ACTION_COPY |
351
 
                                                GDK_ACTION_MOVE);
352
 
 
353
 
        g_signal_connect (G_OBJECT (obj->priv->tree), "drag_data_get",
354
 
                          G_CALLBACK (brasero_playlist_drag_data_get_cb),
355
 
                          obj);
356
 
 
357
 
        g_signal_connect (G_OBJECT (obj->priv->tree), "row_activated",
358
 
                          G_CALLBACK (brasero_playlist_row_activated_cb),
359
 
                          obj);
360
 
 
361
 
        g_signal_connect (G_OBJECT (gtk_tree_view_get_selection (GTK_TREE_VIEW (obj->priv->tree))),
362
 
                          "changed",
363
 
                          G_CALLBACK (brasero_playlist_selection_changed_cb),
364
 
                          obj);
365
 
 
366
 
        gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (obj->priv->tree)),
367
 
                                     GTK_SELECTION_MULTIPLE);
368
 
 
369
 
        scroll = gtk_scrolled_window_new (NULL, NULL);
370
 
        gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
371
 
                                        GTK_POLICY_AUTOMATIC,
372
 
                                        GTK_POLICY_AUTOMATIC);
373
 
        gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll),
374
 
                                             GTK_SHADOW_IN);
375
 
 
376
 
        gtk_container_add (GTK_CONTAINER (scroll), obj->priv->tree);
377
 
        gtk_box_pack_start (GTK_BOX (obj), scroll, TRUE, TRUE, 0);
378
 
}
379
 
 
380
 
static void
381
121
brasero_playlist_increase_activity_counter (BraseroPlaylist *playlist)
382
122
{
383
 
        if (!GTK_WIDGET (playlist->priv->tree)->window)
 
123
        GdkWindow *window;
 
124
 
 
125
        window = gtk_widget_get_window (GTK_WIDGET (playlist->priv->tree));
 
126
        if (!window)
384
127
                return;
385
128
 
386
129
        if (playlist->priv->activity_counter == 0) {
387
130
                GdkCursor *cursor;
388
131
 
389
132
                cursor = gdk_cursor_new (GDK_WATCH);
390
 
                gdk_window_set_cursor (GTK_WIDGET (playlist->priv->tree)->window,
 
133
                gdk_window_set_cursor (window,
391
134
                                       cursor);
392
 
                gdk_cursor_unref (cursor);
 
135
                g_object_unref (cursor);
393
136
        }
394
137
        playlist->priv->activity_counter++;
395
138
}
397
140
static void
398
141
brasero_playlist_decrease_activity_counter (BraseroPlaylist *playlist)
399
142
{
 
143
        GdkWindow *window;
 
144
 
400
145
        if (playlist->priv->activity_counter > 0)
401
146
                playlist->priv->activity_counter--;
402
147
 
403
 
        if (!GTK_WIDGET (playlist->priv->tree)->window)
 
148
        window = gtk_widget_get_window (GTK_WIDGET (playlist->priv->tree));
 
149
        if (!window)
404
150
                return;
405
151
 
406
152
        if (playlist->priv->activity_counter == 0)
407
 
                gdk_window_set_cursor (GTK_WIDGET (playlist->priv->tree)->window,
408
 
                                       NULL);
409
 
}
410
 
 
411
 
static void
412
 
brasero_playlist_destroy (GtkObject *object)
413
 
{
414
 
        BraseroPlaylist *playlist = BRASERO_PLAYLIST (object);
415
 
 
416
 
#ifdef BUILD_SEARCH
417
 
 
418
 
        if (playlist->priv->id) {
419
 
                g_source_remove (playlist->priv->id);
420
 
                playlist->priv->id = 0;
421
 
        }
422
 
 
423
 
        if (playlist->priv->client) {
424
 
                g_object_unref (playlist->priv->client);
425
 
                playlist->priv->client = NULL;
426
 
        }
427
 
 
428
 
        if (playlist->priv->query) {
429
 
                g_object_unref (playlist->priv->query);
430
 
                playlist->priv->query = NULL;
431
 
        }
432
 
 
433
 
#endif
434
 
 
435
 
        /* NOTE: we must do it here since cancel could call brasero_playlist_end
436
 
         * itself calling decrease_activity_counter. In finalize the latter will
437
 
         * raise problems since the GdkWindow has been destroyed */
438
 
        if (playlist->priv->parse_type) {
439
 
                brasero_io_cancel_by_base (playlist->priv->parse_type);
440
 
                g_free (playlist->priv->parse_type);
441
 
                playlist->priv->parse_type = NULL;
442
 
        }
443
 
 
444
 
        if (GTK_OBJECT_CLASS (parent_class)->destroy)
445
 
                GTK_OBJECT_CLASS (parent_class)->destroy (object);
446
 
}
447
 
 
448
 
static void
449
 
brasero_playlist_finalize (GObject *object)
450
 
{
451
 
        BraseroPlaylist *cobj;
452
 
 
453
 
        cobj = BRASERO_PLAYLIST (object);
454
 
 
455
 
        g_free (cobj->priv);
456
 
 
457
 
        G_OBJECT_CLASS (parent_class)->finalize (object);
458
 
}
459
 
 
460
 
#ifdef BUILD_SEARCH
 
153
                gdk_window_set_cursor (window, NULL);
 
154
}
 
155
 
 
156
static void
 
157
brasero_playlist_search_playlists_rhythmbox (BraseroPlaylist *playlist)
 
158
{
 
159
/*      RBSource *source;
 
160
 
 
161
        manager = rb_playlist_manager_new ();
 
162
        lists = rb_playlist_manager_get_playlists (manager);
 
163
*/
 
164
}
 
165
 
 
166
static void
 
167
brasero_playlist_search (BraseroPlaylist *playlist)
 
168
{
 
169
        const gchar* mimes [] = {"audio/x-ms-asx",
 
170
                "audio/x-mpegurl",
 
171
                "audio/x-scpls",
 
172
                "audio/x-mp3-playlist",
 
173
                NULL};
 
174
 
 
175
        brasero_search_engine_new_query (playlist->priv->engine, NULL);
 
176
        brasero_search_engine_set_query_mime (playlist->priv->engine, mimes);
 
177
        brasero_search_engine_start_query (playlist->priv->engine);
 
178
        brasero_playlist_increase_activity_counter (playlist);
 
179
}
461
180
 
462
181
static gboolean
463
182
brasero_playlist_try_again (BraseroPlaylist *playlist)
464
183
{
465
 
        playlist->priv->client = beagle_client_new (NULL);
466
 
        if (!playlist->priv->client)
 
184
        if (!brasero_search_engine_is_available (playlist->priv->engine))
467
185
                return TRUE;
468
186
 
 
187
        brasero_playlist_search (playlist);
 
188
 
469
189
        playlist->priv->id = 0;
470
190
        return FALSE;
471
191
}
472
192
 
473
193
static void
474
 
brasero_playlist_start_beagle_search (BraseroPlaylist *playlist)
 
194
brasero_playlist_start_search (BraseroPlaylist *playlist)
475
195
{
476
 
        playlist->priv->client = beagle_client_new (NULL);
477
 
        if(playlist->priv->client) {
478
 
                GError *error = NULL;
479
 
                BeagleQueryPartOr *or_part;
480
 
                BeagleQueryPartHuman *type;
481
 
                BeagleQueryPartProperty *filetype;
482
 
 
483
 
                playlist->priv->query = beagle_query_new ();
484
 
 
485
 
                g_signal_connect (G_OBJECT (playlist->priv->query), "hits-added",
486
 
                                  G_CALLBACK (brasero_playlist_beagle_hit_added_cb),
487
 
                                  playlist);
488
 
                g_signal_connect (G_OBJECT (playlist->priv->query), "hits-subtracted",
489
 
                                  G_CALLBACK (brasero_playlist_beagle_hit_substracted_cb),
490
 
                                  playlist);
491
 
                g_signal_connect (G_OBJECT (playlist->priv->query), "finished",
492
 
                                  G_CALLBACK (brasero_playlist_beagle_finished_cb),
493
 
                                  playlist);
494
 
        
495
 
                type = beagle_query_part_human_new ();
496
 
                beagle_query_part_human_set_string (type, "type:File");
497
 
                beagle_query_add_part (playlist->priv->query, BEAGLE_QUERY_PART (type));
498
 
 
499
 
                or_part = beagle_query_part_or_new ();
500
 
 
501
 
                filetype = beagle_query_part_property_new ();
502
 
                beagle_query_part_property_set_property_type (filetype, BEAGLE_PROPERTY_TYPE_KEYWORD);
503
 
                beagle_query_part_property_set_key (filetype, "beagle:MimeType");
504
 
                beagle_query_part_property_set_value (filetype, "audio/x-ms-asx");
505
 
                beagle_query_part_or_add_subpart (or_part, BEAGLE_QUERY_PART (filetype));
506
 
 
507
 
                filetype = beagle_query_part_property_new ();
508
 
                beagle_query_part_property_set_property_type (filetype, BEAGLE_PROPERTY_TYPE_KEYWORD);
509
 
                beagle_query_part_property_set_key (filetype, "beagle:MimeType");
510
 
                beagle_query_part_property_set_value (filetype, "audio/x-mpegurl");
511
 
                beagle_query_part_or_add_subpart (or_part, BEAGLE_QUERY_PART (filetype));
512
 
 
513
 
                filetype = beagle_query_part_property_new ();
514
 
                beagle_query_part_property_set_property_type (filetype, BEAGLE_PROPERTY_TYPE_KEYWORD);
515
 
                beagle_query_part_property_set_key (filetype, "beagle:MimeType");
516
 
                beagle_query_part_property_set_value (filetype, "audio/x-scpls");
517
 
                beagle_query_part_or_add_subpart (or_part, BEAGLE_QUERY_PART (filetype));
518
 
 
519
 
                filetype = beagle_query_part_property_new ();
520
 
                beagle_query_part_property_set_property_type (filetype, BEAGLE_PROPERTY_TYPE_KEYWORD);
521
 
                beagle_query_part_property_set_key (filetype, "beagle:FileType");
522
 
                beagle_query_part_property_set_value (filetype, "audio/x-mp3-playlist");
523
 
                beagle_query_part_or_add_subpart (or_part, BEAGLE_QUERY_PART (filetype));
524
 
 
525
 
                beagle_query_add_part (playlist->priv->query, BEAGLE_QUERY_PART (or_part));
526
 
 
527
 
                brasero_playlist_increase_activity_counter (playlist);
528
 
                beagle_client_send_request_async (playlist->priv->client,
529
 
                                                  BEAGLE_REQUEST (playlist->priv->query),
530
 
                                                  &error);
531
 
                if (error) {
532
 
                        g_warning ("Could not connect to beagle : %s\n",
533
 
                                   error->message);
534
 
                        g_error_free (error);
535
 
                }
536
 
        }
537
 
        else {
 
196
        if (!playlist->priv->engine)
 
197
                return;
 
198
 
 
199
        if (!brasero_search_engine_is_available (playlist->priv->engine)) {
538
200
                /* we will retry in 10 seconds */
539
201
                playlist->priv->id = g_timeout_add_seconds (10,
540
202
                                                            (GSourceFunc) brasero_playlist_try_again,
541
203
                                                            playlist);
 
204
                return;
542
205
        }
543
 
}
544
 
 
545
 
#else
546
 
 
547
 
static void
548
 
brasero_playlist_start_beagle_search (BraseroPlaylist *playlist)
549
 
{
550
 
        
551
 
}
552
 
 
553
 
#endif /* BUILD_SEARCH */
 
206
 
 
207
        brasero_playlist_search (playlist);
 
208
}
554
209
 
555
210
static gboolean
556
 
brasero_playlist_expose_event_cb (GtkWidget *widget,
557
 
                                  gpointer event,
558
 
                                  gpointer null_data)
 
211
brasero_playlist_draw_cb (GtkWidget *widget,
 
212
                          cairo_t *cr,
 
213
                          gpointer null_data)
559
214
{
560
215
        BraseroPlaylist *playlist = BRASERO_PLAYLIST (widget);
561
216
 
563
218
         * is if they become apparent. That will avoid overhead */
564
219
        if (!playlist->priv->searched) {
565
220
                playlist->priv->searched = 1;
566
 
                brasero_playlist_start_beagle_search (playlist);
 
221
                brasero_playlist_start_search (playlist);
567
222
                brasero_playlist_search_playlists_rhythmbox (playlist);
568
223
        }
569
224
 
570
225
        return FALSE;
571
226
}
572
227
 
573
 
GtkWidget *
574
 
brasero_playlist_new ()
575
 
{
576
 
        BraseroPlaylist *obj;
577
 
 
578
 
        obj = BRASERO_PLAYLIST (g_object_new (BRASERO_TYPE_PLAYLIST, NULL));
579
 
 
580
 
        g_signal_connect (obj,
581
 
                          "expose-event",
582
 
                          G_CALLBACK (brasero_playlist_expose_event_cb),
583
 
                          NULL);
584
 
 
585
 
        return GTK_WIDGET (obj);
586
 
}
587
 
 
588
 
static gchar **
589
 
brasero_playlist_get_selected_uris (BraseroURIContainer *container)
590
 
{
591
 
        BraseroPlaylist *playlist;
592
 
 
593
 
        playlist = BRASERO_PLAYLIST (container);
594
 
        return brasero_playlist_get_selected_uris_real (playlist);
595
 
}
596
 
 
597
 
static gchar *
598
 
brasero_playlist_get_selected_uri (BraseroURIContainer *container)
599
 
{
600
 
        BraseroPlaylist *playlist;
601
 
        gchar **uris = NULL;
602
 
        gchar *uri;
603
 
 
604
 
        playlist = BRASERO_PLAYLIST (container);
605
 
        uris = brasero_playlist_get_selected_uris_real (playlist);
606
 
 
607
 
        if (uris) {
608
 
                uri = g_strdup (uris [0]);
609
 
                g_strfreev (uris);
610
 
                return uri;
611
 
        }
612
 
 
613
 
        return NULL;
614
 
}
615
 
 
616
 
void
617
 
brasero_playlist_unselect_all (BraseroPlaylist *playlist)
618
 
{
619
 
        GtkTreeSelection *selection;
620
 
 
621
 
        selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (playlist->priv->tree));
622
 
        gtk_tree_selection_unselect_all (selection);
623
 
}
624
 
 
625
 
static void
626
 
brasero_playlist_add_cb (GtkButton *button, BraseroPlaylist *playlist)
627
 
{
628
 
        GtkWidget *dialog, *toplevel;
629
 
        gchar *uri;
630
 
        GSList *uris, *iter;
631
 
        gint result;
632
 
 
633
 
        toplevel = gtk_widget_get_toplevel (GTK_WIDGET (playlist));
634
 
        if (!GTK_WIDGET_TOPLEVEL (toplevel))
635
 
                return;
636
 
 
637
 
        dialog = gtk_file_chooser_dialog_new (_("Select Playlist"),
638
 
                                              GTK_WINDOW (toplevel),
639
 
                                              GTK_FILE_CHOOSER_ACTION_OPEN,
640
 
                                              GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
641
 
                                              GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
642
 
                                              NULL);
643
 
 
644
 
        gtk_dialog_set_default_response (GTK_DIALOG (dialog),
645
 
                                         GTK_RESPONSE_ACCEPT);
646
 
        gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (dialog), FALSE);
647
 
        gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
648
 
        gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (dialog),
649
 
                                                 g_get_home_dir ());
650
 
 
651
 
        gtk_widget_show_all (dialog);
652
 
        result = gtk_dialog_run (GTK_DIALOG (dialog));
653
 
        if (result == GTK_RESPONSE_CANCEL) {
654
 
                gtk_widget_destroy (dialog);
655
 
                return;
656
 
        }
657
 
 
658
 
        uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
659
 
        gtk_widget_destroy (dialog);
660
 
 
661
 
        for (iter = uris; iter; iter = iter->next) {
662
 
                uri = iter->data;
663
 
                brasero_playlist_add_uri_playlist (playlist, uri, FALSE);
664
 
                g_free (uri);
665
 
        }
666
 
        g_slist_free (uris);
667
 
}
668
 
 
669
 
static void
670
 
brasero_playlist_remove_cb (GtkButton *button, BraseroPlaylist *playlist)
671
 
{
672
 
        GtkTreeSelection *selection;
673
 
        GtkTreeModel *model;
674
 
        GtkTreePath *path;
675
 
        GtkTreeIter row;
676
 
        GList *rows, *iter;
677
 
        gboolean valid;
678
 
 
679
 
        selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (playlist->priv->tree));
680
 
        rows = gtk_tree_selection_get_selected_rows (selection, &model);
681
 
 
682
 
        if (rows == NULL)
683
 
                return;
684
 
 
685
 
        /* we just remove the lists removing particular songs would be a nonsense */
686
 
        /* we must reverse the list otherwise the last paths wouldn't be valid */
687
 
        for (iter = g_list_last (rows); iter; iter = iter->prev) {
688
 
                path = iter->data;
689
 
                valid = gtk_tree_model_get_iter (model, &row, path);
690
 
                gtk_tree_path_free (path);
691
 
 
692
 
                if (valid == FALSE)     /* if we remove the whole list it could happen that we try to remove twice a song */
693
 
                        continue;
694
 
 
695
 
                if (gtk_tree_model_iter_has_child (model, &row)) {
696
 
                        GtkTreeIter child;
697
 
 
698
 
                        /* we remove the songs if it's a list */
699
 
                        gtk_tree_model_iter_children (model, &child, &row);
700
 
                        while (gtk_tree_store_remove (GTK_TREE_STORE (model), &child) == TRUE);
701
 
                        gtk_tree_store_remove (GTK_TREE_STORE (model),
702
 
                                               &row);
703
 
                }
704
 
        }
705
 
 
706
 
        g_list_free (rows);
707
 
}
708
 
 
709
228
static gchar **
710
229
brasero_playlist_get_selected_uris_real (BraseroPlaylist *playlist)
711
230
{
769
288
        return uris;
770
289
}
771
290
 
 
291
static gchar **
 
292
brasero_playlist_get_selected_uris (BraseroURIContainer *container)
 
293
{
 
294
        BraseroPlaylist *playlist;
 
295
 
 
296
        playlist = BRASERO_PLAYLIST (container);
 
297
        return brasero_playlist_get_selected_uris_real (playlist);
 
298
}
 
299
 
 
300
static gchar *
 
301
brasero_playlist_get_selected_uri (BraseroURIContainer *container)
 
302
{
 
303
        BraseroPlaylist *playlist;
 
304
        gchar **uris = NULL;
 
305
        gchar *uri;
 
306
 
 
307
        playlist = BRASERO_PLAYLIST (container);
 
308
        uris = brasero_playlist_get_selected_uris_real (playlist);
 
309
 
 
310
        if (uris) {
 
311
                uri = g_strdup (uris [0]);
 
312
                g_strfreev (uris);
 
313
                return uri;
 
314
        }
 
315
 
 
316
        return NULL;
 
317
}
 
318
 
 
319
static void
 
320
brasero_playlist_remove_cb (GtkButton *button, BraseroPlaylist *playlist)
 
321
{
 
322
        GtkTreeSelection *selection;
 
323
        GtkTreeModel *model;
 
324
        GtkTreePath *path;
 
325
        GtkTreeIter row;
 
326
        GList *rows, *iter;
 
327
        gboolean valid;
 
328
 
 
329
        selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (playlist->priv->tree));
 
330
        rows = gtk_tree_selection_get_selected_rows (selection, &model);
 
331
 
 
332
        if (rows == NULL)
 
333
                return;
 
334
 
 
335
        /* we just remove the lists removing particular songs would be a nonsense */
 
336
        /* we must reverse the list otherwise the last paths wouldn't be valid */
 
337
        for (iter = g_list_last (rows); iter; iter = iter->prev) {
 
338
                path = iter->data;
 
339
                valid = gtk_tree_model_get_iter (model, &row, path);
 
340
                gtk_tree_path_free (path);
 
341
 
 
342
                if (valid == FALSE)     /* if we remove the whole list it could happen that we try to remove twice a song */
 
343
                        continue;
 
344
 
 
345
                if (gtk_tree_model_iter_has_child (model, &row)) {
 
346
                        GtkTreeIter child;
 
347
 
 
348
                        /* we remove the songs if it's a list */
 
349
                        gtk_tree_model_iter_children (model, &child, &row);
 
350
                        while (gtk_tree_store_remove (GTK_TREE_STORE (model), &child) == TRUE);
 
351
                        gtk_tree_store_remove (GTK_TREE_STORE (model),
 
352
                                               &row);
 
353
                }
 
354
        }
 
355
 
 
356
        g_list_free (rows);
 
357
}
 
358
 
772
359
static void
773
360
brasero_playlist_drag_data_get_cb (GtkTreeView *tree,
774
361
                                   GdkDragContext *drag_context,
803
390
        primary = g_strdup_printf (_("Error parsing playlist \"%s\"."), name);
804
391
        brasero_app_alert (brasero_app_get_default (),
805
392
                           primary,
806
 
                           _("An unknown error occured"),
 
393
                           _("An unknown error occurred"),
807
394
                           GTK_MESSAGE_ERROR);
808
395
        g_free (primary);
809
396
        g_free (name);
946
533
        gtk_tree_store_set (GTK_TREE_STORE (model), &parent,
947
534
                            BRASERO_PLAYLIST_DISPLAY_COL, name,
948
535
                            BRASERO_PLAYLIST_URI_COL, uri,
949
 
                            BRASERO_PLAYLIST_NB_SONGS_COL, _("(loading ...)"),
 
536
                            BRASERO_PLAYLIST_NB_SONGS_COL, _("(loading…)"),
950
537
                            -1);
951
538
        g_free (name);
952
539
 
983
570
}
984
571
 
985
572
static void
986
 
brasero_playlist_search_playlists_rhythmbox (BraseroPlaylist *playlist)
 
573
brasero_playlist_add_cb (GtkButton *button, BraseroPlaylist *playlist)
987
574
{
988
 
/*      RBSource *source;
989
 
 
990
 
        manager = rb_playlist_manager_new ();
991
 
        lists = rb_playlist_manager_get_playlists (manager);
992
 
*/
 
575
        GtkWidget *dialog, *toplevel;
 
576
        gchar *uri;
 
577
        GSList *uris, *iter;
 
578
        gint result;
 
579
 
 
580
        toplevel = gtk_widget_get_toplevel (GTK_WIDGET (playlist));
 
581
        if (!gtk_widget_is_toplevel (toplevel))
 
582
                return;
 
583
 
 
584
        dialog = gtk_file_chooser_dialog_new (_("Select Playlist"),
 
585
                                              GTK_WINDOW (toplevel),
 
586
                                              GTK_FILE_CHOOSER_ACTION_OPEN,
 
587
                                              GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
 
588
                                              GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
 
589
                                              NULL);
 
590
 
 
591
        gtk_dialog_set_default_response (GTK_DIALOG (dialog),
 
592
                                         GTK_RESPONSE_ACCEPT);
 
593
        gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (dialog), FALSE);
 
594
        gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
 
595
        gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (dialog),
 
596
                                                 g_get_home_dir ());
 
597
 
 
598
        gtk_widget_show_all (dialog);
 
599
        result = gtk_dialog_run (GTK_DIALOG (dialog));
 
600
        if (result == GTK_RESPONSE_CANCEL) {
 
601
                gtk_widget_destroy (dialog);
 
602
                return;
 
603
        }
 
604
 
 
605
        uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
 
606
        gtk_widget_destroy (dialog);
 
607
 
 
608
        for (iter = uris; iter; iter = iter->next) {
 
609
                uri = iter->data;
 
610
                brasero_playlist_add_uri_playlist (playlist, uri, FALSE);
 
611
                g_free (uri);
 
612
        }
 
613
        g_slist_free (uris);
993
614
}
994
615
 
995
 
#ifdef BUILD_SEARCH
996
 
 
997
616
static void
998
 
brasero_playlist_beagle_hit_added_cb (BeagleQuery *query,
999
 
                                      BeagleHitsAddedResponse *response,
1000
 
                                      BraseroPlaylist *playlist)
 
617
brasero_playlist_search_hit_added_cb (BraseroSearchEngine *engine,
 
618
                                      gpointer hit,
 
619
                                      BraseroPlaylist *playlist)
1001
620
{
1002
 
        GSList *list, *iter;
1003
 
        BeagleHit *hit;
1004
621
        const char *uri;
1005
622
 
1006
 
        list = beagle_hits_added_response_get_hits (response);
1007
 
        for (iter = list; iter; iter = iter->next) {
1008
 
                hit = iter->data;
1009
 
                uri = beagle_hit_get_uri (hit);
1010
 
                brasero_playlist_add_uri_playlist (playlist, uri, TRUE);
1011
 
        }
 
623
        uri = brasero_search_engine_uri_from_hit (engine, hit);
 
624
        brasero_playlist_add_uri_playlist (playlist, uri, TRUE);
1012
625
        brasero_playlist_decrease_activity_counter (playlist);
1013
626
}
1014
627
 
1015
628
static void
1016
 
brasero_playlist_beagle_hit_substracted_cb (BeagleQuery *query,
1017
 
                                            BeagleHitsSubtractedResponse *response,
1018
 
                                            BraseroPlaylist *playlist)
 
629
brasero_playlist_search_hit_substracted_cb (BraseroSearchEngine *engine,
 
630
                                            gpointer hit,
 
631
                                            BraseroPlaylist *playlist)
1019
632
{
1020
 
        GSList *list, *iter;
1021
 
        const char *uri;
1022
 
        char *row_uri;
1023
 
 
1024
633
        GtkTreeModel *model;
1025
634
        GtkTreeIter row;
 
635
        const gchar *uri;
1026
636
 
1027
637
        model = gtk_tree_view_get_model (GTK_TREE_VIEW (playlist->priv->tree));
1028
 
 
1029
 
        list = beagle_hits_subtracted_response_get_uris (response);
1030
 
        for (iter = list; iter; iter = iter->next) {
1031
 
                uri = iter->data;
1032
 
 
1033
 
                if (!gtk_tree_model_get_iter_first (model, &row))
1034
 
                        continue;
1035
 
 
1036
 
                do {
1037
 
                        gtk_tree_model_get (model, &row,
1038
 
                                            BRASERO_PLAYLIST_URI_COL, &row_uri,
1039
 
                                            -1);
1040
 
 
1041
 
                        if (!strcmp (row_uri, uri)) {
1042
 
                                gtk_tree_store_remove (GTK_TREE_STORE (model), &row);
1043
 
                                g_free (row_uri);
1044
 
                                break;
1045
 
                        }
 
638
        uri = brasero_search_engine_uri_from_hit (engine, hit);
 
639
 
 
640
        if (!gtk_tree_model_get_iter_first (model, &row))
 
641
                return;
 
642
 
 
643
        do {
 
644
                char *row_uri;
 
645
 
 
646
                gtk_tree_model_get (model, &row,
 
647
                                    BRASERO_PLAYLIST_URI_COL, &row_uri,
 
648
                                    -1);
 
649
 
 
650
                if (!strcmp (row_uri, uri)) {
 
651
                        gtk_tree_store_remove (GTK_TREE_STORE (model), &row);
1046
652
                        g_free (row_uri);
1047
 
                } while (gtk_tree_model_iter_next (model, &row));
1048
 
        }
 
653
                        return;
 
654
                }
 
655
 
 
656
                g_free (row_uri);
 
657
        } while (gtk_tree_model_iter_next (model, &row));
1049
658
}
1050
659
 
1051
660
static void
1052
 
brasero_playlist_beagle_finished_cb (BeagleQuery *query,
1053
 
                                     BeagleFinishedResponse *response,
1054
 
                                     BraseroPlaylist *playlist)
 
661
brasero_playlist_search_finished_cb (BraseroSearchEngine *engine,
 
662
                                     BraseroPlaylist *playlist)
1055
663
{
1056
664
        brasero_playlist_decrease_activity_counter (playlist);
1057
665
}
1058
666
 
1059
 
#endif /* BUILD_SEARCH */
 
667
static void
 
668
brasero_playlist_search_error_cb (BraseroSearchEngine *engine,
 
669
                                  BraseroPlaylist *playlist)
 
670
{
 
671
 
 
672
}
1060
673
 
1061
674
static void
1062
675
brasero_playlist_row_activated_cb (GtkTreeView *tree,
1074
687
        brasero_uri_container_uri_selected (BRASERO_URI_CONTAINER (playlist));
1075
688
}
1076
689
 
1077
 
#endif /* BUILD_PLAYLIST */
 
690
static void
 
691
brasero_playlist_init (BraseroPlaylist *obj)
 
692
{
 
693
        GtkWidget *hbox, *scroll;
 
694
        GtkTreeStore *store = NULL;
 
695
        GtkCellRenderer *renderer;
 
696
        GtkTreeViewColumn *column;
 
697
 
 
698
        obj->priv = g_new0 (BraseroPlaylistPrivate, 1);
 
699
        gtk_box_set_spacing (GTK_BOX (obj), BRASERO_PLAYLIST_SPACING);
 
700
 
 
701
        hbox = gtk_hbox_new (FALSE, 8);
 
702
        gtk_widget_show (hbox);
 
703
 
 
704
        obj->priv->button_add = gtk_button_new_from_stock (GTK_STOCK_ADD);
 
705
        gtk_widget_show (obj->priv->button_add);
 
706
        gtk_box_pack_end (GTK_BOX (hbox),
 
707
                          obj->priv->button_add,
 
708
                          FALSE,
 
709
                          FALSE,
 
710
                          0);
 
711
        g_signal_connect (G_OBJECT (obj->priv->button_add),
 
712
                          "clicked",
 
713
                          G_CALLBACK (brasero_playlist_add_cb),
 
714
                          obj);
 
715
 
 
716
        obj->priv->button_remove = gtk_button_new_from_stock (GTK_STOCK_REMOVE);
 
717
        gtk_widget_show (obj->priv->button_remove);
 
718
        gtk_box_pack_end (GTK_BOX (hbox),
 
719
                          obj->priv->button_remove,
 
720
                          FALSE,
 
721
                          FALSE,
 
722
                          0);
 
723
        g_signal_connect (G_OBJECT (obj->priv->button_remove),
 
724
                          "clicked",
 
725
                          G_CALLBACK (brasero_playlist_remove_cb),
 
726
                          obj);
 
727
 
 
728
        gtk_box_pack_end (GTK_BOX (obj), hbox, FALSE, FALSE, 0);
 
729
 
 
730
        store = gtk_tree_store_new (BRASERO_PLAYLIST_NB_COL,
 
731
                                    G_TYPE_STRING,
 
732
                                    G_TYPE_STRING,
 
733
                                    G_TYPE_STRING,
 
734
                                    G_TYPE_STRING, 
 
735
                                    G_TYPE_STRING,
 
736
                                    G_TYPE_INT64);
 
737
 
 
738
        obj->priv->tree = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
 
739
        egg_tree_multi_drag_add_drag_support (GTK_TREE_VIEW (obj->priv->tree));
 
740
 
 
741
        gtk_tree_view_set_enable_tree_lines (GTK_TREE_VIEW (obj->priv->tree), TRUE);
 
742
        gtk_tree_view_set_rubber_banding (GTK_TREE_VIEW (obj->priv->tree), TRUE);
 
743
        gtk_tree_view_set_headers_clickable (GTK_TREE_VIEW (obj->priv->tree), TRUE);
 
744
        gtk_tree_view_set_enable_search (GTK_TREE_VIEW (obj->priv->tree), TRUE);
 
745
        gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (obj->priv->tree), TRUE);
 
746
        gtk_tree_view_set_expander_column (GTK_TREE_VIEW (obj->priv->tree),
 
747
                                           BRASERO_PLAYLIST_DISPLAY_COL);
 
748
 
 
749
        renderer = gtk_cell_renderer_text_new ();
 
750
        column = gtk_tree_view_column_new_with_attributes (_("Playlists"),
 
751
                                                           renderer, "text",
 
752
                                                           BRASERO_PLAYLIST_DISPLAY_COL,
 
753
                                                           NULL);
 
754
        gtk_tree_view_column_set_sort_column_id (column,
 
755
                                                 BRASERO_PLAYLIST_DISPLAY_COL);
 
756
        gtk_tree_view_append_column (GTK_TREE_VIEW (obj->priv->tree),
 
757
                                     column);
 
758
        gtk_tree_view_column_set_expand (column, TRUE);
 
759
 
 
760
        renderer = gtk_cell_renderer_text_new ();
 
761
        column = gtk_tree_view_column_new_with_attributes (_("Number of Songs"),
 
762
                                                           renderer, "text",
 
763
                                                           BRASERO_PLAYLIST_NB_SONGS_COL,
 
764
                                                           NULL);
 
765
        gtk_tree_view_column_set_sort_column_id (column,
 
766
                                                 BRASERO_PLAYLIST_NB_SONGS_COL);
 
767
        gtk_tree_view_append_column (GTK_TREE_VIEW (obj->priv->tree),
 
768
                                     column);
 
769
 
 
770
        renderer = gtk_cell_renderer_text_new ();
 
771
        column = gtk_tree_view_column_new_with_attributes (_("Length"),
 
772
                                                           renderer, "text",
 
773
                                                           BRASERO_PLAYLIST_LEN_COL,
 
774
                                                           NULL);
 
775
        gtk_tree_view_column_set_sort_column_id (column,
 
776
                                                 BRASERO_PLAYLIST_LEN_COL);
 
777
        gtk_tree_view_append_column (GTK_TREE_VIEW (obj->priv->tree),
 
778
                                     column);
 
779
 
 
780
        renderer = gtk_cell_renderer_text_new ();
 
781
        column = gtk_tree_view_column_new_with_attributes (_("Genre"), renderer,
 
782
                                                           "text",
 
783
                                                           BRASERO_PLAYLIST_GENRE_COL,
 
784
                                                           NULL);
 
785
        gtk_tree_view_column_set_sort_column_id (column,
 
786
                                                 BRASERO_PLAYLIST_GENRE_COL);
 
787
        gtk_tree_view_append_column (GTK_TREE_VIEW (obj->priv->tree),
 
788
                                     column);
 
789
 
 
790
        gtk_tree_view_set_search_column (GTK_TREE_VIEW (obj->priv->tree),
 
791
                                         BRASERO_PLAYLIST_DISPLAY_COL);
 
792
        gtk_tree_view_enable_model_drag_source (GTK_TREE_VIEW (obj->priv->tree),
 
793
                                                GDK_BUTTON1_MASK, ntables,
 
794
                                                nb_ntables,
 
795
                                                GDK_ACTION_COPY |
 
796
                                                GDK_ACTION_MOVE);
 
797
 
 
798
        g_signal_connect (G_OBJECT (obj->priv->tree), "drag_data_get",
 
799
                          G_CALLBACK (brasero_playlist_drag_data_get_cb),
 
800
                          obj);
 
801
 
 
802
        g_signal_connect (G_OBJECT (obj->priv->tree), "row_activated",
 
803
                          G_CALLBACK (brasero_playlist_row_activated_cb),
 
804
                          obj);
 
805
 
 
806
        g_signal_connect (G_OBJECT (gtk_tree_view_get_selection (GTK_TREE_VIEW (obj->priv->tree))),
 
807
                          "changed",
 
808
                          G_CALLBACK (brasero_playlist_selection_changed_cb),
 
809
                          obj);
 
810
 
 
811
        gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (obj->priv->tree)),
 
812
                                     GTK_SELECTION_MULTIPLE);
 
813
 
 
814
        scroll = gtk_scrolled_window_new (NULL, NULL);
 
815
        gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
 
816
                                        GTK_POLICY_AUTOMATIC,
 
817
                                        GTK_POLICY_AUTOMATIC);
 
818
        gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll),
 
819
                                             GTK_SHADOW_IN);
 
820
 
 
821
        gtk_container_add (GTK_CONTAINER (scroll), obj->priv->tree);
 
822
        gtk_box_pack_start (GTK_BOX (obj), scroll, TRUE, TRUE, 0);
 
823
 
 
824
        obj->priv->engine = brasero_search_engine_new_default ();
 
825
        if (!obj->priv->engine)
 
826
                return;
 
827
 
 
828
        g_signal_connect (G_OBJECT (obj->priv->engine), "hit-added",
 
829
                          G_CALLBACK (brasero_playlist_search_hit_added_cb),
 
830
                          obj);
 
831
        g_signal_connect (G_OBJECT (obj->priv->engine), "hit-removed",
 
832
                          G_CALLBACK (brasero_playlist_search_hit_substracted_cb),
 
833
                          obj);
 
834
        g_signal_connect (G_OBJECT (obj->priv->engine), "search-finished",
 
835
                          G_CALLBACK (brasero_playlist_search_finished_cb),
 
836
                          obj);
 
837
        g_signal_connect (G_OBJECT (obj->priv->engine), "search-error",
 
838
                          G_CALLBACK (brasero_playlist_search_error_cb),
 
839
                          obj);
 
840
}
 
841
 
 
842
static void
 
843
brasero_playlist_destroy (GtkWidget *object)
 
844
{
 
845
        BraseroPlaylist *playlist = BRASERO_PLAYLIST (object);
 
846
 
 
847
        if (playlist->priv->id) {
 
848
                g_source_remove (playlist->priv->id);
 
849
                playlist->priv->id = 0;
 
850
        }
 
851
 
 
852
        if (playlist->priv->engine) {
 
853
                g_object_unref (playlist->priv->engine);
 
854
                playlist->priv->engine = NULL;
 
855
        }
 
856
 
 
857
        /* NOTE: we must do it here since cancel could call brasero_playlist_end
 
858
         * itself calling decrease_activity_counter. In finalize the latter will
 
859
         * raise problems since the GdkWindow has been destroyed */
 
860
        if (playlist->priv->parse_type) {
 
861
                brasero_io_cancel_by_base (playlist->priv->parse_type);
 
862
                brasero_io_job_base_free (playlist->priv->parse_type);
 
863
                playlist->priv->parse_type = NULL;
 
864
        }
 
865
 
 
866
        if (GTK_WIDGET_CLASS (brasero_playlist_parent_class)->destroy)
 
867
                GTK_WIDGET_CLASS (brasero_playlist_parent_class)->destroy (object);
 
868
}
 
869
 
 
870
static void
 
871
brasero_playlist_finalize (GObject *object)
 
872
{
 
873
        BraseroPlaylist *cobj;
 
874
 
 
875
        cobj = BRASERO_PLAYLIST (object);
 
876
 
 
877
        g_free (cobj->priv);
 
878
 
 
879
        G_OBJECT_CLASS (brasero_playlist_parent_class)->finalize (object);
 
880
}
 
881
 
 
882
static void
 
883
brasero_playlist_class_init (BraseroPlaylistClass *klass)
 
884
{
 
885
        GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
886
        GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
 
887
 
 
888
        object_class->finalize = brasero_playlist_finalize;
 
889
        widget_class->destroy = brasero_playlist_destroy;
 
890
}
 
891
 
 
892
static void
 
893
brasero_playlist_iface_uri_container_init (BraseroURIContainerIFace *iface)
 
894
{
 
895
        iface->get_selected_uri = brasero_playlist_get_selected_uri;
 
896
        iface->get_selected_uris = brasero_playlist_get_selected_uris;
 
897
}
 
898
 
 
899
static void
 
900
brasero_playlist_iface_layout_object_init (BraseroLayoutObjectIFace *iface)
 
901
{
 
902
        iface->get_proportion = brasero_playlist_get_proportion;
 
903
}
 
904
 
 
905
GtkWidget *
 
906
brasero_playlist_new ()
 
907
{
 
908
        BraseroPlaylist *obj;
 
909
 
 
910
        obj = BRASERO_PLAYLIST (g_object_new (BRASERO_TYPE_PLAYLIST, NULL));
 
911
 
 
912
        g_signal_connect (obj,
 
913
                          "draw",
 
914
                          G_CALLBACK (brasero_playlist_draw_cb),
 
915
                          NULL);
 
916
 
 
917
        return GTK_WIDGET (obj);
 
918
}