static void rb_removable_media_manager_cmd_copy_tracks (GtkAction *action, RBRemovableMediaManager *mgr) { RBRemovableMediaManagerPrivate *priv = GET_PRIVATE (mgr); RBRemovableMediaSource *source; RBLibrarySource *library; RhythmDBQueryModel *model; GList *list = NULL; source = RB_REMOVABLE_MEDIA_SOURCE (priv->selected_source); g_object_get (source, "query-model", &model, NULL); g_object_get (priv->shell, "library-source", &library, NULL); gtk_tree_model_foreach (GTK_TREE_MODEL (model), (GtkTreeModelForeachFunc)copy_entry, &list); rb_source_paste (RB_SOURCE (library), list); g_list_free (list); g_object_unref (model); g_object_unref (library); }
static void rb_mtp_source_constructed (GObject *object) { RBMtpSource *source; RBEntryView *tracks; RBShell *shell; RBShellPlayer *shell_player; GObject *player_backend; RB_CHAIN_GOBJECT_METHOD (rb_mtp_source_parent_class, constructed, object); source = RB_MTP_SOURCE (object); tracks = rb_source_get_entry_view (RB_SOURCE (source)); rb_entry_view_append_column (tracks, RB_ENTRY_VIEW_COL_RATING, FALSE); rb_entry_view_append_column (tracks, RB_ENTRY_VIEW_COL_LAST_PLAYED, FALSE); /* the source element needs our cooperation */ g_object_get (source, "shell", &shell, NULL); g_object_get (shell, "shell-player", &shell_player, NULL); g_object_get (shell_player, "player", &player_backend, NULL); g_object_unref (shell_player); g_signal_connect_object (player_backend, "prepare-source", G_CALLBACK (prepare_player_source_cb), source, 0); g_object_unref (player_backend); g_object_unref (shell); g_signal_connect_object (rb_encoder_factory_get (), "prepare-source", G_CALLBACK (prepare_encoder_source_cb), source, 0); g_signal_connect_object (rb_encoder_factory_get (), "prepare-sink", G_CALLBACK (prepare_encoder_sink_cb), source, 0); rb_display_page_set_icon_name (RB_DISPLAY_PAGE (source), "multimedia-player-symbolic"); }
static void rb_source_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { RBSource *source = RB_SOURCE (object); switch (prop_id) { case PROP_QUERY_MODEL: g_value_set_object (value, source->priv->query_model); break; case PROP_ENTRY_TYPE: g_value_set_object (value, source->priv->entry_type); break; case PROP_BASE_QUERY_MODEL: /* unless the subclass overrides it, just assume the * current query model is the base model. */ g_value_set_object (value, source->priv->query_model); break; case PROP_PLAY_ORDER: g_value_set_object (value, NULL); /* ? */ break; case PROP_SETTINGS: g_value_set_object (value, source->priv->settings); break; case PROP_SHOW_BROWSER: g_value_set_boolean (value, FALSE); break; case PROP_LOAD_STATUS: g_value_set_enum (value, source->priv->load_status); break; case PROP_TOOLBAR_PATH: g_value_set_string (value, source->priv->toolbar_path); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } }
static void rb_source_finalize (GObject *object) { RBSource *source; g_return_if_fail (object != NULL); g_return_if_fail (RB_IS_SOURCE (object)); source = RB_SOURCE (object); if (source->priv->query_model != NULL) { rb_debug ("Unreffing model %p count: %d", source->priv->query_model, G_OBJECT (source->priv->query_model)->ref_count); g_object_unref (source->priv->query_model); } g_free (source->priv->toolbar_path); G_OBJECT_CLASS (rb_source_parent_class)->finalize (object); }
static void impl_search (RBSource *asource, RBSourceSearch *search, const char *cur_text, const char *new_text) { RBIRadioSource *source = RB_IRADIO_SOURCE (asource); if (source->priv->search_query != NULL) { rhythmdb_query_free (source->priv->search_query); } if (search == NULL) { search = source->priv->default_search; } source->priv->search_query = rb_source_search_create_query (search, source->priv->db, new_text); rb_iradio_source_do_query (source); rb_source_notify_filter_changed (RB_SOURCE (source)); }
static void rb_mtp_plugin_maybe_add_source (RBMtpPlugin *plugin, const char *udi, LIBMTP_raw_device_t *raw_devices, int num_raw_devices) { int i; int device_num = 0; DBusError error; rb_debug ("checking if UDI %s matches an MTP device", udi); /* get device number */ dbus_error_init (&error); device_num = libhal_device_get_property_int (plugin->hal_context, udi, "usb.linux.device_number", &error); if (dbus_error_is_set (&error)) { rb_debug ("unable to get USB device number: %s", error.message); dbus_error_free (&error); return; } rb_debug ("USB device number: %d", device_num); for (i = 0; i < num_raw_devices; i++) { rb_debug ("detected MTP device: device number %d (bus location %u)", raw_devices[i].devnum, raw_devices[i].bus_location); if (raw_devices[i].devnum == device_num) { RBSource *source; RBShell *shell; rb_debug ("device matched, creating a source"); g_object_get (plugin, "object", &shell, NULL); source = RB_SOURCE (rb_mtp_source_new (shell, G_OBJECT (plugin), udi, &raw_devices[i])); rb_shell_append_display_page (shell, RB_DISPLAY_PAGE (source), RB_DISPLAY_PAGE_GROUP_DEVICES); plugin->mtp_sources = g_list_prepend (plugin->mtp_sources, source); g_signal_connect_object (source, "deleted", G_CALLBACK (source_deleted_cb), plugin, 0); g_object_unref (shell); } } }
RBSource * rb_podcast_main_source_new (RBShell *shell, RBPodcastManager *podcast_manager) { RBSource *source; RhythmDBQuery *base_query; RhythmDB *db; GSettings *settings; g_object_get (shell, "db", &db, NULL); base_query = rhythmdb_query_parse (db, RHYTHMDB_QUERY_PROP_EQUALS, RHYTHMDB_PROP_TYPE, RHYTHMDB_ENTRY_TYPE_PODCAST_POST, RHYTHMDB_QUERY_END); g_object_unref (db); settings = g_settings_new (PODCAST_SETTINGS_SCHEMA); source = RB_SOURCE (g_object_new (RB_TYPE_PODCAST_MAIN_SOURCE, "name", _("Podcasts"), "shell", shell, "entry-type", RHYTHMDB_ENTRY_TYPE_PODCAST_POST, "podcast-manager", podcast_manager, "base-query", base_query, "settings", g_settings_get_child (settings, "source"), "toolbar-path", "/PodcastSourceToolBar", "show-all-feeds", TRUE, NULL)); g_object_unref (settings); rhythmdb_query_free (base_query); rb_shell_register_entry_type_for_source (shell, source, RHYTHMDB_ENTRY_TYPE_PODCAST_FEED); rb_shell_register_entry_type_for_source (shell, source, RHYTHMDB_ENTRY_TYPE_PODCAST_POST); return source; }
RBRemovableMediaSource * rb_nokia770_source_new (RBPlugin *plugin, RBShell *shell, GMount *mount, MPIDDevice *device_info) { RBNokia770Source *source; RhythmDBEntryType entry_type; RhythmDB *db; GVolume *volume; char *name; char *path; g_assert (rb_nokia770_is_mount_player (mount, device_info)); volume = g_mount_get_volume (mount); g_object_get (G_OBJECT (shell), "db", &db, NULL); path = g_volume_get_identifier (volume, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE); name = g_strdup_printf ("nokia770: %s", path); entry_type = rhythmdb_entry_register_type (db, name); g_object_unref (db); g_free (name); g_free (path); g_object_unref (volume); source = RB_NOKIA770_SOURCE (g_object_new (RB_TYPE_NOKIA770_SOURCE, "plugin", plugin, "entry-type", entry_type, "ignore-entry-type", RHYTHMDB_ENTRY_TYPE_INVALID, "error-entry-type", RHYTHMDB_ENTRY_TYPE_INVALID, "mount", mount, "shell", shell, "source-group", RB_SOURCE_GROUP_DEVICES, "device-info", device_info, NULL)); rb_shell_register_entry_type_for_source (shell, RB_SOURCE (source), entry_type); return RB_REMOVABLE_MEDIA_SOURCE (source); }
static void default_get_status (RBDisplayPage *page, char **text, char **progress_text, float *progress) { RBSource *source = RB_SOURCE (page); /* hack to get these strings marked for translation */ if (0) { ngettext ("%d song", "%d songs", 0); } if (source->priv->query_model) { *text = rhythmdb_query_model_compute_status_normal (source->priv->query_model, "%d song", "%d songs"); if (rhythmdb_query_model_has_pending_changes (source->priv->query_model)) { *progress = -1.0f; } } else { *text = g_strdup (""); } }
static void rb_mtp_source_load_tracks (RBMtpSource *source) { RBMtpSourcePrivate *priv = MTP_SOURCE_GET_PRIVATE (source); char *name = NULL; name = LIBMTP_Get_Friendlyname (priv->device); /* ignore some particular broken device names */ if (name == NULL || strcmp (name, "?????") == 0) { g_free (name); name = LIBMTP_Get_Modelname (priv->device); } if (name == NULL) { name = g_strdup (_("Digital Audio Player")); } g_object_set (RB_SOURCE (source), "name", name, NULL); priv->load_songs_idle_id = g_idle_add ((GSourceFunc)load_mtp_db_idle_cb, source); g_free (name); }
RBBrowserSource * rb_mtp_source_new (RBShell *shell, LIBMTP_mtpdevice_t *device, const char *udi) { RBMtpSource *source = NULL; RhythmDBEntryType entry_type; RhythmDB *db = NULL; char *name = NULL; g_object_get (shell, "db", &db, NULL); name = g_strdup_printf ("MTP-%s", LIBMTP_Get_Serialnumber (device)); entry_type = rhythmdb_entry_register_type (db, name); entry_type->save_to_disk = FALSE; entry_type->category = RHYTHMDB_ENTRY_NORMAL; entry_type->get_playback_uri = (RhythmDBEntryStringFunc)rb_mtp_source_get_playback_uri; g_free (name); g_object_unref (db); source = RB_MTP_SOURCE (g_object_new (RB_TYPE_MTP_SOURCE, "entry-type", entry_type, "shell", shell, "visibility", TRUE, "volume", NULL, "source-group", RB_SOURCE_GROUP_DEVICES, "libmtp-device", device, "udi", udi, NULL)); entry_type->get_playback_uri_data = source; rb_shell_register_entry_type_for_source (shell, RB_SOURCE (source), entry_type); return RB_BROWSER_SOURCE (source); }
static RBSource * create_source_cb (RBRemovableMediaManager *rmm, GMount *mount, MPIDDevice *device_info, RBIpodPlugin *plugin) { RBSource *src; RBShell *shell; if (!rb_ipod_helpers_is_ipod (mount, device_info)) { return NULL; } if (rb_ipod_helpers_needs_init (mount)) { gboolean inited; gchar *builder_file; builder_file = rb_find_plugin_data_file (G_OBJECT (plugin), "ipod-init.ui"); inited = rb_ipod_helpers_show_first_time_dialog (mount, builder_file); g_free (builder_file); if (!inited) { return NULL; } } g_object_get (plugin, "object", &shell, NULL); src = RB_SOURCE (rb_ipod_source_new (G_OBJECT (plugin), shell, mount, device_info)); g_object_unref (shell); plugin->ipod_sources = g_list_prepend (plugin->ipod_sources, src); g_signal_connect_object (G_OBJECT (src), "deleted", G_CALLBACK (rb_ipod_plugin_source_deleted), plugin, 0); return src; }
static RBSource * create_source_cb (RBRemovableMediaManager *rmm, GMount *mount, MPIDDevice *device_info, RBIpodPlugin *plugin) { RBSource *src; if (!rb_ipod_helpers_is_ipod (mount, device_info)) { return NULL; } if (rb_ipod_helpers_needs_init (mount)) { gboolean inited; gchar *builder_file; builder_file = rb_plugin_find_file (RB_PLUGIN (plugin), "ipod-init.ui"); inited = rb_ipod_helpers_show_first_time_dialog (mount, builder_file); g_free (builder_file); if (!inited) { return NULL; } } GtkAction *sync_action = gtk_action_group_get_action (plugin->action_group, "iPodSourceSync"); src = RB_SOURCE (rb_ipod_source_new (RB_PLUGIN (plugin), plugin->shell, mount, device_info, &plugin->key_file, sync_action)); plugin->ipod_sources = g_list_prepend (plugin->ipod_sources, src); g_signal_connect_object (G_OBJECT (src), "deleted", G_CALLBACK (rb_ipod_plugin_source_deleted), plugin, 0); return src; }
static void playing_source_changed_cb (RBShellPlayer *player, RBSource *source, RBIRadioSource *iradio_source) { GObject *backend; g_object_get (player, "player", &backend, NULL); if (source == RB_SOURCE (iradio_source) && (iradio_source->priv->info_available_id == 0)) { rb_debug ("connecting info-available signal handler"); iradio_source->priv->info_available_id = g_signal_connect_object (backend, "info", G_CALLBACK (info_available_cb), iradio_source, 0); } else if (iradio_source->priv->info_available_id) { rb_debug ("disconnecting info-available signal handler"); g_signal_handler_disconnect (backend, iradio_source->priv->info_available_id); iradio_source->priv->info_available_id = 0; } g_object_unref (backend); }
static void load_playlist_file (RBGenericPlayerSource *source, const char *playlist_path, const char *rel_path) { RhythmDBEntryType *entry_type; RBGenericPlayerPlaylistSource *playlist; RBShell *shell; GMenuModel *playlist_menu; char *mount_path; g_object_get (source, "shell", &shell, "entry-type", &entry_type, "playlist-menu", &playlist_menu, NULL); mount_path = rb_generic_player_source_get_mount_path (source); rb_debug ("loading playlist %s", playlist_path); playlist = RB_GENERIC_PLAYER_PLAYLIST_SOURCE ( rb_generic_player_playlist_source_new (shell, source, playlist_path, mount_path, entry_type, playlist_menu)); if (playlist != NULL) { rb_generic_player_source_add_playlist (source, shell, RB_SOURCE (playlist)); } g_object_unref (playlist_menu); g_object_unref (entry_type); g_object_unref (shell); g_free (mount_path); }
static void rb_ipod_plugin_cmd_playlist_delete (GtkAction *action, RBIpodPlugin *plugin) { RBIpodStaticPlaylistSource *source = NULL; RBiPodSource *ipod_source; g_object_get (G_OBJECT (plugin->shell), "selected-source", &source, NULL); if ((source == NULL) || !RB_IS_IPOD_STATIC_PLAYLIST_SOURCE (source)) { g_critical ("got iPodPlaylistSourceDelete action for non-ipod playlist source"); if (source != NULL) g_object_unref (source); return; } /* delete playlist*/ ipod_source = rb_ipod_static_playlist_source_get_ipod_source (source); rb_ipod_source_remove_playlist (ipod_source, RB_SOURCE (source)); g_object_unref (source); }
static void sync_delete_done_cb (RBMediaPlayerSource *source, gpointer dontcare) { RBMediaPlayerSourcePrivate *priv = MEDIA_PLAYER_SOURCE_GET_PRIVATE (source); rb_debug ("finished deleting %d files from media player", priv->sync_state->sync_remove_count); /* Transfer needed tracks and podcasts from itinerary to device */ if (priv->sync_state->sync_add_count != 0) { RBTrackTransferBatch *batch; rb_debug ("transferring %d files to media player", priv->sync_state->sync_add_count); batch = rb_source_paste (RB_SOURCE (source), priv->sync_state->sync_to_add); if (batch != NULL) { g_signal_connect_object (batch, "complete", G_CALLBACK (transfer_batch_complete_cb), source, 0); g_signal_connect_object (batch, "cancelled", G_CALLBACK (transfer_batch_cancelled_cb), source, 0); } else { rb_debug ("weird, transfer was apparently synchronous"); g_idle_add ((GSourceFunc) sync_idle_cb_playlists, source); } } else { rb_debug ("no files to transfer to the device"); g_idle_add ((GSourceFunc) sync_idle_cb_playlists, source); } }
static void impl_delete_thyself (RBSource *source) { GList *pl; GList *p; RBGenericPlayerSourcePrivate *priv = GENERIC_PLAYER_SOURCE_GET_PRIVATE (source); /* take a copy of the list first, as playlist_deleted_cb modifies priv->playlists */ pl = g_list_copy (priv->playlists); for (p = pl; p != NULL; p = p->next) { RBSource *playlist = RB_SOURCE (p->data); rb_source_delete_thyself (playlist); } g_list_free (priv->playlists); g_list_free (pl); priv->playlists = NULL; if (priv->import_errors != NULL) { rb_source_delete_thyself (priv->import_errors); priv->import_errors = NULL; } RB_SOURCE_CLASS (rb_generic_player_source_parent_class)->impl_delete_thyself (source); }
static void metadata_gather_cb (RhythmDB *db, RhythmDBEntry *entry, RBStringValueMap *data, RBAudioCdSource *source) { RBAudioCdSourcePrivate *priv = AUDIOCD_SOURCE_GET_PRIVATE (source); GValue value = {0,}; if (_rb_source_check_entry_type (RB_SOURCE (source), entry) == FALSE) { return; } if (gtk_entry_get_text_length (GTK_ENTRY (priv->artist_entry)) > 0) { g_value_init (&value, G_TYPE_STRING); g_value_set_string (&value, gtk_entry_get_text (GTK_ENTRY (priv->artist_entry))); rb_string_value_map_set (data, RHYTHMDB_PROP_ALBUM_ARTIST, &value); g_value_unset (&value); } if (gtk_entry_get_text_length (GTK_ENTRY (priv->artist_sort_entry)) > 0) { g_value_init (&value, G_TYPE_STRING); g_value_set_string (&value, gtk_entry_get_text (GTK_ENTRY (priv->artist_sort_entry))); rb_string_value_map_set (data, RHYTHMDB_PROP_ALBUM_ARTIST_SORTNAME, &value); g_value_unset (&value); } }
static void impl_activate (RBPlugin *plugin, RBShell *shell) { // rb_error_dialog (NULL, _("Spotify Plugin"), "Spotify plugin activated, with shell %p", shell); RBSpotifySource *source; RhythmDBEntryType type; RhythmDB *db; char *entry_type_name, *username, *password; int err; RBSpotifyPluginPrivate *pprivate = RB_SPOTIFY_PLUGIN_GET_PRIVATE(plugin); pthread_mutex_init(&g_notify_mutex, NULL); pthread_cond_init(&g_notify_cond, NULL); audio_fifo_init(&g_audio_fifo); spconfig.application_key_size = g_appkey_size; err = sp_session_init(&spconfig, &pprivate->sess); if (err != SP_ERROR_OK) { rb_error_dialog (NULL, _("Spotify Plugin"), "Error initialising spotify session"); pprivate->sess = NULL; return; } fprintf(stderr, "err: %x", err); err = pthread_create(&pprivate->notify_thread, 0, notification_routine, pprivate->sess); fprintf(stderr, "Thread created"); if (err != 0) { fprintf(stderr, "Error creating notification thread %x\n", err); return; } username = eel_gconf_get_string (CONF_SPOTIFY_USERNAME); password = eel_gconf_get_string (CONF_SPOTIFY_PASSWORD); if (username == NULL || password == NULL) { rb_error_dialog (NULL, _("Spotify Plugin"), "Username and password not set."); return; } err = sp_session_login(pprivate->sess, username, password); fprintf(stderr, "err: %x", err); rbspotifysrc_set_plugin(plugin); g_object_get (shell, "db", &db, NULL); entry_type_name = g_strdup_printf ("spotify"); type = rhythmdb_entry_register_type (db, entry_type_name); g_free (entry_type_name); type->save_to_disk = FALSE; type->category = RHYTHMDB_ENTRY_NORMAL; // type->get_playback_uri = (RhythmDBEntryStringFunc) rb_daap_source_get_playback_uri; g_object_unref (db); // icon = rb_daap_plugin_get_icon (RB_DAAP_PLUGIN (plugin), password_protected, FALSE); source = (RBSpotifySource*)RB_SOURCE (g_object_new (RBSPOTIFYSOURCE_TYPE, "name", "spotify", "entry-type", type, "shell", shell, "visibility", TRUE, // "sorting-key", CONF_STATE_SORTING, "source-group", RB_SOURCE_GROUP_SHARED, "plugin", RB_PLUGIN (plugin), NULL)); source->priv->sess = pprivate->sess; source->priv->db = db; source->priv->type = type; rb_shell_register_entry_type_for_source (shell, (RBSource*)source, type); rb_shell_append_source (shell, (RBSource*)source, NULL); // return source; }
static void sync_playlists (RBMediaPlayerSource *source) { RBMediaPlayerSourcePrivate *priv = MEDIA_PLAYER_SOURCE_GET_PRIVATE (source); RBMediaPlayerSourceClass *klass = RB_MEDIA_PLAYER_SOURCE_GET_CLASS (source); RBPlaylistManager *playlist_manager; RBShell *shell; GHashTable *device; GList *all_playlists; GList *l; if (klass->add_playlist == NULL || klass->remove_playlists == NULL) { rb_debug ("source class doesn't support playlists"); return; } /* build an updated device contents map, so we can find the device entries * corresponding to the entries in the local playlists. */ device = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify)rhythmdb_entry_unref); rb_media_player_source_get_entries (source, SYNC_CATEGORY_MUSIC, device); /* remove all playlists from the device, then add the synced playlists. */ klass->remove_playlists (source); /* get all local playlists */ g_object_get (source, "shell", &shell, NULL); g_object_get (shell, "playlist-manager", &playlist_manager, NULL); all_playlists = rb_playlist_manager_get_playlists (playlist_manager); g_object_unref (playlist_manager); g_object_unref (shell); for (l = all_playlists; l != NULL; l = l->next) { char *name; RBSource *playlist_source = RB_SOURCE (l->data); RhythmDBQueryModel *model; GList *tracks = NULL; GtkTreeIter iter; /* is this playlist selected for syncing? */ g_object_get (playlist_source, "name", &name, NULL); if (rb_sync_settings_sync_group (priv->sync_settings, SYNC_CATEGORY_MUSIC, name) == FALSE) { rb_debug ("not syncing playlist %s", name); g_free (name); continue; } /* match playlist entries to entries on the device */ g_object_get (playlist_source, "base-query-model", &model, NULL); if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (model), &iter) == FALSE) { rb_debug ("not syncing empty playlist %s", name); g_free (name); g_object_unref (model); continue; } do { char *trackid; RhythmDBEntry *entry; RhythmDBEntry *device_entry; entry = rhythmdb_query_model_iter_to_entry (model, &iter); trackid = rb_sync_state_make_track_uuid (entry); device_entry = g_hash_table_lookup (device, trackid); if (device_entry != NULL) { tracks = g_list_prepend (tracks, device_entry); } else { rb_debug ("unable to find entry on device for track %s (id %s)", rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION), trackid); } g_free (trackid); } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (model), &iter)); tracks = g_list_reverse (tracks); /* transfer the playlist to the device */ rb_debug ("syncing playlist %s", name); klass->add_playlist (source, name, tracks); g_free (name); g_list_free (tracks); g_object_unref (model); } g_hash_table_destroy (device); }
gboolean impl_receive_drag (RBDisplayPage *page, GtkSelectionData *data) { GList *entries; RhythmDB *db; char *type; entries = NULL; type = gdk_atom_name (gtk_selection_data_get_data_type (data)); db = get_db_for_source (RB_SOURCE (page)); if (strcmp (type, "text/uri-list") == 0) { GList *list; GList *i; rb_debug ("parsing uri list"); list = rb_uri_list_parse ((const char *) gtk_selection_data_get_data (data)); for (i = list; i != NULL; i = g_list_next (i)) { char *uri; RhythmDBEntry *entry; if (i->data == NULL) continue; uri = i->data; entry = rhythmdb_entry_lookup_by_location (db, uri); if (entry == NULL) { /* add to the library */ rb_debug ("received drop of unknown uri: %s", uri); } else { /* add to list of entries to copy */ entries = g_list_prepend (entries, entry); } g_free (uri); } g_list_free (list); } else if (strcmp (type, "application/x-rhythmbox-entry") == 0) { char **list; char **i; rb_debug ("parsing entry ids"); list = g_strsplit ((const char*) gtk_selection_data_get_data (data), "\n", -1); for (i = list; *i != NULL; i++) { RhythmDBEntry *entry; gulong id; id = atoi (*i); entry = rhythmdb_entry_lookup_by_id (db, id); if (entry != NULL) entries = g_list_prepend (entries, entry); } g_strfreev (list); } else { rb_debug ("received unknown drop type"); } g_object_unref (db); g_free (type); if (entries) { entries = g_list_reverse (entries); if (rb_source_can_paste (RB_SOURCE (page))) { rb_source_paste (RB_SOURCE (page), entries); } g_list_free (entries); } return TRUE; }
RBSource * rb_generic_player_source_new (GObject *plugin, RBShell *shell, GMount *mount, MPIDDevice *device_info) { RBGenericPlayerSource *source; RhythmDBEntryType *entry_type; RhythmDBEntryType *error_type; RhythmDBEntryType *ignore_type; RhythmDB *db; GVolume *volume; GSettings *settings; char *name; char *path; volume = g_mount_get_volume (mount); g_object_get (shell, "db", &db, NULL); path = g_volume_get_identifier (volume, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE); name = g_strdup_printf ("generic audio player: %s", path); entry_type = g_object_new (RHYTHMDB_TYPE_ENTRY_TYPE, "db", db, "name", name, "save-to-disk", FALSE, "category", RHYTHMDB_ENTRY_NORMAL, NULL); rhythmdb_register_entry_type (db, entry_type); g_free (name); name = g_strdup_printf ("generic audio player (ignore): %s", path); ignore_type = g_object_new (RHYTHMDB_TYPE_ENTRY_TYPE, "db", db, "name", name, "save-to-disk", FALSE, "category", RHYTHMDB_ENTRY_VIRTUAL, NULL); rhythmdb_register_entry_type (db, ignore_type); g_free (name); name = g_strdup_printf ("generic audio player (errors): %s", path); error_type = g_object_new (RHYTHMDB_TYPE_ENTRY_TYPE, "db", db, "name", name, "save-to-disk", FALSE, "category", RHYTHMDB_ENTRY_VIRTUAL, NULL); rhythmdb_register_entry_type (db, error_type); g_free (name); g_object_unref (db); g_object_unref (volume); g_free (path); settings = g_settings_new ("org.gnome.rhythmbox.plugins.generic-player"); source = RB_GENERIC_PLAYER_SOURCE (g_object_new (RB_TYPE_GENERIC_PLAYER_SOURCE, "plugin", plugin, "entry-type", entry_type, "ignore-entry-type", ignore_type, "error-entry-type", error_type, "mount", mount, "shell", shell, "device-info", device_info, "load-status", RB_SOURCE_LOAD_STATUS_LOADING, "settings", g_settings_get_child (settings, "source"), "toolbar-path", "/GenericPlayerSourceToolBar", NULL)); g_object_unref (settings); rb_shell_register_entry_type_for_source (shell, RB_SOURCE (source), entry_type); return RB_SOURCE (source); }
static void rb_mtp_source_constructed (GObject *object) { RBMtpSource *source; RBMtpSourcePrivate *priv; RBEntryView *tracks; RBShell *shell; RBShellPlayer *shell_player; GObject *player_backend; GtkIconTheme *theme; GdkPixbuf *pixbuf; #if defined(HAVE_GUDEV) GMount *mount; #endif gint size; RB_CHAIN_GOBJECT_METHOD (rb_mtp_source_parent_class, constructed, object); source = RB_MTP_SOURCE (object); priv = MTP_SOURCE_GET_PRIVATE (source); /* try to open the device. if gvfs has mounted it, unmount it first */ #if defined(HAVE_GUDEV) mount = find_mount_for_device (priv->udev_device); if (mount != NULL) { rb_debug ("device is already mounted, waiting until activated"); g_mount_unmount_with_operation (mount, G_MOUNT_UNMOUNT_NONE, NULL, NULL, unmount_done_cb, g_object_ref (source)); /* mount gets unreffed in callback */ } else #endif open_device (source); tracks = rb_source_get_entry_view (RB_SOURCE (source)); rb_entry_view_append_column (tracks, RB_ENTRY_VIEW_COL_RATING, FALSE); rb_entry_view_append_column (tracks, RB_ENTRY_VIEW_COL_LAST_PLAYED, FALSE); /* the source element needs our cooperation */ g_object_get (source, "shell", &shell, NULL); shell_player = RB_SHELL_PLAYER (rb_shell_get_player (shell)); g_object_get (shell_player, "player", &player_backend, NULL); g_signal_connect_object (player_backend, "prepare-source", G_CALLBACK (prepare_player_source_cb), source, 0); g_object_unref (player_backend); g_object_unref (shell); g_signal_connect_object (rb_encoder_factory_get (), "prepare-source", G_CALLBACK (prepare_encoder_source_cb), source, 0); g_signal_connect_object (rb_encoder_factory_get (), "prepare-sink", G_CALLBACK (prepare_encoder_sink_cb), source, 0); /* icon */ theme = gtk_icon_theme_get_default (); gtk_icon_size_lookup (GTK_ICON_SIZE_LARGE_TOOLBAR, &size, NULL); pixbuf = gtk_icon_theme_load_icon (theme, "multimedia-player", size, 0, NULL); rb_source_set_pixbuf (RB_SOURCE (source), pixbuf); g_object_unref (pixbuf); if (priv->album_art_supported) { RhythmDB *db; db = get_db_for_source (source); g_signal_connect_object (db, "entry-extra-metadata-notify::rb:coverArt", G_CALLBACK (artwork_notify_cb), source, 0); g_object_unref (db); } }
static void impl_eject (RBRemovableMediaSource *source) { rb_source_delete_thyself (RB_SOURCE (source)); }
static gboolean impl_show_popup (RBSource *source) { _rb_source_show_popup (RB_SOURCE (source), "/MTPSourcePopup"); return TRUE; }
static void rb_static_playlist_source_constructed (GObject *object) { RBStaticPlaylistSource *source; RBStaticPlaylistSourcePrivate *priv; RBPlaylistSource *psource; RBEntryView *songs; RBShell *shell; RhythmDBEntryType *entry_type; RB_CHAIN_GOBJECT_METHOD (rb_static_playlist_source_parent_class, constructed, object); source = RB_STATIC_PLAYLIST_SOURCE (object); priv = RB_STATIC_PLAYLIST_SOURCE_GET_PRIVATE (source); psource = RB_PLAYLIST_SOURCE (source); priv->base_model = rb_playlist_source_get_query_model (RB_PLAYLIST_SOURCE (psource)); g_object_set (priv->base_model, "show-hidden", TRUE, NULL); g_object_ref (priv->base_model); g_signal_connect_object (priv->base_model, "filter-entry-drop", G_CALLBACK (rb_static_playlist_source_filter_entry_drop), source, 0); priv->paned = gtk_vpaned_new (); g_object_get (source, "shell", &shell, NULL); priv->action_group = _rb_display_page_register_action_group (RB_DISPLAY_PAGE (source), "StaticPlaylistActions", NULL, 0, shell); if (gtk_action_group_get_action (priv->action_group, rb_static_playlist_source_radio_actions[0].name) == NULL) { gtk_action_group_add_radio_actions (priv->action_group, rb_static_playlist_source_radio_actions, G_N_ELEMENTS (rb_static_playlist_source_radio_actions), 0, NULL, NULL); rb_source_search_basic_create_for_actions (priv->action_group, rb_static_playlist_source_radio_actions, G_N_ELEMENTS (rb_static_playlist_source_radio_actions)); } priv->default_search = rb_source_search_basic_new (RHYTHMDB_PROP_SEARCH_MATCH); g_object_unref (shell); g_object_get (source, "entry-type", &entry_type, NULL); priv->browser = rb_library_browser_new (rb_playlist_source_get_db (RB_PLAYLIST_SOURCE (source)), entry_type); if (entry_type != NULL) { g_object_unref (entry_type); } gtk_paned_pack1 (GTK_PANED (priv->paned), GTK_WIDGET (priv->browser), TRUE, FALSE); g_signal_connect_object (priv->browser, "notify::output-model", G_CALLBACK (rb_static_playlist_source_browser_changed_cb), source, 0); rb_library_browser_set_model (priv->browser, priv->base_model, FALSE); rb_static_playlist_source_do_query (source); /* reparent the entry view */ songs = rb_source_get_entry_view (RB_SOURCE (source)); g_object_ref (songs); gtk_container_remove (GTK_CONTAINER (source), GTK_WIDGET (songs)); gtk_paned_pack2 (GTK_PANED (priv->paned), GTK_WIDGET (songs), TRUE, FALSE); gtk_container_add (GTK_CONTAINER (source), priv->paned); rb_source_bind_settings (RB_SOURCE (source), GTK_WIDGET (songs), priv->paned, GTK_WIDGET (priv->browser)); g_object_unref (songs); /* watch these to find out when things are dropped into the entry view */ g_signal_connect_object (priv->base_model, "row-inserted", G_CALLBACK (rb_static_playlist_source_row_inserted), source, 0); g_signal_connect_object (priv->base_model, "non-entry-dropped", G_CALLBACK (rb_static_playlist_source_non_entry_dropped), source, 0); g_signal_connect_object (priv->base_model, "rows-reordered", G_CALLBACK (rb_static_playlist_source_rows_reordered), source, 0); gtk_widget_show_all (GTK_WIDGET (source)); }
static void import_status_changed_cb (RhythmDBImportJob *job, int total, int imported, RBGenericPlayerSource *source) { rb_source_notify_status_changed (RB_SOURCE (source)); }
static void rb_audiocd_source_constructed (GObject *object) { RBAudioCdSourcePrivate *priv; RBAudioCdSource *source; RBEntryView *entry_view; GtkCellRenderer *renderer; GtkTreeViewColumn *extract; GtkWidget *widget; GtkAction *action; RhythmDB *db; RBPlugin *plugin; RBShell *shell; char *ui_file; int toggle_width; RB_CHAIN_GOBJECT_METHOD (rb_audiocd_source_parent_class, constructed, object); source = RB_AUDIOCD_SOURCE (object); priv = AUDIOCD_SOURCE_GET_PRIVATE (source); g_object_set (G_OBJECT (source), "name", "Unknown Audio", NULL); g_object_get (source, "shell", &shell, NULL); priv->action_group = _rb_source_register_action_group (RB_SOURCE (source), "AudioCdActions", NULL, 0, NULL); _rb_action_group_add_source_actions (priv->action_group, G_OBJECT (shell), rb_audiocd_source_actions, G_N_ELEMENTS (rb_audiocd_source_actions)); g_object_unref (shell); action = gtk_action_group_get_action (priv->action_group, "AudioCdCopyTracks"); /* Translators: this is the toolbar button label for Copy to Library action. */ g_object_set (action, "short-label", _("Extract"), NULL); #if !defined(HAVE_SJ_METADATA_GETTER) action = gtk_action_group_get_action (priv->action_group, "AudioCdSourceReloadMetadata"); g_object_set (action, "visible", FALSE, NULL); #endif /* we want audio cds to sort by track# by default */ entry_view = rb_source_get_entry_view (RB_SOURCE (source)); rb_entry_view_set_sorting_order (entry_view, "Track", GTK_SORT_ASCENDING); /* enable in-place editing for titles, artists, and genres */ rb_entry_view_set_column_editable (entry_view, RB_ENTRY_VIEW_COL_TITLE, TRUE); rb_entry_view_set_column_editable (entry_view, RB_ENTRY_VIEW_COL_ARTIST, TRUE); rb_entry_view_set_column_editable (entry_view, RB_ENTRY_VIEW_COL_GENRE, TRUE); /* create the 'extract' column */ renderer = gtk_cell_renderer_toggle_new (); extract = gtk_tree_view_column_new (); gtk_tree_view_column_pack_start (extract, renderer, FALSE); gtk_tree_view_column_set_cell_data_func (extract, renderer, (GtkTreeCellDataFunc) extract_cell_data_func, source, NULL); gtk_tree_view_column_set_clickable (extract, TRUE); widget = gtk_check_button_new (); g_object_set (widget, "active", TRUE, NULL); gtk_widget_show_all (widget); g_signal_connect_object (extract, "clicked", G_CALLBACK (extract_column_clicked_cb), source, 0); gtk_tree_view_column_set_widget (extract, widget); g_signal_connect_object (renderer, "toggled", G_CALLBACK (extract_toggled_cb), source, 0); /* set column width */ gtk_cell_renderer_get_size (renderer, GTK_WIDGET (entry_view), NULL, NULL, NULL, &toggle_width, NULL); gtk_tree_view_column_set_sizing (extract, GTK_TREE_VIEW_COLUMN_FIXED); gtk_tree_view_column_set_fixed_width (extract, toggle_width + 5); rb_entry_view_insert_column_custom (entry_view, extract, "", "Extract", NULL, NULL, NULL, 1); gtk_widget_set_tooltip_text (gtk_tree_view_column_get_widget (extract), _("Select tracks to be extracted")); /* hide the 'album' column */ gtk_tree_view_column_set_visible (rb_entry_view_get_column (entry_view, RB_ENTRY_VIEW_COL_ALBUM), FALSE); /* handle extra metadata requests for album artist and album artist sortname */ db = get_db_for_source (source); g_signal_connect_object (G_OBJECT (db), "entry-extra-metadata-request::" RHYTHMDB_PROP_ALBUM_ARTIST, G_CALLBACK (album_artist_metadata_request_cb), source, 0); g_signal_connect_object (G_OBJECT (db), "entry-extra-metadata-request::" RHYTHMDB_PROP_ALBUM_ARTIST_SORTNAME, G_CALLBACK (album_artist_sortname_metadata_request_cb), source, 0); g_signal_connect_object (G_OBJECT (db), "entry-extra-metadata-gather", G_CALLBACK (metadata_gather_cb), source, 0); g_object_unref (db); /* set up the album info widgets */ g_object_get (source, "plugin", &plugin, NULL); ui_file = rb_plugin_find_file (plugin, "album-info.ui"); g_object_unref (plugin); if (ui_file == NULL) { g_warning ("couldn't find album-info.ui"); } else { RBAudioCdSourcePrivate *priv; GtkWidget *table; GtkBuilder *builder; #if defined(HAVE_SJ_METADATA_GETTER) && GTK_CHECK_VERSION(2,17,6) GtkWidget *box; char *message; #endif priv = AUDIOCD_SOURCE_GET_PRIVATE (source); builder = rb_builder_load (ui_file, NULL); g_free (ui_file); table = GTK_WIDGET (gtk_builder_get_object (builder, "album_info")); g_assert (table != NULL); #if defined(HAVE_SJ_METADATA_GETTER) && GTK_CHECK_VERSION(2,17,6) /* Info bar for non-Musicbrainz data */ priv->info_bar = gtk_info_bar_new_with_buttons (_("S_ubmit Album"), GTK_RESPONSE_OK, _("Hide"), GTK_RESPONSE_CANCEL, NULL); message = g_strdup_printf ("<b>%s</b>\n%s", _("Could not find this album on MusicBrainz."), _("You can improve the MusicBrainz database by adding this album.")); priv->info_bar_label = gtk_label_new (NULL); gtk_label_set_markup (GTK_LABEL (priv->info_bar_label), message); gtk_label_set_justify (GTK_LABEL (priv->info_bar_label), GTK_JUSTIFY_LEFT); g_free (message); box = gtk_info_bar_get_content_area (GTK_INFO_BAR (priv->info_bar)); gtk_container_add (GTK_CONTAINER (box), priv->info_bar_label); gtk_widget_show_all (box); gtk_widget_set_no_show_all (priv->info_bar, TRUE); g_signal_connect (G_OBJECT (priv->info_bar), "response", G_CALLBACK (info_bar_response_cb), source); gtk_table_attach_defaults (GTK_TABLE (table), priv->info_bar, 0, 2, 0, 1); #endif priv->artist_entry = GTK_WIDGET (gtk_builder_get_object (builder, "artist_entry")); priv->artist_sort_entry = GTK_WIDGET (gtk_builder_get_object (builder, "artist_sort_entry")); priv->album_entry = GTK_WIDGET (gtk_builder_get_object (builder, "album_entry")); priv->year_entry = GTK_WIDGET (gtk_builder_get_object (builder, "year_entry")); priv->genre_entry = GTK_WIDGET (gtk_builder_get_object (builder, "genre_entry")); priv->disc_number_entry = GTK_WIDGET (gtk_builder_get_object (builder, "disc_number_entry")); g_signal_connect_object (priv->album_entry, "focus-out-event", G_CALLBACK (update_album_cb), source, 0); g_signal_connect_object (priv->genre_entry, "focus-out-event", G_CALLBACK (update_genre_cb), source, 0); g_signal_connect_object (priv->year_entry, "focus-out-event", G_CALLBACK (update_year_cb), source, 0); g_signal_connect_object (priv->disc_number_entry, "focus-out-event", G_CALLBACK (update_disc_number_cb), source, 0); gtk_box_pack_start (GTK_BOX (priv->box), table, FALSE, FALSE, 0); gtk_box_reorder_child (GTK_BOX (priv->box), table, 0); g_object_unref (builder); } g_object_ref (G_OBJECT (source)); g_thread_create ((GThreadFunc)rb_audiocd_load_songs, source, FALSE, NULL); }
static void rb_grilo_source_constructed (GObject *object) { RBGriloSource *source; RBShell *shell; RBShellPlayer *shell_player; const GList *source_keys; GtkTreeViewColumn *column; GtkCellRenderer *renderer; GtkTreeSelection *selection; GtkWidget *scrolled; GtkWidget *browserbox; GtkWidget *vbox; GtkWidget *mainbox; GtkAdjustment *adjustment; RB_CHAIN_GOBJECT_METHOD (rb_grilo_source_parent_class, constructed, object); source = RB_GRILO_SOURCE (object); g_object_get (source, "shell", &shell, NULL); g_object_get (shell, "db", &source->priv->db, "shell-player", &shell_player, NULL); g_object_unref (shell); g_object_get (source, "entry-type", &source->priv->entry_type, NULL); source->priv->entry_view = rb_entry_view_new (source->priv->db, G_OBJECT (shell_player), TRUE, FALSE); g_object_unref (shell_player); g_signal_connect (source->priv->entry_view, "notify::sort-order", G_CALLBACK (notify_sort_order_cb), source); source_keys = grl_source_supported_keys (source->priv->grilo_source); if (g_list_find ((GList *)source_keys, GUINT_TO_POINTER(GRL_METADATA_KEY_TRACK_NUMBER))) { rb_entry_view_append_column (source->priv->entry_view, RB_ENTRY_VIEW_COL_TRACK_NUMBER, FALSE); source->priv->grilo_keys = g_list_prepend (source->priv->grilo_keys, GUINT_TO_POINTER(GRL_METADATA_KEY_TRACK_NUMBER)); } if (g_list_find ((GList *)source_keys, GUINT_TO_POINTER(GRL_METADATA_KEY_TITLE))) { rb_entry_view_append_column (source->priv->entry_view, RB_ENTRY_VIEW_COL_TITLE, TRUE); source->priv->grilo_keys = g_list_prepend (source->priv->grilo_keys, GUINT_TO_POINTER(GRL_METADATA_KEY_TITLE)); } if (g_list_find ((GList *)source_keys, GUINT_TO_POINTER(GRL_METADATA_KEY_GENRE))) { rb_entry_view_append_column (source->priv->entry_view, RB_ENTRY_VIEW_COL_GENRE, FALSE); source->priv->grilo_keys = g_list_prepend (source->priv->grilo_keys, GUINT_TO_POINTER(GRL_METADATA_KEY_GENRE)); } if (g_list_find ((GList *)source_keys, GUINT_TO_POINTER(GRL_METADATA_KEY_ARTIST))) { rb_entry_view_append_column (source->priv->entry_view, RB_ENTRY_VIEW_COL_ARTIST, FALSE); source->priv->grilo_keys = g_list_prepend (source->priv->grilo_keys, GUINT_TO_POINTER(GRL_METADATA_KEY_ARTIST)); } if (g_list_find ((GList *)source_keys, GUINT_TO_POINTER(GRL_METADATA_KEY_ALBUM))) { rb_entry_view_append_column (source->priv->entry_view, RB_ENTRY_VIEW_COL_ALBUM, FALSE); source->priv->grilo_keys = g_list_prepend (source->priv->grilo_keys, GUINT_TO_POINTER(GRL_METADATA_KEY_ALBUM)); } /* if (g_list_find ((GList *)source_keys, GUINT_TO_POINTER(GRL_METADATA_KEY_DATE))) { rb_entry_view_append_column (source->priv->entry_view, RB_ENTRY_VIEW_COL_YEAR, FALSE); source->priv->grilo_keys = g_list_prepend (source->priv->grilo_keys, GUINT_TO_POINTER(GRL_METADATA_KEY_DATE)); } */ if (g_list_find ((GList *)source_keys, GUINT_TO_POINTER(GRL_METADATA_KEY_DURATION))) { rb_entry_view_append_column (source->priv->entry_view, RB_ENTRY_VIEW_COL_DURATION, FALSE); source->priv->grilo_keys = g_list_prepend (source->priv->grilo_keys, GUINT_TO_POINTER(GRL_METADATA_KEY_DURATION)); } source->priv->grilo_keys = g_list_prepend (source->priv->grilo_keys, GUINT_TO_POINTER(GRL_METADATA_KEY_CHILDCOUNT)); source->priv->grilo_keys = g_list_prepend (source->priv->grilo_keys, GUINT_TO_POINTER(GRL_METADATA_KEY_URL)); source->priv->grilo_keys = g_list_prepend (source->priv->grilo_keys, GUINT_TO_POINTER(GRL_METADATA_KEY_THUMBNAIL)); /* probably add an image column too? */ source->priv->browser_model = gtk_tree_store_new (4, GRL_TYPE_MEDIA, G_TYPE_STRING, G_TYPE_INT, G_TYPE_INT); source->priv->browser_view = gtk_tree_view_new (); gtk_tree_view_set_model (GTK_TREE_VIEW (source->priv->browser_view), GTK_TREE_MODEL (source->priv->browser_model)); column = gtk_tree_view_column_new (); renderer = gtk_cell_renderer_text_new (); gtk_tree_view_column_set_title (column, _("Browse")); gtk_tree_view_column_pack_start (column, renderer, FALSE); gtk_tree_view_column_add_attribute (column, renderer, "text", 1); gtk_tree_view_column_set_expand (column, TRUE); gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_FIXED); gtk_tree_view_append_column (GTK_TREE_VIEW (source->priv->browser_view), column); gtk_tree_view_set_show_expanders (GTK_TREE_VIEW (source->priv->browser_view), TRUE); gtk_tree_view_set_expander_column (GTK_TREE_VIEW (source->priv->browser_view), column); gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (source->priv->browser_view), TRUE); gtk_tree_view_set_fixed_height_mode (GTK_TREE_VIEW (source->priv->browser_view), TRUE); g_signal_connect (source->priv->browser_view, "row-expanded", G_CALLBACK (browser_row_expanded_cb), source); selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (source->priv->browser_view)); gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE); /* should be multiple eventually */ g_signal_connect (selection, "changed", G_CALLBACK (browser_selection_changed_cb), source); scrolled = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled), GTK_SHADOW_IN); adjustment = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (scrolled)); g_signal_connect (adjustment, "changed", G_CALLBACK (scroll_adjust_changed_cb), source); g_signal_connect (adjustment, "value-changed", G_CALLBACK (scroll_adjust_value_changed_cb), source); browserbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); /* search bar (if the source supports searching) */ if (grl_source_supported_operations (source->priv->grilo_source) & GRL_OP_SEARCH) { source->priv->search_entry = rb_search_entry_new (FALSE); g_object_set (source->priv->search_entry, "explicit-mode", TRUE, NULL); g_signal_connect (source->priv->search_entry, "search", G_CALLBACK (search_cb), source); g_signal_connect (source->priv->search_entry, "activate", G_CALLBACK (search_cb), source); gtk_box_pack_start (GTK_BOX (browserbox), GTK_WIDGET (source->priv->search_entry), FALSE, FALSE, 6); } gtk_container_add (GTK_CONTAINER (scrolled), source->priv->browser_view); gtk_box_pack_start (GTK_BOX (browserbox), scrolled, TRUE, TRUE, 0); mainbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); gtk_box_pack_start (GTK_BOX (source), mainbox, TRUE, TRUE, 0); /* info bar */ source->priv->info_bar_label = gtk_label_new (""); source->priv->info_bar = gtk_info_bar_new (); gtk_info_bar_set_message_type (GTK_INFO_BAR (source->priv->info_bar), GTK_MESSAGE_INFO); gtk_info_bar_add_button (GTK_INFO_BAR (source->priv->info_bar), _("Fetch more tracks"), GTK_RESPONSE_OK); gtk_container_add (GTK_CONTAINER (gtk_info_bar_get_content_area (GTK_INFO_BAR (source->priv->info_bar))), source->priv->info_bar_label); gtk_widget_show (GTK_WIDGET (source->priv->info_bar_label)); gtk_widget_set_no_show_all (GTK_WIDGET (source->priv->info_bar), TRUE); g_signal_connect (source->priv->info_bar, "response", G_CALLBACK (fetch_more_cb), source); /* don't allow the browser to be hidden? */ source->priv->paned = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL); rb_source_bind_settings (RB_SOURCE (source), GTK_WIDGET (source->priv->entry_view), source->priv->paned, NULL); gtk_paned_pack1 (GTK_PANED (source->priv->paned), browserbox, FALSE, FALSE); vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET (source->priv->entry_view), TRUE, TRUE, 0); gtk_box_pack_start (GTK_BOX (vbox), source->priv->info_bar, FALSE, FALSE, 0); gtk_paned_pack2 (GTK_PANED (source->priv->paned), vbox, TRUE, FALSE); gtk_box_pack_start (GTK_BOX (mainbox), source->priv->paned, TRUE, TRUE, 0); gtk_widget_show_all (GTK_WIDGET (source)); }