1 /* PSPPIRE - a graphical user interface for PSPP.
2 Copyright (C) 2004, 2005, 2006, 2009, 2010, 2011 Free Software Foundation
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 3 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, see <http://www.gnu.org/licenses/>. */
20 #include <gsl/gsl_errno.h>
25 #include "data/any-reader.h"
26 #include "data/casereader.h"
27 #include "data/dataset.h"
28 #include "data/datasheet.h"
29 #include "data/file-handle-def.h"
30 #include "data/file-name.h"
31 #include "data/por-file-reader.h"
32 #include "data/session.h"
33 #include "data/settings.h"
34 #include "data/sys-file-reader.h"
36 #include "language/lexer/lexer.h"
37 #include "libpspp/i18n.h"
38 #include "libpspp/message.h"
39 #include "libpspp/version.h"
41 #include "output/driver.h"
42 #include "output/journal.h"
43 #include "output/message-item.h"
45 #include "ui/gui/dict-display.h"
46 #include "ui/gui/executor.h"
47 #include "ui/gui/psppire-data-store.h"
48 #include "ui/gui/psppire-data-window.h"
49 #include "ui/gui/psppire-dict.h"
50 #include "ui/gui/psppire.h"
51 #include "ui/gui/psppire-output-window.h"
52 #include "ui/gui/psppire-syntax-window.h"
53 #include "ui/gui/psppire-selector.h"
54 #include "ui/gui/psppire-var-store.h"
55 #include "ui/gui/psppire-var-view.h"
56 #include "ui/gui/psppire-window-register.h"
57 #include "ui/gui/widgets.h"
58 #include "ui/source-init-opts.h"
59 #include "ui/syntax-gen.h"
61 #include "gl/configmake.h"
62 #include "gl/xalloc.h"
63 #include "gl/relocatable.h"
65 static void inject_renamed_icons (void);
66 static void create_icon_factory (void);
67 static gchar *local_to_filename_encoding (const char *fn);
70 #define _(msgid) gettext (msgid)
71 #define N_(msgid) msgid
75 initialize (const char *data_file)
77 PsppireDataWindow *data_window;
81 preregister_widgets ();
83 gsl_set_error_handler_off ();
87 psppire_set_lexer (NULL);
89 bind_textdomain_codeset (PACKAGE, "UTF-8");
91 inject_renamed_icons ();
92 create_icon_factory ();
94 psppire_output_window_setup ();
99 psppire_selector_set_default_selection_func (GTK_TYPE_ENTRY, insert_source_row_into_entry);
100 psppire_selector_set_default_selection_func (PSPPIRE_VAR_VIEW_TYPE, insert_source_row_into_tree_view);
101 psppire_selector_set_default_selection_func (GTK_TYPE_TREE_VIEW, insert_source_row_into_tree_view);
103 data_window = psppire_default_data_window ();
107 gchar *filename = local_to_filename_encoding (data_file);
109 /* Check to see if the file is a .sav or a .por file. If not
110 assume that it is a syntax file */
111 if ( any_reader_may_open (filename))
112 psppire_window_load (PSPPIRE_WINDOW (data_window), filename);
114 open_syntax_window (filename, NULL);
130 func (gpointer key, gpointer value, gpointer data)
133 PsppireWindow *window = PSPPIRE_WINDOW (value);
135 g_signal_emit_by_name (window, "delete-event", 0, &rv);
141 PsppireWindowRegister *reg = psppire_window_register_new ();
142 psppire_window_register_foreach (reg, func, NULL);
148 inject_renamed_icon (const char *icon, const char *substitute)
150 GtkIconTheme *theme = gtk_icon_theme_get_default ();
151 if (!gtk_icon_theme_has_icon (theme, icon)
152 && gtk_icon_theme_has_icon (theme, substitute))
154 gint *sizes = gtk_icon_theme_get_icon_sizes (theme, substitute);
157 for (p = sizes; *p != 0; p++)
162 pb = gtk_icon_theme_load_icon (theme, substitute, size, 0, NULL);
165 GdkPixbuf *copy = gdk_pixbuf_copy (pb);
167 gtk_icon_theme_add_builtin_icon (icon, size, copy);
173 /* Avoid a bug in GTK+ 2.22 that can cause a segfault at startup time. Earlier
174 and later versions of GTK+ do not have the bug. Bug #31511.
176 Based on this patch against Inkscape:
177 https://launchpadlibrarian.net/60175914/copy_renamed_icons.patch */
179 inject_renamed_icons (void)
181 if (gtk_major_version == 2 && gtk_minor_version == 22)
183 inject_renamed_icon ("gtk-file", "document-x-generic");
184 inject_renamed_icon ("gtk-directory", "folder");
190 const char *file_name;
195 static const struct icon_info icons[] =
197 {PKGDATADIR "/value-labels.png", "pspp-value-labels"},
198 {PKGDATADIR "/weight-cases.png", "pspp-weight-cases"},
199 {PKGDATADIR "/goto-variable.png", "pspp-goto-variable"},
200 {PKGDATADIR "/insert-variable.png", "pspp-insert-variable"},
201 {PKGDATADIR "/insert-case.png", "pspp-insert-case"},
202 {PKGDATADIR "/split-file.png", "pspp-split-file"},
203 {PKGDATADIR "/select-cases.png", "pspp-select-cases"},
204 {PKGDATADIR "/recent-dialogs.png", "pspp-recent-dialogs"},
205 {PKGDATADIR "/nominal.png", "var-nominal"},
206 {PKGDATADIR "/ordinal.png", "var-ordinal"},
207 {PKGDATADIR "/scale.png", "var-scale"},
208 {PKGDATADIR "/string.png", "var-string"},
209 {PKGDATADIR "/date-scale.png", "var-date-scale"}
213 create_icon_factory (void)
216 GtkIconFactory *factory = gtk_icon_factory_new ();
218 for (i = 0 ; i < sizeof (icons) / sizeof(icons[0]); ++i)
222 gdk_pixbuf_new_from_file (relocate (icons[i].file_name), &err);
226 GtkIconSet *icon_set = gtk_icon_set_new_from_pixbuf (pixbuf);
227 g_object_unref (pixbuf);
228 gtk_icon_factory_add ( factory, icons[i].id, icon_set);
232 g_warning ("Cannot create icon: %s", err->message);
233 g_clear_error (&err);
238 /* Create our own "pspp-stock-reset" item, using the
239 GTK_STOCK_REFRESH icon set */
241 GtkStockItem items[] = {
242 {"pspp-stock-reset", N_("_Reset"), 0, 0, PACKAGE},
243 {"pspp-stock-select", N_("_Select"), 0, 0, PACKAGE}
247 gtk_stock_add (items, 2);
248 gtk_icon_factory_add (factory, "pspp-stock-reset",
249 gtk_icon_factory_lookup_default (GTK_STOCK_REFRESH)
252 gtk_icon_factory_add (factory, "pspp-stock-select",
253 gtk_icon_factory_lookup_default (GTK_STOCK_INDEX)
257 gtk_icon_factory_add_default (factory);
261 Convert a filename from the local encoding into "filename" encoding.
262 The return value will be allocated on the heap. It is the responsibility
263 of the caller to free it.
266 local_to_filename_encoding (const char *fn)
268 gchar *filename = NULL;
270 const gchar *local_encoding = NULL;
272 const gboolean local_is_utf8 = g_get_charset (&local_encoding);
274 /* There seems to be no Glib function to convert from local encoding
275 to filename encoding. Therefore it has to be done in two steps:
276 the intermediate encoding is UTF8.
278 Either step could fail. However, in many cases the file can still
279 be loaded even if the conversion fails. So in those cases, after showing
280 a warning, we simply copy the locally encoded filename to the destination
281 and hope for the best.
291 utf8 = g_locale_to_utf8 (fn, -1, NULL, &written, &err);
294 g_warning ("Cannot convert filename from local encoding `%s' to UTF-8: %s",
297 g_clear_error (&err);
304 filename = g_filename_from_utf8 (utf8, written, NULL, NULL, &err);
305 if ( NULL == filename)
307 g_warning ("Cannot convert filename from UTF8 to filename encoding: %s",
309 g_clear_error (&err);
315 if ( filename == NULL)
316 filename = xstrdup (fn);
322 handle_msg (const struct msg *m_, void *lexer_)
324 struct lexer *lexer = lexer_;
327 if (lexer != NULL && m.file_name == NULL)
329 m.file_name = CONST_CAST (char *, lex_get_file_name (lexer));
330 m.first_line = lex_get_first_line_number (lexer, 0);
331 m.last_line = lex_get_last_line_number (lexer, 0);
332 m.first_column = lex_get_first_column (lexer, 0);
333 m.last_column = lex_get_last_column (lexer, 0);
336 message_item_submit (message_item_create (&m));
340 psppire_set_lexer (struct lexer *lexer)
342 msg_set_handler (handle_msg, lexer);