The following adds "Restore", "P1".."P4" buttons at the left side of
the zoom buttons under the preview window. The Options dialog now has 5
buttons for saving "Configuration" and "P1".."P4". The new buttons only
save image manipulation parameters. The "Restore" button resets the image
manipulation parameters to what they were at the start for the image.

The configuration data for P1..P4 is kept in $HOME/.ufraw-P<num>.

Maybe the restore/preset buttons should contain some GUI parameters too
such as for controlling non-manual WB settings.


diff --git a/ufraw.h b/ufraw.h
index 96dcca8..747c5e9 100644
--- a/ufraw.h
+++ b/ufraw.h
@@ -21,6 +21,8 @@
 #include <time.h> // for time_t
 #include "dcraw_api.h"
 
+#define ARRAYSIZE(x) ((int)(sizeof (x) / sizeof ((x)[0])))
+
 /* macro to clamp a number between two values */
 #ifndef LIM
 #define LIM(x,min,max) MAX(min,MIN(x,max))
@@ -374,7 +376,7 @@ void ptr_array_insert_index (GPtrArray *array, const void 
*item, int index);
 
 /* prototypes for functions in ufraw_conf.c */
 int conf_load(conf_data *c, const char *confFilename);
-int conf_save(conf_data *c, char *confFilename, char **confBuffer);
+int conf_save(conf_data *c, char *confFilename, char **confBuffer, gboolean 
preset);
 /* copy default config to given instance and initialize non-const fields */
 void conf_init (conf_data *c);
 /* Copy the image manipulation options from *src to *dst */
diff --git a/ufraw_conf.c b/ufraw_conf.c
index ac0a848..7dfffd3 100644
--- a/ufraw_conf.c
+++ b/ufraw_conf.c
@@ -814,7 +814,7 @@ int conf_load(conf_data *c, const char *IDFilename)
     return UFRAW_SUCCESS;
 }
 
