[Rawstudio-commit] r3000 - in branches/rawstudio-ng-color: pixmaps src

Anders Brander anders at brander.dk
Sat Jan 16 08:54:05 CET 2010


Author: abrander
Date: 2010-01-16 08:54:05 +0100 (Sat, 16 Jan 2010)
New Revision: 3000

Added:
   branches/rawstudio-ng-color/pixmaps/camera-photo.png
   branches/rawstudio-ng-color/src/rs-camera-db.c
   branches/rawstudio-ng-color/src/rs-camera-db.h
Modified:
   branches/rawstudio-ng-color/pixmaps/Makefile.am
   branches/rawstudio-ng-color/src/Makefile.am
   branches/rawstudio-ng-color/src/rs-actions.c
   branches/rawstudio-ng-color/src/rs-cache.c
   branches/rawstudio-ng-color/src/rs-cache.h
   branches/rawstudio-ng-color/src/rs-photo.c
   branches/rawstudio-ng-color/src/ui.xml
Log:
Added camera database and the ability to save settings as default for a specific camera model. Happy new year.

Modified: branches/rawstudio-ng-color/pixmaps/Makefile.am
===================================================================
--- branches/rawstudio-ng-color/pixmaps/Makefile.am	2010-01-16 00:42:13 UTC (rev 2999)
+++ branches/rawstudio-ng-color/pixmaps/Makefile.am	2010-01-16 07:54:05 UTC (rev 3000)
@@ -12,6 +12,7 @@
 		transform_90.png \
 		transform_180.png \
 		transform_270.png \
+		camera-photo.png \
 		cursor-color-picker.png \
 		cursor-crop.png \
 		cursor-rotate.png \

Added: branches/rawstudio-ng-color/pixmaps/camera-photo.png
===================================================================
(Binary files differ)


Property changes on: branches/rawstudio-ng-color/pixmaps/camera-photo.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Modified: branches/rawstudio-ng-color/src/Makefile.am
===================================================================
--- branches/rawstudio-ng-color/src/Makefile.am	2010-01-16 00:42:13 UTC (rev 2999)
+++ branches/rawstudio-ng-color/src/Makefile.am	2010-01-16 07:54:05 UTC (rev 3000)
@@ -32,6 +32,7 @@
 	rs-save-dialog.c rs-save-dialog.h \
 	gtk-progress.c gtk-progress.h \
 	conf_interface.c conf_interface.h \
+	rs-camera-db.c rs-camera-db.h \
 	rs-cms.c rs-cms.h \
 	rs-cache.c rs-cache.h \
 	rs-batch.c rs-batch.h \

Modified: branches/rawstudio-ng-color/src/rs-actions.c
===================================================================
--- branches/rawstudio-ng-color/src/rs-actions.c	2010-01-16 00:42:13 UTC (rev 2999)
+++ branches/rawstudio-ng-color/src/rs-actions.c	2010-01-16 07:54:05 UTC (rev 3000)
@@ -38,6 +38,7 @@
 #include "rs-save-dialog.h"
 #include "rs-library.h"
 #include "rs-lens-db-editor.h"
+#include "rs-camera-db.h"
 
 static GtkActionGroup *core_action_group = NULL;
 GStaticMutex rs_actions_spinlock = G_STATIC_MUTEX_INIT;
@@ -73,6 +74,7 @@
 	rs_core_action_group_set_sensivity("RevertSettings", RS_IS_PHOTO(rs->photo));
 	rs_core_action_group_set_sensivity("CopySettings", RS_IS_PHOTO(rs->photo));
 	rs_core_action_group_set_sensivity("PasteSettings", !!(rs->settings_buffer));
+	rs_core_action_group_set_sensivity("SaveDefaultSettings", RS_IS_PHOTO(rs->photo));
 }
 
 ACTION(photo_menu)
@@ -501,6 +503,12 @@
 		rs_settings_reset(rs->photo->settings[rs->current_setting], MASK_ALL);
 }
 
