[rhythmbox] Add base class for media player sources



commit 980cb9338a6e80be2991aa3e00b834b16c1ee0cf
Author: Jonathan Matthew <jonathan d14n org>
Date:   Sun Dec 13 11:29:00 2009 +1000

    Add base class for media player sources
    
    For now, this only has some code for setting up a common properties
    dialog, but this is where library/playlist/podcast sync will be
    implemented.

 data/ui/Makefile.am                |    1 +
 data/ui/media-player-properties.ui |  140 ++++++++++++++++++++++
 sources/Makefile.am                |    2 +
 sources/rb-media-player-source.c   |  231 ++++++++++++++++++++++++++++++++++++
 sources/rb-media-player-source.h   |   74 ++++++++++++
 5 files changed, 448 insertions(+), 0 deletions(-)
---
diff --git a/data/ui/Makefile.am b/data/ui/Makefile.am
index 1b830ff..63f95cb 100644
--- a/data/ui/Makefile.am
+++ b/data/ui/Makefile.am
@@ -6,6 +6,7 @@ GTK_BUILDER_FILES =					\
 	create-playlist.ui				\
 	general-prefs.ui				\
 	library-prefs.ui				\
+	media-player-properties.ui			\
 	playback-prefs.ui				\
 	playlist-save.ui				\
 	plugins.ui					\
diff --git a/data/ui/media-player-properties.ui b/data/ui/media-player-properties.ui
new file mode 100644
index 0000000..5194cd8
--- /dev/null
+++ b/data/ui/media-player-properties.ui
@@ -0,0 +1,140 @@
+<?xml version="1.0"?>
+<interface>
+  <!-- interface-requires gtk+ 2.12 -->
+  <!-- interface-naming-policy toplevel-contextual -->
+  <object class="GtkTreeStore" id="treestore1"/>
+  <object class="GtkDialog" id="media-player-properties">
+    <property name="visible">True</property>
+    <property name="title" translatable="yes">iPod Properties</property>
+    <property name="type_hint">dialog</property>
+    <property name="has_separator">False</property>
+    <child internal-child="vbox">
+      <object class="GtkVBox" id="dialog-vbox1">
+        <property name="visible">True</property>
+        <property name="orientation">vertical</property>
+        <child>
+          <object class="GtkNotebook" id="media-player-notebook">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="border_width">6</property>
+            <child>
+              <object class="GtkVBox" id="vbox1">
+                <property name="visible">True</property>
+                <property name="border_width">12</property>
+                <property name="orientation">vertical</property>
+                <child>
+                  <object class="GtkFrame" id="frame1">
+                    <property name="visible">True</property>
+                    <property name="label_xalign">0</property>
+                    <property name="shadow_type">none</property>
+                    <child>
+                      <object class="GtkVBox" id="device-info-box">
+                        <property name="visible">True</property>
+                        <property name="border_width">12</property>
+                        <property name="orientation">vertical</property>
+                        <child>
+                          <placeholder/>
+                        </child>
+                      </object>
+                    </child>
+                    <child type="label">
+                      <object class="GtkLabel" id="label-frame-information">
+                        <property name="visible">True</property>
+                        <property name="label" translatable="yes">&lt;b&gt;Information&lt;/b&gt;</property>
+                        <property name="use_markup">True</property>
+                      </object>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkFrame" id="frame2">
+                    <property name="visible">True</property>
+                    <property name="label_xalign">0</property>
+                    <property name="shadow_type">none</property>
+                    <child>
+                      <object class="GtkVBox" id="vbox3">
+                        <property name="visible">True</property>
+                        <property name="border_width">12</property>
+                        <property name="orientation">vertical</property>
+                        <child>
+                          <object class="GtkProgressBar" id="progressbar-device-usage">
+                            <property name="visible">True</property>
+                            <property name="pulse_step">0.10000000149</property>
+                          </object>
+                          <packing>
+                            <property name="position">0</property>
+                          </packing>
+                        </child>
+                      </object>
+                    </child>
+                    <child type="label">
+                      <object class="GtkLabel" id="label-frame-usage">
+                        <property name="visible">True</property>
+                        <property name="label" translatable="yes">&lt;b&gt;Volume usage&lt;/b&gt;</property>
+                        <property name="use_markup">True</property>
+                      </object>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
+                    <property name="padding">6</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </object>
+            </child>
+            <child type="tab">
+              <object class="GtkLabel" id="label-notebook-basic">
+                <property name="visible">True</property>
+                <property name="label" translatable="yes">Basic</property>
+              </object>
+              <packing>
+                <property name="tab_fill">False</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <child internal-child="action_area">
+          <object class="GtkHButtonBox" id="dialog-action_area1">
+            <property name="visible">True</property>
+            <property name="layout_style">end</property>
+            <child>
+              <object class="GtkButton" id="closebutton1">
+                <property name="label">gtk-close</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="can_default">True</property>
+                <property name="receives_default">False</property>
+                <property name="use_stock">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="pack_type">end</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+    <action-widgets>
+      <action-widget response="-7">closebutton1</action-widget>
+    </action-widgets>
+  </object>
+  <object class="GtkTreeSelection" id="treeselection1"/>
+  <object class="GtkTreeSelection" id="treeselection2"/>
+</interface>
diff --git a/sources/Makefile.am b/sources/Makefile.am
index cd50ea2..1a316b5 100644
--- a/sources/Makefile.am
+++ b/sources/Makefile.am
@@ -26,6 +26,8 @@ libsourcesimpl_la_SOURCES =		\
 	rb-podcast-source.h		\
 	rb-removable-media-source.c	\
 	rb-removable-media-source.h	\
