Update Spanish translation
[gnumeric.git] / src / main-application.c
blobaa3a2cac80162944090f5af75f58a7a98180f397
1 /*
2 * main-application.c: Main entry point for the Gnumeric application
4 * Author:
5 * Jon Kåre Hellan <hellan@acm.org>
6 * Morten Welinder <terra@gnome.org>
7 * Jody Goldberg <jody@gnome.org>
9 * Copyright (C) 2002-2004, Jon Kåre Hellan
12 #include <gnumeric-config.h>
13 #include <glib/gi18n.h>
14 #include <gnumeric.h>
15 #include <libgnumeric.h>
16 #ifdef G_OS_WIN32
17 #define _WIN32_WINNT 0x0501
18 #include <windows.h>
19 #include <io.h>
20 #endif
22 #include <command-context.h>
23 #include <goffice/goffice.h>
24 #include <io-context-gtk.h>
25 /* TODO: Get rid of this one */
26 #include <command-context-stderr.h>
27 #include <wbc-gtk-impl.h>
28 #include <workbook-view.h>
29 #include <workbook.h>
30 #include <gui-file.h>
31 #include <gnumeric-conf.h>
32 #include <gnumeric-paths.h>
33 #include <session.h>
34 #include <sheet.h>
35 #include <gutils.h>
36 #include <gnm-plugin.h>
37 #include <application.h>
38 #include <func.h>
40 #include <glib/gstdio.h>
42 #include <sys/types.h>
43 #include <time.h>
44 #include <string.h>
45 #include <locale.h>
47 #ifdef HAVE_FPU_CONTROL_H
48 #include <fpu_control.h>
49 #endif
51 static gboolean immediate_exit_flag = FALSE;
52 static gboolean gnumeric_no_splash = FALSE;
53 static gboolean gnumeric_no_warnings = FALSE;
54 static gchar *geometry = NULL;
55 static gchar **startup_files;
57 static const GOptionEntry gnumeric_options [] = {
58 /*********************************
59 * Public Variables */
60 { "geometry", 'g', 0, G_OPTION_ARG_STRING, &geometry,
61 N_("Specify the size and location of the initial window"),
62 N_("WIDTHxHEIGHT+XOFF+YOFF")
64 { "no-splash", 0, 0, G_OPTION_ARG_NONE, &gnumeric_no_splash,
65 N_("Don't show splash screen"), NULL },
66 { "no-warnings", 0, 0, G_OPTION_ARG_NONE, &gnumeric_no_warnings,
67 N_("Don't display warning dialogs when importing"),
68 NULL
71 /*********************************
72 * Hidden Actions */
74 "quit", 0,
75 G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &immediate_exit_flag,
76 N_("Exit immediately after loading the selected books"),
77 NULL
79 { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &startup_files, NULL, NULL },
80 { NULL }
84 static void
85 handle_paint_events (void)
87 /* FIXME: we need to mask input events correctly here */
88 /* Show something coherent */
89 while (gtk_events_pending () && !gnm_app_shutting_down ())
90 gtk_main_iteration_do (FALSE);
93 static GObject *program = NULL;
95 static void
96 gnumeric_arg_shutdown (void)
98 if (program) {
99 g_object_unref (program);
100 program = NULL;
104 static void
105 gnumeric_arg_parse (int argc, char **argv)
107 GOptionContext *ocontext;
108 GError *error = NULL;
110 ocontext = g_option_context_new (_("[FILE ...]"));
111 g_option_context_add_main_entries (ocontext, gnumeric_options, GETTEXT_PACKAGE);
112 g_option_context_add_group (ocontext, gnm_get_option_group ());
114 #if defined(G_OS_WIN32)
115 /* we have already translated to utf8, do not do it again.
116 * http://bugzilla.gnome.org/show_bug.cgi?id=361321 */
117 g_option_context_set_delocalize (ocontext, FALSE);
118 #endif
120 g_option_context_add_group (ocontext, gtk_get_option_group (TRUE));
121 g_option_context_parse (ocontext, &argc, &argv, &error);
123 if (ocontext)
124 g_option_context_free (ocontext);
126 if (error) {
127 g_printerr (_("%s\nRun '%s --help' to see a full list of available command line options.\n"),
128 error->message, argv[0]);
129 g_error_free (error);
130 exit (1);
133 gtk_init (&argc, &argv);
137 * WARNING WARNING WARNING
138 * This does not belong here
139 * but it is expedient for now to get things to compile
141 #warning "REMOVE REMOVE REMOVE"
142 static void
143 store_plugin_state (void)
145 GSList *active_plugins = go_plugins_get_active_plugins ();
146 gnm_conf_set_plugins_active (active_plugins);
147 g_slist_free (active_plugins);
150 static gboolean
151 cb_kill_wbcg (WBCGtk *wbcg)
153 gboolean still_open = wbc_gtk_close (wbcg);
154 g_assert (!still_open);
155 return FALSE;
158 static void
159 cb_workbook_removed (void)
161 if (gnm_app_workbook_list () == NULL) {
162 gtk_main_quit ();
166 static void
167 cpu_sanity_check (void)
169 #if (defined(i386) || defined(__i386__) || defined(__i386) || defined(__x86_64__) || defined(__x86_64)) && HAVE_FPU_CONTROL_H
170 fpu_control_t state;
171 const fpu_control_t mask = _FPU_EXTENDED | _FPU_DOUBLE | _FPU_SINGLE;
173 _FPU_GETCW (state);
174 if ((state & mask) != _FPU_EXTENDED) {
175 // Evidently currentlly happinging when Windows runs Linux
176 // binaries. See bug 794515.
177 g_warning ("Sanity check failed! The cpu is not in \"extended\" mode as it should be. Attempting to fix, but expect trouble.");
178 state = (state & ~mask) | _FPU_EXTENDED;
179 _FPU_SETCW (state);
181 #else
182 // Hope for the best
183 #endif
188 main (int argc, char const **argv)
190 gboolean opened_workbook = FALSE;
191 GOIOContext *ioc;
192 WorkbookView *wbv;
193 GSList *wbcgs_to_kill = NULL;
194 GOCmdContext *cc;
195 gboolean any_error = FALSE;
197 #ifdef G_OS_WIN32
198 gboolean has_console;
199 #endif
201 /* No code before here, we need to init threads */
202 argv = gnm_pre_parse_init (argc, argv);
204 cpu_sanity_check ();
207 * Attempt to disable Ubuntu's funky, non-working scroll
208 * bars. This needs to be done before gtk starts loading
209 * modules. Note: the following call will not replace
210 * an existing setting, so you can run with =1 if you like.
212 g_setenv ("LIBOVERLAY_SCROLLBAR", "0", FALSE);
214 #ifdef G_OS_WIN32
215 has_console = FALSE;
217 typedef BOOL (CALLBACK* LPFNATTACHCONSOLE)(DWORD);
218 LPFNATTACHCONSOLE MyAttachConsole;
219 HMODULE hmod;
221 if ((hmod = GetModuleHandle("kernel32.dll"))) {
222 MyAttachConsole = (LPFNATTACHCONSOLE) GetProcAddress(hmod, "AttachConsole");
223 if (MyAttachConsole && MyAttachConsole(ATTACH_PARENT_PROCESS)) {
224 freopen("CONOUT$", "w", stdout);
225 freopen("CONOUT$", "w", stderr);
226 dup2(fileno(stdout), 1);
227 dup2(fileno(stderr), 2);
228 has_console = TRUE;
232 #endif
234 gnumeric_arg_parse (argc, (char **)argv);
235 bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
236 bind_textdomain_codeset (GETTEXT_PACKAGE "-functions", "UTF-8");
238 gnm_session_init (argv[0]);
240 gnm_init ();
242 cc = gnm_cmd_context_stderr_new ();
243 go_component_set_default_command_context (cc);
244 g_object_unref (cc);
246 cc = g_object_new (GNM_TYPE_IO_CONTEXT_GTK,
247 "show-splash", !gnumeric_no_splash,
248 "show-warnings", !gnumeric_no_warnings,
249 NULL);
250 ioc = GO_IO_CONTEXT (g_object_ref (cc));
251 handle_paint_events ();
253 /* Keep in sync with .desktop file */
254 g_set_application_name (_("Gnumeric Spreadsheet"));
255 gnm_plugins_init (GO_CMD_CONTEXT (ioc));
257 if (startup_files) {
258 int i, N;
260 N = g_strv_length (startup_files);
261 go_io_context_set_num_files (ioc, N);
262 for (i = 0; i < N && !gnm_app_shutting_down (); i++) {
263 char *uri = go_shell_arg_to_uri (startup_files[i]);
265 if (uri == NULL) {
266 g_warning ("Ignoring invalid URI.");
267 any_error = TRUE;
268 continue;
271 go_io_context_processing_file (ioc, uri);
272 wbv = workbook_view_new_from_uri (uri, NULL, ioc, NULL);
273 g_free (uri);
275 if (go_io_error_occurred (ioc) ||
276 go_io_warning_occurred (ioc)) {
277 if (go_io_error_occurred (ioc))
278 any_error = TRUE;
279 go_io_error_display (ioc);
280 go_io_error_clear (ioc);
282 if (wbv != NULL) {
283 WBCGtk *wbcg;
285 workbook_update_history (wb_view_get_workbook (wbv), GNM_FILE_SAVE_AS_STYLE_SAVE);
287 wbcg = wbc_gtk_new (wbv, NULL, NULL, geometry);
288 geometry = NULL;
289 sheet_update (wb_view_cur_sheet (wbv));
290 opened_workbook = TRUE;
291 gnm_io_context_gtk_set_transient_for (GNM_IO_CONTEXT_GTK (ioc),
292 wbcg_toplevel (wbcg));
293 if (immediate_exit_flag)
294 wbcgs_to_kill = g_slist_prepend (wbcgs_to_kill,
295 wbcg);
297 /* cheesy attempt to keep the ui from freezing during
298 load */
299 handle_paint_events ();
300 if (gnm_io_context_gtk_get_interrupted (GNM_IO_CONTEXT_GTK (ioc)))
301 break; /* Don't load any more workbooks */
305 g_object_unref (cc);
306 cc = NULL;
308 // If we actually opened a workbook, we are not about to exit so
309 // suppress the error. (Returning an error when the GUI exits
310 // down the line is not helpful.)
311 if (opened_workbook)
312 any_error = FALSE;
314 // If we were intentionally short circuited exit now
315 if (any_error || gnm_app_shutting_down ()) {
316 g_object_unref (ioc);
317 g_slist_foreach (wbcgs_to_kill, (GFunc)cb_kill_wbcg, NULL);
318 } else {
319 g_object_set (gnm_app_get_app (),
320 "initial-open-complete", TRUE, NULL);
322 if (!opened_workbook) {
323 gint n_of_sheets = gnm_conf_get_core_workbook_n_sheet ();
324 wbc_gtk_new (NULL,
325 workbook_new_with_sheets (n_of_sheets),
326 NULL, geometry);
329 if (immediate_exit_flag) {
330 GSList *l;
331 for (l = wbcgs_to_kill; l; l = l->next)
332 g_idle_add ((GSourceFunc)cb_kill_wbcg, l->data);
335 g_signal_connect (gnm_app_get_app (),
336 "workbook_removed",
337 G_CALLBACK (cb_workbook_removed),
338 NULL);
340 gnm_io_context_gtk_discharge_splash (GNM_IO_CONTEXT_GTK (ioc));
341 g_object_unref (ioc);
343 gtk_main ();
346 g_object_set (gnm_app_get_app (), "shutting-down", TRUE, NULL);
348 g_slist_free (wbcgs_to_kill);
349 gnumeric_arg_shutdown ();
350 store_plugin_state ();
351 gnm_shutdown ();
353 #if defined(G_OS_WIN32)
354 if (has_console) {
355 close(1);
356 close(2);
357 FreeConsole();
359 #endif
361 gnm_pre_parse_shutdown ();
362 go_component_set_default_command_context (NULL);
365 * This helps finding leaks. We might want it in developent
366 * only.
368 if (gnm_debug_flag ("close-displays")) {
369 GSList *displays;
371 gdk_flush();
372 while (g_main_context_iteration (NULL, FALSE))
373 ;/* nothing */
375 displays = gdk_display_manager_list_displays
376 (gdk_display_manager_get ());
377 g_slist_foreach (displays, (GFunc)gdk_display_close, NULL);
378 g_slist_free (displays);
381 return any_error ? 1 : 0;