[rhythmbox] generic-player: convert into a media player source, add properties dialog



commit 72919db07904ef1a260383b4d0f2e2ca57b77e1a
Author: Jonathan Matthew <jonathan d14n org>
Date:   Thu Feb 11 22:04:45 2010 +1000

    generic-player: convert into a media player source, add properties dialog

 plugins/generic-player/Makefile.am                |    5 +-
 plugins/generic-player/generic-player-info.ui     |  212 +++++++++++++++++++++
 plugins/generic-player/generic-player-ui.xml      |    1 +
 plugins/generic-player/rb-generic-player-plugin.c |   16 ++-
 plugins/generic-player/rb-generic-player-source.c |  197 +++++++++++++++++---
 plugins/generic-player/rb-generic-player-source.h |   10 +-
 plugins/generic-player/rb-nokia770-source.c       |    3 +-
 plugins/generic-player/rb-nokia770-source.h       |    6 +-
 plugins/generic-player/rb-psp-source.c            |    3 +-
 plugins/generic-player/rb-psp-source.h            |    6 +-
 10 files changed, 421 insertions(+), 38 deletions(-)
---
diff --git a/plugins/generic-player/Makefile.am b/plugins/generic-player/Makefile.am
index 6e57978..04a7f31 100644
--- a/plugins/generic-player/Makefile.am
+++ b/plugins/generic-player/Makefile.am
@@ -45,13 +45,16 @@ INCLUDES = 						\
 uixmldir = $(plugindir)
 uixml_DATA = generic-player-ui.xml
 
+gtkbuilderdir = $(plugindir)
+gtkbuilder_DATA = generic-player-info.ui
+
 plugin_in_files = generic-player.rb-plugin.in
 
 %.rb-plugin: %.rb-plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
 
 plugin_DATA = $(plugin_in_files:.rb-plugin.in=.rb-plugin)
 
-EXTRA_DIST = $(uixml_DATA) $(plugin_in_files)
+EXTRA_DIST = $(uixml_DATA) $(gtkbuilder_DATA) $(plugin_in_files)
 
 CLEANFILES = $(plugin_DATA)
 DISTCLEANFILES = $(plugin_DATA)
