[gnome-color-manager] Add GetProfilesForFile() DBus API call to get the ICC profiles for a given file



commit 3f419c6c13ab665ba9cdc5ab1f7320992e80fa61
Author: Richard Hughes <richard hughsie com>
Date:   Fri May 21 14:32:39 2010 +0100

    Add GetProfilesForFile() DBus API call to get the ICC profiles for a given file

 src/Makefile.am                |    2 +
 src/gcm-dbus.c                 |  123 ++++++++++++++++++++++++++++++++++++++++
 src/gcm-dbus.h                 |    4 +
 src/gcm-inspect.c              |   73 ++++++++++++++++++++++++
 src/org.gnome.ColorManager.xml |   39 +++++++++++++
 5 files changed, 241 insertions(+), 0 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 2ecd2c9..684b583 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -302,6 +302,8 @@ gcm_session_LDADD =					\
 	$(DBUS_GLIB_LIBS)				\
 	$(XORG_LIBS)					\
 	$(GTK_LIBS)					\
+	$(TIFF_LIBS)					\
+	$(EXIF_LIBS)					\
 	$(SANE_LIBS)					\
 	$(NOTIFY_LIBS)					\
 	$(CUPS_LIBS)					\
diff --git a/src/gcm-dbus.c b/src/gcm-dbus.c
index 0cf286a..7369998 100644
--- a/src/gcm-dbus.c
+++ b/src/gcm-dbus.c
@@ -27,6 +27,7 @@
 #include "egg-debug.h"
 
 #include "gcm-utils.h"
+#include "gcm-exif.h"
 #include "gcm-dbus.h"
 #include "gcm-device-xrandr.h"
 #include "gcm-client.h"
@@ -159,6 +160,76 @@ gcm_dbus_get_idle_time (GcmDbus	*dbus)
 #define GCM_DBUS_STRUCT_STRING_STRING (dbus_g_type_get_struct ("GValueArray", G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID))
 
 /**
+ * gcm_dbus_get_profiles_for_file_internal:
+ **/
+static GPtrArray *
+gcm_dbus_get_profiles_for_file_internal (GcmDbus *dbus, const gchar *filename, GError **error)
+{
+	guint i;
+	gboolean ret;
+	GcmExif *exif;
+	GcmDevice *device;
+	GPtrArray *array = NULL;
+	GPtrArray *array_devices;
+	GFile *file;
+	GFile *file_tmp;
+	GcmProfile *profile;
+	GError *error_local = NULL;
+
+	exif = gcm_exif_new ();
+	file = g_file_new_for_path (filename);
+	ret = gcm_exif_parse (exif, file, error);
+	if (!ret)
+		goto out;
+
+	/* create a temp array */
+	array = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
+
+	/* get list */
+	egg_debug ("query=%s", filename);
+	array_devices = gcm_client_get_devices (dbus->priv->client);
+	for (i=0; i<array_devices->len; i++) {
+		device = g_ptr_array_index (array_devices, i);
+
+		/* match up critical parts */
+		if (g_strcmp0 (gcm_device_get_manufacturer (device), gcm_exif_get_manufacturer (exif)) == 0 &&
+		    g_strcmp0 (gcm_device_get_model (device), gcm_exif_get_model (exif)) == 0 &&
+		    g_strcmp0 (gcm_device_get_serial (device), gcm_exif_get_serial (exif)) == 0) {
+
+			/* we have a profile? */
+			filename = gcm_device_get_profile_filename (device);
+			if (filename == NULL) {
+				egg_warning ("%s does not have a profile set", gcm_device_get_id (device));
+				continue;
+			}
+
+			/* open and parse filename */
+			profile = gcm_profile_default_new ();
+			file_tmp = g_file_new_for_path (filename);
+			ret = gcm_profile_parse (profile, file_tmp, &error_local);
+			if (!ret) {
+				egg_warning ("failed to parse %s: %s", filename, error_local->message);
+				g_clear_error (&error_local);
+			} else {
+				g_ptr_array_add (array, g_object_ref (profile));
+			}
+
+			/* unref */
+			g_object_unref (file_tmp);
+			g_object_unref (profile);
+		}
+	}
+
+	/* unref list of devices */
+	g_ptr_array_unref (array_devices);
+
+out:
+	g_object_unref (file);
+	g_object_unref (exif);
+	return array;
+}
+
+/**
  * gcm_dbus_get_profiles_for_device_internal:
  **/
 static GPtrArray *