+ACTION(save_default_settings)
+{
+	if (RS_IS_PHOTO(rs->photo))
+		rs_camera_db_save_defaults(rs_camera_db_get_singleton(), rs->photo);
+}
+
 ACTION(preferences)
 {
 	gui_make_preference_window(rs);
@@ -948,6 +956,7 @@
 	{ "CopySettings", GTK_STOCK_COPY, _("_Copy settings"), "<control>C", NULL, ACTION_CB(copy_settings) },
 	{ "PasteSettings", GTK_STOCK_PASTE, _("_Paste settings"), "<control>V", NULL, ACTION_CB(paste_settings) },
 	{ "ResetSettings", GTK_STOCK_REFRESH, _("_Reset settings"), NULL, NULL, ACTION_CB(reset_settings) },
+	{ "SaveDefaultSettings", NULL, _("_Save default settings"), NULL, NULL, ACTION_CB(save_default_settings) },
 	{ "Preferences", GTK_STOCK_PREFERENCES, _("_Preferences"), NULL, NULL, ACTION_CB(preferences) },
 
 	/* Photo menu */

Modified: branches/rawstudio-ng-color/src/rs-cache.c
===================================================================
--- branches/rawstudio-ng-color/src/rs-cache.c	2010-01-16 00:42:13 UTC (rev 2999)
+++ branches/rawstudio-ng-color/src/rs-cache.c	2010-01-16 07:54:05 UTC (rev 3000)
@@ -28,8 +28,6 @@
 /* This will be written to XML files for making backward compatibility easier to implement */
 #define CACHEVERSION 4
 
-static guint rs_cache_load_setting(RSSettings *rss, xmlDocPtr doc, xmlNodePtr cur, gint version);
-
 gchar *
 rs_cache_get_name(const gchar *src)
 {
@@ -55,7 +53,7 @@
 void
 rs_cache_save(RS_PHOTO *photo, const RSSettingsMask mask)
 {
-	gint id, i;
+	gint id;
 	xmlTextWriterPtr writer;
 	gchar *cachename;
 
@@ -92,59 +90,7 @@
 	{
 		xmlTextWriterStartElement(writer, BAD_CAST "settings");
 		xmlTextWriterWriteFormatAttribute(writer, BAD_CAST "id", "%d", id);
-		if (mask & MASK_EXPOSURE)
-			xmlTextWriterWriteFormatElement(writer, BAD_CAST "exposure", "%f",
-				photo->settings[id]->exposure);
-		if (mask & MASK_SATURATION)
-		xmlTextWriterWriteFormatElement(writer, BAD_CAST "saturation", "%f",
-			photo->settings[id]->saturation);
-		if (mask & MASK_HUE)
-		xmlTextWriterWriteFormatElement(writer, BAD_CAST "hue", "%f",
-			photo->settings[id]->hue);
-		if (mask & MASK_CONTRAST)
-		xmlTextWriterWriteFormatElement(writer, BAD_CAST "contrast", "%f",
-			photo->settings[id]->contrast);
-		if (mask & MASK_WARMTH)
-		xmlTextWriterWriteFormatElement(writer, BAD_CAST "warmth", "%f",
-			photo->settings[id]->warmth);
-		if (mask & MASK_TINT)
-		xmlTextWriterWriteFormatElement(writer, BAD_CAST "tint", "%f",
-			photo->settings[id]->tint);
-		if (mask & MASK_SHARPEN)
-		xmlTextWriterWriteFormatElement(writer, BAD_CAST "sharpen", "%f",
-			photo->settings[id]->sharpen);
-		xmlTextWriterWriteFormatElement(writer, BAD_CAST "denoise_luma", "%f",
-			photo->settings[id]->denoise_luma);
-		xmlTextWriterWriteFormatElement(writer, BAD_CAST "denoise_chroma", "%f",
-			photo->settings[id]->denoise_chroma);
-		if (mask & MASK_CHANNELMIXER)
-		{
-			xmlTextWriterWriteFormatElement(writer, BAD_CAST "channelmixer_red", "%f",
-				photo->settings[id]->channelmixer_red);
-			xmlTextWriterWriteFormatElement(writer, BAD_CAST "channelmixer_green", "%f",
-				photo->settings[id]->channelmixer_green);
-			xmlTextWriterWriteFormatElement(writer, BAD_CAST "channelmixer_blue", "%f",
-				photo->settings[id]->channelmixer_blue);
-		}
-		if (mask & MASK_TCA_KR)
-			xmlTextWriterWriteFormatElement(writer, BAD_CAST "tca_kr", "%f",
-				photo->settings[id]->tca_kr);
-		if (mask & MASK_TCA_KB)
-			xmlTextWriterWriteFormatElement(writer, BAD_CAST "tca_kb", "%f",
-				photo->settings[id]->tca_kb);
-		if (mask & MASK_VIGNETTING_K2)
-			xmlTextWriterWriteFormatElement(writer, BAD_CAST "vignetting_k2", "%f",
-				photo->settings[id]->vignetting_k2);
-		if (mask & MASK_CURVE && photo->settings[id]->curve_nknots > 0)
-		{
-			xmlTextWriterStartElement(writer, BAD_CAST "curve");
-			xmlTextWriterWriteFormatAttribute(writer, BAD_CAST "num", "%d", photo->settings[id]->curve_nknots);
-			for(i=0;i<photo->settings[id]->curve_nknots;i++)
-				xmlTextWriterWriteFormatElement(writer, BAD_CAST "knot", "%f %f",
-					photo->settings[id]->curve_knots[i*2+0],
-					photo->settings[id]->curve_knots[i*2+1]);
-			xmlTextWriterEndElement(writer);
-		}
+		rs_cache_save_settings(photo->settings[id], mask, writer);
 		xmlTextWriterEndElement(writer);
 	}
 	xmlTextWriterEndDocument(writer);
@@ -153,7 +99,53 @@
 	return;
 }
 
-static guint
+void
+rs_cache_save_settings(RSSettings *rss, const RSSettingsMask mask, xmlTextWriterPtr writer)
+{
+	if (mask & MASK_EXPOSURE)
+		xmlTextWriterWriteFormatElement(writer, BAD_CAST "exposure", "%f", rss->exposure);
+	if (mask & MASK_SATURATION)
+		xmlTextWriterWriteFormatElement(writer, BAD_CAST "saturation", "%f", rss->saturation);
+	if (mask & MASK_HUE)
+		xmlTextWriterWriteFormatElement(writer, BAD_CAST "hue", "%f", rss->hue);
+	if (mask & MASK_CONTRAST)
+		xmlTextWriterWriteFormatElement(writer, BAD_CAST "contrast", "%f", rss->contrast);
+	if (mask & MASK_WARMTH)
+		xmlTextWriterWriteFormatElement(writer, BAD_CAST "warmth", "%f", rss->warmth);
+	if (mask & MASK_TINT)
+		xmlTextWriterWriteFormatElement(writer, BAD_CAST "tint", "%f", rss->tint);
+	if (mask & MASK_SHARPEN)
+		xmlTextWriterWriteFormatElement(writer, BAD_CAST "sharpen", "%f", rss->sharpen);
+	if (mask & MASK_DENOISE_LUMA)
+		xmlTextWriterWriteFormatElement(writer, BAD_CAST "denoise_luma", "%f", rss->denoise_luma);
+	if (mask & MASK_DENOISE_CHROMA)
+		xmlTextWriterWriteFormatElement(writer, BAD_CAST "denoise_chroma", "%f", rss->denoise_chroma);
+	if (mask & MASK_CHANNELMIXER)
+	{
+		xmlTextWriterWriteFormatElement(writer, BAD_CAST "channelmixer_red", "%f", rss->channelmixer_red);
+		xmlTextWriterWriteFormatElement(writer, BAD_CAST "channelmixer_green", "%f", rss->channelmixer_green);
+		xmlTextWriterWriteFormatElement(writer, BAD_CAST "channelmixer_blue", "%f", rss->channelmixer_blue);
+	}
+	if (mask & MASK_TCA_KR)
+		xmlTextWriterWriteFormatElement(writer, BAD_CAST "tca_kr", "%f", rss->tca_kr);
+	if (mask & MASK_TCA_KB)
+		xmlTextWriterWriteFormatElement(writer, BAD_CAST "tca_kb", "%f", rss->tca_kb);
+	if (mask & MASK_VIGNETTING_K2)
+		xmlTextWriterWriteFormatElement(writer, BAD_CAST "vignetting_k2", "%f", rss->vignetting_k2);
+	if (mask & MASK_CURVE && rss->curve_nknots > 0)
+	{
+		gint i;
+		xmlTextWriterStartElement(writer, BAD_CAST "curve");
+		xmlTextWriterWriteFormatAttribute(writer, BAD_CAST "num", "%d", rss->curve_nknots);
+		for(i=0;i<rss->curve_nknots;i++)
+			xmlTextWriterWriteFormatElement(writer, BAD_CAST "knot", "%f %f",
+				rss->curve_knots[i*2+0],
+				rss->curve_knots[i*2+1]);
+		xmlTextWriterEndElement(writer);
+	}
+}
+
+guint
 rs_cache_load_setting(RSSettings *rss, xmlDocPtr doc, xmlNodePtr cur, gint version)
 {
 	RSSettingsMask mask = 0;

Modified: branches/rawstudio-ng-color/src/rs-cache.h
===================================================================
--- branches/rawstudio-ng-color/src/rs-cache.h	2010-01-16 00:42:13 UTC (rev 2999)
+++ branches/rawstudio-ng-color/src/rs-cache.h	2010-01-16 07:54:05 UTC (rev 3000)
@@ -20,9 +20,13 @@
 #ifndef RS_CACHE_H
 #define RS_CACHE_H
 
+#include <libxml/xmlwriter.h>
+
 extern gchar *rs_cache_get_name(const gchar *src);
 extern void rs_cache_save(RS_PHOTO *photo, const RSSettingsMask mask);
+extern void rs_cache_save_settings(RSSettings *rss, const RSSettingsMask mask, xmlTextWriterPtr writer);
 extern guint rs_cache_load(RS_PHOTO *photo);
+extern guint rs_cache_load_setting(RSSettings *rss, xmlDocPtr doc, xmlNodePtr cur, gint version);
 extern void rs_cache_load_quick(const gchar *filename, gint *priority, gboolean *exported);
 extern void rs_cache_save_flags(const gchar *filename, const guint *priority, const gboolean *exported);
 

Added: branches/rawstudio-ng-color/src/rs-camera-db.c
===================================================================
--- branches/rawstudio-ng-color/src/rs-camera-db.c	                        (rev 0)
+++ branches/rawstudio-ng-color/src/rs-camera-db.c	2010-01-16 07:54:05 UTC (rev 3000)
@@ -0,0 +1,466 @@
+/*
+ * 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 "config.h"
+#include "gettext.h"
+#include <libxml/encoding.h>
+#include <libxml/xmlwriter.h>
+#include "rs-camera-db.h"
+#include "rs-photo.h"
+#include "rs-toolbox.h"
+#include "rs-cache.h"
+
+/* FIXME: Make this thread safe! */
+
+struct _RSCameraDb {
+	GObject parent;
+
+	gchar *path;
+	GtkListStore *cameras;
+};
+
+enum {
+	COLUMN_MAKE,
+	COLUMN_MODEL,
+	COLUMN_PROFILE,
+	COLUMN_SETTINGS0,
+	COLUMN_SETTINGS1,
+	COLUMN_SETTINGS2,
+	NUM_COLUMNS
+};
+
+G_DEFINE_TYPE(RSCameraDb, rs_camera_db, G_TYPE_OBJECT)
+
+static void load_db(RSCameraDb *db);
+static void save_db(RSCameraDb *db);
+
+enum {
+	PROP_0,
+	PROP_PATH
+};
+
+static void
+get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
+{
+	RSCameraDb *camera_db = RS_CAMERA_DB(object);
+
+	switch (property_id)
+	{
+		case PROP_PATH:
+			g_value_set_string(value, camera_db->path);
+			break;
+		default:
+			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+	}
+}
+
+static void
+set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
+{
+	RSCameraDb *camera_db = RS_CAMERA_DB(object);
+
+	switch (property_id)
+	{
+		case PROP_PATH:
+			camera_db->path = g_value_dup_string(value);
+			load_db(camera_db);
+			break;
+		default:
+			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+	}
+}
+
+static void
+dispose(GObject *object)
+{
+	G_OBJECT_CLASS(rs_camera_db_parent_class)->dispose(object);
+}
+
+static void
+rs_camera_db_class_init(RSCameraDbClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS(klass);
+
+	object_class->get_property = get_property;
+	object_class->set_property = set_property;
+	object_class->dispose = dispose;
+
+	g_object_class_install_property(object_class,
+		PROP_PATH, g_param_spec_string(
+		"path", "Path", "Path to XML database",
+		NULL, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
+}
+
+static void
+rs_camera_db_init(RSCameraDb *camera_db)
+{
+	camera_db->cameras = gtk_list_store_new(NUM_COLUMNS,
+		G_TYPE_STRING, /* COLUMN_MAKE */
+		G_TYPE_STRING, /* COLUMN_MODEL */
+		G_TYPE_POINTER, /* COLUMN_PROFILE */
+		RS_TYPE_SETTINGS, /* COLUMN_SETTINGS0 */
+		RS_TYPE_SETTINGS, /* COLUMN_SETTINGS1 */
+		RS_TYPE_SETTINGS /* COLUMN_SETTINGS2 */
+	);
+}
+
+RSCameraDb *
+rs_camera_db_new(const char *path)
+{
+	g_assert(path != NULL);
+	g_assert(g_path_is_absolute(path));
+
+	return g_object_new (RS_TYPE_CAMERA_DB, "path", path, NULL);
+}
+
+RSCameraDb *
+rs_camera_db_get_singleton(void)
+{
+	static RSCameraDb *camera_db = NULL;
+	static GStaticMutex lock = G_STATIC_MUTEX_INIT;
+
+	g_static_mutex_lock(&lock);
+	if (!camera_db)
+	{
+		gchar *path = g_build_filename(rs_confdir_get(), "camera-database.xml", NULL);
+		camera_db = rs_camera_db_new(path);
+		g_free(path);
+	}
+	g_static_mutex_unlock(&lock);
+
+	return camera_db;
+}
+
+static void
+camera_db_add_camera(RSCameraDb *camera_db, const gchar *make, const gchar *model)
+{
+	GtkTreeIter iter;
+
+	gtk_list_store_append(camera_db->cameras, &iter);
+
+	gtk_list_store_set(camera_db->cameras, &iter,
+		COLUMN_MAKE, make,
+		COLUMN_MODEL, model,
+		-1);
+
+	save_db(camera_db);
+}
+
+void
+rs_camera_db_save_defaults(RSCameraDb *camera_db, RS_PHOTO *photo)
+{
+	g_return_if_fail(RS_IS_PHOTO(photo));
+	g_return_if_fail(RS_IS_METADATA(photo->metadata));
+
+	gboolean found = FALSE;
+	gint snapshot;
+	gchar *db_make, *db_model;
+	const gchar *needle_make = photo->metadata->make_ascii;
+	const gchar *needle_model = photo->metadata->model_ascii;
+
+	GtkTreeIter iter;
+	GtkTreeModel *model = GTK_TREE_MODEL(camera_db->cameras);
+
+	if (needle_make && needle_model && gtk_tree_model_get_iter_first(model, &iter))
+		do {
+			gtk_tree_model_get(model, &iter,
+				COLUMN_MAKE, &db_make,
+				COLUMN_MODEL, &db_model,
+				-1);
+			if (db_make && db_model && g_str_equal(needle_make, db_make) && g_str_equal(needle_model, db_model))
+			{
+				gpointer profile = rs_photo_get_dcp_profile(photo); /* FIXME: Support ICC profiles */
+
+				gtk_list_store_set(camera_db->cameras, &iter,
+					COLUMN_PROFILE, profile,
+					-1);
+
+				RSSettings *settings[3];
+
+				for(snapshot=0;snapshot<3;snapshot++)
+				{
+					settings[snapshot] = rs_settings_new();
+					rs_settings_copy(photo->settings[snapshot], MASK_ALL, settings[snapshot]);
+					gtk_list_store_set(camera_db->cameras, &iter,
+						COLUMN_SETTINGS0 + snapshot, settings[snapshot],
+						-1);
+					g_object_unref(settings[snapshot]);
+				}
+
+				found = TRUE;
+			}
+			g_free(db_make);
+			g_free(db_model);
+		} while (!found && gtk_tree_model_iter_next(model, &iter));
+
+	save_db(camera_db);
+}
+
+gboolean
+rs_camera_db_photo_set_defaults(RSCameraDb *camera_db, RS_PHOTO *photo)
+{
+	g_return_val_if_fail(RS_IS_PHOTO(photo), FALSE);
+	g_return_val_if_fail(RS_IS_METADATA(photo->metadata), FALSE);
+
+	gboolean found = FALSE;
+
+	gchar *db_make, *db_model;
+	const gchar *needle_make = photo->metadata->make_ascii;
+	const gchar *needle_model = photo->metadata->model_ascii;
+
+	GtkTreeIter iter;
+	GtkTreeModel *model = GTK_TREE_MODEL(camera_db->cameras);
+
+	if (needle_make && needle_model && gtk_tree_model_get_iter_first(model, &iter))
+		do {
+			gtk_tree_model_get(model, &iter,
+				COLUMN_MAKE, &db_make,
+				COLUMN_MODEL, &db_model,
+				-1);
+			if (db_make && db_model && g_str_equal(needle_make, db_make) && g_str_equal(needle_model, db_model))
+			{
+				gint i;
+				gpointer p;
+				RSSettings *s[3];
+
+				gtk_tree_model_get(model, &iter,
+					COLUMN_PROFILE, &p,
+					COLUMN_SETTINGS0, &s[0],
+					COLUMN_SETTINGS1, &s[1],
+					COLUMN_SETTINGS2, &s[2],
+					-1);
+
+				if (RS_IS_DCP_FILE(p))
+					rs_photo_set_dcp_profile(photo, p);
+				/* FIXME: support ICC */
+
+				for(i=0;i<3;i++)
+					if (RS_IS_SETTINGS(s[0]))
+					    {
+							rs_settings_copy(s[i], MASK_ALL, photo->settings[i]);
+							g_object_unref(s[i]);
+						}
+
+				found = TRUE;
+			}
+			g_free(db_make);
+			g_free(db_model);
+		} while (!found && gtk_tree_model_iter_next(model, &iter));
+
+	if (!found)
+		camera_db_add_camera(camera_db, needle_make, needle_model);
+
+	return found;
+}
+
+static void
+load_db(RSCameraDb *camera_db)
+{
+	xmlDocPtr doc;
+	xmlNodePtr cur;
+	xmlNodePtr entry = NULL;
+	xmlChar *val;
+
+	doc = xmlParseFile(camera_db->path);
+	if (!doc)
+		return;
+
+	cur = xmlDocGetRootElement(doc);
+	if (cur && (xmlStrcmp(cur->name, BAD_CAST "rawstudio-camera-database") == 0))
+	{
+		cur = cur->xmlChildrenNode;
+		while(cur)
+		{
+			if ((!xmlStrcmp(cur->name, BAD_CAST "camera")))
+			{
+				GtkTreeIter iter;
+
+				gtk_list_store_append(camera_db->cameras, &iter);
+
+				entry = cur->xmlChildrenNode;
+
+				while (entry)
+				{
+					val = xmlNodeListGetString(doc, entry->xmlChildrenNode, 1);
+					if ((!xmlStrcmp(entry->name, BAD_CAST "make")))
+						gtk_list_store_set(camera_db->cameras, &iter, COLUMN_MAKE, val, -1);
+					else if ((!xmlStrcmp(entry->name, BAD_CAST "model")))
+						gtk_list_store_set(camera_db->cameras, &iter, COLUMN_MODEL, val, -1);
+					xmlFree(val);
+					
+					if ((!xmlStrcmp(cur->name, BAD_CAST "settings")))
+					{
+						val = xmlGetProp(cur, BAD_CAST "id");
+						gint id = atoi((gchar *) val);
+						xmlFree(val);
+						id = CLAMP(id, 0, 2);
+						RSSettings *settings = rs_settings_new();
+						rs_cache_load_setting(settings, doc, cur->xmlChildrenNode, 100); /* FIXME: Correct version somehow! */
+						gtk_list_store_set(camera_db->cameras, &iter, COLUMN_SETTINGS0 + id, settings, -1);
+						g_object_unref(settings);
+					}
+					entry = entry->next;
+				}
+			}
+			cur = cur->next;
+		}
+	}
+	else
+		g_warning(PACKAGE " did not understand the format in %s", camera_db->path);
+
+	xmlFreeDoc(doc);
+}
+
+static void
+save_db(RSCameraDb *camera_db)
+{
+	xmlTextWriterPtr writer;
+	gint snapshot;
+	gchar *db_make, *db_model;
+	gpointer profile;
+	RSSettings *settings[3];
+	GtkTreeIter iter;
+	GtkTreeModel *model = GTK_TREE_MODEL(camera_db->cameras);
+
+	writer = xmlNewTextWriterFilename(camera_db->path, 0);
+	if (!writer)
+		return;
+
+	xmlTextWriterSetIndent(writer, 1);
+	xmlTextWriterStartDocument(writer, NULL, "ISO-8859-1", NULL);
+	xmlTextWriterStartElement(writer, BAD_CAST "rawstudio-camera-database");
+
+	if (gtk_tree_model_get_iter_first(model, &iter))
+		do {
+			gtk_tree_model_get(model, &iter,
+				COLUMN_MAKE, &db_make,
+				COLUMN_MODEL, &db_model,
+				COLUMN_PROFILE, &profile,
+				COLUMN_SETTINGS0, &settings[0],
+				COLUMN_SETTINGS1, &settings[1],
+				COLUMN_SETTINGS2, &settings[2],
+				-1);
+
+			xmlTextWriterStartElement(writer, BAD_CAST "camera");
+
+			if (db_make)
+				xmlTextWriterWriteFormatElement(writer, BAD_CAST "make", "%s", db_make);
+			if (db_model)
+				xmlTextWriterWriteFormatElement(writer, BAD_CAST "model", "%s", db_model);
+
+			if (profile)
+			{
+				if (RS_IS_DCP_FILE(profile))
+					xmlTextWriterWriteFormatElement(writer, BAD_CAST "dcp-profile", "%s", rs_tiff_get_filename(RS_TIFF(profile)));
+				/* FIXME: Add support for ICC profiles */
+			}
+
+			for(snapshot=0;snapshot<3;snapshot++)
+				if (RS_IS_SETTINGS(settings[snapshot]))
+				    {
+						xmlTextWriterStartElement(writer, BAD_CAST "settings");
+						xmlTextWriterWriteFormatAttribute(writer, BAD_CAST "id", "%d", snapshot);
+						rs_cache_save_settings(settings[snapshot], MASK_ALL-MASK_WB, writer);
+						xmlTextWriterEndElement(writer);
+						g_object_unref(settings[snapshot]);
+					}
+
+			xmlTextWriterEndElement(writer);
+
+			g_free(db_make);
+			g_free(db_model);
+		} while (gtk_tree_model_iter_next(model, &iter));
+
+	xmlTextWriterEndDocument(writer);
+	xmlFreeTextWriter(writer);
+
+	return;
+}
+
+static void
+icon_func(GtkTreeViewColumn *tree_column, GtkCellRenderer *cell, GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
+{
+	/* This will always be called from the GTK+ main thread, we should be safe */
+	static GdkPixbuf *pixbuf = NULL;
+
+	if (!pixbuf)
+		pixbuf = gdk_pixbuf_new_from_file(PACKAGE_DATA_DIR "/pixmaps/" PACKAGE "/camera-photo.png", NULL);
+
+	g_object_set(cell, "pixbuf", pixbuf, NULL);
+}
+
+GtkWidget *
+rs_camera_db_editor_new(RSCameraDb *camera_db)
+{
+	GtkWidget *dialog = NULL;
+
+	if (dialog)
+		return dialog;
+
+	dialog = gtk_dialog_new();
+
+	gtk_window_set_title(GTK_WINDOW(dialog), _("Camera defaults editor"));
+	gtk_window_set_type_hint(GTK_WINDOW(dialog), GDK_WINDOW_TYPE_HINT_DIALOG);
+	gtk_window_set_destroy_with_parent(GTK_WINDOW(dialog), TRUE);
+
+	gtk_dialog_set_has_separator (GTK_DIALOG(dialog), FALSE);
+
+	/* Is this wise? */
+	g_signal_connect_swapped(dialog, "delete_event", G_CALLBACK (gtk_widget_hide), dialog);
+	g_signal_connect_swapped(dialog, "response", G_CALLBACK (gtk_widget_hide), dialog);
+
+#if GTK_CHECK_VERSION(2,14,0)
+	GtkWidget *vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
+#else
+	GtkWidget *vbox = GTK_DIALOG(dialog)->vbox;
+#endif
+
+	GtkWidget *camera_selector = gtk_tree_view_new_with_model(GTK_TREE_MODEL(camera_db->cameras));
+
+    GtkCellRenderer *renderer;
+    GtkTreeViewColumn *column;
+	
+	column = gtk_tree_view_column_new();
+	gtk_tree_view_column_set_title (column, _("Model"));
+
+	/* Icon */
+	renderer = gtk_cell_renderer_pixbuf_new();
+	gtk_tree_view_column_pack_start (column, renderer, FALSE);
+	gtk_tree_view_column_set_cell_data_func(column, renderer, icon_func, NULL, NULL);
+
+	/* Model */
+	renderer = gtk_cell_renderer_text_new();
+	gtk_tree_view_column_pack_start(column, renderer, TRUE);
+	gtk_tree_view_column_set_attributes(column, renderer, "text", COLUMN_MODEL, NULL);
+
+	gtk_tree_view_append_column(GTK_TREE_VIEW(camera_selector), column);
+
+	gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(camera_db->cameras), COLUMN_MODEL, GTK_SORT_ASCENDING);
+
+	GtkWidget *hbox = gtk_hbox_new(FALSE, 4);
+
+	gtk_box_pack_start(GTK_BOX(hbox), camera_selector, FALSE, FALSE, 3);
+
+	GtkWidget *toolbox = rs_toolbox_new();
+	gtk_box_pack_start(GTK_BOX(hbox), toolbox, TRUE, TRUE, 3);
+
+	gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 3);
+
+	return dialog;
+}

Added: branches/rawstudio-ng-color/src/rs-camera-db.h
===================================================================
--- branches/rawstudio-ng-color/src/rs-camera-db.h	                        (rev 0)
+++ branches/rawstudio-ng-color/src/rs-camera-db.h	2010-01-16 07:54:05 UTC (rev 3000)
@@ -0,0 +1,53 @@
+/*
+ * 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_CAMERA_DB_H
+#define RS_CAMERA_DB_H
+
+#include <glib-object.h>
+#include "application.h"
+
+G_BEGIN_DECLS
+
+#define RS_TYPE_CAMERA_DB rs_camera_db_get_type()
+#define RS_CAMERA_DB(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RS_TYPE_CAMERA_DB, RSCameraDb))
+#define RS_CAMERA_DB_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RS_TYPE_CAMERA_DB, RSCameraDbClass))
+#define RS_IS_CAMERA_DB(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RS_TYPE_CAMERA_DB))
+#define RS_IS_CAMERA_DB_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RS_TYPE_CAMERA_DB))
+#define RS_CAMERA_DB_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RS_TYPE_CAMERA_DB, RSCameraDbClass))
+
+typedef struct _RSCameraDb RSCameraDb;
+
+typedef struct {
+	GObjectClass parent_class;
+} RSCameraDbClass;
+
+GType rs_camera_db_get_type(void);
+
+RSCameraDb *rs_camera_db_new(const gchar *path);
+
+RSCameraDb *rs_camera_db_get_singleton(void);
+
+void rs_camera_db_save_defaults(RSCameraDb *camera_db, RS_PHOTO *photo);
+
+gboolean rs_camera_db_photo_set_defaults(RSCameraDb *camera_db, RS_PHOTO *photo);
+
+G_END_DECLS
+
+#endif /* RS_CAMERA_DB_H */

Modified: branches/rawstudio-ng-color/src/rs-photo.c
===================================================================
--- branches/rawstudio-ng-color/src/rs-photo.c	2010-01-16 00:42:13 UTC (rev 2999)
+++ branches/rawstudio-ng-color/src/rs-photo.c	2010-01-16 07:54:05 UTC (rev 3000)
@@ -20,6 +20,7 @@
 #include <rawstudio.h>
 #include "rs-photo.h"
 #include "rs-cache.h"
+#include "rs-camera-db.h"
 
 static void rs_photo_class_init (RS_PHOTOClass *klass);
 
@@ -581,6 +582,9 @@
 			}
 		}
 
+		/* Load defaults */
+		rs_camera_db_photo_set_defaults(rs_camera_db_get_singleton(), photo);
+
 		/* Load cache */
 		mask = rs_cache_load(photo);
 		/* If we have no cache, try to set some sensible defaults */

Modified: branches/rawstudio-ng-color/src/ui.xml
===================================================================
--- branches/rawstudio-ng-color/src/ui.xml	2010-01-16 00:42:13 UTC (rev 2999)
+++ branches/rawstudio-ng-color/src/ui.xml	2010-01-16 07:54:05 UTC (rev 3000)
@@ -14,6 +14,7 @@
    <menuitem action="CopySettings" />
    <menuitem action="PasteSettings" />
    <menuitem action="ResetSettings" />
+   <menuitem action="SaveDefaultSettings" />
    <separator />
    <menuitem action="Preferences" />
   </menu>




More information about the Rawstudio-commit mailing list