diff --git a/plugins/generic-player/generic-player-info.ui b/plugins/generic-player/generic-player-info.ui
new file mode 100644
index 0000000..40173ed
--- /dev/null
+++ b/plugins/generic-player/generic-player-info.ui
@@ -0,0 +1,212 @@
+<?xml version="1.0"?>
+<interface>
+  <!-- interface-requires gtk+ 2.12 -->
+  <!-- interface-naming-policy toplevel-contextual -->
+  <object class="GtkTable" id="generic-player-basic-info">
+    <property name="visible">True</property>
+    <property name="border_width">12</property>
+    <property name="n_rows">3</property>
+    <property name="n_columns">2</property>
+    <property name="column_spacing">12</property>
+    <property name="row_spacing">6</property>
+    <child>
+      <object class="GtkEntry" id="entry-device-name">
+        <property name="visible">True</property>
+        <property name="can_focus">True</property>
+        <property name="invisible_char">&#x25CF;</property>
+      </object>
+      <packing>
+        <property name="left_attach">1</property>
+        <property name="right_attach">2</property>
+        <property name="y_options"></property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel" id="label-device-name">
+        <property name="visible">True</property>
+        <property name="xalign">0</property>
+        <property name="label" translatable="yes">Device _name:</property>
+        <property name="use_underline">True</property>
+        <property name="mnemonic_widget">entry-device-name</property>
+      </object>
+      <packing>
+        <property name="x_options">GTK_FILL</property>
+        <property name="y_options"></property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel" id="label-num-tracks">
+        <property name="visible">True</property>
+        <property name="xalign">0</property>
+        <property name="label" translatable="yes">Tracks:</property>
+      </object>
+      <packing>
+        <property name="top_attach">1</property>
+        <property name="bottom_attach">2</property>
+        <property name="y_options">GTK_FILL</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel" id="label-num-playlists">
+        <property name="visible">True</property>
+        <property name="xalign">0</property>
+        <property name="label" translatable="yes">Playlists:</property>
+      </object>
+      <packing>
+        <property name="top_attach">2</property>
+        <property name="bottom_attach">3</property>
+        <property name="y_options">GTK_FILL</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel" id="num-tracks">
+        <property name="visible">True</property>
+        <property name="xalign">0</property>
+      </object>
+      <packing>
+        <property name="left_attach">1</property>
+        <property name="right_attach">2</property>
+        <property name="top_attach">1</property>
+        <property name="bottom_attach">2</property>
+        <property name="y_options">GTK_FILL</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel" id="num-playlists">
+        <property name="visible">True</property>
+        <property name="xalign">0</property>
+      </object>
+      <packing>
+        <property name="left_attach">1</property>
+        <property name="right_attach">2</property>
+        <property name="top_attach">2</property>
+        <property name="bottom_attach">3</property>
+        <property name="y_options">GTK_FILL</property>
+      </packing>
+    </child>
+  </object>
+  <object class="GtkFrame" id="generic-player-advanced-tab">
+    <property name="visible">True</property>
+    <property name="border_width">12</property>
+    <property name="label_xalign">0</property>
+    <property name="shadow_type">none</property>
+    <child>
+      <object class="GtkTable" id="table2">
+        <property name="visible">True</property>
+        <property name="border_width">12</property>
+        <property name="n_rows">4</property>
+        <property name="n_columns">2</property>
+        <property name="column_spacing">12</property>
+        <property name="row_spacing">6</property>
+        <child>
+          <object class="GtkLabel" id="label-model-value">
+            <property name="visible">True</property>
+            <property name="xalign">0</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="right_attach">2</property>
+            <property name="top_attach">1</property>
+            <property name="bottom_attach">2</property>
+            <property name="x_options">GTK_FILL</property>
+            <property name="y_options"></property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="label-model">
+            <property name="visible">True</property>
+            <property name="xalign">0</property>
+            <property name="label" translatable="yes">Model:</property>
+          </object>
+          <packing>
+            <property name="top_attach">1</property>
+            <property name="bottom_attach">2</property>
+            <property name="x_options">GTK_FILL</property>
+            <property name="y_options"></property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="label-serial-number-value">
+            <property name="visible">True</property>
+            <property name="xalign">0</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="right_attach">2</property>
+            <property name="top_attach">2</property>
+            <property name="bottom_attach">3</property>
+            <property name="y_options"></property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="label-serial-number">
+            <property name="visible">True</property>
+            <property name="xalign">0</property>
+            <property name="label" translatable="yes">Serial number:</property>
+          </object>
+          <packing>
+            <property name="top_attach">2</property>
+            <property name="bottom_attach">3</property>
+            <property name="x_options">GTK_FILL</property>
+            <property name="y_options"></property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="label-manufacturer">
+            <property name="visible">True</property>
+            <property name="xalign">0</property>
+            <property name="label" translatable="yes">Manufacturer:</property>
+          </object>
+          <packing>
+            <property name="x_options">GTK_FILL</property>
+            <property name="y_options"></property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="label-manufacturer-value">
+            <property name="visible">True</property>
+            <property name="xalign">0</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="right_attach">2</property>
+            <property name="y_options"></property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="label-audio-formats">
+            <property name="visible">True</property>
+            <property name="xalign">0</property>
+            <property name="yalign">0</property>
+            <property name="label" translatable="yes">Audio formats:</property>
+          </object>
+          <packing>
+            <property name="top_attach">3</property>
+            <property name="bottom_attach">4</property>
+            <property name="x_options">GTK_FILL</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="audio-format-list">
+            <property name="visible">True</property>
+            <property name="xalign">0</property>
+            <property name="wrap">True</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="right_attach">2</property>
+            <property name="top_attach">3</property>
+            <property name="bottom_attach">4</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+    <child type="label">
+      <object class="GtkLabel" id="label-frame-system">
+        <property name="visible">True</property>
+        <property name="label" translatable="yes">&lt;b&gt;System&lt;/b&gt;</property>
+        <property name="use_markup">True</property>
+      </object>
+    </child>
+  </object>
+</interface>
diff --git a/plugins/generic-player/generic-player-ui.xml b/plugins/generic-player/generic-player-ui.xml
index aa7aaac..22347c1 100644
--- a/plugins/generic-player/generic-player-ui.xml
+++ b/plugins/generic-player/generic-player-ui.xml
@@ -2,6 +2,7 @@
   <popup name="GenericPlayerSourcePopup">
     <menuitem name="GenericPlayerSourcePopupEject" action="RemovableSourceEject"/>
     <menuitem name="GenericPlayerSourcePopupNewPlaylist" action="GenericPlayerSourceNewPlaylist"/>
+    <menuitem name="GenericPlayerSourcePopupProperties" action="GenericPlayerSourceProperties"/>
   </popup>
 
   <popup name="GenericPlayerPlaylistSourcePopup">
diff --git a/plugins/generic-player/rb-generic-player-plugin.c b/plugins/generic-player/rb-generic-player-plugin.c
index 7891dae..aea9118 100644
--- a/plugins/generic-player/rb-generic-player-plugin.c
+++ b/plugins/generic-player/rb-generic-player-plugin.c
@@ -87,6 +87,7 @@ static void impl_deactivate (RBPlugin *plugin, RBShell *shell);
 
 static void rb_generic_player_plugin_new_playlist (GtkAction *action, RBSource *source);
 static void rb_generic_player_plugin_delete_playlist (GtkAction *action, RBSource *source);
