~ubuntu-branches/ubuntu/utopic/rhythmbox/utopic-proposed

« back to all changes in this revision

Viewing changes to sources/rb-source.c

Tags: upstream-0.9.2
ImportĀ upstreamĀ versionĀ 0.9.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
 */
22
22
 
23
23
#include <config.h>
24
 
#include <bonobo/bonobo-ui-component.h>
25
 
#include <bonobo/bonobo-ui-util.h>
26
24
#include <libgnome/gnome-i18n.h>
 
25
#include <gtk/gtkuimanager.h>
27
26
#include <time.h>
28
27
 
29
 
#include "rb-source.h"
 
28
 
 
29
#include "rb-cut-and-paste-code.h"
30
30
#include "rb-debug.h"
31
31
#include "rb-dialog.h"
32
 
#include "rb-cut-and-paste-code.h"
33
 
#include "rb-bonobo-helpers.h"
 
32
#include "rb-shell.h"
 
33
#include "rb-source.h"
 
34
#include "rb-util.h"
34
35
 
35
36
static void rb_source_class_init (RBSourceClass *klass);
36
37
static void rb_source_init (RBSource *source);
45
46
                                        GParamSpec *pspec);
46
47
 
47
48
static const char * default_get_browser_key (RBSource *status);
48
 
static const char * default_get_search_key (RBSource *status);
49
49
static GList *default_get_extra_views (RBSource *source);
50
50
static gboolean default_can_rename (RBSource *source);
51
51
static gboolean default_can_search (RBSource *source);
52
52
static gboolean default_can_cut (RBSource *source);
 
53
static GdkPixbuf *default_get_pixbuf (RBSource *source);
53
54
static GList *default_copy (RBSource *source);
54
55
static void default_reset_filters (RBSource *source);
55
56
static void default_song_properties (RBSource *source);
56
57
static GtkWidget * default_get_config_widget (RBSource *source);
 
58
static gboolean default_try_playlist (RBSource *source);
57
59
static RBSourceEOFType default_handle_eos (RBSource *source);
58
 
static void default_buffering_done  (RBSource *source);
59
 
static gboolean default_receive_drag  (RBSource *source, GtkSelectionData *data);
60
60
static gboolean default_show_popup  (RBSource *source);
61
61
static void default_delete_thyself (RBSource *source);
62
 
 
63
 
struct RBSourcePrivate
 
62
static void default_activate (RBSource *source);
 
63
static void default_deactivate (RBSource *source);
 
64
static gboolean default_disconnect (RBSource *source);
 
65
 
 
66
G_DEFINE_ABSTRACT_TYPE (RBSource, rb_source, GTK_TYPE_HBOX)
 
67
#define RB_SOURCE_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), RB_TYPE_SOURCE, RBSourcePrivate))
 
68
 
 
69
struct _RBSourcePrivate
64
70
{
65
71
        char *name;
66
 
        char *internal_name;
67
72
        
68
 
        BonoboUIComponent *component;
 
73
        RBShell *shell;
 
74
        gboolean visible;
69
75
};
70
76
 
71
77
enum
72
78
{
73
79
        PROP_0,
74
80
        PROP_NAME,
75
 
        PROP_INTERNAL_NAME,
76
 
        PROP_COMPONENT
 
81
        PROP_SHELL,
 
82
        PROP_UI_MANAGER,
 
83
        PROP_VISIBLE
77
84
};
78
85
 
79
86
enum
86
93
 
87
94
static guint rb_source_signals[LAST_SIGNAL] = { 0 };
88
95
 
89
 
static GObjectClass *parent_class = NULL;
90
 
 
91
 
GType
92
 
rb_source_get_type (void)
93
 
