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 static void inject_renamed_icons (void);
64 static void create_icon_factory (void);
65 static void load_data_file (PsppireDataWindow *, const char *);
67 #define _(msgid) gettext (msgid)
68 #define N_(msgid) msgid
72 initialize (const char *data_file)
74 PsppireDataWindow *data_window;
78 preregister_widgets ();
80 gsl_set_error_handler_off ();
84 psppire_set_lexer (NULL);
86 bind_textdomain_codeset (PACKAGE, "UTF-8");
88 inject_renamed_icons ();
89 create_icon_factory ();
91 psppire_output_window_setup ();
96 psppire_selector_set_default_selection_func (GTK_TYPE_ENTRY, insert_source_row_into_entry);
97 psppire_selector_set_default_selection_func (PSPPIRE_VAR_VIEW_TYPE, insert_source_row_into_tree_view);
98 psppire_selector_set_default_selection_func (GTK_TYPE_TREE_VIEW, insert_source_row_into_tree_view);
100 data_window = psppire_default_data_window ();
101 if (data_file != NULL)
102 load_data_file (data_window, data_file);
115 func (gpointer key, gpointer value, gpointer data)
118 PsppireWindow *window = PSPPIRE_WINDOW (value);
120 g_signal_emit_by_name (window, "delete-event", 0, &rv);
126 PsppireWindowRegister *reg = psppire_window_register_new ();
127 psppire_window_register_foreach (reg, func, NULL);
133 inject_renamed_icon (const char *icon, const char *substitute)
135 GtkIconTheme *theme = gtk_icon_theme_get_default ();
136 if (!gtk_icon_theme_has_icon (theme, icon)
137 && gtk_icon_theme_has_icon (theme, substitute))
139 gint *sizes = gtk_icon_theme_get_icon_sizes (theme, substitute);
142 for (p = sizes; *p != 0; p++)
147 pb = gtk_icon_theme_load_icon (theme, substitute, size, 0, NULL);
150 GdkPixbuf *copy = gdk_pixbuf_copy (pb);
152 gtk_icon_theme_add_builtin_icon (icon, size, copy);
158 /* Avoid a bug in GTK+ 2.22 that can cause a segfault at startup time. Earlier
159 and later versions of GTK+ do not have the bug. Bug #31511.
161 Based on this patch against Inkscape:
162 https://launchpadlibrarian.net/60175914/copy_renamed_icons.patch */
164 inject_renamed_icons (void)
166 if (gtk_major_version == 2 && gtk_minor_version == 22)
168 inject_renamed_icon ("gtk-file", "document-x-generic");
169 inject_renamed_icon ("gtk-directory", "folder");
175 const char *file_name;
180 static const struct icon_info icons[] =
182 {PKGDATADIR "/value-labels.png", "pspp-value-labels"},
183 {PKGDATADIR "/weight-cases.png", "pspp-weight-cases"},
184 {PKGDATADIR "/goto-variable.png", "pspp-goto-variable"},
185 {PKGDATADIR "/insert-variable.png", "pspp-insert-variable"},
186 {PKGDATADIR "/insert-case.png", "pspp-insert-case"},
187 {PKGDATADIR "/split-file.png", "pspp-split-file"},
188 {PKGDATADIR "/select-cases.png", "pspp-select-cases"},
189 {PKGDATADIR "/recent-dialogs.png", "pspp-recent-dialogs"},
190 {PKGDATADIR "/nominal.png", "var-nominal"},
191 {PKGDATADIR "/ordinal.png", "var-ordinal"},
192 {PKGDATADIR "/scale.png", "var-scale"},
193 {PKGDATADIR "/string.png", "var-string"},
194 {PKGDATADIR "/date-scale.png", "var-date-scale"}
198 create_icon_factory (void)
201 GtkIconFactory *factory = gtk_icon_factory_new ();
203 for (i = 0 ; i < sizeof (icons) / sizeof(icons[0]); ++i)
207 gdk_pixbuf_new_from_file (relocate (icons[i].file_name), &err);
211 GtkIconSet *icon_set = gtk_icon_set_new_from_pixbuf (pixbuf);
212 g_object_unref (pixbuf);
213 gtk_icon_factory_add ( factory, icons[i].id, icon_set);
217 g_warning ("Cannot create icon: %s", err->message);
218 g_clear_error (&err);
223 /* Create our own "pspp-stock-reset" item, using the
224 GTK_STOCK_REFRESH icon set */
226 GtkStockItem items[] = {
227 {"pspp-stock-reset", N_("_Reset"), 0, 0, PACKAGE},
228 {"pspp-stock-select", N_("_Select"), 0, 0, PACKAGE}
232 gtk_stock_add (items, 2);
233 gtk_icon_factory_add (factory, "pspp-stock-reset",
234 gtk_icon_factory_lookup_default (GTK_STOCK_REFRESH)
237 gtk_icon_factory_add (factory, "pspp-stock-select",
238 gtk_icon_factory_lookup_default (GTK_STOCK_INDEX)
242 gtk_icon_factory_add_default (factory);
246 load_data_file (PsppireDataWindow *window, const char *arg)
248 gchar *filename = NULL;
250 const gchar *local_encoding = NULL;
252 const gboolean local_is_utf8 = g_get_charset (&local_encoding);
254 /* There seems to be no Glib function to convert from local encoding
255 to filename encoding. Therefore it has to be done in two steps:
256 the intermediate encoding is UTF8.
258 Either step could fail. However, in many cases the file can still
259 be loaded even if the conversion fails. So in those cases, after showing
260 a warning, we simply copy the locally encoded filename to the destination
261 and hope for the best.
266 utf8 = xstrdup (arg);
271 utf8 = g_locale_to_utf8 (arg, -1, NULL, &written, &err);
274 g_warning ("Cannot convert filename from local encoding `%s' to UTF-8: %s",
277 g_clear_error (&err);
284 filename = g_filename_from_utf8 (utf8, written, NULL, NULL, &err);
285 if ( NULL == filename)
287 g_warning ("Cannot convert filename from UTF8 to filename encoding: %s",
289 g_clear_error (&err);
295 if ( filename == NULL)
296 filename = xstrdup (arg);
298 psppire_window_load (PSPPIRE_WINDOW (window), filename);
304 handle_msg (const struct msg *m_, void *lexer_)
306 struct lexer *lexer = lexer_;
309 if (lexer != NULL && m.file_name == NULL)
311 m.file_name = CONST_CAST (char *, lex_get_file_name (lexer));
312 m.first_line = lex_get_first_line_number (lexer, 0);
313 m.last_line = lex_get_last_line_number (lexer, 0);
314 m.first_column = lex_get_first_column (lexer, 0);
315 m.last_column = lex_get_last_column (lexer, 0);
318 message_item_submit (message_item_create (&m));
322 psppire_set_lexer (struct lexer *lexer)
324 msg_set_handler (handle_msg, lexer);