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/casereader.h"
26 #include "data/dataset.h"
27 #include "data/datasheet.h"
28 #include "data/file-handle-def.h"
29 #include "data/file-name.h"
30 #include "data/por-file-reader.h"
31 #include "data/session.h"
32 #include "data/settings.h"
33 #include "data/sys-file-reader.h"
35 #include "language/lexer/lexer.h"
36 #include "libpspp/i18n.h"
37 #include "libpspp/message.h"
38 #include "libpspp/version.h"
40 #include "output/driver.h"
41 #include "output/journal.h"
42 #include "output/message-item.h"
44 #include "ui/gui/dict-display.h"
45 #include "ui/gui/executor.h"
46 #include "ui/gui/psppire-data-store.h"
47 #include "ui/gui/psppire-data-window.h"
48 #include "ui/gui/psppire-dict.h"
49 #include "ui/gui/psppire.h"
50 #include "ui/gui/psppire-output-window.h"
51 #include "ui/gui/psppire-selector.h"
52 #include "ui/gui/psppire-var-store.h"
53 #include "ui/gui/psppire-var-view.h"
54 #include "ui/gui/psppire-window-register.h"
55 #include "ui/gui/widgets.h"
56 #include "ui/source-init-opts.h"
57 #include "ui/syntax-gen.h"
59 #include "gl/configmake.h"
60 #include "gl/xalloc.h"
61 #include "gl/relocatable.h"
63 GtkRecentManager *the_recent_mgr;
65 static void inject_renamed_icons (void);
66 static void create_icon_factory (void);
67 static void load_data_file (PsppireDataWindow *, const char *);
69 #define _(msgid) gettext (msgid)
70 #define N_(msgid) msgid
74 initialize (const char *data_file)
76 PsppireDataWindow *data_window;
80 preregister_widgets ();
82 gsl_set_error_handler_off ();
86 psppire_set_lexer (NULL);
88 bind_textdomain_codeset (PACKAGE, "UTF-8");
90 inject_renamed_icons ();
91 create_icon_factory ();
93 psppire_output_window_setup ();
99 the_recent_mgr = gtk_recent_manager_get_default ();
101 psppire_selector_set_default_selection_func (GTK_TYPE_ENTRY, insert_source_row_into_entry);
102 psppire_selector_set_default_selection_func (PSPPIRE_VAR_VIEW_TYPE, insert_source_row_into_tree_view);
103 psppire_selector_set_default_selection_func (GTK_TYPE_TREE_VIEW, insert_source_row_into_tree_view);
105 data_window = psppire_default_data_window ();
106 if (data_file != NULL)
107 load_data_file (data_window, data_file);
108 execute_const_syntax_string (data_window, "");
121 func (gpointer key, gpointer value, gpointer data)
124 PsppireWindow *window = PSPPIRE_WINDOW (value);
126 g_signal_emit_by_name (window, "delete-event", 0, &rv);
132 PsppireWindowRegister *reg = psppire_window_register_new ();
133 psppire_window_register_foreach (reg, func, NULL);
139 inject_renamed_icon (const char *icon, const char *substitute)
141 GtkIconTheme *theme = gtk_icon_theme_get_default ();
142 if (!gtk_icon_theme_has_icon (theme, icon)
143 && gtk_icon_theme_has_icon (theme, substitute))
145 gint *sizes = gtk_icon_theme_get_icon_sizes (theme, substitute);
148 for (p = sizes; *p != 0; p++)
153 pb = gtk_icon_theme_load_icon (theme, substitute, size, 0, NULL);
156 GdkPixbuf *copy = gdk_pixbuf_copy (pb);
158 gtk_icon_theme_add_builtin_icon (icon, size, copy);
164 /* Avoid a bug in GTK+ 2.22 that can cause a segfault at startup time. Earlier
165 and later versions of GTK+ do not have the bug. Bug #31511.
167 Based on this patch against Inkscape:
168 https://launchpadlibrarian.net/60175914/copy_renamed_icons.patch */
170 inject_renamed_icons (void)
172 if (gtk_major_version == 2 && gtk_minor_version == 22)
174 inject_renamed_icon ("gtk-file", "document-x-generic");
175 inject_renamed_icon ("gtk-directory", "folder");
181 const char *file_name;
186 static const struct icon_info icons[] =
188 {PKGDATADIR "/value-labels.png", "pspp-value-labels"},
189 {PKGDATADIR "/weight-cases.png", "pspp-weight-cases"},
190 {PKGDATADIR "/goto-variable.png", "pspp-goto-variable"},
191 {PKGDATADIR "/insert-variable.png", "pspp-insert-variable"},
192 {PKGDATADIR "/insert-case.png", "pspp-insert-case"},
193 {PKGDATADIR "/split-file.png", "pspp-split-file"},
194 {PKGDATADIR "/select-cases.png", "pspp-select-cases"},
195 {PKGDATADIR "/recent-dialogs.png", "pspp-recent-dialogs"},
196 {PKGDATADIR "/nominal.png", "var-nominal"},
197 {PKGDATADIR "/ordinal.png", "var-ordinal"},
198 {PKGDATADIR "/scale.png", "var-scale"},
199 {PKGDATADIR "/string.png", "var-string"},
200 {PKGDATADIR "/date-scale.png", "var-date-scale"}
204 create_icon_factory (void)
207 GtkIconFactory *factory = gtk_icon_factory_new ();
209 for (i = 0 ; i < sizeof (icons) / sizeof(icons[0]); ++i)
213 gdk_pixbuf_new_from_file (relocate (icons[i].file_name), &err);
217 GtkIconSet *icon_set = gtk_icon_set_new_from_pixbuf (pixbuf);
218 g_object_unref (pixbuf);
219 gtk_icon_factory_add ( factory, icons[i].id, icon_set);
223 g_warning ("Cannot create icon: %s", err->message);
224 g_clear_error (&err);
229 /* Create our own "pspp-stock-reset" item, using the
230 GTK_STOCK_REFRESH icon set */
232 GtkStockItem items[] = {
233 {"pspp-stock-reset", N_("_Reset"), 0, 0, PACKAGE},
234 {"pspp-stock-select", N_("_Select"), 0, 0, PACKAGE}
238 gtk_stock_add (items, 2);
239 gtk_icon_factory_add (factory, "pspp-stock-reset",
240 gtk_icon_factory_lookup_default (GTK_STOCK_REFRESH)
243 gtk_icon_factory_add (factory, "pspp-stock-select",
244 gtk_icon_factory_lookup_default (GTK_STOCK_INDEX)
248 gtk_icon_factory_add_default (factory);
252 load_data_file (PsppireDataWindow *window, const char *arg)
254 gchar *filename = NULL;
256 const gchar *local_encoding = NULL;
258 const gboolean local_is_utf8 = g_get_charset (&local_encoding);
260 /* There seems to be no Glib function to convert from local encoding
261 to filename encoding. Therefore it has to be done in two steps:
262 the intermediate encoding is UTF8.
264 Either step could fail. However, in many cases the file can still
265 be loaded even if the conversion fails. So in those cases, after showing
266 a warning, we simply copy the locally encoded filename to the destination
267 and hope for the best.
272 utf8 = xstrdup (arg);
277 utf8 = g_locale_to_utf8 (arg, -1, NULL, &written, &err);
280 g_warning ("Cannot convert filename from local encoding `%s' to UTF-8: %s",
283 g_clear_error (&err);
290 filename = g_filename_from_utf8 (utf8, written, NULL, NULL, &err);
291 if ( NULL == filename)
293 g_warning ("Cannot convert filename from UTF8 to filename encoding: %s",
295 g_clear_error (&err);
301 if ( filename == NULL)
302 filename = xstrdup (arg);
304 psppire_window_load (PSPPIRE_WINDOW (window), filename);
310 handle_msg (const struct msg *m_, void *lexer_)
312 struct lexer *lexer = lexer_;
315 if (lexer != NULL && m.file_name == NULL)
317 m.file_name = CONST_CAST (char *, lex_get_file_name (lexer));
318 m.first_line = lex_get_first_line_number (lexer, 0);
319 m.last_line = lex_get_last_line_number (lexer, 0);
320 m.first_column = lex_get_first_column (lexer, 0);
321 m.last_column = lex_get_last_column (lexer, 0);
324 message_item_submit (message_item_create (&m));
328 psppire_set_lexer (struct lexer *lexer)
330 msg_set_handler (handle_msg, lexer);