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); } } }
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; } }
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); }
/** * 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)); }