[Rawstudio-commit] r2208 - trunk/librawstudio

Anders Brander anders at brander.dk
Sun Feb 22 17:05:15 CET 2009


Author: abrander
Date: 2009-02-22 17:05:14 +0100 (Sun, 22 Feb 2009)
New Revision: 2208

Added:
   trunk/librawstudio/rs-output.c
   trunk/librawstudio/rs-output.h
Modified:
   trunk/librawstudio/Makefile.am
   trunk/librawstudio/rawstudio.h
   trunk/librawstudio/rs-plugin-manager.c
Log:
Added RSOutput-type (for plugable export modules).

Modified: trunk/librawstudio/Makefile.am
===================================================================
--- trunk/librawstudio/Makefile.am	2009-02-21 21:57:23 UTC (rev 2207)
+++ trunk/librawstudio/Makefile.am	2009-02-22 16:05:14 UTC (rev 2208)
@@ -16,6 +16,7 @@
 	rs-metadata.h \
 	rs-filetypes.h \
 	rs-filter.h \
+	rs-output.h \
 	rs-plugin-manager.h \
 	rs-utils.h \
 	rs-math.h \
@@ -36,6 +37,7 @@
 	rs-metadata.c rs-metadata.h \
 	rs-filetypes.c rs-filetypes.h \
 	rs-filter.c rs-filter.h \
+	rs-output.c rs-output.h \
 	rs-plugin-manager.c rs-plugin-manager.h \
 	rs-utils.c rs-utils.h \
 	rs-math.c rs-math.h \

Modified: trunk/librawstudio/rawstudio.h
===================================================================
--- trunk/librawstudio/rawstudio.h	2009-02-21 21:57:23 UTC (rev 2207)
+++ trunk/librawstudio/rawstudio.h	2009-02-22 16:05:14 UTC (rev 2208)
@@ -37,6 +37,7 @@
 #include "rs-filetypes.h"
 #include "rs-plugin.h"
 #include "rs-filter.h"
+#include "rs-output.h"
 #include "rs-plugin-manager.h"
 #include "rs-utils.h"
 #include "rs-settings.h"