+	rb-media-player-source.c	\
+	rb-media-player-source.h	\
 	rb-playlist-source.c            \
 	rb-playlist-source.h		\
 	rb-playlist-xml.h		\
diff --git a/sources/rb-media-player-source.c b/sources/rb-media-player-source.c
new file mode 100644
index 0000000..9e27d3a
--- /dev/null
+++ b/sources/rb-media-player-source.c
@@ -0,0 +1,231 @@
+/*
+ *  arch-tag: Implementation of the Media Player Source object
+ *
+ *  Copyright (C) 2009 Paul Bellamy  <paul a bellamy gmail com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The Rhythmbox authors hereby grant permission for non-GPL compatible
+ *  GStreamer plugins to be used and distributed together with GStreamer
+ *  and Rhythmbox. This permission is above and beyond the permissions granted
+ *  by the GPL license by which Rhythmbox is covered. If you modify this code
+ *  you may extend this exception to your version of the code, but you are not
+ *  obligated to do so. If you do not wish to do so, delete this exception
+ *  statement from your version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA.
+ *
+ */
+
+#include "config.h"
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <glib/gstdio.h>
+#include <string.h>
+
+#include "rb-shell.h"
+#include "rb-media-player-source.h"
+#include "rb-dialog.h"
+#include "rb-debug.h"
+#include "rb-file-helpers.h"
+#include "rb-builder-helpers.h"
+#include "rb-util.h"
+
+typedef struct {
+	/* properties dialog bits */
+	GtkDialog *properties_dialog;
+
+} RBMediaPlayerSourcePrivate;
+
+G_DEFINE_TYPE (RBMediaPlayerSource, rb_media_player_source, RB_TYPE_REMOVABLE_MEDIA_SOURCE);
+
+#define MEDIA_PLAYER_SOURCE_GET_PRIVATE(o)   (G_TYPE_INSTANCE_GET_PRIVATE ((o), RB_TYPE_MEDIA_PLAYER_SOURCE, RBMediaPlayerSourcePrivate))
+
+static void rb_media_player_source_class_init (RBMediaPlayerSourceClass *klass);
+static void rb_media_player_source_init (RBMediaPlayerSource *source);
+
+static void rb_media_player_source_set_property (GObject *object,
+					 guint prop_id,
+					 const GValue *value,
+					 GParamSpec *pspec);
+static void rb_media_player_source_get_property (GObject *object,
+					 guint prop_id,
+					 GValue *value,
+					 GParamSpec *pspec);
+
+enum
+{
+	PROP_0,
+	PROP_DEVICE_SERIAL
+};
+
+static void
+rb_media_player_source_class_init (RBMediaPlayerSourceClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+	object_class->set_property = rb_media_player_source_set_property;
+	object_class->get_property = rb_media_player_source_get_property;
+
+	klass->impl_get_capacity = NULL;
+	klass->impl_get_free_space = NULL;
+	klass->impl_show_properties = NULL;
+
+	g_object_class_install_property (object_class,
+					 PROP_DEVICE_SERIAL,
+					 g_param_spec_string ("serial",
+							      "serial",
+							      "device serial number",
+							      NULL,
+							      G_PARAM_READABLE));
+
+	g_type_class_add_private (klass, sizeof (RBMediaPlayerSourcePrivate));
+}
+
+static void
+rb_media_player_source_init (RBMediaPlayerSource *source)
+{
+}
+
+static void
+rb_media_player_source_set_property (GObject *object,
+			     guint prop_id,
+			     const GValue *value,
+			     GParamSpec *pspec)
+{
+	/*RBMediaPlayerSourcePrivate *priv = MEDIA_PLAYER_SOURCE_GET_PRIVATE (object);*/
+	switch (prop_id) {
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+		break;
+	}
+}
+
+static void
+rb_media_player_source_get_property (GObject *object,
+			     guint prop_id,
+			     GValue *value,
+			     GParamSpec *pspec)
+{
+	/*RBMediaPlayerSourcePrivate *priv = MEDIA_PLAYER_SOURCE_GET_PRIVATE (object);*/
+	switch (prop_id) {
+	case PROP_DEVICE_SERIAL:
+		/* not actually supported in the base class */
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+		break;
+	}
+}
+
+
+
+static guint64
+get_capacity (RBMediaPlayerSource *source)
+{
+	RBMediaPlayerSourceClass *klass = RB_MEDIA_PLAYER_SOURCE_GET_CLASS (source);
+
+	return klass->impl_get_capacity (source);
+}
+
+static guint64
+get_free_space (RBMediaPlayerSource *source)
+{
+	RBMediaPlayerSourceClass *klass = RB_MEDIA_PLAYER_SOURCE_GET_CLASS (source);
+
+	return klass->impl_get_free_space (source);
+}
+
+static void
+properties_dialog_response_cb (GtkDialog *dialog,
+			       int response_id,
+			       RBMediaPlayerSource *source)
+{
+	RBMediaPlayerSourcePrivate *priv = MEDIA_PLAYER_SOURCE_GET_PRIVATE (source);
+	rb_debug ("media player properties dialog closed");
+	gtk_widget_destroy (GTK_WIDGET (dialog));
+	g_object_unref (priv->properties_dialog);
+	priv->properties_dialog = NULL;
+}
+
+void
+rb_media_player_source_show_properties (RBMediaPlayerSource *source)
+{
+	RBMediaPlayerSourcePrivate *priv = MEDIA_PLAYER_SOURCE_GET_PRIVATE (source);
+	RBMediaPlayerSourceClass *klass = RB_MEDIA_PLAYER_SOURCE_GET_CLASS (source);
+	GtkBuilder *builder;
+	GtkWidget *widget;
+	const char *ui_file;
+	char *used_str;
+	char *capacity_str;
+	char *text;
+	guint64 capacity;
+	guint64 free_space;
+
+	if (priv->properties_dialog != NULL) {
+		gtk_window_present (GTK_WINDOW (priv->properties_dialog));
+		return;
+	}
+
+	/* load dialog UI */
+	ui_file = rb_file ("media-player-properties.ui");
+	if (ui_file == NULL) {
+		g_warning ("Couldn't find media-player-properties.ui");
+		return;
+	}
+
+	builder = rb_builder_load (ui_file, NULL);
+	if (builder == NULL) {
+		g_warning ("Couldn't load media-player-properties.ui");
+		return;
+	}
+
+	priv->properties_dialog = GTK_DIALOG (gtk_builder_get_object (builder, "media-player-properties"));
+	g_signal_connect_object (priv->properties_dialog,
+				 "response",
+				 G_CALLBACK (properties_dialog_response_cb),
+				 source, 0);
+
+	/*
+	 * fill in some common details:
+	 * - volume usage (need to hook up signals etc. to update this live)
+	 */
+	widget = GTK_WIDGET (gtk_builder_get_object (builder, "progressbar-device-usage"));
+	capacity = get_capacity (source);
+	free_space = get_free_space (source);
+	used_str = g_format_size_for_display (capacity - free_space);
+	capacity_str = g_format_size_for_display (capacity);
+	gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (widget),
+				       (double)(capacity - free_space)/(double)capacity);
+	/* Translators: this is used to display the amount of storage space
+	 * used and the total storage space on an device.
+	 */
+	text = g_strdup_printf (_("%s of %s"), used_str, capacity_str);
+	gtk_progress_bar_set_text (GTK_PROGRESS_BAR (widget), text);
+	g_free (text);
+	g_free (capacity_str);
+	g_free (used_str);
+
+	/* let the subclass fill in device type specific details (model names, device names,
+	 * .. battery levels?) and add more tabs to the notebook to display 'advanced' stuff.
+	 */
+
+	if (klass->impl_show_properties) {
+		klass->impl_show_properties (source,
+					     GTK_WIDGET (gtk_builder_get_object (builder, "device-info-box")),
+					     GTK_WIDGET (gtk_builder_get_object (builder, "media-player-notebook")));
+	}
+
+	gtk_widget_show (GTK_WIDGET (priv->properties_dialog));
+}
diff --git a/sources/rb-media-player-source.h b/sources/rb-media-player-source.h
new file mode 100644
index 0000000..980a442
--- /dev/null
+++ b/sources/rb-media-player-source.h
@@ -0,0 +1,74 @@
+/*
+ *  arch-tag: Header for the Media Player Source object
+ *
+ *  Copyright (C) 2009 Paul Bellamy  <paul a bellamy gmail com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The Rhythmbox authors hereby grant permission for non-GPL compatible
+ *  GStreamer plugins to be used and distributed together with GStreamer
+ *  and Rhythmbox. This permission is above and beyond the permissions granted
+ *  by the GPL license by which Rhythmbox is covered. If you modify this code
+ *  you may extend this exception to your version of the code, but you are not
+ *  obligated to do so. If you do not wish to do so, delete this exception
+ *  statement from your version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA.
+ *
+ */
+
+#ifndef __RB_MEDIA_PLAYER_SOURCE_H
+#define __RB_MEDIA_PLAYER_SOURCE_H
+
+#include <glib.h>
+
+#include "rb-shell.h"
+#include "rb-removable-media-source.h"
+#include "rhythmdb.h"
+
+G_BEGIN_DECLS
+
+#define RB_TYPE_MEDIA_PLAYER_SOURCE         (rb_media_player_source_get_type ())
+#define RB_MEDIA_PLAYER_SOURCE(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), RB_TYPE_MEDIA_PLAYER_SOURCE, RBMediaPlayerSource))
+#define RB_MEDIA_PLAYER_SOURCE_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), RB_TYPE_MEDIA_PLAYER_SOURCE, RBMediaPlayerSourceClass))
+#define RB_IS_MEDIA_PLAYER_SOURCE(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), RB_TYPE_MEDIA_PLAYER_SOURCE))
+#define RB_IS_MEDIA_PLAYER_SOURCE_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), RB_TYPE_MEDIA_PLAYER_SOURCE))
+#define RB_MEDIA_PLAYER_SOURCE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), RB_TYPE_MEDIA_PLAYER_SOURCE, RBMediaPlayerSourceClass))
+
+typedef struct _RBMediaPlayerSource RBMediaPlayerSource;
+typedef struct _RBMediaPlayerSourceClass RBMediaPlayerSourceClass;
+
+typedef void (*RBMediaPlayerSourceDeleteCallback) (RBMediaPlayerSource *source, gpointer data);
+
+struct _RBMediaPlayerSource
+{
+	RBRemovableMediaSource parent_instance;
+};
+
+struct _RBMediaPlayerSourceClass
+{
+	RBRemovableMediaSourceClass parent_class;
+
+	/* class members */
+	guint64		(*impl_get_capacity)	(RBMediaPlayerSource *source);
+	guint64		(*impl_get_free_space)	(RBMediaPlayerSource *source);
+	void		(*impl_show_properties)	(RBMediaPlayerSource *source, GtkWidget *info_box, GtkWidget *notebook);
+};
+
+GType	rb_media_player_source_get_type	(void);
+
+void	rb_media_player_source_show_properties (RBMediaPlayerSource *source);
+
+G_END_DECLS
+
+#endif



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