1 /* Dia -- an diagram creation/manipulation program
2 * Copyright (C) 1998 Alexander Larsson
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 #include <sys/types.h>
42 #if (defined (HAVE_LIBPOPT) && defined (HAVE_POPT_H)) || defined (GNOME)
55 #if defined(LIBXML_VERSION) && LIBXML_VERSION >= 20000
61 #define mkdir(s,a) _mkdir(s)
65 #include "app_procs.h"
69 #include "interface.h"
70 #include "modify_tool.h"
74 #include "layer_dialog.h"
75 #include "load_save.h"
76 #include "preferences.h"
78 #include "render_eps.h"
81 #include "recent_files.h"
83 #if defined(HAVE_LIBPNG) && defined(HAVE_LIBART)
84 extern DiaExportFilter png_export_filter
;
87 static void create_user_dirs(void);
88 static PluginInitResult
internal_plugin_init(PluginInfo
*info
);
90 static gboolean dia_is_interactive
= TRUE
;
95 session_die (gpointer client_data
)
101 save_state (GnomeClient
*client
,
103 GnomeRestartStyle save_style
,
105 GnomeInteractStyle interact_style
,
107 gpointer client_data
)
116 for(l
= open_diagrams
; l
!= NULL
; l
= g_list_next(l
)) {
117 dia
= (Diagram
*)l
->data
;
119 argv
[i
++] = dia
->filename
;
123 gnome_client_set_restart_command (client
, i
, argv
);
124 gnome_client_set_clone_command (client
, i
, argv
);
131 build_output_file_name(const char *infname
, const char *format
)
133 /* FIXME: probably overly confident... */
134 char *p
= strrchr(infname
,'.');
137 return g_strconcat(infname
,".",format
,NULL
);
139 tmp
= g_malloc0(strlen(infname
)+1+strlen(format
)+1);
140 memcpy(tmp
,infname
,p
-infname
);
146 const char *argv0
= NULL
;
149 do_convert(const char *infname
,
150 const char *outfname
)
152 DiaExportFilter
*ef
= NULL
;
153 DiaImportFilter
*inf
= NULL
;
154 DiagramData
*diagdata
= NULL
;
156 dia_is_interactive
= FALSE
;
158 if (0==strcmp(infname
,outfname
)) {
160 _("%s error: input and output file name is identical: %s"),
165 diagdata
= new_diagram_data();
166 inf
= filter_guess_import_filter(infname
);
168 inf
= &dia_import_filter
;
169 if (!inf
->import(infname
,diagdata
,inf
->user_data
)) {
171 _("%s error: need valid input file %s\n"),
175 ef
= filter_guess_export_filter(outfname
);
178 _("%s error: don't know how to export into %s\n"),
182 ef
->export(diagdata
, outfname
, infname
, ef
->user_data
);
183 /* if (!quiet) */ fprintf(stdout
,
186 diagram_data_destroy(diagdata
);
190 void debug_break(void); /* shut gcc up */
194 /* Break here. All symbols are loaded. */
198 app_is_interactive(void)
200 return dia_is_interactive
;
205 myXmlErrorReporting (void *ctx
, const char* msg
, ...)
211 string
= g_strdup_vprintf (msg
, args
);
220 app_init (int argc
, char **argv
)
222 gboolean nosplash
= FALSE
;
226 char *export_file_name
= NULL
;
227 char *export_file_format
= NULL
;
228 gboolean made_conversions
= FALSE
;
234 poptContext poptCtx
= NULL
;
235 struct poptOption options
[] =
237 {"export", 'e', POPT_ARG_STRING
, NULL
/* &export_file_name */, 0,
238 N_("Export loaded file and exit"), N_("OUTPUT")},
239 {"export-to-format",'t', POPT_ARG_STRING
, NULL
/* &export_file_format */,
240 0, N_("Export to file format and exit"), N_("eps,png,wmf,cgm,dxf,fig")},
241 {"nosplash", 'n', POPT_ARG_NONE
, &nosplash
, 0,
242 N_("Don't show the splash screen"), NULL
},
244 {"help", 'h', POPT_ARG_NONE
, 0, 1, N_("Show this help message") },
246 {(char *) NULL
, '\0', 0, NULL
, 0}
251 options
[0].arg
= &export_file_name
;
252 options
[1].arg
= &export_file_format
;
255 argv0
= (argc
> 0) ? argv
[0] : "(none)";
258 setlocale(LC_NUMERIC
, "C");
264 bindtextdomain(PACKAGE
, LOCALEDIR
);
265 #if defined GTK_TALKS_UTF8 && defined ENABLE_NLS
266 bind_textdomain_codeset(PACKAGE
,"UTF-8");
272 gnome_init_with_popt_table(PACKAGE
, VERSION
, argc
, argv
, options
,
275 client
= gnome_master_client();
277 g_warning(_("Can't connect to session manager!\n"));
280 gtk_signal_connect(GTK_OBJECT (client
), "save_yourself",
281 GTK_SIGNAL_FUNC (save_state
), NULL
);
282 gtk_signal_connect(GTK_OBJECT (client
), "die",
283 GTK_SIGNAL_FUNC (session_die
), NULL
);
287 poptCtx
= poptGetContext(PACKAGE
, argc
, (const char **)argv
, options
, 0);
288 poptSetOtherOptionHelp(poptCtx
, _("[OPTION...] [FILE...]"));
290 if((rc
= poptGetNextOpt(poptCtx
)) < -1) {
292 _("Error on option %s: %s.\nRun '%s --help' to see a full list of available command line options.\n"),
293 poptBadOption(poptCtx
, 0),
299 poptPrintHelp(poptCtx
, stderr
, 0);
303 if (export_file_format
&& export_file_name
) {
305 _("%s error: can specify only one of -f or -o."),
312 gtk_init (&argc
, &argv
);
319 xmlSetGenericErrorFunc(NULL
, myXmlErrorReporting
);
328 gtk_rc_parse ("diagtkrc");
340 default_cursor
= gdk_cursor_new(GDK_LEFT_PTR
);
341 ddisplay_set_all_cursor(default_cursor
);
343 object_registry_init();
345 dia_register_plugins();
346 dia_register_builtin_plugin(internal_plugin_init
);
348 load_all_sheets(); /* new mechanism */
352 if (object_get_type("Standard - Box") == NULL
) {
353 message_error(_("Couldn't find standard objects when looking for "
354 "object-libs, exiting...\n"));
355 fprintf(stderr
, _("Couldn't find standard objects when looking for "
356 "object-libs, exiting...\n"));
362 create_layer_dialog();
364 /* further initialization *before* reading files */
365 active_tool
= create_modify_tool();
369 /*fill recent file menu */
370 recent_file_history_init();
372 create_tree_window();
374 /*autosave_restore_documents();*/
378 while (poptPeekArg(poptCtx
)) {
379 Diagram
*diagram
= NULL
;
380 DDisplay
*ddisp
= NULL
;
381 char *in_file_name
= (char *)poptGetArg(poptCtx
);
383 if (export_file_name
) {
384 made_conversions
|= do_convert(in_file_name
,export_file_name
);
385 } else if (export_file_format
) {
386 export_file_name
= build_output_file_name(in_file_name
,
388 made_conversions
|= do_convert(in_file_name
,export_file_name
);
389 g_free(export_file_name
);
391 diagram
= diagram_load (in_file_name
, NULL
);
392 if (diagram
!= NULL
) {
393 diagram_update_extents(diagram
);
394 layer_dialog_set_diagram(diagram
);
396 ddisp
= new_display(diagram
);
400 poptFreeContext(poptCtx
);
404 for (i
=1; i
<argc
; i
++) {
405 Diagram
*diagram
= NULL
;
407 char *in_file_name
= argv
[i
]; /* unless it's an option... */
409 if (0==strcmp(argv
[i
],"-t")) {
412 export_file_format
= argv
[i
];
415 } else if (0 == strcmp(argv
[i
],"-e")) {
418 export_file_name
= argv
[i
];
423 if (export_file_name
) {
424 made_conversions
|= do_convert(in_file_name
,export_file_name
);
425 } else if (export_file_format
) {
426 export_file_name
= build_output_file_name(in_file_name
,
428 made_conversions
|= do_convert(in_file_name
,export_file_name
);
429 g_free(export_file_name
);
431 diagram
= diagram_load(in_file_name
, NULL
);
433 if (diagram
!= NULL
) {
434 diagram_update_extents(diagram
);
435 layer_dialog_set_diagram(diagram
);
437 ddisp
= new_display(diagram
);
439 /* Error messages are done in diagram_load() */
444 if (made_conversions
) exit(0);
448 set_true_callback(GtkWidget
*w
, int *data
)
460 * The following "solves" a crash related to a second call of app_exit,
461 * after gtk_main_quit was called. It may be a win32 gtk-1.3.x bug only
462 * but the check shouldn't hurt on *ix either. --hb
464 static gboolean app_exit_once
= FALSE
;
466 g_return_if_fail (!app_exit_once
);
468 if (diagram_modified_exists()) {
478 dialog
= gnome_dialog_new(_("Quit, are you sure?"), NULL
);
479 vbox
= GNOME_DIALOG(dialog
)->vbox
;
480 gnome_dialog_set_close(GNOME_DIALOG(dialog
), TRUE
);
482 dialog
= gtk_dialog_new();
483 vbox
= GTK_DIALOG(dialog
)->vbox
;
484 gtk_window_set_title (GTK_WINDOW (dialog
), _("Quit, are you sure?"));
485 gtk_container_set_border_width (GTK_CONTAINER (dialog
), 0);
488 gtk_signal_connect (GTK_OBJECT (dialog
), "destroy",
489 GTK_SIGNAL_FUNC(gtk_main_quit
), NULL
);
491 label
= gtk_label_new (_("Modified diagrams exists.\n"
492 "Are you sure you want to quit?"));
494 gtk_misc_set_padding (GTK_MISC (label
), 10, 10);
495 gtk_box_pack_start (GTK_BOX (vbox
), label
, TRUE
, TRUE
, 0);
497 gtk_widget_show (label
);
500 gnome_dialog_append_button_with_pixmap(GNOME_DIALOG(dialog
),
501 _("Quit"), GNOME_STOCK_PIXMAP_QUIT
);
502 gnome_dialog_append_button(GNOME_DIALOG(dialog
),GNOME_STOCK_BUTTON_CANCEL
);
504 result
= (gnome_dialog_run(GNOME_DIALOG(dialog
)) == 0);
506 button
= gtk_button_new_with_label (_("Quit"));
507 GTK_WIDGET_SET_FLAGS (button
, GTK_CAN_DEFAULT
);
508 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog
)->action_area
),
509 button
, TRUE
, TRUE
, 0);
510 gtk_signal_connect (GTK_OBJECT (button
), "clicked",
511 GTK_SIGNAL_FUNC(set_true_callback
),
513 gtk_signal_connect_object (GTK_OBJECT (button
), "clicked",
514 GTK_SIGNAL_FUNC (gtk_widget_destroy
),
515 GTK_OBJECT (dialog
));
516 gtk_widget_show (button
);
518 button
= gtk_button_new_with_label (_("Cancel"));
519 GTK_WIDGET_SET_FLAGS (button
, GTK_CAN_DEFAULT
);
520 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog
)->action_area
),
521 button
, TRUE
, TRUE
, 0);
522 gtk_widget_grab_default (button
);
523 gtk_signal_connect_object (GTK_OBJECT (button
), "clicked",
524 GTK_SIGNAL_FUNC (gtk_widget_destroy
),
525 GTK_OBJECT (dialog
));
527 gtk_widget_show (button
);
529 gtk_widget_show (dialog
);
531 /* Make dialog modal: */
532 gtk_widget_grab_focus(dialog
);
533 gtk_grab_add(dialog
);
542 /* Save menu accelerators */
543 filename
= dia_config_filename("menus" G_DIR_SEPARATOR_S
"toolbox");
544 if (filename
!=NULL
) {
545 GtkPatternSpec pattern
;
547 gtk_pattern_spec_init(&pattern
, "*<Toolbox>*");
549 gtk_item_factory_dump_rc (filename
, &pattern
, TRUE
);
551 gtk_pattern_spec_free_segs(&pattern
);
554 /* Free loads of stuff (toolbox) */
556 list
= open_diagrams
;
558 Diagram
*dia
= (Diagram
*)list
->data
;
559 list
= g_list_next(list
);
561 slist
= dia
->displays
;
562 while (slist
!=NULL
) {
563 DDisplay
*ddisp
= (DDisplay
*)slist
->data
;
564 slist
= g_slist_next(slist
);
566 gtk_widget_destroy(ddisp
->shell
);
569 /* The diagram is freed when the last display is destroyed */
574 dia_pluginrc_write();
576 /* save recent file history */
577 recent_file_history_write();
580 app_exit_once
= TRUE
;
583 static void create_user_dirs(void)
588 /* not necessary to quit the program with g_error, everywhere else
589 * dia_config_filename appears to be used. Spit out a warning ...
591 if (!g_get_home_dir())
593 g_warning(_("Could not create per-user Dia config directory"));
594 return; /* ... and return. Probably removes my one and only FAQ. --HB */
597 dir
= g_strconcat(g_get_home_dir(), G_DIR_SEPARATOR_S
".dia", NULL
);
598 if (mkdir(dir
, 0755) && errno
!= EEXIST
)
600 g_error(_("Could not create per-user Dia config directory"));
601 #else /* HB: it this really a reason to exit the program on *nix ? */
602 g_warning(_("Could not create per-user Dia config directory. Please make "
603 "sure that the environment variable HOME points to an existing directory."));
606 /* it is no big deal if these directories can't be created */
607 subdir
= g_strconcat(dir
, G_DIR_SEPARATOR_S
"objects", NULL
);
610 subdir
= g_strconcat(dir
, G_DIR_SEPARATOR_S
"shapes", NULL
);
613 subdir
= g_strconcat(dir
, G_DIR_SEPARATOR_S
"sheets", NULL
);
620 static PluginInitResult
621 internal_plugin_init(PluginInfo
*info
)
623 if (!dia_plugin_info_init(info
, "Internal",
624 _("Objects and filters internal to dia"),
626 return DIA_PLUGIN_INIT_ERROR
;
628 /* register the group object type */
629 object_register_type(&group_type
);
631 /* register import filters */
632 filter_register_import(&dia_import_filter
);
634 /* register export filters */
635 filter_register_export(&dia_export_filter
);
636 filter_register_export(&eps_export_filter
);
637 #if defined(HAVE_LIBPNG) && defined(HAVE_LIBART)
638 filter_register_export(&png_export_filter
);
641 return DIA_PLUGIN_INIT_OK
;