Added: trunk/librawstudio/rs-output.c
===================================================================
--- trunk/librawstudio/rs-output.c	                        (rev 0)
+++ trunk/librawstudio/rs-output.c	2009-02-22 16:05:14 UTC (rev 2208)
@@ -0,0 +1,247 @@
+/*
+ * Copyright (C) 2006-2009 Anders Brander <anders at brander.dk> and 
+ * Anders Kvist <akv at lnxbx.dk>
+ *
+ * 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.
+ *
+ * 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 Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#include <rawstudio.h>
+#include "rs-output.h"
+
+G_DEFINE_TYPE (RSOutput, rs_output, G_TYPE_OBJECT)
+
+static void integer_changed(GtkAdjustment *adjustment, gpointer user_data);
+static void boolean_changed(GtkToggleButton *togglebutton, gpointer user_data);
+
+static void
+rs_output_class_init(RSOutputClass *klass)
+{
+	klass->display_name = "N/A";
+}
+
+static void
+rs_output_init(RSOutput *self)
+{
+}
+
+/**
+ * Instantiate a new RSOutput type
+ * @param identifier A string representing a type, for example "RSJpegfile"
+ * @return A new RSOutput or NULL on failure
+ */
+RSOutput *
+rs_output_new(const gchar *identifier)
+{
+	RSOutput *output = NULL;
+
+	g_assert(identifier != NULL);
+
+	GType type = g_type_from_name(identifier);
+
+	if (g_type_is_a (type, RS_TYPE_OUTPUT))
+		output = g_object_new(type, NULL);
+	else
+		g_warning("%s is not a RSOutput",identifier);
+
+	if (!RS_IS_OUTPUT(output))
+		g_warning("Could not instantiate output of type \"%s\"", identifier);
+
+	return output;
+}
+
+/**
+ * Actually execute the saver
+ * @param output A RSOutput
+ * @param pixbuf A 8 bit pixbuf that should be saved
+ * @return TRUE on success, FALSE on error
+ */
+gboolean
+rs_output_execute(RSOutput *output, GdkPixbuf *pixbuf)
+{
+	g_assert(RS_IS_OUTPUT(output));
+
+	if (RS_OUTPUT_GET_CLASS(output)->execute8)
+		return RS_OUTPUT_GET_CLASS(output)->execute8(output, pixbuf);
+	else
+		return FALSE;
+}
+
+static void
+integer_changed(GtkAdjustment *adjustment, gpointer user_data)
+{
+	RSOutput *output = RS_OUTPUT(user_data);
+	gint value = (gint) gtk_adjustment_get_value(adjustment);
+	gchar *name = g_object_get_data(G_OBJECT(adjustment), "spec-name");
+	gchar *confpath = g_object_get_data(G_OBJECT(adjustment), "conf-path");
+
+	if (name)
+		g_object_set(output, name, value, NULL);
+
+	if (confpath)
+		rs_conf_set_integer(confpath, value);
+}
+
+static void
+boolean_changed(GtkToggleButton *togglebutton, gpointer user_data)
+{
+	RSOutput *output = RS_OUTPUT(user_data);
+	gboolean value = (gint) gtk_toggle_button_get_active(togglebutton);
+	gchar *name = g_object_get_data(G_OBJECT(togglebutton), "spec-name");
+	gchar *confpath = g_object_get_data(G_OBJECT(togglebutton), "conf-path");
+
+	if (name)
+		g_object_set(output, name, value, NULL);
+
+	if (confpath)
+		rs_conf_set_boolean(confpath, value);
+}
+
+/**
+ * Load parameters from config for a RSOutput
+ * @param output A RSOutput
+ * @param conf_prefix The prefix to prepend on config-keys.
+ */
+void
+rs_output_set_from_conf(RSOutput *output, const gchar *conf_prefix)
+{
+	GObjectClass *klass = G_OBJECT_GET_CLASS(output);
+	GParamSpec **specs;
+	gint n_specs = 0;
+	gint i;
+
+	g_assert(RS_IS_OUTPUT(output));
+	g_assert(conf_prefix != NULL);
+
+	specs = g_object_class_list_properties(G_OBJECT_CLASS(klass), &n_specs);
+	for(i=0; i<n_specs; i++)
+	{
+		gchar *confpath = NULL;
+
+		confpath = g_strdup_printf("%s:%s:%s", conf_prefix, G_OBJECT_TYPE_NAME(output), specs[i]->name);
+
+		switch (G_PARAM_SPEC_VALUE_TYPE(specs[i]))
+		{
+			case G_TYPE_BOOLEAN:
+			{
+				gboolean boolean = FALSE;
+				if (rs_conf_get_boolean(confpath, &boolean))
+					g_object_set(output, specs[i]->name, boolean, NULL);
+				break;
+			}
+			case G_TYPE_INT:
+			{
+				gint integer = 0;
+				if (rs_conf_get_integer(confpath, &integer))
+					g_object_set(output, specs[i]->name, integer, NULL);
+				break;
+			}
+			default:
+				g_assert_not_reached();
+				break;
+		}
+	}
+}
+
+/**
+ * Build a GtkWidget that can edit parameters of a RSOutput
+ * @param output A RSOutput
+ * @param conf_prefix If this is non-NULL, the value will be saved in config,
+ *                    and reloaded next time.
+ * @return A new GtkWidget representing all parameters of output
+ */
+GtkWidget *
+rs_output_get_parameter_widget(RSOutput *output, const gchar *conf_prefix)
+{
+	GtkWidget *box = gtk_vbox_new(FALSE, 0);
+	GObjectClass *klass = G_OBJECT_GET_CLASS(output);
+	GParamSpec **specs;
+	gint n_specs = 0;
+	gint i;
+
+	/* Iterate through all GParamSpec's and build a GtkWidget representing them */
+	specs = g_object_class_list_properties(G_OBJECT_CLASS(klass), &n_specs);
+	for(i=0; i<n_specs; i++)
+	{
+		gchar *confpath = NULL;
+		GtkWidget *widget = NULL;
+
+		/* Ignore "filename" for now */
+		if (g_str_equal(specs[i]->name, "filename"))
+			continue;
+
+		/* Iw the caller has supplied ud with a conf prefix, sync everything
+		 * with config system */
+		if (conf_prefix)
+			confpath = g_strdup_printf("%s:%s:%s", conf_prefix, G_OBJECT_TYPE_NAME(output), specs[i]->name);
+
+		switch (G_PARAM_SPEC_VALUE_TYPE(specs[i]))
+		{
+			case G_TYPE_BOOLEAN:
+			{
+				gboolean boolean = FALSE;
+
+				/* Should this be dropped, and then let the user worry about
+				 * calling rs_output_set_from_conf()? */
+				if (confpath && rs_conf_get_boolean(confpath, &boolean))
+					g_object_set(output, specs[i]->name, boolean, NULL);
+
+				g_object_get(output, specs[i]->name, &boolean, NULL);
+				widget = gtk_check_button_new_with_label(g_param_spec_get_blurb(specs[i]));
+				gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), boolean);
+				g_object_set_data(G_OBJECT(widget), "spec-name", specs[i]->name);
+				g_object_set_data_full(G_OBJECT(widget), "conf-path", confpath, g_free);
+				g_signal_connect(widget, "toggled", G_CALLBACK(boolean_changed), output);
+				break;
+			}
+			case G_TYPE_INT:
+			{
+				GtkObject *adj;
+				GtkWidget *label;
+				GtkWidget *scale;
+				GtkWidget *spin;
+				gint integer = 0;
+
+				if (confpath && rs_conf_get_integer(confpath, &integer))
+					g_object_set(output, specs[i]->name, integer, NULL);
+
+				g_object_get(output, specs[i]->name, &integer, NULL);
+
+				adj = gtk_adjustment_new((gdouble) integer,
+					(gdouble) (((GParamSpecInt*)specs[i])->minimum),
+					(gdouble) (((GParamSpecInt*)specs[i])->maximum),
+					1.0, 10.0, 0.0);
+				g_object_set_data(G_OBJECT(adj), "spec-name", specs[i]->name);
+				g_object_set_data_full(G_OBJECT(adj), "conf-path", confpath, g_free);
+				g_signal_connect(adj, "value-changed", G_CALLBACK(integer_changed), output);
+
+				label = gtk_label_new(g_param_spec_get_blurb(specs[i]));
+				scale = gtk_hscale_new(GTK_ADJUSTMENT(adj));
+				gtk_scale_set_draw_value(GTK_SCALE(scale), FALSE);
+				spin = gtk_spin_button_new(GTK_ADJUSTMENT(adj), 1.0, 0);
+
+				widget = gtk_hbox_new(FALSE, 2);
+				gtk_box_pack_start(GTK_BOX(widget), label, FALSE, TRUE, 0);
+				gtk_box_pack_start(GTK_BOX(widget), scale, TRUE, TRUE, 0);
+				gtk_box_pack_start(GTK_BOX(widget), spin, FALSE, TRUE, 0);
+				break;
+			}
+			default:
+				g_assert_not_reached();
+				break;
+		}
+		gtk_box_pack_start(GTK_BOX(box), widget, FALSE, FALSE, 3);
+	}
+	return box;
+}

