Refactor SVG save action/dialog to be a general image saving function
This commit is contained in:
parent
93ef0d2263
commit
8e60f5611c
@ -43,6 +43,8 @@ struct _AgChartClass {
|
|||||||
GsweMomentClass parent_class;
|
GsweMomentClass parent_class;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef void (*AgChartSaveImageFunc)(AgChart *, GFile *, GError **);
|
||||||
|
|
||||||
GType ag_chart_get_type(void) G_GNUC_CONST;
|
GType ag_chart_get_type(void) G_GNUC_CONST;
|
||||||
|
|
||||||
AgChart *ag_chart_new_full(GsweTimestamp *timestamp,
|
AgChart *ag_chart_new_full(GsweTimestamp *timestamp,
|
||||||
|
215
src/ag-window.c
215
src/ag-window.c
@ -808,12 +808,12 @@ ag_window_recalculate_chart(AgWindow *window, gboolean set_everything)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ag_window_export_svg(AgWindow *window, GError **err)
|
ag_window_export_image(AgWindow *window, GError **err)
|
||||||
{
|
{
|
||||||
const gchar *name;
|
const gchar *name;
|
||||||
gchar *file_name;
|
|
||||||
GtkWidget *fs;
|
GtkWidget *fs;
|
||||||
gint response;
|
gint response;
|
||||||
|
GError *local_err = NULL;
|
||||||
AgWindowPrivate *priv = ag_window_get_instance_private(window);
|
AgWindowPrivate *priv = ag_window_get_instance_private(window);
|
||||||
|
|
||||||
ag_window_recalculate_chart(window, TRUE);
|
ag_window_recalculate_chart(window, TRUE);
|
||||||
@ -851,41 +851,196 @@ ag_window_export_svg(AgWindow *window, GError **err)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
file_name = g_strdup_printf("%s.svg", name);
|
|
||||||
|
|
||||||
fs = gtk_file_chooser_dialog_new(_("Export Chart as SVG"),
|
fs = gtk_file_chooser_dialog_new(_("Export Chart as SVG"),
|
||||||
GTK_WINDOW(window),
|
GTK_WINDOW(window),
|
||||||
GTK_FILE_CHOOSER_ACTION_SAVE,
|
GTK_FILE_CHOOSER_ACTION_SAVE,
|
||||||
_("_Cancel"), GTK_RESPONSE_CANCEL,
|
_("_Cancel"), GTK_RESPONSE_CANCEL,
|
||||||
_("_Save"), GTK_RESPONSE_ACCEPT,
|
_("_Save"), GTK_RESPONSE_ACCEPT,
|
||||||
NULL);
|
NULL);
|
||||||
|
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(fs), filter_svg);
|
||||||
|
gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(fs), filter_svg);
|
||||||
gtk_dialog_set_default_response(GTK_DIALOG(fs), GTK_RESPONSE_ACCEPT);
|
gtk_dialog_set_default_response(GTK_DIALOG(fs), GTK_RESPONSE_ACCEPT);
|
||||||
gtk_file_chooser_set_local_only(GTK_FILE_CHOOSER(fs), FALSE);
|
gtk_file_chooser_set_local_only(GTK_FILE_CHOOSER(fs), FALSE);
|
||||||
gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(fs), TRUE);
|
// Due to file name modifying later (depending on the file type selection),
|
||||||
gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(fs), file_name);
|
// we must do this manually
|
||||||
g_free(file_name);
|
gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(fs), FALSE);
|
||||||
|
gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(fs), name);
|
||||||
|
|
||||||
response = gtk_dialog_run(GTK_DIALOG(fs));
|
while (TRUE) {
|
||||||
gtk_widget_hide(fs);
|
response = gtk_dialog_run(GTK_DIALOG(fs));
|
||||||
|
gtk_widget_hide(fs);
|
||||||
|
|
||||||
if (response == GTK_RESPONSE_ACCEPT) {
|
if (response == GTK_RESPONSE_ACCEPT) {
|
||||||
GFile *file = gtk_file_chooser_get_file(GTK_FILE_CHOOSER(fs));
|
GFile *file = gtk_file_chooser_get_file(
|
||||||
|
GTK_FILE_CHOOSER(fs)
|
||||||
|
);
|
||||||
|
GtkFileFilter *filter = gtk_file_chooser_get_filter(
|
||||||
|
GTK_FILE_CHOOSER(fs)
|
||||||
|
);
|
||||||
|
gchar *filename = g_file_get_uri(file),
|
||||||
|
*extension,
|
||||||
|
*current_extension;
|
||||||
|
AgChartSaveImageFunc save_func = NULL;
|
||||||
|
gboolean can_save = FALSE;
|
||||||
|
|
||||||
ag_chart_export_svg_to_file(priv->chart, file, err);
|
if (filter == filter_svg) {
|
||||||
|
extension = ".svg";
|
||||||
|
save_func = &ag_chart_export_svg_to_file;
|
||||||
|
} else {
|
||||||
|
g_warning("Unknown file type");
|
||||||
|
gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(fs), filter_svg);
|
||||||
|
}
|
||||||
|
|
||||||
|
current_extension = g_utf8_strrchr(filename, -1, '.');
|
||||||
|
|
||||||
|
if (current_extension == NULL) {
|
||||||
|
gchar *tmp;
|
||||||
|
|
||||||
|
tmp = filename;
|
||||||
|
filename = g_strdup_printf("%s%s", tmp, extension);
|
||||||
|
g_free(tmp);
|
||||||
|
} else {
|
||||||
|
GFileInfo *fileinfo;
|
||||||
|
GFile *tmp_file;
|
||||||
|
gboolean valid;
|
||||||
|
GtkFileFilterInfo filter_info;
|
||||||
|
|
||||||
|
tmp_file = g_file_new_for_uri(filename);
|
||||||
|
fileinfo = g_file_query_info(
|
||||||
|
tmp_file,
|
||||||
|
G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME,
|
||||||
|
G_FILE_QUERY_INFO_NONE,
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
g_object_unref(tmp_file);
|
||||||
|
|
||||||
|
filter_info.contains =
|
||||||
|
GTK_FILE_FILTER_URI
|
||||||
|
| GTK_FILE_FILTER_DISPLAY_NAME;
|
||||||
|
filter_info.uri = filename;
|
||||||
|
filter_info.display_name = g_file_info_get_display_name(
|
||||||
|
fileinfo
|
||||||
|
);
|
||||||
|
|
||||||
|
valid = gtk_file_filter_filter(filter, &filter_info);
|
||||||
|
g_object_unref(fileinfo);
|
||||||
|
|
||||||
|
if (!valid) {
|
||||||
|
GtkResponseType response;
|
||||||
|
gchar *message,
|
||||||
|
*new_filename;
|
||||||
|
|
||||||
|
new_filename = g_strdup_printf("%s%s", filename, extension);
|
||||||
|
|
||||||
|
message = g_strdup_printf(
|
||||||
|
"File extension doesn’t match the chosen format. " \
|
||||||
|
"Do you want Astrognome to append the correct " \
|
||||||
|
"extension (the new filename will be %s) or " \
|
||||||
|
"choose a new name?",
|
||||||
|
new_filename
|
||||||
|
);
|
||||||
|
|
||||||
|
response = ag_app_buttoned_dialog(
|
||||||
|
GTK_WINDOW(window),
|
||||||
|
GTK_MESSAGE_QUESTION,
|
||||||
|
message,
|
||||||
|
"Cancel", GTK_RESPONSE_CANCEL,
|
||||||
|
"Append extension", GTK_RESPONSE_APPLY,
|
||||||
|
"Choose new file", GTK_RESPONSE_NO,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
if (response == GTK_RESPONSE_APPLY) {
|
||||||
|
g_free(filename);
|
||||||
|
filename = new_filename;
|
||||||
|
} else {
|
||||||
|
g_free(filename);
|
||||||
|
g_clear_object(&file);
|
||||||
|
|
||||||
|
if (response == GTK_RESPONSE_NO) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_clear_object(&file);
|
||||||
|
file = g_file_new_for_uri(filename);
|
||||||
|
g_free(filename);
|
||||||
|
|
||||||
|
// Now check if a file under the modified name exists
|
||||||
|
if (g_file_query_exists(file, NULL)) {
|
||||||
|
GtkResponseType sub_response;
|
||||||
|
gchar *message;
|
||||||
|
GFileInfo *fileinfo;
|
||||||
|
|
||||||
|
fileinfo = g_file_query_info(
|
||||||
|
file,
|
||||||
|
G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME,
|
||||||
|
G_FILE_QUERY_INFO_NONE,
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
message = g_strdup_printf(
|
||||||
|
"File %s already exists. Do you want to overwrite it?",
|
||||||
|
g_file_info_get_display_name(fileinfo)
|
||||||
|
);
|
||||||
|
g_object_unref(fileinfo);
|
||||||
|
|
||||||
|
sub_response = ag_app_buttoned_dialog(
|
||||||
|
GTK_WINDOW(window), GTK_MESSAGE_QUESTION,
|
||||||
|
message,
|
||||||
|
_("No"), GTK_RESPONSE_NO,
|
||||||
|
_("Yes"), GTK_RESPONSE_YES,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
g_free(message);
|
||||||
|
|
||||||
|
can_save = (sub_response == GTK_RESPONSE_YES);
|
||||||
|
} else {
|
||||||
|
can_save = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (can_save) {
|
||||||
|
g_clear_error(&local_err);
|
||||||
|
save_func(priv->chart, file, &local_err);
|
||||||
|
|
||||||
|
if (local_err) {
|
||||||
|
ag_app_message_dialog(
|
||||||
|
GTK_WINDOW(window),
|
||||||
|
GTK_MESSAGE_ERROR,
|
||||||
|
"%s",
|
||||||
|
local_err->message
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_clear_object(&file);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_clear_object(&file);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gtk_widget_destroy(fs);
|
gtk_widget_destroy(fs);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ag_window_export_svg_action(GSimpleAction *action,
|
ag_window_export_image_action(GSimpleAction *action,
|
||||||
GVariant *parameter,
|
GVariant *parameter,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
AgWindow *window = AG_WINDOW(user_data);
|
AgWindow *window = AG_WINDOW(user_data);
|
||||||
GError *err = NULL;
|
GError *err = NULL;
|
||||||
|
|
||||||
ag_window_export_svg(window, &err);
|
ag_window_export_image(window, &err);
|
||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
ag_app_message_dialog(
|
ag_app_message_dialog(
|
||||||
@ -1612,19 +1767,19 @@ ag_window_connection_action(GSimpleAction *action,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static GActionEntry win_entries[] = {
|
static GActionEntry win_entries[] = {
|
||||||
{ "close", ag_window_close_action, NULL, NULL, NULL },
|
{ "close", ag_window_close_action, NULL, NULL, NULL },
|
||||||
{ "save", ag_window_save_action, NULL, NULL, NULL },
|
{ "save", ag_window_save_action, NULL, NULL, NULL },
|
||||||
{ "export-agc", ag_window_export_agc_action, NULL, NULL, NULL },
|
{ "export-agc", ag_window_export_agc_action, NULL, NULL, NULL },
|
||||||
{ "export-svg", ag_window_export_svg_action, NULL, NULL, NULL },
|
{ "export-image", ag_window_export_image_action, NULL, NULL, NULL },
|
||||||
{ "view-menu", ag_window_view_menu_action, NULL, "false", NULL },
|
{ "view-menu", ag_window_view_menu_action, NULL, "false", NULL },
|
||||||
{ "gear-menu", ag_window_gear_menu_action, NULL, "false", NULL },
|
{ "gear-menu", ag_window_gear_menu_action, NULL, "false", NULL },
|
||||||
{ "change-tab", ag_window_change_tab_action, "s", "'edit'", NULL },
|
{ "change-tab", ag_window_change_tab_action, "s", "'edit'", NULL },
|
||||||
{ "new-chart", ag_window_new_chart_action, NULL, NULL, NULL },
|
{ "new-chart", ag_window_new_chart_action, NULL, NULL, NULL },
|
||||||
{ "back", ag_window_back_action, NULL, NULL, NULL },
|
{ "back", ag_window_back_action, NULL, NULL, NULL },
|
||||||
{ "refresh", ag_window_refresh_action, NULL, NULL, NULL },
|
{ "refresh", ag_window_refresh_action, NULL, NULL, NULL },
|
||||||
{ "selection", ag_window_selection_mode_action, NULL, "false", NULL },
|
{ "selection", ag_window_selection_mode_action, NULL, "false", NULL },
|
||||||
{ "delete", ag_window_delete_action, NULL, NULL, NULL },
|
{ "delete", ag_window_delete_action, NULL, NULL, NULL },
|
||||||
{ "connection", ag_window_connection_action, "s", "'aspects'", NULL },
|
{ "connection", ag_window_connection_action, "s", "'aspects'", NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -24,6 +24,7 @@ GtkBuilder *builder;
|
|||||||
GtkFileFilter *filter_all = NULL;
|
GtkFileFilter *filter_all = NULL;
|
||||||
GtkFileFilter *filter_chart = NULL;
|
GtkFileFilter *filter_chart = NULL;
|
||||||
GtkFileFilter *filter_hor = NULL;
|
GtkFileFilter *filter_hor = NULL;
|
||||||
|
GtkFileFilter *filter_svg = NULL;
|
||||||
GtkTreeModel *country_list = NULL;
|
GtkTreeModel *country_list = NULL;
|
||||||
GtkTreeModel *city_list = NULL;
|
GtkTreeModel *city_list = NULL;
|
||||||
GHashTable *xinclude_positions;
|
GHashTable *xinclude_positions;
|
||||||
@ -84,6 +85,11 @@ init_filters(void)
|
|||||||
gtk_file_filter_set_name(filter_hor, _("Placidus charts"));
|
gtk_file_filter_set_name(filter_hor, _("Placidus charts"));
|
||||||
gtk_file_filter_add_pattern(filter_hor, "*.hor");
|
gtk_file_filter_add_pattern(filter_hor, "*.hor");
|
||||||
g_object_ref_sink(filter_hor);
|
g_object_ref_sink(filter_hor);
|
||||||
|
|
||||||
|
filter_svg = gtk_file_filter_new();
|
||||||
|
gtk_file_filter_set_name(filter_svg, _("SVG image"));
|
||||||
|
gtk_file_filter_add_pattern(filter_svg, "*.svg");
|
||||||
|
g_object_ref_sink(filter_svg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -13,6 +13,7 @@ typedef struct {
|
|||||||
extern GtkFileFilter *filter_all;
|
extern GtkFileFilter *filter_all;
|
||||||
extern GtkFileFilter *filter_chart;
|
extern GtkFileFilter *filter_chart;
|
||||||
extern GtkFileFilter *filter_hor;
|
extern GtkFileFilter *filter_hor;
|
||||||
|
extern GtkFileFilter *filter_svg;
|
||||||
extern GtkTreeModel *country_list;
|
extern GtkTreeModel *country_list;
|
||||||
extern GtkTreeModel *city_list;
|
extern GtkTreeModel *city_list;
|
||||||
extern const GswePlanet used_planets[];
|
extern const GswePlanet used_planets[];
|
||||||
|
@ -45,8 +45,8 @@
|
|||||||
</section>
|
</section>
|
||||||
<section>
|
<section>
|
||||||
<item>
|
<item>
|
||||||
<attribute name="label" translatable="yes">Export as SVG</attribute>
|
<attribute name="label" translatable="yes">Export as image…</attribute>
|
||||||
<attribute name="action">win.export-svg</attribute>
|
<attribute name="action">win.export-image</attribute>
|
||||||
</item>
|
</item>
|
||||||
</section>
|
</section>
|
||||||
<section>
|
<section>
|
||||||
|
Loading…
Reference in New Issue
Block a user