+static void rb_generic_player_plugin_properties (GtkAction *action, RBSource *source);
 
 RB_PLUGIN_REGISTER(RBGenericPlayerPlugin, rb_generic_player_plugin)
 
@@ -97,6 +98,9 @@ static GtkActionEntry rb_generic_player_plugin_actions[] = {
 	{ "GenericPlayerPlaylistDelete", GTK_STOCK_DELETE, N_("Delete Playlist"), NULL,
 	  N_("Delete this playlist"),
 	  G_CALLBACK (rb_generic_player_plugin_delete_playlist) },
+	{ "GenericPlayerSourceProperties", GTK_STOCK_PROPERTIES, N_("_Properties"), NULL,
+	  N_("Display device properties"),
+	  G_CALLBACK (rb_generic_player_plugin_properties) }
 };
 
 static void
@@ -182,11 +186,11 @@ create_source_cb (RBRemovableMediaManager *rmm, GMount *mount, MPIDDevice *devic
 	RBSource *source = NULL;
 
 	if (rb_psp_is_mount_player (mount, device_info))
-		source = RB_SOURCE (rb_psp_source_new (plugin->shell, mount, device_info));
+		source = RB_SOURCE (rb_psp_source_new (RB_PLUGIN (plugin), plugin->shell, mount, device_info));
 	if (source == NULL && rb_nokia770_is_mount_player (mount, device_info))
-		source = RB_SOURCE (rb_nokia770_source_new (plugin->shell, mount, device_info));
+		source = RB_SOURCE (rb_nokia770_source_new (RB_PLUGIN (plugin), plugin->shell, mount, device_info));
 	if (source == NULL && rb_generic_player_is_mount_player (mount, device_info))
-		source = RB_SOURCE (rb_generic_player_source_new (plugin->shell, mount, device_info));
+		source = RB_SOURCE (rb_generic_player_source_new (RB_PLUGIN (plugin), plugin->shell, mount, device_info));
 
 	if (plugin->actions == NULL) {
 		plugin->actions = gtk_action_group_new ("GenericPlayerActions");
@@ -282,3 +286,9 @@ impl_deactivate	(RBPlugin *bplugin,
 	g_object_unref (G_OBJECT (rmm));
 }
 
+static void
+rb_generic_player_plugin_properties (GtkAction *action, RBSource *source)
+{
+	g_return_if_fail (RB_IS_GENERIC_PLAYER_SOURCE (source));
+	rb_media_player_source_show_properties (RB_MEDIA_PLAYER_SOURCE (source));
+}
diff --git a/plugins/generic-player/rb-generic-player-source.c b/plugins/generic-player/rb-generic-player-source.c
index 500453c..c61a2de 100644
--- a/plugins/generic-player/rb-generic-player-source.c
+++ b/plugins/generic-player/rb-generic-player-source.c
@@ -51,6 +51,7 @@
 #include "rb-plugin.h"
 #include "rhythmdb-import-job.h"
 #include "rb-import-errors-source.h"
+#include "rb-builder-helpers.h"
 
 static void impl_constructed (GObject *object);
 static void impl_dispose (GObject *object);
@@ -78,6 +79,9 @@ static char* impl_build_dest_uri (RBRemovableMediaSource *source,
 				  RhythmDBEntry *entry,
 				  const char *mimetype,
 				  const char *extension);
+static guint64 impl_get_capacity (RBMediaPlayerSource *source);
+static guint64 impl_get_free_space (RBMediaPlayerSource *source);
+static void impl_show_properties (RBMediaPlayerSource *source, GtkWidget *info_box, GtkWidget *notebook);
 
 static char *default_get_mount_path (RBGenericPlayerSource *source);
 static void default_load_playlists (RBGenericPlayerSource *source);
@@ -117,14 +121,15 @@ typedef struct
 
 } RBGenericPlayerSourcePrivate;
 
-RB_PLUGIN_DEFINE_TYPE(RBGenericPlayerSource, rb_generic_player_source, RB_TYPE_REMOVABLE_MEDIA_SOURCE)
-#define GENERIC_PLAYER_SOURCE_GET_PRIVATE(o)   (G_TYPE_INSTANCE_GET_PRIVATE ((o), RB_TYPE_GENERIC_PLAYER_SOURCE, RBGenericPlayerSourcePrivate))
+RB_PLUGIN_DEFINE_TYPE(RBGenericPlayerSource, rb_generic_player_source, RB_TYPE_MEDIA_PLAYER_SOURCE)
+#define GET_PRIVATE(o)   (G_TYPE_INSTANCE_GET_PRIVATE ((o), RB_TYPE_GENERIC_PLAYER_SOURCE, RBGenericPlayerSourcePrivate))
 
 static void
 rb_generic_player_source_class_init (RBGenericPlayerSourceClass *klass)
 {
 	GObjectClass *object_class = G_OBJECT_CLASS (klass);
 	RBSourceClass *source_class = RB_SOURCE_CLASS (klass);
+	RBMediaPlayerSourceClass *mps_class = RB_MEDIA_PLAYER_SOURCE_CLASS (klass);
 	RBRemovableMediaSourceClass *rms_class = RB_REMOVABLE_MEDIA_SOURCE_CLASS (klass);
 
 	object_class->set_property = impl_set_property;
@@ -141,6 +146,10 @@ rb_generic_player_source_class_init (RBGenericPlayerSourceClass *klass)
 	source_class->impl_can_paste = impl_can_paste;
 	source_class->impl_get_status = impl_get_status;
 
+	mps_class->impl_get_capacity = impl_get_capacity;
+	mps_class->impl_get_free_space = impl_get_free_space;
+	mps_class->impl_show_properties = impl_show_properties;
+
 	rms_class->impl_build_dest_uri = impl_build_dest_uri;
 	rms_class->impl_get_mime_types = impl_get_mime_types;
 	rms_class->impl_should_paste = rb_removable_media_source_should_paste_no_duplicate;
@@ -199,7 +208,7 @@ impl_constructed (GObject *object)
 	RB_CHAIN_GOBJECT_METHOD (rb_generic_player_source_parent_class, constructed, object);
 	source = RB_GENERIC_PLAYER_SOURCE (object);
 
-	priv = GENERIC_PLAYER_SOURCE_GET_PRIVATE (source);
+	priv = GET_PRIVATE (source);
 
 	g_object_get (source, "shell", &shell, NULL);
 
@@ -244,7 +253,7 @@ impl_constructed (GObject *object)
 static void
 impl_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
 {
-	RBGenericPlayerSourcePrivate *priv = GENERIC_PLAYER_SOURCE_GET_PRIVATE (object);
+	RBGenericPlayerSourcePrivate *priv = GET_PRIVATE (object);
 
 	switch (prop_id) {
 	case PROP_IGNORE_ENTRY_TYPE:
@@ -265,7 +274,7 @@ impl_set_property (GObject *object, guint prop_id, const GValue *value, GParamSp
 static void
 impl_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
 {
-	RBGenericPlayerSourcePrivate *priv = GENERIC_PLAYER_SOURCE_GET_PRIVATE (object);
+	RBGenericPlayerSourcePrivate *priv = GET_PRIVATE (object);
 
 	switch (prop_id) {
 	case PROP_IGNORE_ENTRY_TYPE:
@@ -286,7 +295,7 @@ impl_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *ps
 static void
 impl_dispose (GObject *object)
 {
-	RBGenericPlayerSourcePrivate *priv = GENERIC_PLAYER_SOURCE_GET_PRIVATE (object);
+	RBGenericPlayerSourcePrivate *priv = GET_PRIVATE (object);
 
 	if (priv->load_playlists_id != 0) {
 		g_source_remove (priv->load_playlists_id);
@@ -329,11 +338,11 @@ impl_finalize (GObject *object)
 	RBGenericPlayerSourcePrivate *priv;
 
 	g_return_if_fail (RB_IS_GENERIC_PLAYER_SOURCE (object));
-	priv = GENERIC_PLAYER_SOURCE_GET_PRIVATE (object);
+	priv = GET_PRIVATE (object);
 }
 
 RBRemovableMediaSource *
-rb_generic_player_source_new (RBShell *shell, GMount *mount, MPIDDevice *device_info)
+rb_generic_player_source_new (RBPlugin *plugin, RBShell *shell, GMount *mount, MPIDDevice *device_info)
 {
 	RBGenericPlayerSource *source;
 	RhythmDBEntryType entry_type;
@@ -366,6 +375,7 @@ rb_generic_player_source_new (RBShell *shell, GMount *mount, MPIDDevice *device_
 	g_free (path);
 
 	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,
@@ -385,7 +395,7 @@ impl_delete_thyself (RBSource *source)
 {
 	GList *pl;
 	GList *p;
-	RBGenericPlayerSourcePrivate *priv = GENERIC_PLAYER_SOURCE_GET_PRIVATE (source);
+	RBGenericPlayerSourcePrivate *priv = GET_PRIVATE (source);
 
 	/* take a copy of the list first, as playlist_deleted_cb modifies priv->playlists */
 	pl = g_list_copy (priv->playlists);
@@ -409,7 +419,7 @@ static void
 import_complete_cb (RhythmDBImportJob *job, int total, RBGenericPlayerSource *source)
 {
 	RBGenericPlayerSourceClass *klass = RB_GENERIC_PLAYER_SOURCE_GET_CLASS (source);
-	RBGenericPlayerSourcePrivate *priv = GENERIC_PLAYER_SOURCE_GET_PRIVATE (source);
+	RBGenericPlayerSourcePrivate *priv = GET_PRIVATE (source);
 	RBShell *shell;
 
 	GDK_THREADS_ENTER ();
@@ -438,7 +448,7 @@ import_status_changed_cb (RhythmDBImportJob *job, int total, int imported, RBGen
 static void
 load_songs (RBGenericPlayerSource *source)
 {
-	RBGenericPlayerSourcePrivate *priv = GENERIC_PLAYER_SOURCE_GET_PRIVATE (source);
+	RBGenericPlayerSourcePrivate *priv = GET_PRIVATE (source);
 	RhythmDBEntryType entry_type;
 	char **audio_folders;
 	char *mount_path;
@@ -487,7 +497,7 @@ rb_generic_player_source_get_mount_path (RBGenericPlayerSource *source)
 static char *
 default_get_mount_path (RBGenericPlayerSource *source)
 {
-	RBGenericPlayerSourcePrivate *priv = GENERIC_PLAYER_SOURCE_GET_PRIVATE (source);
+	RBGenericPlayerSourcePrivate *priv = GET_PRIVATE (source);
 
 	if (priv->mount_path == NULL) {
 		GMount *mount;
@@ -539,7 +549,7 @@ impl_show_popup (RBSource *source)
 static void
 impl_get_status (RBSource *source, char **text, char **progress_text, float *progress)
 {
-	RBGenericPlayerSourcePrivate *priv = GENERIC_PLAYER_SOURCE_GET_PRIVATE (source);
+	RBGenericPlayerSourcePrivate *priv = GET_PRIVATE (source);
 
 	/* get default status text first */
 	RB_SOURCE_CLASS (rb_generic_player_source_parent_class)->impl_get_status (source, text, progress_text, progress);
@@ -563,7 +573,7 @@ impl_get_status (RBSource *source, char **text, char **progress_text, float *pro
 static void
 playlist_deleted_cb (RBSource *playlist, RBGenericPlayerSource *source)
 {
-	RBGenericPlayerSourcePrivate *priv = GENERIC_PLAYER_SOURCE_GET_PRIVATE (source);
+	RBGenericPlayerSourcePrivate *priv = GET_PRIVATE (source);
 	GList *p;
 
 	p = g_list_find (priv->playlists, playlist);
@@ -578,7 +588,7 @@ rb_generic_player_source_add_playlist (RBGenericPlayerSource *source,
 				       RBShell *shell,
 				       RBSource *playlist)
 {
-	RBGenericPlayerSourcePrivate *priv = GENERIC_PLAYER_SOURCE_GET_PRIVATE (source);
+	RBGenericPlayerSourcePrivate *priv = GET_PRIVATE (source);
 	g_object_ref (playlist);
 	priv->playlists = g_list_prepend (priv->playlists, playlist);
 
@@ -692,7 +702,7 @@ visit_playlist_dirs (GFile *file,
 	char *uri;
 	RhythmDBEntry *entry;
 	RhythmDBEntryType entry_type;
-	RBGenericPlayerSourcePrivate *priv = GENERIC_PLAYER_SOURCE_GET_PRIVATE (source);
+	RBGenericPlayerSourcePrivate *priv = GET_PRIVATE (source);
 
 	if (dir) {
 		return TRUE;
@@ -736,7 +746,7 @@ visit_playlist_dirs (GFile *file,
 static void
 default_load_playlists (RBGenericPlayerSource *source)
 {
-	RBGenericPlayerSourcePrivate *priv = GENERIC_PLAYER_SOURCE_GET_PRIVATE (source);
+	RBGenericPlayerSourcePrivate *priv = GET_PRIVATE (source);
 	char *mount_path;
 	char *playlist_path;
 	char *full_playlist_path;
@@ -786,7 +796,7 @@ default_load_playlists (RBGenericPlayerSource *source)
 static gboolean
 impl_can_paste (RBSource *source)
 {
-	RBGenericPlayerSourcePrivate *priv = GENERIC_PLAYER_SOURCE_GET_PRIVATE (source);
+	RBGenericPlayerSourcePrivate *priv = GET_PRIVATE (source);
 
 	return (priv->read_only == FALSE);
 }
@@ -794,7 +804,7 @@ impl_can_paste (RBSource *source)
 static gboolean
 impl_can_delete (RBSource *source)
 {
-	RBGenericPlayerSourcePrivate *priv = GENERIC_PLAYER_SOURCE_GET_PRIVATE (source);
+	RBGenericPlayerSourcePrivate *priv = GET_PRIVATE (source);
 
 	return (priv->read_only == FALSE);
 }
@@ -802,7 +812,7 @@ impl_can_delete (RBSource *source)
 static gboolean
 can_delete_directory (RBGenericPlayerSource *source, GFile *dir)
 {
-	RBGenericPlayerSourcePrivate *priv = GENERIC_PLAYER_SOURCE_GET_PRIVATE (source);
+	RBGenericPlayerSourcePrivate *priv = GET_PRIVATE (source);
 	gboolean result;
 	GMount *mount;
 	GFile *root;
@@ -845,7 +855,7 @@ can_delete_directory (RBGenericPlayerSource *source, GFile *dir)
 void
 rb_generic_player_source_delete_entries (RBGenericPlayerSource *source, GList *entries)
 {
-	RBGenericPlayerSourcePrivate *priv = GENERIC_PLAYER_SOURCE_GET_PRIVATE (source);
+	RBGenericPlayerSourcePrivate *priv = GET_PRIVATE (source);
 	GList *tem;
 
 	if (priv->read_only != FALSE)
@@ -929,7 +939,7 @@ sanitize_path (const char *str)
 static GList *
 impl_get_mime_types (RBRemovableMediaSource *source)
 {
-	RBGenericPlayerSourcePrivate *priv = GENERIC_PLAYER_SOURCE_GET_PRIVATE (source);
+	RBGenericPlayerSourcePrivate *priv = GET_PRIVATE (source);
 	GList *list = NULL;
 	char **output_formats;
 	char **mime;
@@ -948,7 +958,7 @@ impl_build_dest_uri (RBRemovableMediaSource *source,
 		     const char *mimetype,
 		     const char *extension)
 {
-	RBGenericPlayerSourcePrivate *priv = GENERIC_PLAYER_SOURCE_GET_PRIVATE (source);
+	RBGenericPlayerSourcePrivate *priv = GET_PRIVATE (source);
 	char *artist, *album, *title;
 	gulong track_number, disc_number;
 	const char *folders;
@@ -1060,7 +1070,7 @@ strv_contains (char **strv, const char *s)
 void
 rb_generic_player_source_set_supported_formats (RBGenericPlayerSource *source, TotemPlParser *parser)
 {
-	RBGenericPlayerSourcePrivate *priv = GENERIC_PLAYER_SOURCE_GET_PRIVATE (source);
+	RBGenericPlayerSourcePrivate *priv = GET_PRIVATE (source);
 	char **playlist_formats;
 	const char *check[] = { "audio/x-mpegurl", "audio/x-scpls", "audio/x-iriver-pla" };
 
@@ -1081,7 +1091,7 @@ rb_generic_player_source_set_supported_formats (RBGenericPlayerSource *source, T
 TotemPlParserType
 rb_generic_player_source_get_playlist_format (RBGenericPlayerSource *source)
 {
-	RBGenericPlayerSourcePrivate *priv = GENERIC_PLAYER_SOURCE_GET_PRIVATE (source);
+	RBGenericPlayerSourcePrivate *priv = GET_PRIVATE (source);
 	TotemPlParserType result;
 	char **playlist_formats;
 
@@ -1105,7 +1115,7 @@ rb_generic_player_source_get_playlist_format (RBGenericPlayerSource *source)
 char *
 rb_generic_player_source_get_playlist_path (RBGenericPlayerSource *source)
 {
-	RBGenericPlayerSourcePrivate *priv = GENERIC_PLAYER_SOURCE_GET_PRIVATE (source);
+	RBGenericPlayerSourcePrivate *priv = GET_PRIVATE (source);
 	char *path;
 
 	g_object_get (priv->device_info, "playlist-path", &path, NULL);
@@ -1115,3 +1125,138 @@ rb_generic_player_source_get_playlist_path (RBGenericPlayerSource *source)
 	return path;
 }
 
+static guint64
+get_fs_property (RBGenericPlayerSource *source, const char *attr)
+{
+	char *mountpoint;
+	GFile *root;
+	GFileInfo *info;
+	guint64 value = 0;
+
+	mountpoint = rb_generic_player_source_get_mount_path (source);
+	root = g_file_new_for_uri (mountpoint);
+	g_free (mountpoint);
+
+	info = g_file_query_filesystem_info (root, attr, NULL, NULL);
+	g_object_unref (root);
+	if (info != NULL) {
+		if (g_file_info_has_attribute (info, attr)) {
+			value = g_file_info_get_attribute_uint64 (info, attr);
+		}
+		g_object_unref (info);
+	}
+	return value;
+}
+static guint64
+impl_get_capacity (RBMediaPlayerSource *source)
+{
+	return get_fs_property (RB_GENERIC_PLAYER_SOURCE (source), G_FILE_ATTRIBUTE_FILESYSTEM_SIZE);
+}
+
+static guint64
+impl_get_free_space (RBMediaPlayerSource *source)
+{
+	return get_fs_property (RB_GENERIC_PLAYER_SOURCE (source), G_FILE_ATTRIBUTE_FILESYSTEM_FREE);
+}
+
+static void
+impl_show_properties (RBMediaPlayerSource *source, GtkWidget *info_box, GtkWidget *notebook)
+{
+	RBGenericPlayerSourcePrivate *priv = GET_PRIVATE (source);
+	RhythmDBQueryModel *model;
+	GtkBuilder *builder;
+	GtkWidget *widget;
+	GString *str;
+	char *device_name;
+	char *builder_file;
+	char *vendor_name;
+	char *model_name;
+	char *serial_id;
+	RBPlugin *plugin;
+	char *text;
+	GList *output_formats;
+	GList *t;
+
+	g_object_get (source, "plugin", &plugin, NULL);
+	builder_file = rb_plugin_find_file (plugin, "generic-player-info.ui");
+	g_object_unref (plugin);
+
+	if (builder_file == NULL) {
+		g_warning ("Couldn't find generic-player-info.ui");
+		return;
+	}
+
+	builder = rb_builder_load (builder_file, NULL);
+	g_free (builder_file);
+
+	if (builder == NULL) {
+		rb_debug ("Couldn't load generic-player-info.ui");
+		return;
+	}
+
+	/* 'basic' tab stuff */
+
+	widget = GTK_WIDGET (gtk_builder_get_object (builder, "generic-player-basic-info"));
+	gtk_box_pack_start (GTK_BOX (info_box), widget, TRUE, TRUE, 0);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (builder, "entry-device-name"));
+	g_object_get (source, "name", &device_name, NULL);
+	gtk_entry_set_text (GTK_ENTRY (widget), device_name);
+	g_free (device_name);
+	/* don't think we can support this..
+	g_signal_connect (widget, "focus-out-event",
+			  (GCallback)rb_mtp_source_name_changed_cb, source);
+			  */
+
+	g_object_get (source, "base-query-model", &model, NULL);
+	widget = GTK_WIDGET (gtk_builder_get_object (builder, "num-tracks"));
+	text = g_strdup_printf ("%d", gtk_tree_model_iter_n_children (GTK_TREE_MODEL (model), NULL));
+	gtk_label_set_text (GTK_LABEL (widget), text);
+	g_free (text);
+	g_object_unref (model);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (builder, "num-playlists"));
+	text = g_strdup_printf ("%d", g_list_length (priv->playlists));
+	gtk_label_set_text (GTK_LABEL (widget), text);
+	g_free (text);
+
+	/* 'advanced' tab stuff */
+	widget = GTK_WIDGET (gtk_builder_get_object (builder, "generic-player-advanced-tab"));
+	gtk_notebook_append_page (GTK_NOTEBOOK (notebook), widget, gtk_label_new (_("Advanced")));
+
+	g_object_get (priv->device_info,
+		      "model", &model_name,
+		      "vendor", &vendor_name,
+		      "serial", &serial_id,
+		      NULL);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (builder, "label-model-value"));
+	gtk_label_set_text (GTK_LABEL (widget), model_name);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (builder, "label-manufacturer-value"));
+	gtk_label_set_text (GTK_LABEL (widget), vendor_name);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (builder, "label-serial-number-value"));
+	gtk_label_set_text (GTK_LABEL (widget), serial_id);
+
+	g_free (model_name);
+	g_free (vendor_name);
+	g_free (serial_id);
+
+	str = g_string_new ("");
+	output_formats = rb_removable_media_source_get_format_descriptions (RB_REMOVABLE_MEDIA_SOURCE (source));
+	for (t = output_formats; t != NULL; t = t->next) {
+		if (t != output_formats) {
+			g_string_append (str, "\n");
+		}
+		g_string_append (str, t->data);
+	}
+	rb_list_deep_free (output_formats);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (builder, "audio-format-list"));
+	gtk_label_set_text (GTK_LABEL (widget), str->str);
+	g_string_free (str, TRUE);
+
+	g_object_unref (builder);
+}
+
diff --git a/plugins/generic-player/rb-generic-player-source.h b/plugins/generic-player/rb-generic-player-source.h
index 19942ac..a93c018 100644
--- a/plugins/generic-player/rb-generic-player-source.h
+++ b/plugins/generic-player/rb-generic-player-source.h
@@ -29,7 +29,8 @@
 #define __RB_GENERIC_PLAYER_SOURCE_H
 
 #include "rb-shell.h"
-#include "rb-removable-media-source.h"
+#include "rb-plugin.h"
+#include "rb-media-player-source.h"
 #include "rhythmdb.h"
 
 #include "mediaplayerid.h"
@@ -47,12 +48,12 @@ G_BEGIN_DECLS
 
 typedef struct
 {
-	RBRemovableMediaSource parent;
+	RBMediaPlayerSource parent;
 } RBGenericPlayerSource;
 
 typedef struct
 {
-	RBRemovableMediaSourceClass parent;
+	RBMediaPlayerSourceClass parent;
 
 	char *		(*impl_get_mount_path) (RBGenericPlayerSource *source);
 	void		(*impl_load_playlists) (RBGenericPlayerSource *source);
@@ -65,7 +66,8 @@ typedef struct
 	char *		(*impl_build_filename) (RBGenericPlayerSource *source, RhythmDBEntry *entry);
 } RBGenericPlayerSourceClass;
 
-RBRemovableMediaSource *rb_generic_player_source_new			(RBShell *shell,
+RBRemovableMediaSource *rb_generic_player_source_new			(RBPlugin *plugin,
+									 RBShell *shell,
 									 GMount *mount,
 									 MPIDDevice *device_info);
 GType			rb_generic_player_source_get_type		(void);
diff --git a/plugins/generic-player/rb-nokia770-source.c b/plugins/generic-player/rb-nokia770-source.c
index b81df1b..5e5e95e 100644
--- a/plugins/generic-player/rb-nokia770-source.c
+++ b/plugins/generic-player/rb-nokia770-source.c
@@ -78,7 +78,7 @@ rb_nokia770_source_init (RBNokia770Source *source)
 }
 
 RBRemovableMediaSource *
-rb_nokia770_source_new (RBShell *shell, GMount *mount, MPIDDevice *device_info)
+rb_nokia770_source_new (RBPlugin *plugin, RBShell *shell, GMount *mount, MPIDDevice *device_info)
 {
 	RBNokia770Source *source;
 	RhythmDBEntryType entry_type;
@@ -101,6 +101,7 @@ rb_nokia770_source_new (RBShell *shell, GMount *mount, MPIDDevice *device_info)
 	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,
diff --git a/plugins/generic-player/rb-nokia770-source.h b/plugins/generic-player/rb-nokia770-source.h
index f5e1cfb..4738a5a 100644
--- a/plugins/generic-player/rb-nokia770-source.h
+++ b/plugins/generic-player/rb-nokia770-source.h
@@ -30,6 +30,7 @@
 
 #include "mediaplayerid.h"
 
+#include "rb-plugin.h"
 #include "rb-shell.h"
 #include "rb-generic-player-source.h"
 #include "rhythmdb.h"
@@ -53,7 +54,10 @@ typedef struct
 	RBGenericPlayerSourceClass parent;
 } RBNokia770SourceClass;
 
-RBRemovableMediaSource *	rb_nokia770_source_new		(RBShell *shell, GMount *mount, MPIDDevice *device_info);
+RBRemovableMediaSource *	rb_nokia770_source_new		(RBPlugin *plugin,
+								 RBShell *shell,
+								 GMount *mount,
+								 MPIDDevice *device_info);
 GType				rb_nokia770_source_get_type	(void);
 GType				rb_nokia770_source_register_type (GTypeModule *module);
 
diff --git a/plugins/generic-player/rb-psp-source.c b/plugins/generic-player/rb-psp-source.c
index 4168d62..cb3dff5 100644
--- a/plugins/generic-player/rb-psp-source.c
+++ b/plugins/generic-player/rb-psp-source.c
@@ -76,7 +76,7 @@ rb_psp_source_init (RBPspSource *source)
 }
 
 RBRemovableMediaSource *
-rb_psp_source_new (RBShell *shell, GMount *mount, MPIDDevice *device_info)
+rb_psp_source_new (RBPlugin *plugin, RBShell *shell, GMount *mount, MPIDDevice *device_info)
 {
 	RBPspSource *source;
 	RhythmDBEntryType entry_type;
@@ -99,6 +99,7 @@ rb_psp_source_new (RBShell *shell, GMount *mount, MPIDDevice *device_info)
 	g_object_unref (volume);
 
 	source = RB_PSP_SOURCE (g_object_new (RB_TYPE_PSP_SOURCE,
+					  "plugin", plugin,
 					  "entry-type", entry_type,
 					  "ignore-entry-type", RHYTHMDB_ENTRY_TYPE_INVALID,
 					  "error-entry-type", RHYTHMDB_ENTRY_TYPE_INVALID,
diff --git a/plugins/generic-player/rb-psp-source.h b/plugins/generic-player/rb-psp-source.h
index 4f36134..50940b0 100644
--- a/plugins/generic-player/rb-psp-source.h
+++ b/plugins/generic-player/rb-psp-source.h
@@ -31,6 +31,7 @@
 #include "mediaplayerid.h"
 
 #include "rb-shell.h"
+#include "rb-plugin.h"
 #include "rb-generic-player-source.h"
 #include "rhythmdb.h"
 
@@ -53,7 +54,10 @@ typedef struct
 	RBGenericPlayerSourceClass parent;
 } RBPspSourceClass;
 
-RBRemovableMediaSource *rb_psp_source_new		(RBShell *shell, GMount *mount, MPIDDevice *device_info);
+RBRemovableMediaSource *rb_psp_source_new		(RBPlugin *plugin,
+							 RBShell *shell,
+							 GMount *mount,
+							 MPIDDevice *device_info);
 GType			rb_psp_source_get_type		(void);
 GType			rb_psp_source_register_type	(GTypeModule *module);
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]