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 <[email protected]> and 
+ * Anders Kvist <[email protected]>
+ *
+ * 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 <[email protected]> and 
+ * Anders Kvist <[email protected]>
+ *
+ * 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>


_______________________________________________
Rawstudio-commit mailing list
[email protected]
http://rawstudio.org/cgi-bin/mailman/listinfo/rawstudio-commit

Reply via email to