added gas bottle shape
[dia.git] / app / app_procs.c
blobacee7fc98f99545b80fb0a0df183a10e79dd2f68
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.
19 #include "config.h"
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <sys/types.h>
24 #include <errno.h>
25 #ifdef HAVE_DIRENT_H
26 #include <dirent.h>
27 #endif
28 #include <sys/stat.h>
29 #include <string.h>
30 #include <signal.h>
31 #include <locale.h>
32 #ifdef HAVE_UNISTD_H
33 #include <unistd.h>
34 #endif
36 #include <gtk/gtk.h>
37 #include <gmodule.h>
39 #if (defined (HAVE_LIBPOPT) && defined (HAVE_POPT_H)) || defined (GNOME)
40 #define HAVE_POPT
41 #endif
43 #ifdef GNOME
44 #include <gnome.h>
45 #else
46 #ifdef HAVE_POPT_H
47 #include <popt.h>
48 #endif
49 #endif
51 #include <parser.h>
53 #ifdef G_OS_WIN32
54 #include <direct.h>
55 #define mkdir(s,a) _mkdir(s)
56 #endif
58 #include "intl.h"
59 #include "app_procs.h"
60 #include "object.h"
61 #include "color.h"
62 #include "tool.h"
63 #include "modify_tool.h"
64 #include "interface.h"
65 #include "group.h"
66 #include "message.h"
67 #include "display.h"
68 #include "layer_dialog.h"
69 #include "load_save.h"
70 #include "preferences.h"
71 #include "dia_dirs.h"
72 #include "render_eps.h"
73 #include "sheet.h"
74 #include "plug-ins.h"
75 #include "recent_files.h"
77 #if defined(HAVE_LIBPNG) && defined(HAVE_LIBART)
78 extern DiaExportFilter png_export_filter;
79 #endif
81 static void create_user_dirs(void);
82 static PluginInitResult internal_plugin_init(PluginInfo *info);
84 #ifdef GNOME
86 static void
87 session_die (gpointer client_data)
89 gtk_main_quit ();
92 static int
93 save_state (GnomeClient *client,
94 gint phase,
95 GnomeRestartStyle save_style,
96 gint shutdown,
97 GnomeInteractStyle interact_style,
98 gint fast,
99 gpointer client_data)
101 gchar *argv[20];
102 gint i = 0;
103 GList *l;
104 Diagram *dia;
106 argv[i++] = "dia";
108 for(l = open_diagrams; l != NULL; l = g_list_next(l)) {
109 dia = (Diagram *)l->data;
110 if(!dia->unsaved) {
111 argv[i++] = dia->filename;
115 gnome_client_set_restart_command (client, i, argv);
116 gnome_client_set_clone_command (client, i, argv);
118 return TRUE;
120 #endif
122 void
123 debug_break(void)
125 /* Break here. All symbols are loaded. */
128 void
129 app_init (int argc, char **argv)
131 Diagram *diagram = NULL;
132 DDisplay *ddisp = NULL;
133 gboolean nosplash = FALSE;
134 #ifdef GNOME
135 GnomeClient *client;
136 #endif
137 char *in_file_name = NULL;
138 char *export_file_name = NULL;
139 #ifdef HAVE_POPT
140 #ifndef GNOME
141 int rc;
142 #endif
143 poptContext poptCtx = NULL;
144 struct poptOption options[] =
146 {"export", 'e', POPT_ARG_STRING, &export_file_name, 0,
147 N_("Export loaded file and exit"), N_("OUTPUT")},
148 {"nosplash", 0, POPT_ARG_NONE, &nosplash, 0,
149 N_("Don't show the splash screen"), NULL },
150 #ifndef GNOME
151 {"help", 'h', POPT_ARG_NONE, 0, 1, N_("Show this help message") },
152 #endif
153 {(char *) NULL, '\0', 0, NULL, 0}
155 #endif
157 gtk_set_locale();
158 setlocale(LC_NUMERIC, "C");
160 bindtextdomain(PACKAGE, LOCALEDIR);
161 textdomain(PACKAGE);
163 if (argv) {
164 #ifdef GNOME
165 gnome_init_with_popt_table(PACKAGE, VERSION, argc, argv, options,
166 0, &poptCtx);
168 client = gnome_master_client();
169 if(client == NULL) {
170 g_warning(_("Can't connect to session manager!\n"));
172 else {
173 gtk_signal_connect(GTK_OBJECT (client), "save_yourself",
174 GTK_SIGNAL_FUNC (save_state), NULL);
175 gtk_signal_connect(GTK_OBJECT (client), "die",
176 GTK_SIGNAL_FUNC (session_die), NULL);
178 #else
179 #ifdef HAVE_POPT
180 poptCtx = poptGetContext(PACKAGE, argc, (const char **)argv, options, 0);
181 poptSetOtherOptionHelp(poptCtx, _("[OPTION...] [FILE...]"));
182 if((rc = poptGetNextOpt(poptCtx)) < -1) {
183 fprintf(stderr,
184 _("Error on option %s: %s.\nRun '%s --help' to see a full list of available command line options.\n"),
185 poptBadOption(poptCtx, 0),
186 poptStrerror(rc),
187 argv[0]);
188 exit(1);
190 if(rc == 1) {
191 poptPrintHelp(poptCtx, stderr, 0);
192 exit(0);
194 #endif
195 gtk_init (&argc, &argv);
196 #endif
199 #if defined(LIBXML_VERSION) && LIBXML_VERSION >= 20000
200 xmlKeepBlanksDefault(0);
201 #endif
203 dia_image_init();
205 gdk_rgb_init();
207 gtk_rc_parse ("diagtkrc");
209 if (!nosplash)
210 app_splash_init("");
211 /* enable_core_dumps(); */
213 create_user_dirs();
215 color_init();
217 font_init();
219 /* Init cursors: */
220 default_cursor = gdk_cursor_new(GDK_LEFT_PTR);
221 ddisplay_set_all_cursor(default_cursor);
223 object_registry_init();
225 dia_register_plugins();
226 dia_register_builtin_plugin(internal_plugin_init);
228 load_all_sheets(); /* new mechanism */
230 debug_break();
232 if (object_get_type("Standard - Box") == NULL) {
233 message_error(_("Couldn't find standard objects when looking for "
234 "object-libs, exiting...\n"));
235 fprintf(stderr, _("Couldn't find standard objects when looking for "
236 "object-libs, exiting...\n"));
237 exit(1);
240 prefs_load();
242 create_layer_dialog();
244 /* further initialization *before* reading files */
245 active_tool = create_modify_tool();
247 create_toolbox();
249 /*fill recent file menu */
250 recent_file_history_init();
252 if (argv) {
253 #ifdef HAVE_POPT
254 while (poptPeekArg(poptCtx)) {
255 in_file_name = (char *)poptGetArg(poptCtx);
256 diagram = diagram_load (in_file_name, NULL);
257 if (export_file_name) {
258 DiaExportFilter *ef;
259 if (!diagram) {
260 fprintf (stderr, _("Need valid input file\n"));
261 exit (1);
263 ef = filter_guess_export_filter(export_file_name);
264 if (!ef)
265 ef = &eps_export_filter;
266 ef->export(diagram->data, export_file_name, in_file_name, ef->user_data);
267 exit (0);
269 if (diagram != NULL) {
270 diagram_update_extents(diagram);
271 ddisp = new_display(diagram);
274 poptFreeContext(poptCtx);
275 #else
276 int i;
277 for (i=1; i<argc; i++) {
278 Diagram *diagram;
279 DDisplay *ddisp;
281 diagram = diagram_load(argv[i], NULL);
283 if (diagram != NULL) {
284 diagram_update_extents(diagram);
285 layer_dialog_set_diagram(diagram);
287 ddisp = new_display(diagram);
289 /* Error messages are done in diagram_load() */
291 #endif
295 static void
296 set_true_callback(GtkWidget *w, int *data)
298 *data = TRUE;
301 void
302 app_exit(void)
304 GList *list;
305 GSList *slist;
306 gchar *filename;
308 if (diagram_modified_exists()) {
309 GtkWidget *dialog;
310 GtkWidget *vbox;
311 GtkWidget *label;
312 #ifndef GNOME
313 GtkWidget *button;
314 #endif
315 int result = FALSE;
317 #ifdef GNOME
318 dialog = gnome_dialog_new(_("Quit, are you sure?"), NULL);
319 vbox = GNOME_DIALOG(dialog)->vbox;
320 gnome_dialog_set_close(GNOME_DIALOG(dialog), TRUE);
321 #else
322 dialog = gtk_dialog_new();
323 vbox = GTK_DIALOG(dialog)->vbox;
324 gtk_window_set_title (GTK_WINDOW (dialog), _("Quit, are you sure?"));
325 gtk_container_set_border_width (GTK_CONTAINER (dialog), 0);
326 #endif
328 gtk_signal_connect (GTK_OBJECT (dialog), "destroy",
329 GTK_SIGNAL_FUNC(gtk_main_quit), NULL);
331 label = gtk_label_new (_("Modified diagrams exists.\n"
332 "Are you sure you want to quit?"));
334 gtk_misc_set_padding (GTK_MISC (label), 10, 10);
335 gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0);
337 gtk_widget_show (label);
339 #ifdef GNOME
340 gnome_dialog_append_button_with_pixmap(GNOME_DIALOG(dialog),
341 _("Quit"), GNOME_STOCK_PIXMAP_QUIT);
342 gnome_dialog_append_button(GNOME_DIALOG(dialog),GNOME_STOCK_BUTTON_CANCEL);
344 result = (gnome_dialog_run(GNOME_DIALOG(dialog)) == 0);
345 #else
346 button = gtk_button_new_with_label (_("Quit"));
347 GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
348 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area),
349 button, TRUE, TRUE, 0);
350 gtk_signal_connect (GTK_OBJECT (button), "clicked",
351 GTK_SIGNAL_FUNC(set_true_callback),
352 &result);
353 gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
354 GTK_SIGNAL_FUNC (gtk_widget_destroy),
355 GTK_OBJECT (dialog));
356 gtk_widget_show (button);
358 button = gtk_button_new_with_label (_("Cancel"));
359 GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
360 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area),
361 button, TRUE, TRUE, 0);
362 gtk_widget_grab_default (button);
363 gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
364 GTK_SIGNAL_FUNC (gtk_widget_destroy),
365 GTK_OBJECT (dialog));
367 gtk_widget_show (button);
369 gtk_widget_show (dialog);
371 /* Make dialog modal: */
372 gtk_widget_grab_focus(dialog);
373 gtk_grab_add(dialog);
375 gtk_main();
376 #endif
378 if (result == FALSE)
379 return;
382 /* Save menu accelerators */
383 filename = dia_config_filename("menus" G_DIR_SEPARATOR_S "toolbox");
384 if (filename!=NULL) {
385 GtkPatternSpec pattern;
387 gtk_pattern_spec_init(&pattern, "*<Toolbox>*");
389 gtk_item_factory_dump_rc (filename, &pattern, TRUE);
390 g_free (filename);
391 gtk_pattern_spec_free_segs(&pattern);
394 /* Free loads of stuff (toolbox) */
396 list = open_diagrams;
397 while (list!=NULL) {
398 Diagram *dia = (Diagram *)list->data;
399 list = g_list_next(list);
401 slist = dia->displays;
402 while (slist!=NULL) {
403 DDisplay *ddisp = (DDisplay *)slist->data;
404 slist = g_slist_next(slist);
406 gtk_widget_destroy(ddisp->shell);
409 /* The diagram is freed when the last display is destroyed */
413 /* save pluginrc */
414 dia_pluginrc_write();
416 /* save recent file history */
417 recent_file_history_write();
419 gtk_main_quit();
422 static void create_user_dirs(void)
424 gchar *dir, *subdir;
426 #ifdef G_OS_WIN32
427 /* not necessary to quit the program with g_error, everywhere else
428 * dia_config_filename appears to be used. Spit out a warning ...
430 if (!g_get_home_dir())
432 g_warning(_("Could not create per-user Dia config directory"));
433 return; /* ... and return. Probably removes my one and only FAQ. --HB */
435 #endif
436 dir = g_strconcat(g_get_home_dir(), G_DIR_SEPARATOR_S ".dia", NULL);
437 if (mkdir(dir, 0755) && errno != EEXIST)
438 g_error(_("Could not create per-user Dia config directory"));
440 /* it is no big deal if these directories can't be created */
441 subdir = g_strconcat(dir, G_DIR_SEPARATOR_S "objects", NULL);
442 mkdir(subdir, 0755);
443 g_free(subdir);
444 subdir = g_strconcat(dir, G_DIR_SEPARATOR_S "shapes", NULL);
445 mkdir(subdir, 0755);
446 g_free(subdir);
447 subdir = g_strconcat(dir, G_DIR_SEPARATOR_S "sheets", NULL);
448 mkdir(subdir, 0755);
449 g_free(subdir);
451 g_free(dir);
454 static PluginInitResult
455 internal_plugin_init(PluginInfo *info)
457 if (!dia_plugin_info_init(info, "Internal",
458 _("Objects and filters internal to dia"),
459 NULL, NULL))
460 return DIA_PLUGIN_INIT_ERROR;
462 /* register the group object type */
463 object_register_type(&group_type);
465 /* register import filters */
466 filter_register_import(&dia_import_filter);
468 /* register export filters */
469 filter_register_export(&dia_export_filter);
470 filter_register_export(&eps_export_filter);
471 #if defined(HAVE_LIBPNG) && defined(HAVE_LIBART)
472 filter_register_export(&png_export_filter);
473 #endif
475 return DIA_PLUGIN_INIT_OK;