{
94
 
        static GType rb_source_type = 0;
95
 
 
96
 
        if (rb_source_type == 0)
97
 
        {
98
 
                static const GTypeInfo our_info =
99
 
                {
100
 
                        sizeof (RBSourceClass),
101
 
                        NULL,
102
 
                        NULL,
103
 
                        (GClassInitFunc) rb_source_class_init,
104
 
                        NULL,
105
 
                        NULL,
106
 
                        sizeof (RBSource),
107
 
                        0,
108
 
                        (GInstanceInitFunc) rb_source_init
109
 
                };
110
 
 
111
 
                rb_source_type = g_type_register_static (GTK_TYPE_HBOX,
112
 
                                                       "RBSource",
113
 
                                                       &our_info, G_TYPE_FLAG_ABSTRACT);
114
 
        }
115
 
 
116
 
        return rb_source_type;
117
 
}
118
 
 
119
96
static void
120
97
rb_source_class_init (RBSourceClass *klass)
121
98
{
122
99
        GObjectClass *object_class = G_OBJECT_CLASS (klass);
123
100
 
124
 
        parent_class = g_type_class_peek_parent (klass);
125
 
 
126
101
        object_class->finalize = rb_source_finalize;
127
102
 
128
103
        object_class->set_property = rb_source_set_property;
129
104
        object_class->get_property = rb_source_get_property;
130
105
 
131
106
        klass->impl_get_browser_key = default_get_browser_key;
132
 
        klass->impl_get_search_key = default_get_search_key;
133
107
        klass->impl_get_extra_views = default_get_extra_views;
134
108
        klass->impl_can_rename = default_can_rename;
135
109
        klass->impl_can_search = default_can_search;
136
110
        klass->impl_can_cut = default_can_cut;
137
111
        klass->impl_can_delete = default_can_cut;
138
112
        klass->impl_can_copy = default_can_cut;
 
113
        klass->impl_get_pixbuf = default_get_pixbuf;
139
114
        klass->impl_copy = default_copy;
140
115
        klass->impl_reset_filters = default_reset_filters;
141
116
        klass->impl_song_properties = default_song_properties;
142
117
        klass->impl_handle_eos = default_handle_eos;
143
 
        klass->impl_buffering_done = default_buffering_done;
144
118
        klass->impl_get_config_widget = default_get_config_widget;
145
 
        klass->impl_receive_drag = default_receive_drag;
 
119
        klass->impl_receive_drag = NULL;
146
120
        klass->impl_show_popup = default_show_popup;
147
121
        klass->impl_delete_thyself = default_delete_thyself;
 
122
        klass->impl_activate = default_activate;
 
123
        klass->impl_deactivate = default_deactivate;
 
124
        klass->impl_disconnect = default_disconnect;
 
125
        klass->impl_try_playlist = default_try_playlist;
148
126
 
149
127
        g_object_class_install_property (object_class,
150
128
                                         PROP_NAME,
153
131
                                                              "Interface name",
154
132
                                                              NULL,
155
133
                                                              G_PARAM_READWRITE));
156
 
        g_object_class_install_property (object_class,
157
 
                                         PROP_INTERNAL_NAME,
158
 
                                         g_param_spec_string ("internal-name",
159
 
                                                              "Internal name",
160
 
                                                              "Internal name",
161
 
                                                              NULL,
162
 
                                                              G_PARAM_READWRITE));