Added: trunk/librawstudio/rs-output.h
===================================================================
--- trunk/librawstudio/rs-output.h	                        (rev 0)
+++ trunk/librawstudio/rs-output.h	2009-02-22 16:05:14 UTC (rev 2208)
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2006-2009 Anders Brander <anders at brander.dk> and 
+ * Anders Kvist <akv at lnxbx.dk>
+ *
+ * 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.
+ *
+ * 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 Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#ifndef RS_OUTPUT_H
+#define RS_OUTPUT_H
+
+#include "rawstudio.h"
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+/**
+ * Convenience macro to define generic output module
+ */
+#define RS_DEFINE_OUTPUT(type_name, TypeName) \
+static GType type_name##_get_type (GTypeModule *module); \
+static void type_name##_class_init(TypeName##Class *klass); \
+static void type_name##_init(TypeName *output); \
+static GType type_name##_type = 0; \
+static GType \
+type_name##_get_type(GTypeModule *module) \
+{ \
+	if (!type_name##_type) \
+	{ \
+		static const GTypeInfo output_info = \
+		{ \
+			sizeof (TypeName##Class), \
+			(GBaseInitFunc) NULL, \
+			(GBaseFinalizeFunc) NULL, \
+			(GClassInitFunc) type_name##_class_init, \
+			NULL, \
+			NULL, \
+			sizeof (TypeName), \
+			0, \
+			(GInstanceInitFunc) type_name##_init \
+		}; \
+ \
+		type_name##_type = g_type_module_register_type( \
+			module, \
+			RS_TYPE_OUTPUT, \
+			#TypeName, \
+			&output_info, \
+			0); \
+	} \
+	return type_name##_type; \
+}
+
+#define RS_TYPE_OUTPUT rs_output_get_type()
+#define RS_OUTPUT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RS_TYPE_OUTPUT, RSOutput))
+#define RS_OUTPUT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RS_TYPE_OUTPUT, RSOutputClass))
+#define RS_IS_OUTPUT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RS_TYPE_OUTPUT))
+#define RS_IS_OUTPUT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RS_TYPE_OUTPUT))
+#define RS_OUTPUT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RS_TYPE_OUTPUT, RSOutputClass))
+
+#define RS_OUTPUT_NAME(output) (((output)) ? g_type_name(G_TYPE_FROM_CLASS(RS_OUTPUT_GET_CLASS ((output)))) : "(nil)")
+
+typedef struct _RSOutput RSOutput;
+typedef struct _RSOutputClass RSOutputClass;
+
+struct _RSOutput {
+	GObject parent;
+};
+
+struct _RSOutputClass {
+	GObjectClass parent_class;
+	gchar *display_name;
+	gboolean (*execute8)(RSOutput *output, GdkPixbuf *pixbuf);
+};
+
+GType rs_output_get_type() G_GNUC_CONST;
+
+/**
+ * Instantiate a new RSOutput type
+ * @param identifier A string representing a type, for example "RSJpegfile"
+ * @return A new RSOutput or NULL on failure
+ */
+extern RSOutput *
+rs_output_new(const gchar *identifier);
+
+/**
+ * Actually execute the saver
+ * @param output A RSOutput
+ * @param pixbuf A 8 bit pixbuf that should be saved
+ * @return TRUE on success, FALSE on error
+ */
+extern gboolean
+rs_output_execute(RSOutput *output, GdkPixbuf *pixbuf);
+
+/**
+ * Load parameters from config for a RSOutput
+ * @param output A RSOutput
+ * @param conf_prefix The prefix to prepend on config-keys.
+ */
+void
+rs_output_set_from_conf(RSOutput *output, const gchar *conf_prefix);
+
+/**
+ * Build a GtkWidget that can edit parameters of a RSOutput
+ * @param output A RSOutput
+ * @param conf_prefix If this is non-NULL, the value will be saved in config,
+ *                    and reloaded next time.
+ * @return A new GtkWidget representing all parameters of output
+ */
+extern GtkWidget *
+rs_output_get_parameter_widget(RSOutput *output, const gchar *conf_prefix);
+
+G_END_DECLS
+
+#endif /* RS_OUTPUT_H */

Modified: trunk/librawstudio/rs-plugin-manager.c
===================================================================
--- trunk/librawstudio/rs-plugin-manager.c	2009-02-21 21:57:23 UTC (rev 2207)
+++ trunk/librawstudio/rs-plugin-manager.c	2009-02-22 16:05:14 UTC (rev 2208)
@@ -68,19 +68,19 @@
 	g_debug("%d plugins loaded in %.03f second", num, g_timer_elapsed(gt, NULL));
 
 
-	/* Print some debug info about loaded filters */
-	GType *filters;
-	guint n_filters, i;
-	filters = g_type_children (RS_TYPE_FILTER, &n_filters);
-	g_debug("%d filters loaded:", n_filters);
-	for (i = 0; i < n_filters; i++)
+	/* Print some debug info about loaded plugins */
+	GType *plugins;
+	guint n_plugins, i;
+	plugins = g_type_children (RS_TYPE_FILTER, &n_plugins);
+	g_debug("%d filters loaded:", n_plugins);
+	for (i = 0; i < n_plugins; i++)
 	{
 		RSFilterClass *klass;
 		GParamSpec **specs;
 		gint n_specs = 0;
 		gint s;
-		klass = g_type_class_ref(filters[i]);
-		g_debug("* %s: %s", g_type_name(filters[i]), klass->name);
+		klass = g_type_class_ref(plugins[i]);
+		g_debug("* %s: %s", g_type_name(plugins[i]), klass->name);
 		specs = g_object_class_list_properties(G_OBJECT_CLASS(klass), &n_specs);
 		for(s=0;s<n_specs;s++)
 		{
@@ -99,8 +99,38 @@
 		g_free(specs);
 		g_type_class_unref(klass);
 	}
-	g_free(filters);
+	g_free(plugins);
 
+	plugins = g_type_children (RS_TYPE_OUTPUT, &n_plugins);
+	g_debug("%d exporters loaded:", n_plugins);
+	for (i = 0; i < n_plugins; i++)
+	{
+		RSOutputClass *klass;
+		GParamSpec **specs;
+		gint n_specs = 0;
+		gint s;
+		klass = g_type_class_ref(plugins[i]);
+		g_debug("* %s: %s", g_type_name(plugins[i]), klass->display_name);
+		specs = g_object_class_list_properties(G_OBJECT_CLASS(klass), &n_specs);
+		for(s=0;s<n_specs;s++)
+		{
+			g_debug("  + \"%s\":\t%s%s%s%s%s%s%s%s [%s]", specs[s]->name,
+				(specs[s]->flags & G_PARAM_READABLE) ? " READABLE" : "",
+				(specs[s]->flags & G_PARAM_WRITABLE) ? " WRITABLE" : "",
+				(specs[s]->flags & G_PARAM_CONSTRUCT) ? " CONSTRUCT" : "",
+				(specs[s]->flags & G_PARAM_CONSTRUCT_ONLY) ? " CONSTRUCT_ONLY" : "",
+				(specs[s]->flags & G_PARAM_LAX_VALIDATION) ? " LAX_VALIDATION" : "",
+				(specs[s]->flags & G_PARAM_STATIC_NAME) ? " STATIC_NAME" : "",
+				(specs[s]->flags & G_PARAM_STATIC_NICK) ? " STATIC_NICK" : "",
+				(specs[s]->flags & G_PARAM_STATIC_BLURB) ? " STATIC_BLURB" : "",
+				g_param_spec_get_blurb(specs[s])
+			);
+		}
+		g_free(specs);
+		g_type_class_unref(klass);
+	}
+	g_free(plugins);
+
 	if (dir)
 		g_dir_close(dir);
 




More information about the Rawstudio-commit mailing list