1 /* PSPPIRE - a graphical user interface for PSPP.
2 Copyright (C) 2004, 2005, 2006, 2009, 2010, 2011, 2012 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)
79 preregister_widgets ();
81 gsl_set_error_handler_off ();
85 psppire_set_lexer (NULL);
87 bind_textdomain_codeset (PACKAGE, "UTF-8");
89 inject_renamed_icons ();
90 create_icon_factory ();
92 psppire_output_window_setup ();
97 psppire_selector_set_default_selection_func (GTK_TYPE_ENTRY, insert_source_row_into_entry);
98 psppire_selector_set_default_selection_func (PSPPIRE_VAR_VIEW_TYPE, insert_source_row_into_tree_view);
99 psppire_selector_set_default_selection_func (GTK_TYPE_TREE_VIEW, insert_source_row_into_tree_view);
103 gchar *filename = local_to_filename_encoding (data_file);
105 /* Check to see if the file is a .sav or a .por file. If not
106 assume that it is a syntax file */
107 if ( any_reader_may_open (filename))
108 open_data_window (NULL, filename);
111 create_data_window ();
112 open_syntax_window (filename, NULL);
118 create_data_window ();
131 func (gpointer key, gpointer value, gpointer data)
134 PsppireWindow *window = PSPPIRE_WINDOW (value);
136 g_signal_emit_by_name (window, "delete-event", 0, &rv);
142 PsppireWindowRegister *reg = psppire_window_register_new ();
143 psppire_window_register_foreach (reg, func, NULL);
149 inject_renamed_icon (const char *icon, const char *substitute)
151 GtkIconTheme *theme = gtk_icon_theme_get_default ();
152 if (!gtk_icon_theme_has_icon (theme, icon)
153 && gtk_icon_theme_has_icon (theme, substitute))
155 gint *sizes = gtk_icon_theme_get_icon_sizes (theme, substitute);
158 for (p = sizes; *p != 0; p++)
163 pb = gtk_icon_theme_load_icon (theme, substitute, size, 0, NULL);
166 GdkPixbuf *copy = gdk_pixbuf_copy (pb);
168 gtk_icon_theme_add_builtin_icon (icon, size, copy);
174 /* Avoid a bug in GTK+ 2.22 that can cause a segfault at startup time. Earlier
175 and later versions of GTK+ do not have the bug. Bug #31511.
177 Based on this patch against Inkscape:
178 https://launchpadlibrarian.net/60175914/copy_renamed_icons.patch */
180 inject_renamed_icons (void)
182 if (gtk_major_version == 2 && gtk_minor_version == 22)
184 inject_renamed_icon ("gtk-file", "document-x-generic");
185 inject_renamed_icon ("gtk-directory", "folder");
191 const char *file_name;
196 static const struct icon_info icons[] =
198 {PKGDATADIR "/value-labels.png", "pspp-value-labels"},
199 {PKGDATADIR "/weight-cases.png", "pspp-weight-cases"},
200 {PKGDATADIR "/goto-variable.png", "pspp-goto-variable"},
201 {PKGDATADIR "/insert-variable.png", "pspp-insert-variable"},
202 {PKGDATADIR "/insert-case.png", "pspp-insert-case"},
203 {PKGDATADIR "/split-file.png", "pspp-split-file"},
204 {PKGDATADIR "/select-cases.png", "pspp-select-cases"},
205 {PKGDATADIR "/recent-dialogs.png", "pspp-recent-dialogs"},
206 {PKGDATADIR "/nominal.png", "var-nominal"},
207 {PKGDATADIR "/ordinal.png", "var-ordinal"},
208 {PKGDATADIR "/scale.png", "var-scale"},
209 {PKGDATADIR "/string.png", "var-string"},
210 {PKGDATADIR "/date-scale.png", "var-date-scale"}
214 create_icon_factory (void)
217 GtkIconFactory *factory = gtk_icon_factory_new ();
219 for (i = 0 ; i < sizeof (icons) / sizeof(icons[0]); ++i)
223 gdk_pixbuf_new_from_file (relocate (icons[i].file_name), &err);
227 GtkIconSet *icon_set = gtk_icon_set_new_from_pixbuf (pixbuf);
228 g_object_unref (pixbuf);
229 gtk_icon_factory_add ( factory, icons[i].id, icon_set);
233 g_warning ("Cannot create icon: %s", err->message);
234 g_clear_error (&err);
239 /* Create our own "pspp-stock-reset" item, using the
240 GTK_STOCK_REFRESH icon set */
242 GtkStockItem items[] = {
243 {"pspp-stock-reset", N_("_Reset"), 0, 0, PACKAGE},
244 {"pspp-stock-select", N_("_Select"), 0, 0, PACKAGE}
248 gtk_stock_add (items, 2);
249 gtk_icon_factory_add (factory, "pspp-stock-reset",
250 gtk_icon_factory_lookup_default (GTK_STOCK_REFRESH)
253 gtk_icon_factory_add (factory, "pspp-stock-select",
254 gtk_icon_factory_lookup_default (GTK_STOCK_INDEX)
258 gtk_icon_factory_add_default (factory);
262 Convert a filename from the local encoding into "filename" encoding.
263 The return value will be allocated on the heap. It is the responsibility
264 of the caller to free it.
267 local_to_filename_encoding (const char *fn)
269 gchar *filename = NULL;
271 const gchar *local_encoding = NULL;
273 const gboolean local_is_utf8 = g_get_charset (&local_encoding);
275 /* There seems to be no Glib function to convert from local encoding
276 to filename encoding. Therefore it has to be done in two steps:
277 the intermediate encoding is UTF8.
279 Either step could fail. However, in many cases the file can still
280 be loaded even if the conversion fails. So in those cases, after showing
281 a warning, we simply copy the locally encoded filename to the destination
282 and hope for the best.
292 utf8 = g_locale_to_utf8 (fn, -1, NULL, &written, &err);
295 g_warning ("Cannot convert filename from local encoding `%s' to UTF-8: %s",
298 g_clear_error (&err);
305 filename = g_filename_from_utf8 (utf8, written, NULL, NULL, &err);
306 if ( NULL == filename)
308 g_warning ("Cannot convert filename from UTF8 to filename encoding: %s",
310 g_clear_error (&err);
316 if ( filename == NULL)
317 filename = xstrdup (fn);
323 handle_msg (const struct msg *m_, void *lexer_)
325 struct lexer *lexer = lexer_;
328 if (lexer != NULL && m.file_name == NULL)
330 m.file_name = CONST_CAST (char *, lex_get_file_name (lexer));
331 m.first_line = lex_get_first_line_number (lexer, 0);
332 m.last_line = lex_get_last_line_number (lexer, 0);
333 m.first_column = lex_get_first_column (lexer, 0);
334 m.last_column = lex_get_last_column (lexer, 0);
337 message_item_submit (message_item_create (&m));
341 psppire_set_lexer (struct lexer *lexer)
343 msg_set_handler (handle_msg, lexer);