@@ -400,6 +471,58 @@ gcm_dbus_get_profiles_for_type (GcmDbus *dbus, const gchar *kind, const gchar *o
 }
 
 /**
+ * gcm_dbus_get_profiles_for_file:
+ **/
+void
+gcm_dbus_get_profiles_for_file (GcmDbus *dbus, const gchar *filename, const gchar *options, DBusGMethodInvocation *context)
+{
+	GPtrArray *array_profiles;
+	GcmProfile *profile;
+	const gchar *title;
+	const gchar *filename_tmp;
+	guint i;
+	GPtrArray *array_structs;
+	GValue *value;
+	GError *error_local = NULL;
+	GError *error;
+
+	egg_debug ("getting profiles for %s", filename);
+
+	/* get array of profile filenames */
+	array_profiles = gcm_dbus_get_profiles_for_file_internal (dbus, filename, &error_local);
+	if (array_profiles == NULL) {
+		error = g_error_new (1, 0, "failed to find profile for filename: %s", error_local->message);
+		dbus_g_method_return_error (context, error);
+		g_error_free (error);
+		return;
+	}
+
+	/* copy data to dbus struct */
+	array_structs = g_ptr_array_sized_new (array_profiles->len);
+	for (i=0; i<array_profiles->len; i++) {
+		profile = (GcmProfile *) g_ptr_array_index (array_profiles, i);
+
+		/* get the data */
+		value = g_new0 (GValue, 1);
+		g_value_init (value, GCM_DBUS_STRUCT_STRING_STRING);
+		g_value_take_boxed (value, dbus_g_type_specialized_construct (GCM_DBUS_STRUCT_STRING_STRING));
+		title = gcm_profile_get_description (profile);
+		filename_tmp = gcm_profile_get_filename (profile);
+		dbus_g_type_struct_set (value, 0, title, 1, filename_tmp, -1);
+		g_ptr_array_add (array_structs, g_value_get_boxed (value));
+		g_free (value);
+	}
+
+	/* return profiles */
+	dbus_g_method_return (context, array_structs);
+
+	/* reset time */
+	g_timer_reset (dbus->priv->timer);
+
+	g_ptr_array_unref (array_profiles);
+}
+
+/**
  * gcm_dbus_get_profile_for_window:
  **/
 void
diff --git a/src/gcm-dbus.h b/src/gcm-dbus.h
index f033610..99a242a 100644
--- a/src/gcm-dbus.h
+++ b/src/gcm-dbus.h
@@ -72,6 +72,10 @@ void		 gcm_dbus_get_profiles_for_type		(GcmDbus	*dbus,
 							 const gchar	*type,
 							 const gchar	*options,
 							 DBusGMethodInvocation *context);
+void		 gcm_dbus_get_profiles_for_file		(GcmDbus	*dbus,
+							 const gchar	*filename,
+							 const gchar	*options,
+							 DBusGMethodInvocation *context);
 void		 gcm_dbus_get_profile_for_window	(GcmDbus	*dbus,
 							 guint		 xid,
 							 DBusGMethodInvocation *context);
