2006-11-29 James Livingston <doclivingston@gmail.com>
[rhythmbox.git] / plugins / ipod / rb-ipod-plugin.c
blob9154e19f74c5e93a7d4fec24eb1cb8690495fb97
1 /*
2 * rb-ipod-plugin.c
3 *
4 * Copyright (C) 2006 James Livingston <jrl@ids.org.au>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
9 * any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21 #ifdef HAVE_CONFIG_H
22 #include <config.h>
23 #endif
25 #include <glib/gi18n-lib.h>
26 #include <gmodule.h>
27 #include <gtk/gtk.h>
28 #include <glib.h>
29 #include <glib-object.h>
30 #include <libgnomevfs/gnome-vfs.h>
32 #include "rb-removable-media-manager.h"
33 #include "rb-source.h"
34 #include "rb-ipod-source.h"
35 #include "rb-plugin.h"
36 #include "rb-debug.h"
37 #include "rb-file-helpers.h"
38 #include "rb-util.h"
39 #include "rb-shell.h"
42 #define RB_TYPE_IPOD_PLUGIN (rb_ipod_plugin_get_type ())
43 #define RB_IPOD_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), RB_TYPE_IPOD_PLUGIN, RBIpodPlugin))
44 #define RB_IPOD_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), RB_TYPE_IPOD_PLUGIN, RBIpodPluginClass))
45 #define RB_IS_IPOD_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), RB_TYPE_IPOD_PLUGIN))
46 #define RB_IS_IPOD_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), RB_TYPE_IPOD_PLUGIN))
47 #define RB_IPOD_PLUGIN_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), RB_TYPE_IPOD_PLUGIN, RBIpodPluginClass))
49 typedef struct
51 RBPlugin parent;
53 RBShell *shell;
54 GtkActionGroup *action_group;
55 guint ui_merge_id;
57 GList *ipod_sources;
58 } RBIpodPlugin;
60 typedef struct
62 RBPluginClass parent_class;
63 } RBIpodPluginClass;
66 G_MODULE_EXPORT GType register_rb_plugin (GTypeModule *module);
67 GType rb_ipod_plugin_get_type (void) G_GNUC_CONST;
69 static void rb_ipod_plugin_init (RBIpodPlugin *plugin);
70 static void rb_ipod_plugin_finalize (GObject *object);
71 static void impl_activate (RBPlugin *plugin, RBShell *shell);
72 static void impl_deactivate (RBPlugin *plugin, RBShell *shell);
74 static RBSource * create_source_cb (RBRemovableMediaManager *rmm,
75 GnomeVFSVolume *volume,
76 RBIpodPlugin *plugin);
77 static void rb_ipod_plugin_cmd_rename (GtkAction *action,
78 RBIpodPlugin *plugin);
80 RB_PLUGIN_REGISTER(RBIpodPlugin, rb_ipod_plugin)
83 static GtkActionEntry rb_ipod_plugin_actions [] =
85 { "iPodSourceRename", NULL, N_("_Rename"), NULL,
86 N_("Rename iPod"),
87 G_CALLBACK (rb_ipod_plugin_cmd_rename) }
91 static void
92 rb_ipod_plugin_class_init (RBIpodPluginClass *klass)
94 GObjectClass *object_class = G_OBJECT_CLASS (klass);
95 RBPluginClass *plugin_class = RB_PLUGIN_CLASS (klass);
97 object_class->finalize = rb_ipod_plugin_finalize;
99 plugin_class->activate = impl_activate;
100 plugin_class->deactivate = impl_deactivate;
102 /* register types used by the plugin */
103 RB_PLUGIN_REGISTER_TYPE(rb_ipod_source);
106 static void
107 rb_ipod_plugin_init (RBIpodPlugin *plugin)
109 rb_debug ("RBIpodPlugin initialising");
112 static void
113 rb_ipod_plugin_finalize (GObject *object)
115 /*RBIpodPlugin *plugin = RB_IPOD_PLUGIN (object);*/
117 rb_debug ("RBIpodPlugin finalising");
119 G_OBJECT_CLASS (rb_ipod_plugin_parent_class)->finalize (object);
122 static void
123 impl_activate (RBPlugin *bplugin,
124 RBShell *shell)
126 RBIpodPlugin *plugin = RB_IPOD_PLUGIN (bplugin);
127 RBRemovableMediaManager *rmm = NULL;
128 GtkUIManager *uimanager = NULL;
129 gboolean scanned;
130 char *file;
132 plugin->shell = shell;
134 g_object_get (G_OBJECT (shell),
135 "removable-media-manager", &rmm,
136 "ui-manager", &uimanager,
137 NULL);
139 /* add ipod UI */
140 plugin->action_group = gtk_action_group_new ("iPodActions");
141 gtk_action_group_set_translation_domain (plugin->action_group,
142 GETTEXT_PACKAGE);
143 gtk_action_group_add_actions (plugin->action_group,
144 rb_ipod_plugin_actions, G_N_ELEMENTS (rb_ipod_plugin_actions),
145 plugin);
146 gtk_ui_manager_insert_action_group (uimanager, plugin->action_group, 0);
147 file = rb_plugin_find_file (bplugin, "ipod-ui.xml");
148 plugin->ui_merge_id = gtk_ui_manager_add_ui_from_file (uimanager,
149 file,
150 NULL);
151 g_free (file);
153 /* watch for new removable media, and cause a rescan */
154 g_signal_connect (G_OBJECT (rmm),
155 "create-source", G_CALLBACK (create_source_cb),
156 plugin);
158 /* only scan if we're being loaded after the initial scan has been done */
159 g_object_get (G_OBJECT (rmm), "scanned", &scanned, NULL);
160 if (scanned)
161 rb_removable_media_manager_scan (rmm);
163 g_object_unref (G_OBJECT (rmm));
164 g_object_unref (G_OBJECT (uimanager));
167 static void
168 impl_deactivate (RBPlugin *bplugin,
169 RBShell *shell)
171 RBIpodPlugin *plugin = RB_IPOD_PLUGIN (bplugin);
172 RBRemovableMediaManager *rmm = NULL;
173 GtkUIManager *uimanager = NULL;
175 g_object_get (G_OBJECT (shell),
176 "removable-media-manager", &rmm,
177 "ui-manager", &uimanager,
178 NULL);
180 gtk_ui_manager_remove_ui (uimanager, plugin->ui_merge_id);
181 gtk_ui_manager_remove_action_group (uimanager, plugin->action_group);
183 g_signal_handlers_disconnect_by_func (G_OBJECT (rmm), create_source_cb, plugin);
185 g_list_foreach (plugin->ipod_sources, (GFunc)rb_source_delete_thyself, NULL);
186 g_list_free (plugin->ipod_sources);
187 plugin->ipod_sources = NULL;
189 g_object_unref (G_OBJECT (uimanager));
190 g_object_unref (G_OBJECT (rmm));
193 static void
194 rb_ipod_plugin_source_deleted (RBiPodSource *source, RBIpodPlugin *plugin)
196 plugin->ipod_sources = g_list_remove (plugin->ipod_sources, source);
199 static RBSource *
200 create_source_cb (RBRemovableMediaManager *rmm, GnomeVFSVolume *volume, RBIpodPlugin *plugin)
202 if (rb_ipod_is_volume_ipod (volume)) {
203 RBSource *src;
204 src = RB_SOURCE (rb_ipod_source_new (plugin->shell, volume));
206 plugin->ipod_sources = g_list_prepend (plugin->ipod_sources, src);
207 g_signal_connect_object (G_OBJECT (src),
208 "deleted", G_CALLBACK (rb_ipod_plugin_source_deleted),
209 plugin, 0);
211 return src;
214 return NULL;
217 static void
218 rb_ipod_plugin_cmd_rename (GtkAction *action,
219 RBIpodPlugin *plugin)
221 RBRemovableMediaManager *manager = NULL;
222 RBSourceList *sourcelist = NULL;
223 RBSource *source = NULL;
225 /* FIXME: this is pretty ugly, the sourcelist should automatically add
226 * a "rename" menu item for sources that have can_rename == TRUE.
227 * This is a bit trickier to handle though, since playlists want
228 * to make rename sensitive/unsensitive instead of showing/hiding it
230 g_object_get (G_OBJECT (plugin->shell),
231 "selected-source", &source,
232 "removable-media-manager", &manager,
233 NULL);
234 if ((source == NULL) || !RB_IS_IPOD_SOURCE (source)) {
235 g_object_unref (G_OBJECT (manager));
236 g_critical ("got iPodSourceRename action for non-ipod source");
237 return;
240 g_object_get (G_OBJECT (manager), "sourcelist", &sourcelist, NULL);
241 g_object_unref (G_OBJECT (manager));
243 rb_sourcelist_edit_source_name (sourcelist, RB_SOURCE (source));
244 /* Once editing is done, notify::name will be fired on the source, and
245 * we'll catch that in our rename callback
247 g_object_unref (G_OBJECT (sourcelist));