-int conf_save(conf_data *c, char *IDFilename, char **confBuffer)
+int conf_save(conf_data *c, char *IDFilename, char **confBuffer, gboolean 
preset)
 {
     char *buf=NULL;
     int i, j;
@@ -823,17 +823,17 @@ int conf_save(conf_data *c, char *IDFilename, char 
**confBuffer)
 
     buf = uf_markup_buf(buf, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
     buf = uf_markup_buf(buf, "<UFRaw Version='%d'>\n", c->version);
-    if (strlen(c->inputFilename)>0 && IDFilename!=NULL) {
+    if (strlen(c->inputFilename)>0 && IDFilename!=NULL && !preset) {
        char *utf8 = g_filename_display_name(c->inputFilename);
        buf = uf_markup_buf(buf, "<InputFilename>%s</InputFilename>\n", utf8);
        g_free(utf8);
     }
-    if (strlen(c->outputFilename)>0 && IDFilename!=NULL) {
+    if (strlen(c->outputFilename)>0 && IDFilename!=NULL && !preset) {
        char *utf8=g_filename_display_name(c->outputFilename);
        buf = uf_markup_buf(buf, "<OutputFilename>%s</OutputFilename>\n", utf8);
        g_free(utf8);
     }
-    if (strlen(c->outputPath)>0) {
+    if (strlen(c->outputPath)>0 && !preset) {
        char *utf8=g_filename_display_name(c->outputPath);
        buf = uf_markup_buf(buf, "<OutputPath>%s</OutputPath>\n", utf8);
        g_free(utf8);
@@ -1133,7 +1133,7 @@ int conf_save(conf_data *c, char *IDFilename, char 
**confBuffer)
      * to know if the WB setting is relevant */
     buf = uf_markup_buf(buf, "<Make>%s</Make>\n", c->make);
     buf = uf_markup_buf(buf, "<Model>%s</Model>\n", c->model);
-    if (IDFilename!=NULL) {
+    if (IDFilename!=NULL && !preset) {
        if (strcmp(c->darkframeFile, conf_default.darkframeFile)!=0)
            buf = uf_markup_buf(buf,
                    "<DarkframeFile>%s</DarkframeFile>\n", c->darkframeFile);
diff --git a/ufraw_preview.c b/ufraw_preview.c
index 38161a3..fd3c615 100644
--- a/ufraw_preview.c
+++ b/ufraw_preview.c
@@ -72,6 +72,14 @@ static const char *grayscaleModeNames[5] = {
     N_("Channel Mixer")
 };
 
+struct preset {
+    char *name;
+    char *idfile;
+    char *tooltip_load;
+    char *tooltip_save;
+};
+static struct preset presets[4];
+
 preview_data *get_preview_data(void *object)
 {
     GtkWidget *widget;
@@ -219,7 +227,7 @@ static void load_curve(GtkWidget *widget, long curveType)
            cp = g_path_get_dirname(list->data);
            g_strlcpy(CFG->curvePath, cp, max_path);
            g_strlcpy(RC->curvePath, cp, max_path);
-           conf_save(RC, NULL, NULL);
+           conf_save(RC, NULL, NULL, FALSE);
            g_free(cp);
            g_free(list->data);
        }
@@ -384,7 +392,7 @@ static void load_profile(GtkWidget *widget, long type)
            /* Add profile to .ufrawrc but don't make it default */
            RC->profile[type][RC->profileCount[type]++] = p;
            g_strlcpy(RC->profilePath, cp, max_path);
-           conf_save(RC, NULL, NULL);
+           conf_save(RC, NULL, NULL, FALSE);
            g_free(cp);
            g_free(list->data);
        }
@@ -1442,11 +1450,11 @@ static void update_scales(preview_data *data)
     gtk_widget_set_sensitive(data->ResetWBButton,
            ( strcmp(CFG->wb, data->initialWB)
            ||fabs(CFG->temperature-data->initialTemperature)>1
-           ||fabs(CFG->green-data->initialGreen)>0.001
-           ||CFG->chanMul[0]!=data->initialChanMul[0]
-           ||CFG->chanMul[1]!=data->initialChanMul[1]
-           ||CFG->chanMul[2]!=data->initialChanMul[2]
-           ||CFG->chanMul[3]!=data->initialChanMul[3] ) );
+           ||fabs(CFG->green-data->initialGreen)>0.000001
+           ||fabs(CFG->chanMul[0]-data->initialChanMul[0]) > 0.000001
+           ||fabs(CFG->chanMul[1]-data->initialChanMul[1]) > 0.000001
+           ||fabs(CFG->chanMul[2]-data->initialChanMul[2]) > 0.000001
+           ||fabs(CFG->chanMul[3]-data->initialChanMul[3]) > 0.000001 ) );
     gtk_widget_set_sensitive(data->ResetGammaButton,
            fabs( profile_default_gamma(&CFG->profile[0][CFG->profileIndex[0]])
                - CFG->profile[0][CFG->profileIndex[0]].gamma) > 0.001);
@@ -3218,11 +3226,39 @@ static void delete_from_list(GtkWidget *widget, 
gpointer user_data)
     gtk_dialog_response(dialog, GTK_RESPONSE_APPLY);
 }
 
+static void preset_load(GtkWidget *widget, gpointer user_data)
+{
+    preview_data *data = get_preview_data(widget);
+    char *idfile = (char *)user_data;
+    int status = UFRAW_SUCCESS;
+    conf_data c;
+
+    if (idfile)
+       status = conf_load(&c, idfile);
+    else
+       c = data->restore_image;
+    if (status == UFRAW_SUCCESS) {
+       conf_copy_image(data->UF->conf, &c);
+       /* TODO: invalidate denoise/first layer, see 100% zoom work */
+       preview_invalidate_layer(data, ufraw_develop_phase);
+       update_scales(data);
+    }
+}
+
+static void preset_save(GtkWidget *widget, gpointer user_data)
+{
+    preview_data *data = get_preview_data(widget);
+    char *idfile = (char *)user_data;
+    conf_data c = *data->UF->conf;
+
+    conf_save(&c, idfile, NULL, TRUE);
+}
+
 static void configuration_save(GtkWidget *widget, gpointer user_data)
 {
     preview_data *data = get_preview_data(widget);
     user_data = user_data;
-    conf_save(CFG, NULL, NULL);
+    conf_save(CFG, NULL, NULL, FALSE);
     *RC = *data->UF->conf;
 }
 
@@ -3323,12 +3359,22 @@ static void options_dialog(GtkWidget *widget, gpointer 
user_data)
 
     GtkWidget *hBox = gtk_hbox_new(FALSE, 0);
     gtk_box_pack_start(GTK_BOX(box), hBox, FALSE, FALSE, 0);
-    button = gtk_button_new_with_label(_("Save configuration"));
+
+    label = gtk_label_new(_("Save"));
+    gtk_box_pack_start(GTK_BOX(hBox), label, FALSE, FALSE, 6);
+    button = gtk_button_new_with_label(_("Configuration"));
     gtk_box_pack_start(GTK_BOX(hBox), button, FALSE, FALSE, 0);
     uf_widget_set_tooltip(button,
            _("Save configuration to resource file ($HOME/.ufrawrc)"));
     g_signal_connect(G_OBJECT(button), "clicked",
            G_CALLBACK(configuration_save), NULL);
+    for (i = 0; i < ARRAYSIZE(presets); ++i) {
+       button = gtk_button_new_with_label(_(presets[i].name));
+       gtk_box_pack_start(GTK_BOX(hBox), button, FALSE, FALSE, 0);
+       uf_widget_set_tooltip(button, presets[i].tooltip_save);
+       g_signal_connect(G_OBJECT(button), "clicked",
+               G_CALLBACK(preset_save), presets[i].idfile);
+    }
 
     label = gtk_label_new(_("Log"));
     page = gtk_scrolled_window_new(NULL, NULL);
@@ -3408,7 +3454,7 @@ static void options_dialog(GtkWidget *widget, gpointer 
user_data)
                    G_CALLBACK(delete_from_list), (gpointer)i);
            gtk_table_attach(curveTable, button, 1, 2, i, i+1, 0, 0, 0, 0);
        }
-       conf_save(CFG, NULL, &buf);
+       conf_save(CFG, NULL, &buf, FALSE);
        gtk_text_buffer_set_text(confBuffer, buf, -1);
        g_free(buf);
        gtk_widget_show_all(optionsDialog);
@@ -3460,7 +3506,7 @@ static void options_dialog(GtkWidget *widget, gpointer 
user_data)
                    RC->profile[i][j] = CFG->profile[i][j];
                RC->profileCount[i] = CFG->profileCount[i];
            }
-           conf_save(RC, NULL, NULL);
+           conf_save(RC, NULL, NULL, FALSE);
        } else { /* response==GTK_RESPONSE_CANCEL or window closed */
            /* Copy profiles and curves from RC to CFG */
 
@@ -5075,6 +5121,7 @@ int ufraw_preview(ufraw_data *uf, conf_data *rc, int 
plugin,
     int status, curveeditorHeight;
     preview_data PreviewData;
     preview_data *data = &PreviewData;
+    const char *hd = uf_get_home_dir();
 
     /* Fill the whole structure with zeros, to avoid surprises */
     memset(&PreviewData, 0, sizeof(PreviewData));
@@ -5334,9 +5381,33 @@ int ufraw_preview(ufraw_data *uf, conf_data *rc, int 
plugin,
     gtk_box_pack_start(GTK_BOX(vBox), GTK_WIDGET(data->ProgressBar),
            FALSE, FALSE, 0);
 
-    /* Control buttons at the bottom */
+    /* Start of control buttons. They are at the bottom */
     GtkBox *ControlsBox = GTK_BOX(gtk_hbox_new(FALSE, 6));
     gtk_box_pack_start(GTK_BOX(vBox), GTK_WIDGET(ControlsBox), FALSE, FALSE, 
6);
+
+    // Restore and the preset buttons are aligned to the left
+    box = GTK_BOX(gtk_hbox_new(FALSE, 0));
+    gtk_box_pack_start(GTK_BOX(ControlsBox), GTK_WIDGET(box), FALSE, FALSE, 0);
+    button = gtk_button_new_with_label(_("Restore"));
+    gtk_box_pack_start(box, button, FALSE, FALSE, 0);
+    uf_widget_set_tooltip(button, _("Restore image manipulation parameters"));
+    g_signal_connect(G_OBJECT(button), "clicked",
+           G_CALLBACK(preset_load), NULL);
+    for (i = 0; i < ARRAYSIZE(presets); ++i) {
+       struct preset *p = presets + i;
+       char buf[80];
+       p->name = g_strdup_printf("P%d", i + 1);
+       sprintf(buf, ".ufraw-%s", p->name);
+       p->idfile = g_build_filename(hd, buf, NULL);
+       p->tooltip_load = g_strdup_printf(_("Load image manipulation parameters 
from $HOME/%s"), buf);
+       p->tooltip_save = g_strdup_printf(_("Save image manipulation parameters 
to $HOME/%s"), buf);
+       button = gtk_button_new_with_label(_(p->name));
+       gtk_box_pack_start(box, button, FALSE, FALSE, 0);
+       uf_widget_set_tooltip(button, p->tooltip_load);
+       g_signal_connect(G_OBJECT(button), "clicked",
+               G_CALLBACK(preset_load), p->idfile);
+    }
+
     // Zoom buttons are centered:
     GtkBox *ZoomBox = GTK_BOX(gtk_hbox_new(FALSE, 0));
     gtk_box_pack_start(ControlsBox, GTK_WIDGET(ZoomBox), TRUE, FALSE, 0);
@@ -5375,7 +5446,7 @@ int ufraw_preview(ufraw_data *uf, conf_data *rc, int 
plugin,
 #endif // HAVE_GTKIMAGEVIEW
 
     // The rest of the control button are aligned to the right
-    box = GTK_BOX(gtk_hbox_new(FALSE, 6));
+    box = GTK_BOX(gtk_hbox_new(FALSE, 0));
     gtk_box_pack_start(GTK_BOX(ControlsBox), GTK_WIDGET(box), FALSE, FALSE, 0);
     /* Options button */
     button = gtk_button_new();
@@ -5480,6 +5551,7 @@ int ufraw_preview(ufraw_data *uf, conf_data *rc, int 
plugin,
     ufraw_load_raw(uf);
     gtk_widget_set_sensitive(data->Controls, TRUE);
 
+    data->restore_image = *data->UF->conf;
     create_base_image(data);
 
     /* Collect raw histogram data */
@@ -5545,21 +5617,21 @@ int ufraw_preview(ufraw_data *uf, conf_data *rc, int 
plugin,
        if ( CFG->saveConfiguration==enabled_state ) {
            /* Save configuration from CFG, but not the output filename. */
            strcpy(CFG->outputFilename, "");
-           conf_save(CFG, NULL, NULL);
+           conf_save(CFG, NULL, NULL, FALSE);
        /* If save 'only this once' was chosen, then so be it */
        } else if ( CFG->saveConfiguration==apply_state ) {
            CFG->saveConfiguration = disabled_state;
            /* Save configuration from CFG, but not the output filename. */
            strcpy(CFG->outputFilename, "");
-           conf_save(CFG, NULL, NULL);
+           conf_save(CFG, NULL, NULL, FALSE);
        } else if ( CFG->saveConfiguration==disabled_state ) {
            /* If save 'never again' was set in this session, we still
             * need to save this setting */
            if ( RC->saveConfiguration!=disabled_state ) {
                RC->saveConfiguration = disabled_state;
-               conf_save(RC, NULL, NULL);
+               conf_save(RC, NULL, NULL, FALSE);
            } else if ( SaveRC ) {
-               conf_save(RC, NULL, NULL);
+               conf_save(RC, NULL, NULL, FALSE);
            }
            strcpy(RC->inputFilename, "");
            strcpy(RC->outputFilename, "");
@@ -5576,6 +5648,12 @@ int ufraw_preview(ufraw_data *uf, conf_data *rc, int 
plugin,
     g_free(data->DevLabels);
     g_free(data->OverLabels);
     g_free(data->UnderLabels);
+    for (i = 0; i < ARRAYSIZE(presets); ++i) {
+       g_free(presets[i].name);
+       g_free(presets[i].idfile);
+       g_free(presets[i].tooltip_load);
+       g_free(presets[i].tooltip_save);
+    }
 
     if (status!=GTK_RESPONSE_OK) return UFRAW_CANCEL;
     return UFRAW_SUCCESS;
diff --git a/ufraw_saver.c b/ufraw_saver.c
index 8b75955..c04338d 100644
--- a/ufraw_saver.c
+++ b/ufraw_saver.c
@@ -91,7 +91,7 @@ long ufraw_send_to_gimp(ufraw_data *uf)
     char *buffer;
     int saveCreateID = uf->conf->createID;
     uf->conf->createID = send_id;
-    conf_save(uf->conf, confFilename, &buffer);
+    conf_save(uf->conf, confFilename, &buffer, FALSE);
     uf->conf->createID = saveCreateID;
     if ( fwrite(buffer, strlen(buffer), 1, out)!=1 ) {
        g_free(buffer);
diff --git a/ufraw_ui.h b/ufraw_ui.h
index 2c67ba4..99826ee 100644
--- a/ufraw_ui.h
+++ b/ufraw_ui.h
@@ -41,7 +41,7 @@ enum { base_curve, luminosity_curve };
 /* All the "global" information is here: */
 typedef struct {
     ufraw_data *UF;
-    conf_data *rc;
+    conf_data *rc, restore_image;
     char initialWB[max_name];
     double initialTemperature, initialGreen;
     double initialChanMul[4];
diff --git a/ufraw_writer.c b/ufraw_writer.c
index 6f8ab1a..94e296f 100644
--- a/ufraw_writer.c
+++ b/ufraw_writer.c
@@ -304,7 +304,7 @@ int ufraw_write_image(ufraw_data *uf)
        }
     }
     if (uf->conf->createID==only_id) {
-       int status = conf_save(uf->conf, confFilename, NULL);
+       int status = conf_save(uf->conf, confFilename, NULL, FALSE);
        g_free(confFilename);
        return status;
     }
@@ -818,7 +818,7 @@ int ufraw_write_image(ufraw_data *uf)
        if ( ufraw_get_message(uf)!=NULL )
            ufraw_message(UFRAW_SET_LOG, ufraw_get_message(uf));
        // TODO: error handling
-       conf_save(uf->conf, confFilename, NULL);
+       conf_save(uf->conf, confFilename, NULL, FALSE);
        g_free(confFilename);
     }
     return ufraw_get_status(uf);


-- 
Frank

------------------------------------------------------------------------------
Come build with us! The BlackBerry&reg; Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay 
ahead of the curve. Join us from November 9&#45;12, 2009. Register now&#33;
http://p.sf.net/sfu/devconf
_______________________________________________
ufraw-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ufraw-devel

Reply via email to