163
 
 
164
 
        g_object_class_install_property (object_class,
165
 
                                         PROP_COMPONENT,
166
 
                                         g_param_spec_pointer ("component",
167
 
                                                               "BonoboUIComponent",
168
 
                                                               "BonoboUIComponent",
169
 
                                                               G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
 
134
 
 
135
        g_object_class_install_property (object_class,
 
136
                                         PROP_SHELL,
 
137
                                         g_param_spec_object ("shell",
 
138
                                                               "RBShell",
 
139
                                                               "RBShell object",
 
140
                                                              RB_TYPE_SHELL,
 
141
                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
 
142
 
 
143
        g_object_class_install_property (object_class,
 
144
                                         PROP_UI_MANAGER,
 
145
                                         g_param_spec_object ("ui-manager",
 
146
                                                               "GtkUIManager",
 
147
                                                               "GtkUIManager object",
 
148
                                                              GTK_TYPE_UI_MANAGER,
 
149
                                                              G_PARAM_READABLE));
 
150
 
 
151
 
 
152
        g_object_class_install_property (object_class, 
 
153
                                         PROP_VISIBLE,
 
154
                                         /* FIXME: This property could probably
 
155
                                          * be named better, there's already
 
156
                                          * a GtkWidget 'visible' property,
 
157
                                          * since RBSource derives from
 
158
                                          * GtkWidget, this can be confusing
 
159
                                          */
 
160
                                         g_param_spec_boolean ("visibility", 
 
161
                                                               "visibility",
 
162
                                                               "Whether the source should be displayed in the source list",
 
163
                                                               TRUE,
 
164
                                                               G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
170
165
 
171
166
        rb_source_signals[DELETED] =
172
167
                g_signal_new ("deleted",
173
168
                              RB_TYPE_SOURCE,
174
169
                              G_SIGNAL_RUN_LAST,
175
 
                              G_STRUCT_OFFSET (RBSourceClass, status_changed),
 
170
                              G_STRUCT_OFFSET (RBSourceClass, deleted),
176
171
                              NULL, NULL,
177
172
                              g_cclosure_marshal_VOID__VOID,
178
173
                              G_TYPE_NONE,
188
183
                              G_TYPE_NONE,
189
184
                              0);
190
185
 
191
 
        /**
 
186
        /*
192
187
         * Fires when the user changes the filter, either by changing the
193
188
         * contents of the search box or by selecting a different browser
194
189
         * entry.
202
197
                              g_cclosure_marshal_VOID__VOID,
203
198
                              G_TYPE_NONE,
204
199
                              0);
 
200
        
 
201
        g_type_class_add_private (object_class, sizeof (RBSourcePrivate));
205
202
}
206
203
 
207
204
static void
208
205
rb_source_init (RBSource *source)
209
206
{
210
 
        source->priv = g_new0 (RBSourcePrivate, 1);
211
 
 
 
207
        RB_SOURCE_GET_PRIVATE (source)->visible = TRUE;
212
208
}
213
209
 
214
210
static void
215
211
rb_source_finalize (GObject *object)
216
212
{
217
213
        RBSource *source;
218
 
 
 
214
        RBSourcePrivate *priv;
 
215
        
219
216
        g_return_if_fail (object != NULL);
220
217
        g_return_if_fail (RB_IS_SOURCE (object));
221
218
 
222
219
        source = RB_SOURCE (object);
223
 
 
224
 
        g_return_if_fail (source->priv != NULL);
 
220
        priv = RB_SOURCE_GET_PRIVATE (source);
 
221
        g_return_if_fail (priv != NULL);
225
222
 
226
223
        rb_debug ("Finalizing view %p", source);
227
224
 
228
 
        g_free (source->priv->name);
229
 
 
230
 
        g_free (source->priv);
231
 
 
232
 
        G_OBJECT_CLASS (parent_class)->finalize (object);
 
225
        g_free (priv->name);
 
226
 
 
227
        G_OBJECT_CLASS (rb_source_parent_class)->finalize (object);
233
228
}
234
229
 
235
230
static void
238
233
                      const GValue *value,
239
234
                      GParamSpec *pspec)
240
235
{
241
 
        RBSource *source = RB_SOURCE (object);
 
236
        RBSourcePrivate *priv = RB_SOURCE_GET_PRIVATE (object);
242
237
 
243
238
        switch (prop_id)
244
239
        {
245
240
        case PROP_NAME:
246
 
                g_free (source->priv->name);
247
 
                source->priv->name = g_strdup (g_value_get_string (value));
248
 
                break;
249
 
        case PROP_INTERNAL_NAME:
250
 
                g_free (source->priv->internal_name);
251
 
                source->priv->internal_name = g_strdup (g_value_get_string (value));
252
 
                break;
253
 
        case PROP_COMPONENT:
254
 
                source->priv->component = g_value_get_pointer (value);
 
241
                g_free (priv->name);
 
242
                priv->name = g_strdup (g_value_get_string (value));
 
243
                break;
 
244
        case PROP_SHELL:
 
245
                priv->shell = g_value_get_object (value);
 
246
                break;
 
247
        case PROP_VISIBLE:
 
248
                priv->visible = g_value_get_boolean (value);
 
249
                rb_debug ("Setting %s visibility to %u", 
 
250
                          priv->name, 
 
251
                          priv->visible);
255
252
                break;
256
253
        default:
257
254
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
265
262
                      GValue *value,
266
263
                      GParamSpec *pspec)
267
264
{
268
 
        RBSource *source = RB_SOURCE (object);
 
265
        RBSourcePrivate *priv = RB_SOURCE_GET_PRIVATE (object);
269
266
 
270
267
        switch (prop_id)
271
268
        {
272
269
        case PROP_NAME:
273
 
                g_value_set_string (value, source->priv->name);
274
 
                break;
275
 
        case PROP_INTERNAL_NAME:
276
 
                g_value_set_string (value, source->priv->internal_name);
277
 
                break;
278
 
        case PROP_COMPONENT:
279
 
                g_value_set_pointer (value, source->priv->component);
280
 
                break;
 
270
                g_value_set_string (value, priv->name);
 
271
                break;
 
272
        case PROP_SHELL:
 
273
                g_value_set_object (value, priv->shell);
 
274
                break;
 
275
        case PROP_VISIBLE:
 
276
                g_value_set_boolean (value, priv->visible);
 
277
                break;
 
278
        case PROP_UI_MANAGER:
 
279
        {
 
280
                GtkUIManager *manager;
 
281
                g_object_get (G_OBJECT (priv->shell), 
 
282
                              "ui-manager", &manager,
 
283
                              NULL);
 
284
                g_value_set_object (value, manager);
 
285
                g_object_unref (G_OBJECT(manager));
 
286
                break;
 
287
        }
281
288
        default:
282
289
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
283
290
                break;
284
291
        }
285
292
}
286
293
 
287
 
const char *
 
294
/**
 
295
 * rb_source_get_status:
 
296
 * @status: a #RBSource
 
297
 *
 
298
 * FIXME:
 
299
 * Some Random comments
 
300
 *
 
301
 * Returns: The status string
 
302
 **/
 
303
char *
288
304
rb_source_get_status (RBSource *status)
289
305
{
290
306
        RBSourceClass *klass = RB_SOURCE_GET_CLASS (status);
298
314
        return NULL;
299
315
}
300
316
 
301
 
static const char *
302
 
default_get_search_key (RBSource *status)
303
 
{
304
 
        return NULL;
305
 
}
306
 
 
307
317
const char *
308
318
rb_source_get_browser_key (RBSource *status)
309
319
{
312
322
        return klass->impl_get_browser_key (status);
313
323
}
314
324
 
315
 
const char *
316
 
rb_source_get_search_key (RBSource *status)
317
 
{
318
 
        RBSourceClass *klass = RB_SOURCE_GET_CLASS (status);
319
 
 
320
 
        return klass->impl_get_search_key (status);
321
 
}
322
 
 
323
325
void
324
326
rb_source_notify_status_changed (RBSource *status)
325
327
{
336
338
rb_source_update_play_statistics (RBSource *source, RhythmDB *db, RhythmDBEntry *entry)
337
339
{
338
340
        time_t now;
339
 
        guint current_count;
 
341
        gulong current_count;
340
342
        GValue value = { 0, };
341
343
 
342
 
        g_value_init (&value, G_TYPE_INT);
343
 
 
344
 
        rhythmdb_read_lock (db);
345
 
        current_count = rhythmdb_entry_get_int (db, entry, RHYTHMDB_PROP_PLAY_COUNT);
346
 
        rhythmdb_read_unlock (db);
347
 
 
348
 
        g_value_set_int (&value, current_count + 1);
 
344
        g_value_init (&value, G_TYPE_ULONG);
 
345
 
 
346
        current_count = entry->play_count;
 
347
 
 
348
        g_value_set_ulong (&value, current_count + 1);
349
349
 
350
350
        /* Increment current play count */
351
 
        rhythmdb_entry_queue_set (db, entry, RHYTHMDB_PROP_PLAY_COUNT, &value);
 
351
        rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_PLAY_COUNT, &value);
352
352
        g_value_unset (&value);
353
353
        
354
354
        /* Reset the last played time */
355
355
        time (&now);
356
356
 
357
 
        g_value_init (&value, G_TYPE_LONG);
358
 
        g_value_set_long (&value, now);
359
 
        rhythmdb_entry_queue_set (db, entry, RHYTHMDB_PROP_LAST_PLAYED, &value);
 
357
        g_value_init (&value, G_TYPE_ULONG);
 
358
        g_value_set_ulong (&value, now);
 
359
        rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_LAST_PLAYED, &value);
360
360
        g_value_unset (&value);
 
361
 
 
362
        rhythmdb_commit (db);
361
363
}
362
364
 
363
365
RBEntryView *
382
384
        return klass->impl_get_extra_views (source);
383
385
}
384
386
 
 
387
static GdkPixbuf *
 
388
default_get_pixbuf (RBSource *source)
 
389
{
 
390
        return NULL;
 
391
}
 
392
 
385
393
GdkPixbuf *
386
394
rb_source_get_pixbuf (RBSource *source)
387
395
{
423
431
{
424
432
        RBSourceClass *klass = RB_SOURCE_GET_CLASS (source);
425
433
 
426
 
        klass->impl_search (source, text);
 
434
        /* several sources don't have a search ability */
 
435
        if (klass->impl_search != NULL)
 
436
                klass->impl_search (source, text);
427
437
}
428
438
 
429
439
static GtkWidget *
437
447
{
438
448
        RBSourceClass *klass = RB_SOURCE_GET_CLASS (source);
439
449
 
440
 
        return klass->impl_get_config_widget (source);
 
450
        if (klass->impl_get_config_widget) {
 
451
                return klass->impl_get_config_widget (source);
 
452
        } else {
 
453
                return NULL;
 
454
        }
441
455
}
442
456
 
443
457
static gboolean
525
539
static void
526
540
default_song_properties (RBSource *source)
527
541
{
528
 
        rb_error_dialog (_("No properties available."));
 
542
        g_assert_not_reached ();
529
543
}
530
544
 
531
545
void
537
551
}
538
552
 
539
553
gboolean
 
554
rb_source_try_playlist (RBSource *source)
 
555
{
 
556
        RBSourceClass *klass = RB_SOURCE_GET_CLASS (source);
 
557
 
 
558
        return klass->impl_try_playlist (source);
 
559
}
 
560
 
 
561
gboolean
540
562
rb_source_can_pause (RBSource *source)
541
563
{
542
564
        RBSourceClass *klass = RB_SOURCE_GET_CLASS (source);
544
566
        return klass->impl_can_pause (source);
545
567
}
546
568
 
 
569
static gboolean
 
570
default_try_playlist (RBSource *source)
 
571
{
 
572
        return FALSE;
 
573
}
 
574
 
547
575
static RBSourceEOFType
548
576
default_handle_eos (RBSource *source)
549
577
{
559
587
}
560
588
 
561
589
gboolean
562
 
rb_source_have_artist_album (RBSource *source)
563
 
{
564
 
        RBSourceClass *klass = RB_SOURCE_GET_CLASS (source);
565
 
 
566
 
        return klass->impl_have_artist_album (source);
567
 
}
568
 
 
569
 
const char *
570
 
rb_source_get_artist (RBSource *source)
571
 
{
572
 
        RBSourceClass *klass = RB_SOURCE_GET_CLASS (source);
573
 
 
574
 
        return klass->impl_get_artist (source);
575
 
}
576
 
 
577
 
const char *
578
 
rb_source_get_album (RBSource *source)
579
 
{
580
 
        RBSourceClass *klass = RB_SOURCE_GET_CLASS (source);
581
 
 
582
 
        return klass->impl_get_album (source);
583
 
}
584
 
 
585
 
gboolean
586
590
rb_source_have_url (RBSource *source)
587
591
{
588
592
        RBSourceClass *klass = RB_SOURCE_GET_CLASS (source);
590
594
        return klass->impl_have_url (source);
591
595
}
592
596
 
593
 
static void
594
 
default_buffering_done  (RBSource *source)
595
 
{
596
 
        rb_debug ("No implementation of buffering_done for active source");
597
 
}
598
 
        
599
 
 
600
 
void
601
 
rb_source_buffering_done (RBSource *source)
602
 
{
603
 
        RBSourceClass *klass = RB_SOURCE_GET_CLASS (source);
604
 
 
605
 
        klass->impl_buffering_done (source);
606
 
}
607
 
 
608
 
gboolean
609
 
default_receive_drag (RBSource *source, GtkSelectionData *data)
610
 
{
611
 
        rb_error_dialog (_("This source does not support drag and drop."));
612
 
        return FALSE;
613
 
}
614
 
 
615
597
gboolean
616
598
rb_source_receive_drag (RBSource *source, GtkSelectionData *data)
617
599
{
618
600
        RBSourceClass *klass = RB_SOURCE_GET_CLASS (source);
619
601
 
620
 
        return klass->impl_receive_drag (source, data);
 
602
        if (klass->impl_receive_drag)
 
603
                return klass->impl_receive_drag (source, data);
 
604
        else
 
605
                return FALSE;
 
606
}
 
607
 
 
608
void
 
609
_rb_source_show_popup (RBSource *source, const char *ui_path)
 
610
{
 
611
        GtkUIManager *uimanager;
 
612
 
 
613
        g_object_get (G_OBJECT (RB_SOURCE_GET_PRIVATE (source)->shell), 
 
614
                      "ui-manager", &uimanager, NULL);
 
615
        rb_gtk_action_popup_menu (uimanager, ui_path);
 
616
        g_object_unref (G_OBJECT (uimanager));
 
617
 
621
618
}
622
619
 
623
620
static gboolean
648
645
        klass->impl_delete_thyself (source);
649
646
        g_signal_emit (G_OBJECT (source), rb_source_signals[DELETED], 0);
650
647
}
 
648
 
 
649
static void default_activate (RBSource *source)
 
650
{
 
651
        return;
 
652
}
 
653
 
 
654
static void default_deactivate (RBSource *source)
 
655
{
 
656
        return;
 
657
}
 
658
 
 
659
static gboolean default_disconnect (RBSource *source)
 
660
{
 
661
        return TRUE;
 
662
}
 
663
 
 
664
void rb_source_activate (RBSource *source)
 
665
{
 
666
        RBSourceClass *klass = RB_SOURCE_GET_CLASS (source);
 
667
 
 
668
        klass->impl_activate (source);
 
669
 
 
670
        return;
 
671
}
 
672
 
 
673
void rb_source_deactivate (RBSource *source)
 
674
{
 
675
        RBSourceClass *klass = RB_SOURCE_GET_CLASS (source);
 
676
 
 
677
        klass->impl_deactivate (source);
 
678
 
 
679
        return;
 
680
}
 
681
 
 
682
gboolean rb_source_disconnect (RBSource *source)
 
683
{
 
684
        RBSourceClass *klass = RB_SOURCE_GET_CLASS (source);
 
685
 
 
686
        return klass->impl_disconnect (source);
 
687
}
 
688