diff options
Diffstat (limited to 'src/window.c')
| -rw-r--r-- | src/window.c | 216 |
1 files changed, 162 insertions, 54 deletions
diff --git a/src/window.c b/src/window.c index 529711b..65ef229 100644 --- a/src/window.c +++ b/src/window.c @@ -72,8 +72,156 @@ static void _show_info(GgazeWindow *p_win); static void _hide_info(GgazeWindow *p_win); static gboolean _slideshow_tick(gpointer p_data); #if GGAZE_HAVE_GEGL -static void _enhance_update_highlights(GgazeWindow *p_win); -static void _enhance_panel_reparent(GgazeWindow *p_win, gboolean b_overlay); +static void _enhance_update_highlights(GgazeWindow *p_win); +static void _enhance_panel_reparent(GgazeWindow *p_win, gboolean b_overlay); +static gboolean _enhance_do_save(GgazeWindow *p_win); +#endif + +#if GGAZE_HAVE_GEGL +/* Export the current image with the enabled-preset chain to + * <stem>-enhanced.<ext>. Returns TRUE on success; prints the saved name. */ +static gboolean +_enhance_do_save(GgazeWindow *p_win) { + if (p_win->p_nav == NULL || p_win->p_enhancer == NULL || + p_win->u_enhance_mask == 0) { + return (FALSE); + } + GFile *p_file = navigator_get_current(p_win->p_nav); + if (p_file == NULL) { + return (FALSE); + } + char *c_base = g_file_get_basename(p_file); + char *c_dot = strrchr(c_base, '.'); + const char *c_ext = ".jpg"; + if (c_dot != NULL && (g_ascii_strcasecmp(c_dot, ".jpg") == 0 || + g_ascii_strcasecmp(c_dot, ".jpeg") == 0 || + g_ascii_strcasecmp(c_dot, ".png") == 0 || + g_ascii_strcasecmp(c_dot, ".webp") == 0)) { + c_ext = c_dot; + } + char *c_stem; + if (c_dot != NULL && c_ext == c_dot) { + c_stem = g_strndup(c_base, (gsize)(c_dot - c_base)); + } else { + c_stem = g_strdup(c_base); + } + GFile *p_dir = g_file_get_parent(p_file); + char *c_outname = g_strdup_printf("%s-enhanced%s", c_stem, c_ext); + GFile *p_out = g_file_get_child(p_dir, c_outname); + g_free(c_outname); + g_free(c_stem); + g_free(c_base); + g_object_unref(p_dir); + + GError *p_err = NULL; + GeglBuffer *p_buf = enhancer_load(p_file, &p_err); + gboolean b_ok = FALSE; + if (p_buf != NULL) { + const GPtrArray *p_presets = enhancer_get_presets(p_win->p_enhancer); + b_ok = enhancer_export_chain(p_win->p_enhancer, p_buf, p_presets, + p_win->u_enhance_mask, p_out, &p_err); + g_object_unref(p_buf); + } + char *c_saved = b_ok ? g_file_get_basename(p_out) : NULL; + g_object_unref(p_out); + if (b_ok) { + g_printerr("ggaze: saved %s\n", c_saved); + } else { + g_warning("ggaze: enhance-save failed: %s", + p_err != NULL ? p_err->message : "(no detail)"); + } + g_free(c_saved); + g_clear_error(&p_err); + return (b_ok); +} + +typedef struct { + GgazeWindow *p_win; + GSourceFunc fn; + gpointer data; +} _SaveCtx; + +/* Alert-dialog response: 0=Cancel, 1=Discard, 2=Save. */ +static void +_save_dialog_cb(GObject *p_dlg, GAsyncResult *p_res, gpointer p_data) { + _SaveCtx *p_ctx = (_SaveCtx *)p_data; + GgazeWindow *p_win = p_ctx->p_win; + GError *p_err = NULL; + gint i_btn = + gtk_alert_dialog_choose_finish(GTK_ALERT_DIALOG(p_dlg), p_res, &p_err); + g_object_unref(GTK_ALERT_DIALOG(p_dlg)); + if (p_err != NULL) { /* dismissed / error -> treat as Cancel */ + g_clear_error(&p_err); + g_free(p_ctx); + return; + } + if (i_btn == 2) { /* Save */ + _enhance_do_save(p_win); + } + if (i_btn == 1 || i_btn == 2) { /* Discard or Save: clear + proceed */ + p_win->u_enhance_mask = 0; + _enhance_update_highlights(p_win); + _update_header(p_win); + if (p_ctx->fn != NULL) { + p_ctx->fn(p_ctx->data); + } + } /* Cancel: keep the preview, do not navigate. */ + g_free(p_ctx); +} + +/* If an enhance preview is active (unsaved), ask Save / Discard / Cancel + * before proceeding with fn. If no preview, just run fn. */ +static void +_maybe_save_then(GgazeWindow *p_win, GSourceFunc fn, gpointer data) { + if (p_win->u_enhance_mask == 0 || p_win->p_enhancer == NULL) { + if (fn != NULL) { + fn(data); + } + return; + } + GtkAlertDialog *p_dlg = + gtk_alert_dialog_new("Save the enhanced copy before leaving this image?"); + static const char *const c_btns[] = {"Cancel", "Discard", "Save", NULL}; + gtk_alert_dialog_set_buttons(p_dlg, c_btns); + gtk_alert_dialog_set_default_button(p_dlg, 2); + gtk_alert_dialog_set_cancel_button(p_dlg, 0); + gtk_alert_dialog_set_modal(p_dlg, TRUE); + _SaveCtx *p_ctx = g_new(_SaveCtx, 1); + p_ctx->p_win = p_win; + p_ctx->fn = fn; + p_ctx->data = data; + gtk_alert_dialog_choose(p_dlg, GTK_WINDOW(p_win), NULL, _save_dialog_cb, + p_ctx); +} + +static gboolean +_proceed_prev(gpointer d) { + ggaze_window_prev(GGAZE_WINDOW(d)); + return (G_SOURCE_REMOVE); +} +static gboolean +_proceed_next(gpointer d) { + ggaze_window_next(GGAZE_WINDOW(d)); + return (G_SOURCE_REMOVE); +} +static gboolean +_proceed_first(gpointer d) { + ggaze_window_first(GGAZE_WINDOW(d)); + return (G_SOURCE_REMOVE); +} +static gboolean +_proceed_last(gpointer d) { + ggaze_window_last(GGAZE_WINDOW(d)); + return (G_SOURCE_REMOVE); +} +#else /* !GGAZE_HAVE_GEGL */ +static void +_maybe_save_then(GgazeWindow *p_win, GSourceFunc fn, gpointer data) { + (void)p_win; + if (fn != NULL) { + fn(data); + } +} #endif /* --- actions ------------------------------------------------------------- */ @@ -82,28 +230,28 @@ static void _action_prev(GSimpleAction *p_a, GVariant *p_v, gpointer p_data) { (void)p_a; (void)p_v; - ggaze_window_prev(GGAZE_WINDOW(p_data)); + _maybe_save_then(GGAZE_WINDOW(p_data), _proceed_prev, p_data); } static void _action_next(GSimpleAction *p_a, GVariant *p_v, gpointer p_data) { (void)p_a; (void)p_v; - ggaze_window_next(GGAZE_WINDOW(p_data)); + _maybe_save_then(GGAZE_WINDOW(p_data), _proceed_next, p_data); } static void _action_first(GSimpleAction *p_a, GVariant *p_v, gpointer p_data) { (void)p_a; (void)p_v; - ggaze_window_first(GGAZE_WINDOW(p_data)); + _maybe_save_then(GGAZE_WINDOW(p_data), _proceed_first, p_data); } static void _action_last(GSimpleAction *p_a, GVariant *p_v, gpointer p_data) { (void)p_a; (void)p_v; - ggaze_window_last(GGAZE_WINDOW(p_data)); + _maybe_save_then(GGAZE_WINDOW(p_data), _proceed_last, p_data); } static void @@ -751,6 +899,13 @@ _build_enhance_panel(GgazeWindow *p_win) { p_win); gtk_box_append(GTK_BOX(p_box), p_btn0); + /* A dim hint that 's' saves the enhanced copy. */ + GtkWidget *p_hint = gtk_label_new("s Save enhanced copy"); + gtk_widget_set_halign(p_hint, GTK_ALIGN_START); + gtk_widget_set_margin_top(p_hint, 8); + gtk_widget_add_css_class(p_hint, "dim-label"); + gtk_box_append(GTK_BOX(p_box), p_hint); + GtkWidget *p_rev = gtk_revealer_new(); gtk_revealer_set_transition_type(GTK_REVEALER(p_rev), GTK_REVEALER_TRANSITION_TYPE_SLIDE_RIGHT); @@ -844,54 +999,7 @@ _action_enhance_save(GSimpleAction *p_a, GVariant *p_v, gpointer p_data) { g_warning("ggaze: nothing to save (no enhance preset enabled)"); return; } - GFile *p_file = navigator_get_current(p_win->p_nav); - if (p_file == NULL) { - return; - } - - /* Build <stem>-enhanced.<ext>; default .jpg for unknown extensions. */ - char *c_base = g_file_get_basename(p_file); - char *c_dot = strrchr(c_base, '.'); - const char *c_ext = ".jpg"; - if (c_dot != NULL && (g_ascii_strcasecmp(c_dot, ".jpg") == 0 || - g_ascii_strcasecmp(c_dot, ".jpeg") == 0 || - g_ascii_strcasecmp(c_dot, ".png") == 0 || - g_ascii_strcasecmp(c_dot, ".webp") == 0)) { - c_ext = c_dot; - } - char *c_stem; - if (c_dot != NULL && c_ext == c_dot) { - c_stem = g_strndup(c_base, (gsize)(c_dot - c_base)); - } else { - c_stem = g_strdup(c_base); - } - GFile *p_dir = g_file_get_parent(p_file); - char *c_outname = g_strdup_printf("%s-enhanced%s", c_stem, c_ext); - GFile *p_out = g_file_get_child(p_dir, c_outname); - g_free(c_outname); - g_free(c_stem); - g_free(c_base); - g_object_unref(p_dir); - - GError *p_err = NULL; - GeglBuffer *p_buf = enhancer_load(p_file, &p_err); - gboolean b_ok = FALSE; - if (p_buf != NULL) { - const GPtrArray *p_presets = enhancer_get_presets(p_win->p_enhancer); - b_ok = enhancer_export_chain(p_win->p_enhancer, p_buf, p_presets, - p_win->u_enhance_mask, p_out, &p_err); - g_object_unref(p_buf); - } - char *c_saved = b_ok ? g_file_get_basename(p_out) : NULL; - g_object_unref(p_out); - if (b_ok) { - g_printerr("ggaze: saved %s\n", c_saved); - } else { - g_warning("ggaze: enhance-save failed: %s", - p_err != NULL ? p_err->message : "(no detail)"); - } - g_free(c_saved); - g_clear_error(&p_err); + _enhance_do_save(p_win); } #else /* !GGAZE_HAVE_GEGL */ static void |