diff --git a/src/gcm-inspect.c b/src/gcm-inspect.c
index 9d20646..4a0c72c 100644
--- a/src/gcm-inspect.c
+++ b/src/gcm-inspect.c
@@ -221,6 +221,72 @@ out:
 }
 
 /**
+ * gcm_inspect_show_profiles_for_file:
+ **/
+static gboolean
+gcm_inspect_show_profiles_for_file (const gchar *filename)
+{
+	gboolean ret = FALSE;
+	const gchar *description;
+	guint i = 0;
+	GDBusConnection *connection;
+	GError *error = NULL;
+	GVariant *args;
+	GVariant *response = NULL;
+	GVariantIter *iter = NULL;
+
+	/* get a session bus connection */
+	connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
+	if (connection == NULL) {
+		/* TRANSLATORS: no DBus session bus */
+		g_print ("%s: %s\n", _("Failed to connect to session bus"), error->message);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* execute sync method */
+	args = g_variant_new ("(ss)", filename, ""),
+	response = g_dbus_connection_call_sync (connection,
+						GCM_DBUS_SERVICE,
+						GCM_DBUS_PATH,
+						GCM_DBUS_INTERFACE,
+						"GetProfilesForFile",
+						args,
+						G_DBUS_CALL_FLAGS_NONE,
+						-1, NULL, &error);
+	if (response == NULL) {
+		/* TRANSLATORS: the DBus method failed */
+		g_print ("%s: %s\n", _("The request failed"), error->message);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* unpack the array */
+	g_variant_get (response, "(a(ss))", &iter);
+	if (g_variant_iter_n_children (iter) == 0) {
+		/* TRANSLATORS: no profile has been asigned to this device */
+		g_print ("%s\n", _("There are no ICC profiles assigned to this file"));
+		goto out;
+	}
+
+	/* TRANSLATORS: this is a list of profiles suitable for the device */
+	g_print ("%s %s\n", _("Suitable profiles for:"), filename);
+
+	/* for each entry in the array */
+	while (g_variant_iter_loop (iter, "(ss)", &filename, &description))
+		g_print ("%i.\t%s\n\t%s\n", ++i, description, filename);
+
+	/* success */
+	ret = TRUE;
+out:
+	if (iter != NULL)
+		g_variant_iter_free (iter);
+	if (response != NULL)
+		g_variant_unref (response);
+	return ret;
+}
+
+/**
  * gcm_inspect_show_profiles_for_devices:
  **/
 static gboolean
@@ -505,6 +571,7 @@ main (int argc, char **argv)
 	guint xid = 0;
 	gchar *device_id = NULL;
 	gchar *type = NULL;
+	gchar *filename = NULL;
 	GcmDeviceKind kind_enum;
 	guint retval = 0;
 	GOptionContext *context;
@@ -516,6 +583,9 @@ main (int argc, char **argv)
 		{ "device", '\0', 0, G_OPTION_ARG_STRING, &device_id,
 			/* TRANSLATORS: command line option */
 			_("Get the profiles for a specific device"), NULL },
+		{ "file", '\0', 0, G_OPTION_ARG_STRING, &filename,
+			/* TRANSLATORS: command line option */
+			_("Get the profiles for a specific file"), NULL },
 		{ "xid", '\0', 0, G_OPTION_ARG_INT, &xid,
 			/* TRANSLATORS: command line option */
 			_("Get the profile for a specific window"), NULL },
@@ -548,6 +618,8 @@ main (int argc, char **argv)
 		gcm_inspect_show_x11_atoms ();
 	if (device_id != NULL)
 		gcm_inspect_show_profiles_for_device (device_id);
+	if (filename != NULL)
+		gcm_inspect_show_profiles_for_file (filename);
 	if (xid != 0)
 		gcm_inspect_show_profile_for_window (xid);
 	if (type != NULL) {
@@ -566,6 +638,7 @@ main (int argc, char **argv)
 	}
 
 	g_free (device_id);
+	g_free (filename);
 	g_free (type);
 	return retval;
 }
diff --git a/src/org.gnome.ColorManager.xml b/src/org.gnome.ColorManager.xml
index 74a1fd7..70d7c3a 100644
--- a/src/org.gnome.ColorManager.xml
+++ b/src/org.gnome.ColorManager.xml
@@ -153,6 +153,45 @@
     </method>
 
     <!--*****************************************************************************************-->
+    <method name="GetProfilesForFile">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+      <doc:doc>
+        <doc:description>
+          <doc:para>
+            Gets the profiles for a file.
+          </doc:para>
+        </doc:description>
+      </doc:doc>
+      <arg type="s" name="filename" direction="in">
+        <doc:doc>
+          <doc:summary>
+            <doc:para>
+              Fully qualified filename, e.g. <doc:tt>/home/hughsie/Photos/Hughsie.jpg</doc:tt>.
+            </doc:para>
+          </doc:summary>
+        </doc:doc>
+      </arg>
+      <arg type="s" name="options" direction="in">
+        <doc:doc>
+          <doc:summary>
+            <doc:para>
+              Options to give hints about what profiles to choose. Currently unused.
+            </doc:para>
+          </doc:summary>
+        </doc:doc>
+      </arg>
+      <arg type="a(ss)" name="profiles" direction="out">
+        <doc:doc>
+          <doc:summary>
+            <doc:para>
+              An array of profile display names and filenames of suitable profiles to use with this type of device.
+            </doc:para>
+          </doc:summary>
+        </doc:doc>
+      </arg>
+    </method>
+
+    <!--*****************************************************************************************-->
     <method name="GetProfileForWindow">
       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
       <doc:doc>



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