[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