static void _dae_draw(DiagramAsElement *dae, DiaRenderer *renderer) { DiaRendererClass *renderer_ops = DIA_RENDERER_GET_CLASS (renderer); Element *elem = &dae->element; if (!dae->data) { /* just draw the box */ Point lower_right = { elem->corner.x + elem->width, elem->corner.y + elem->height }; renderer_ops->draw_rect(renderer,&elem->corner, &lower_right, &dae->border_color); } else { if (FALSE) { /* if the renderer supports transformations ... */ /* temporary messing with it (not enough) */ dae->data->paper.scaling *= dae->scale; data_render (dae->data, DIA_RENDERER (renderer), NULL, NULL, NULL); dae->data->paper.scaling /= dae->scale; } else { /* we have to render to an image and draw that */ if (!dae->image) { /* lazy creation */ gchar *imgfname = NULL; gint fd = g_file_open_tmp ("diagram-as-elementXXXXXX.png", &imgfname, NULL); if (fd != -1) { DiaExportFilter *ef = filter_export_get_by_name ("cairo-alpha-png"); if (!ef) /* prefer cairo with alpha, but don't require it */ ef = filter_guess_export_filter (imgfname); close(fd); if (ef) { DiaContext *ctx = dia_context_new ("Diagram as Object"); dia_context_set_filename (ctx, imgfname); if (ef->export_func (dae->data, ctx, imgfname, dae->filename, ef->user_data)) { DiaImage *tmp_image = dia_image_load (imgfname); /* some extra gymnastics to create an image w/o filename */ if (tmp_image) { dae->image = dia_image_new_from_pixbuf ((GdkPixbuf *)dia_image_pixbuf (tmp_image)); g_object_unref (tmp_image); } /* FIXME: where to put the message in case of an error? */ dia_context_release (ctx); } } /* found a filter */ g_unlink (imgfname); g_free (imgfname); } /* temporary file created*/ } /* only if we have no image yet */ if (dae->image) renderer_ops->draw_image (renderer, &elem->corner, elem->width, elem->height, dae->image); } } }
/*! Allows to save an Object to ObjectNode file filename. * . Not sure if this becomes useful for language bindings. */ void dia::ObjectType::save (Object* o, ObjectNode node, const char* filename) const { assert (self); DiaContext *ctx = dia_context_new ("Object save"); self->ops->save (o->Self(), node, ctx); dia_context_reset (ctx); dia_context_release (ctx); }
static void _dae_update_data(DiagramAsElement *dae) { struct stat statbuf; Element *elem = &dae->element; DiaObject *obj = &elem->object; static int working = 0; if (working > 2) return; /* protect against infinite recursion */ ++working; if ( strlen(dae->filename) && g_stat(dae->filename, &statbuf) == 0 && dae->mtime != statbuf.st_mtime) { DiaImportFilter *inf; if (dae->data) g_object_unref(dae->data); dae->data = g_object_new (DIA_TYPE_DIAGRAM_DATA, NULL); inf = filter_guess_import_filter(dae->filename); if (inf) { DiaContext *ctx = dia_context_new (diagram_as_element_type.name); dia_context_set_filename (ctx, dae->filename); if (inf->import_func(dae->filename, dae->data, ctx, inf->user_data)) { data_update_extents (dae->data); /* should already be called by importer? */ dae->scale = dae->element.width / (dae->data->extents.right - dae->data->extents.left); dae->element.height = (dae->data->extents.bottom - dae->data->extents.top) * dae->scale; dae->mtime = statbuf.st_mtime; } /* FIXME: where to put the message in case of an error? */ dia_context_release (ctx); } /* invalidate possibly cached image */ if (dae->image) { g_object_unref (dae->image); dae->image = NULL; } } /* fixme - fit the scale to draw the diagram in elements size ?*/ if (dae->scale) dae->scale = dae->element.width / (dae->data->extents.right - dae->data->extents.left); elem->extra_spacing.border_trans = dae->border_line_width/2.0; element_update_boundingbox(elem); element_update_handles(elem); element_update_connections_rectangle(elem, dae->connections); /* adjust objects position, otherwise it'll jump on move */ obj->position = elem->corner; --working; }
int diagram_load_into(Diagram *diagram, const char *filename, DiaImportFilter *ifilter) { /* ToDo: move context further up in the callstack and to sth useful with it's content */ DiaContext *ctx = dia_context_new(_("Load Into")); gboolean was_default = diagram->is_default; if (!ifilter) ifilter = filter_guess_import_filter(filename); /* slightly hacked to avoid 'Not a Dia File' for .shape */ if (!ifilter && g_str_has_suffix (filename, ".shape")) ifilter = filter_import_get_by_name ("dia-svg"); if (!ifilter) /* default to native format */ ifilter = &dia_import_filter; dia_context_set_filename (ctx, filename); if (ifilter->import_func(filename, diagram->data, ctx, ifilter->user_data)) { if (ifilter != &dia_import_filter) { /* When loading non-Dia files, change filename to reflect that saving * will produce a Dia file. See bug #440093 */ if (strcmp (diagram->filename, filename) == 0) { /* not a real load into but initial load */ gchar *old_filename = g_strdup (diagram->filename); gchar *suffix_offset = g_utf8_strrchr(old_filename, -1, (gunichar)'.'); gchar *new_filename; if (suffix_offset != NULL) { new_filename = g_strndup(old_filename, suffix_offset - old_filename); g_free(old_filename); } else { new_filename = old_filename; } old_filename = g_strconcat(new_filename, ".dia", NULL); g_free(new_filename); diagram_set_filename(diagram, old_filename); g_free(old_filename); diagram->unsaved = TRUE; diagram_update_for_filename (diagram); diagram_modified(diagram); } } else { /* the initial diagram should have confirmed filename */ diagram->unsaved = strcmp(filename, diagram->filename) == 0 ? FALSE : was_default; } diagram_set_modified(diagram, TRUE); dia_context_release(ctx); return TRUE; } else { dia_context_release(ctx); return FALSE; } }
static void are_you_sure_close_dialog_respond(GtkWidget *widget, /* the dialog */ gint response_id, gpointer user_data) /* the display */ { DDisplay *ddisp = (DDisplay *)user_data; gboolean close_ddisp = TRUE; switch (response_id) { case GTK_RESPONSE_YES : /* save changes */ if (ddisp->diagram->unsaved) { /* we have to open the file dlg, close this one first */ gtk_widget_destroy(widget); if (file_save_as(ddisp->diagram, ddisp)) ddisp_destroy (ddisp); /* no way back */ return; } else { DiaContext *ctx = dia_context_new (_("Save")); if (!diagram_save(ddisp->diagram, ddisp->diagram->filename, ctx)) close_ddisp = FALSE; dia_context_release (ctx); } if (close_ddisp) /* saving succeeded */ recent_file_history_add(ddisp->diagram->filename); if (ddisp->update_id && close_ddisp) { g_source_remove (ddisp->update_id); ddisp->update_id = 0; } /* fall through */ case GTK_RESPONSE_NO : if (close_ddisp) ddisp_destroy (ddisp); /* fall through */ case GTK_RESPONSE_CANCEL : case GTK_RESPONSE_NONE : case GTK_RESPONSE_DELETE_EVENT : /* closing via window manager */ gtk_widget_destroy(widget); break; default : g_assert_not_reached(); } }
void app_init (int argc, char **argv) { static gboolean nosplash = FALSE; static gboolean nonew = FALSE; static gboolean use_integrated_ui = TRUE; static gboolean credits = FALSE; static gboolean version = FALSE; static gboolean verbose = FALSE; static gboolean log_to_stderr = FALSE; #ifdef HAVE_GNOME GnomeClient *client; #endif static char *export_file_name = NULL; static char *export_file_format = NULL; static char *size = NULL; static char *show_layers = NULL; gboolean made_conversions = FALSE; GSList *files = NULL; static const gchar **filenames = NULL; int i = 0; gchar *export_format_string = /* Translators: The argument is a list of options, not to be translated */ g_strdup_printf(_("Select the filter/format out of: %s"), "cgm, dia, dxf, eps, eps-builtin, " EPS_PANGO "fig, mp, plt, hpgl, png (" # if defined(HAVE_LIBPNG) && defined(HAVE_LIBART) "png-libart, " # endif # ifdef HAVE_CAIRO "cairo-png, cairo-alpha-png, " # endif /* we always have pixbuf but don't know exactly all it's *few* save formats */ "pixbuf-png), jpg, " "shape, svg, tex (pgf-tex, pstricks-tex), " WMF "wpg"); GOptionContext *context = NULL; static GOptionEntry options[] = { {"export", 'e', 0, G_OPTION_ARG_FILENAME, NULL /* &export_file_name */, N_("Export loaded file and exit"), N_("OUTPUT")}, {"filter",'t', 0, G_OPTION_ARG_STRING, NULL /* &export_file_format */, NULL /* &export_format_string */, N_("TYPE") }, {"size", 's', 0, G_OPTION_ARG_STRING, NULL, N_("Export graphics size"), N_("WxH")}, {"show-layers", 'L', 0, G_OPTION_ARG_STRING, NULL, N_("Show only specified layers (e.g. when exporting). Can be either the layer name or a range of layer numbers (X-Y)"), N_("LAYER,LAYER,...")}, {"nosplash", 'n', 0, G_OPTION_ARG_NONE, &nosplash, N_("Don't show the splash screen"), NULL }, {"nonew", 'n', 0, G_OPTION_ARG_NONE, &nonew, N_("Don't create an empty diagram"), NULL }, {"classic", '\0', G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &use_integrated_ui, N_("Start classic user interface (no diagrams in tabs)"), NULL }, {"log-to-stderr", 'l', 0, G_OPTION_ARG_NONE, &log_to_stderr, N_("Send error messages to stderr instead of showing dialogs."), NULL }, {"input-directory", 'I', 0, G_OPTION_ARG_CALLBACK, _check_option_input_directory, N_("Directory containing input files"), N_("DIRECTORY")}, {"output-directory", 'O', 0, G_OPTION_ARG_CALLBACK, _check_option_output_directory, N_("Directory containing output files"), N_("DIRECTORY")}, {"credits", 'c', 0, G_OPTION_ARG_NONE, &credits, N_("Display credits list and exit"), NULL }, {"verbose", 0, 0, G_OPTION_ARG_NONE, &verbose, N_("Generate verbose output"), NULL }, {"version", 'v', 0, G_OPTION_ARG_NONE, &version, N_("Display version and exit"), NULL }, { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, NULL /* &filenames */, NULL, NULL }, { NULL } }; /* for users of app_init() the default is interactive */ dia_is_interactive = TRUE; options[0].arg_data = &export_file_name; options[1].arg_data = &export_file_format; options[1].description = export_format_string; options[2].arg_data = &size; options[3].arg_data = &show_layers; g_assert (strcmp (options[13].long_name, G_OPTION_REMAINING) == 0); options[13].arg_data = (void*)&filenames; argv0 = (argc > 0) ? argv[0] : "(none)"; #if GTK_CHECK_VERSION(2,24,0) /* ... use setlocale directly? */ #else gtk_set_locale(); #endif setlocale(LC_NUMERIC, "C"); _setup_textdomains (); context = g_option_context_new(_("[FILE...]")); g_option_context_add_main_entries (context, options, GETTEXT_PACKAGE); #ifndef HAVE_GNOME /* avoid to add it a second time */ g_option_context_add_group (context, gtk_get_option_group (FALSE)); #endif if (argv) { GError *error = NULL; if (!g_option_context_parse (context, &argc, &argv, &error)) { if (error) { /* IMO !error here is a bug upstream, triggered e.g. with --gdk-debug=updates */ g_print ("%s", error->message); g_error_free (error); } else { g_print (_("Invalid option?")); } g_option_context_free(context); exit(1); } /* second level check of command line options, existance of input files etc. */ if (filenames) { while (filenames[i] != NULL) { gchar *filename; gchar *testpath; if (g_str_has_prefix (filenames[i], "file://")) { filename = g_filename_from_uri (filenames[i], NULL, NULL); if (!g_utf8_validate(filename, -1, NULL)) { gchar *tfn = filename; filename = g_filename_to_utf8(filename, -1, NULL, NULL, NULL); g_free(tfn); } } else filename = g_filename_to_utf8 (filenames[i], -1, NULL, NULL, NULL); if (!filename) { g_print (_("Filename conversion failed: %s\n"), filenames[i]); continue; } if (g_path_is_absolute(filename)) testpath = filename; else testpath = g_build_filename(input_directory ? input_directory : ".", filename, NULL); /* we still have a problem here, if GLib's file name encoding would not be utf-8 */ if (g_file_test (testpath, G_FILE_TEST_IS_REGULAR)) files = g_slist_append(files, filename); else { g_print (_("Missing input: %s\n"), filename); g_free (filename); } if (filename != testpath) g_free (testpath); ++i; } } /* given some files to output, we are not starting up the UI */ if (export_file_name || export_file_format || size) dia_is_interactive = FALSE; } if (argv && dia_is_interactive && !version) { #ifdef HAVE_GNOME GnomeProgram *program = gnome_program_init (PACKAGE, VERSION, LIBGNOMEUI_MODULE, argc, argv, /* haven't found a quick way to pass GOption here */ GNOME_PARAM_GOPTION_CONTEXT, context, GNOME_PROGRAM_STANDARD_PROPERTIES, GNOME_PARAM_NONE); client = gnome_master_client(); if(client == NULL) { g_warning(_("Can't connect to session manager!\n")); } else { g_signal_connect(G_OBJECT (client), "save_yourself", G_CALLBACK (save_state), NULL); g_signal_connect(G_OBJECT (client), "die", G_CALLBACK (session_die), NULL); } /* This smaller icon is 48x48, standard Gnome size */ /* gnome_window_icon_set_default_from_file (GNOME_ICONDIR"/dia_gnome_icon.png");*/ #else # ifdef G_THREADS_ENABLED g_thread_init (NULL); # endif gtk_init(&argc, &argv); #endif } else { #ifdef G_THREADS_ENABLED g_thread_init (NULL); #endif g_type_init(); /* * On Windows there is no command line without display so that gtk_init is harmless. * On X11 we need gtk_init_check() to avoid exit() just because there is no display * running outside of X11. */ if (!gtk_init_check(&argc, &argv)) dia_log_message ("Running without display"); } /* done with option parsing, don't leak */ g_free(export_format_string); if (version) { gchar *ver_utf8; gchar *ver_locale; #if (defined __TIME__) && (defined __DATE__) /* TRANSLATOR: 2nd and 3rd %s are time and date respectively. */ ver_utf8 = g_strdup_printf(_("Dia version %s, compiled %s %s\n"), VERSION, __TIME__, __DATE__); #else ver_utf8 = g_strdup_printf(_("Dia version %s\n"), VERSION); #endif ver_locale = g_locale_from_utf8(ver_utf8, -1, NULL, NULL, NULL); printf("%s\n", ver_locale); g_free(ver_locale); g_free(ver_utf8); if (verbose) dump_dependencies(); exit(0); } if (!dia_is_interactive) log_to_stderr = TRUE; libdia_init ( (dia_is_interactive ? DIA_INTERACTIVE : 0) | (log_to_stderr ? DIA_MESSAGE_STDERR : 0) | (verbose ? DIA_VERBOSE : 0) ); print_credits(credits); if (dia_is_interactive) { create_user_dirs(); if (!nosplash) app_splash_init(""); /* Init cursors: */ default_cursor = gdk_cursor_new(GDK_LEFT_PTR); ddisplay_set_all_cursor(default_cursor); } dia_register_plugins(); dia_register_builtin_plugin(internal_plugin_init); load_all_sheets(); /* new mechanism */ dia_log_message ("object defaults"); { DiaContext *ctx = dia_context_new (_("Object Defaults")); dia_object_defaults_load (NULL, TRUE /* prefs.object_defaults_create_lazy */, ctx); dia_context_release (ctx); } debug_break(); if (object_get_type("Standard - Box") == NULL) { message_error(_("Couldn't find standard objects when looking for " "object-libs; exiting...\n")); g_critical( _("Couldn't find standard objects when looking for " "object-libs in '%s'; exiting...\n"), dia_get_lib_directory("dia")); exit(1); } persistence_load(); /** Must load prefs after persistence */ prefs_init(); if (dia_is_interactive) { /* further initialization *before* reading files */ active_tool = create_modify_tool(); dia_log_message ("ui creation"); if (use_integrated_ui) { create_integrated_ui(); } else { create_toolbox(); /* for the integrated ui case it is integrated */ persistence_register_window_create("layer_window", (NullaryFunc*)&layer_dialog_create); } /*fill recent file menu */ recent_file_history_init(); /* Set up autosave to check every 5 minutes */ g_timeout_add_seconds(5*60, autosave_check_autosave, NULL); #if 0 /* do we really open these automatically in the next session? */ persistence_register_window_create("diagram_tree", &diagram_tree_show); #endif persistence_register_window_create("sheets_main_dialog", (NullaryFunc*)&sheets_dialog_create); /* In current setup, we can't find the autosaved files. */ /*autosave_restore_documents();*/ } dia_log_message ("diagrams"); made_conversions = handle_all_diagrams(files, export_file_name, export_file_format, size, show_layers, input_directory, output_directory); if (dia_is_interactive && files == NULL && !nonew) { if (use_integrated_ui) { GList * list; file_new_callback(NULL); list = dia_open_diagrams(); if (list) { Diagram * diagram = list->data; diagram_update_extents(diagram); diagram->is_default = TRUE; } } else { gchar *filename = g_filename_from_utf8(_("Diagram1.dia"), -1, NULL, NULL, NULL); Diagram *diagram = new_diagram (filename); g_free(filename); if (diagram != NULL) { diagram_update_extents(diagram); diagram->is_default = TRUE; /* I think this is done in diagram_init() with a call to * layer_dialog_update_diagram_list() */ layer_dialog_set_diagram(diagram); new_display(diagram); } } } g_slist_free(files); if (made_conversions) exit(0); dynobj_refresh_init(); dia_log_message ("initialized"); }
/** Convert infname to outfname, using input filter inf and export filter * ef. If either is null, try to guess them. * size might be NULL. */ static gboolean do_convert(const char *infname, const char *outfname, DiaExportFilter *ef, const char *size, char *show_layers) { DiaImportFilter *inf; DiagramData *diagdata = NULL; DiaContext *ctx; inf = filter_guess_import_filter(infname); if (!inf) inf = &dia_import_filter; if (ef == NULL) { ef = filter_guess_export_filter(outfname); if (!ef) { g_critical(_("%s error: don't know how to export into %s\n"), argv0,outfname); exit(1); } } dia_is_interactive = FALSE; if (0==strcmp(infname,outfname)) { g_critical(_("%s error: input and output filenames are identical: %s"), argv0, infname); exit(1); } diagdata = g_object_new (DIA_TYPE_DIAGRAM_DATA, NULL); ctx = dia_context_new(_("Import")); if (!inf->import_func(infname, diagdata, ctx, inf->user_data)) { g_critical(_("%s error: need valid input file %s\n"), argv0, infname); exit(1); } /* Apply --show-layers */ if (show_layers) handle_show_layers(diagdata, show_layers); /* recalculate before export */ data_update_extents(diagdata); /* Do our best in providing the size to the filter, but don't abuse user_data * too much for it. It _must not_ be changed after initialization and there * are quite some filter selecting their output format by it. --hb */ if (size) { if (ef == filter_export_get_by_name ("png-libart")) /* the warning we get is appropriate, don't cast */ ef->export_func(diagdata, ctx, outfname, infname, size); else { g_warning ("--size parameter unsupported for %s filter", ef->unique_name ? ef->unique_name : "selected"); ef->export_func(diagdata, ctx, outfname, infname, ef->user_data); } } else ef->export_func(diagdata, ctx, outfname, infname, ef->user_data); /* if (!quiet) */ fprintf(stdout, _("%s --> %s\n"), infname,outfname); g_object_unref(diagdata); dia_context_release(ctx); return TRUE; }
gboolean app_exit(void) { GList *list; GSList *slist; /* * The following "solves" a crash related to a second call of app_exit, * after gtk_main_quit was called. It may be a win32 gtk-1.3.x bug only * but the check shouldn't hurt on *ix either. --hb */ static gboolean app_exit_once = FALSE; if (app_exit_once) { g_error(_("This shouldn't happen. Please file a bug report at bugzilla.gnome.org\n" "describing how you caused this message to appear.\n")); return FALSE; } if (diagram_modified_exists()) { if (is_integrated_ui ()) { GtkWidget *dialog; int result; exit_dialog_item_array_t *items = NULL; GList * list; Diagram * diagram; dialog = exit_dialog_make (GTK_WINDOW (interface_get_toolbox_shell ()), _("Exiting Dia")); list = dia_open_diagrams(); while (list) { diagram = list->data; if (diagram_is_modified (diagram)) { const gchar * name = diagram_get_name (diagram); const gchar * path = diagram->filename; exit_dialog_add_item (dialog, name, path, diagram); } list = g_list_next (list); } result = exit_dialog_run (dialog, &items); gtk_widget_destroy (dialog); if (result == EXIT_DIALOG_EXIT_CANCEL) { return FALSE; } else if (result == EXIT_DIALOG_EXIT_SAVE_SELECTED) { DiaContext *ctx = dia_context_new(_("Save")); int i; for (i = 0 ; i < items->array_size ; i++) { gchar *filename; diagram = items->array[i].data; filename = g_filename_from_utf8 (diagram->filename, -1, NULL, NULL, NULL); diagram_update_extents (diagram); dia_context_set_filename (ctx, filename); if (!diagram_save (diagram, filename, ctx)) { exit_dialog_free_items (items); dia_context_release (ctx); return FALSE; } else { dia_context_reset (ctx); } g_free (filename); } dia_context_release (ctx); exit_dialog_free_items (items); } else if (result == EXIT_DIALOG_EXIT_NO_SAVE) { list = dia_open_diagrams(); while (list) { diagram = list->data; /* slight hack: don't ask again */ diagram_set_modified (diagram, FALSE); undo_clear(diagram->undo); list = g_list_next (list); } } } else { GtkWidget *dialog; GtkWidget *button; dialog = gtk_message_dialog_new( NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE, /* no standard buttons */ _("Quitting without saving modified diagrams")); gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog), _("Modified diagrams exist. " "Are you sure you want to quit Dia " "without saving them?")); gtk_window_set_title (GTK_WINDOW(dialog), _("Quit Dia")); button = gtk_button_new_from_stock (GTK_STOCK_CANCEL); gtk_dialog_add_action_widget (GTK_DIALOG(dialog), button, GTK_RESPONSE_CANCEL); #if GTK_CHECK_VERSION(2,18,0) gtk_widget_set_can_default (GTK_WIDGET (button), TRUE); #else GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT); #endif gtk_dialog_set_default_response (GTK_DIALOG(dialog), GTK_RESPONSE_CANCEL); button = gtk_button_new_from_stock (GTK_STOCK_QUIT); gtk_dialog_add_action_widget (GTK_DIALOG(dialog), button, GTK_RESPONSE_OK); gtk_widget_show_all (dialog); if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_OK) { gtk_widget_destroy(dialog); return FALSE; } gtk_widget_destroy(dialog); } } prefs_save(); persistence_save(); dynobj_refresh_finish(); { DiaContext *ctx = dia_context_new (_("Exit")); dia_object_defaults_save (NULL, ctx); dia_context_release (ctx); } /* Free loads of stuff (toolbox) */ list = dia_open_diagrams(); while (list!=NULL) { Diagram *dia = (Diagram *)list->data; list = g_list_next(list); slist = dia->displays; while (slist!=NULL) { DDisplay *ddisp = (DDisplay *)slist->data; slist = g_slist_next(slist); gtk_widget_destroy(ddisp->shell); } /* The diagram is freed when the last display is destroyed */ } /* save pluginrc */ if (dia_is_interactive) dia_pluginrc_write(); gtk_main_quit(); /* This printf seems to prevent a race condition with unrefs. */ /* Yuck. -Lars */ /* Trying to live without it. -Lars 10/8/07*/ /* g_print(_("Thank you for using Dia.\n")); */ app_exit_once = TRUE; return TRUE; }
/** * A button hit in the Export Dialog */ static void file_export_response_callback(GtkWidget *fs, gint response, gpointer user_data) { char *filename; Diagram *dia; DiaExportFilter *ef; struct stat statbuf; dia = g_object_get_data (G_OBJECT (fs), "user_data"); g_assert (dia); if (response == GTK_RESPONSE_ACCEPT) { gint index; diagram_update_extents(dia); filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fs)); if (g_stat(filename, &statbuf) == 0) { GtkWidget *dialog = NULL; dialog = gtk_message_dialog_new (GTK_WINDOW(fs), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, _("File already exists")); gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog), _("The file '%s' already exists.\n" "Do you want to overwrite it?"), dia_message_filename(filename)); gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_YES); if (gtk_dialog_run (GTK_DIALOG (dialog)) != GTK_RESPONSE_YES) { /* if not overwrite allow to select another filename */ gtk_widget_destroy(dialog); g_free (filename); return; } gtk_widget_destroy(dialog); } index = gtk_combo_box_get_active (GTK_COMBO_BOX(user_data)); if (index >= 0) persistence_set_integer ("export-filter", index); ef = efilter_by_index (index - 1, NULL); if (!ef) ef = filter_guess_export_filter(filename); if (ef) { DiaContext *ctx = dia_context_new (_("Export")); g_object_ref(dia->data); dia_context_set_filename (ctx, filename); ef->export_func(dia->data, ctx, filename, dia->filename, ef->user_data); g_object_unref(dia->data); dia_context_release (ctx); } else message_error(_("Could not determine which export filter\n" "to use to save '%s'"), dia_message_filename(filename)); g_free (filename); } g_object_unref (dia); /* drop our diagram reference */ gtk_widget_destroy(exportdlg); }
static GtkWidget * file_save_as_dialog_prepare (Diagram *dia, DDisplay *ddisp) { gchar *filename = NULL; if (!savedlg) { GtkWidget *compressbutton; savedlg = gtk_file_chooser_dialog_new(_("Save Diagram"), GTK_WINDOW(ddisp->shell), GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL); /* vfs saving is as easy - if you see 'bad file descriptor' there is * something wrong with the permissions of the share ;) */ gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER(savedlg), FALSE); gtk_dialog_set_default_response(GTK_DIALOG(savedlg), GTK_RESPONSE_ACCEPT); gtk_window_set_role(GTK_WINDOW(savedlg), "save_diagram"); /* Need better way to make it a reasonable size. Isn't there some*/ /* standard look for them (or is that just Gnome?)*/ compressbutton = gtk_check_button_new_with_label(_("Compress diagram files")); gtk_file_chooser_set_extra_widget(GTK_FILE_CHOOSER(savedlg), compressbutton); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(compressbutton), dia->data->is_compressed); g_signal_connect(G_OBJECT(compressbutton), "toggled", G_CALLBACK(toggle_compress_callback), NULL); gtk_widget_show(compressbutton); gtk_widget_set_tooltip_text (compressbutton, _("Compression reduces file size to less than 1/10th " "size and speeds up loading and saving. Some text " "programs cannot manipulate compressed files.")); g_signal_connect (GTK_FILE_CHOOSER(savedlg), "response", G_CALLBACK(file_save_as_response_callback), compressbutton); g_signal_connect(G_OBJECT(savedlg), "destroy", G_CALLBACK(gtk_widget_destroyed), &savedlg); } else { GtkWidget *compressbutton = gtk_file_chooser_get_extra_widget(GTK_FILE_CHOOSER(savedlg)); gtk_widget_set_sensitive(savedlg, TRUE); g_signal_handlers_block_by_func(G_OBJECT(compressbutton), toggle_compress_callback, NULL); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(compressbutton), dia->data->is_compressed); g_signal_handlers_unblock_by_func(G_OBJECT(compressbutton), toggle_compress_callback, NULL); if (g_object_get_data (G_OBJECT (savedlg), "user_data") != NULL) g_object_unref (g_object_get_data (G_OBJECT (savedlg), "user_data")); #if GTK_CHECK_VERSION(2,20,0) if (gtk_widget_get_visible(savedlg)) { #else if (GTK_WIDGET_VISIBLE(savedlg)) { #endif /* keep a refernce to the diagram */ g_object_ref(dia); g_object_set_data (G_OBJECT (savedlg), "user_data", dia); gtk_window_present (GTK_WINDOW(savedlg)); return savedlg; } } if (dia && dia->filename) filename = g_filename_from_utf8(dia->filename, -1, NULL, NULL, NULL); if (filename != NULL) { char* fnabs = dia_get_absolute_filename (filename); if (fnabs) { gchar *base = g_path_get_basename(dia->filename); gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(savedlg), fnabs); /* FileChooser api insist on exiting files for set_filename */ /* ... and does not use filename encoding on this one. */ gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(savedlg), base); g_free(base); } g_free(fnabs); g_free(filename); } g_object_ref(dia); g_object_set_data (G_OBJECT (savedlg), "user_data", dia); return savedlg; } /** * Respond to the File/Save menu entry. * * Delegates to Save As if there is no filename set yet. */ void file_save_callback(GtkAction *action) { Diagram *diagram; diagram = ddisplay_active_diagram(); if (!diagram) return; if (diagram->unsaved) { file_save_as_callback(action); } else { gchar *filename = g_filename_from_utf8(diagram->filename, -1, NULL, NULL, NULL); DiaContext *ctx = dia_context_new (_("Save")); diagram_update_extents(diagram); if (diagram_save(diagram, filename, ctx)) recent_file_history_add(filename); g_free (filename); dia_context_release (ctx); } }
/** * Respond to a button press (also destroy) in the save as dialog. */ static void file_save_as_response_callback(GtkWidget *fs, gint response, gpointer user_data) { char *filename; Diagram *dia; struct stat stat_struct; if (response == GTK_RESPONSE_ACCEPT) { dia = g_object_get_data (G_OBJECT(fs), "user_data"); filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fs)); if (!filename) { /* Not getting a filename looks like a contract violation in Gtk+ to me. * Still Dia would be crashing (bug #651949) - instead simply go back to the dialog. */ gtk_window_present (GTK_WINDOW (fs)); return; } if (g_stat(filename, &stat_struct) == 0) { GtkWidget *dialog = NULL; char *utf8filename = NULL; if (!g_utf8_validate(filename, -1, NULL)) { utf8filename = g_filename_to_utf8(filename, -1, NULL, NULL, NULL); if (utf8filename == NULL) { message_warning(_("Some characters in the filename are neither UTF-8\n" "nor your local encoding.\nSome things will break.")); } } if (utf8filename == NULL) utf8filename = g_strdup(filename); dialog = gtk_message_dialog_new (GTK_WINDOW(fs), GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, _("File already exists")); gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog), _("The file '%s' already exists.\n" "Do you want to overwrite it?"), utf8filename); g_free(utf8filename); gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_YES); if (gtk_dialog_run (GTK_DIALOG (dialog)) != GTK_RESPONSE_YES) { /* don't hide/destroy the dialog, but simply go back to it */ gtk_window_present (GTK_WINDOW (fs)); gtk_widget_destroy(dialog); g_free (filename); return; } gtk_widget_destroy(dialog); } dia->data->is_compressed = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(user_data)); diagram_update_extents(dia); { DiaContext *ctx = dia_context_new (_("Save as")); diagram_set_filename(dia, filename); dia_context_set_filename (ctx, filename); if (diagram_save(dia, filename, ctx)) recent_file_history_add(filename); dia_context_release (ctx); } g_free (filename); } /* if we have our own reference, drop it before destroy */ if ((dia = g_object_get_data (G_OBJECT(fs), "user_data")) != NULL) { g_object_set_data (G_OBJECT(fs), "user_data", NULL); g_object_unref (dia); } /* if we destroy it gtk_dialog_run wont give the response */ if (!g_object_get_data (G_OBJECT(fs), "dont-destroy")) gtk_widget_destroy(GTK_WIDGET(fs)); }