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 gchar *local_to_filename_encoding (const char *fn);
68 #define _(msgid) gettext (msgid)
69 #define N_(msgid) msgid
73 initialize (const char *data_file)
75 PsppireDataWindow *data_window;
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);
101 data_window = psppire_default_data_window ();
105 gchar *filename = local_to_filename_encoding (data_file);
107 /* Check to see if the file is a .sav or a .por file. If not
108 assume that it is a syntax file */
109 if ( any_reader_may_open (filename))
110 psppire_window_load (PSPPIRE_WINDOW (data_window), filename);
112 open_syntax_window (filename, NULL);
128 func (gpointer key, gpointer value, gpointer data)
131 PsppireWindow *window = PSPPIRE_WINDOW (value);
133 g_signal_emit_by_name (window, "delete-event", 0, &rv);
139 PsppireWindowRegister *reg = psppire_window_register_new ();
140 psppire_window_register_foreach (reg, func, NULL);
146 inject_renamed_icon (const char *icon, const char *substitute)
148 GtkIconTheme *theme = gtk_icon_theme_get_default ();
149 if (!gtk_icon_theme_has_icon (theme, icon)
150 && gtk_icon_theme_has_icon (theme, substitute))
152 gint *sizes = gtk_icon_theme_get_icon_sizes (theme, substitute);
155 for (p = sizes; *p != 0; p++)
160 pb = gtk_icon_theme_load_icon (theme, substitute, size, 0, NULL);
163 GdkPixbuf *copy = gdk_pixbuf_copy (pb);
165 gtk_icon_theme_add_builtin_icon (icon, size, copy);
171 /* Avoid a bug in GTK+ 2.22 that can cause a segfault at startup time. Earlier
172 and later versions of GTK+ do not have the bug. Bug #31511.
174 Based on this patch against Inkscape:
175 https://launchpadlibrarian.net/60175914/copy_renamed_icons.patch */
177 inject_renamed_icons (void)
179 if (gtk_major_version == 2 && gtk_minor_version == 22)
181 inject_renamed_icon ("gtk-file", "document-x-generic");
182 inject_renamed_icon ("gtk-directory", "folder");
188 const char *file_name;
193 static const struct icon_info icons[] =
195 {PKGDATADIR "/value-labels.png", "pspp-value-labels"},
196 {PKGDATADIR "/weight-cases.png", "pspp-weight-cases"},
197 {PKGDATADIR "/goto-variable.png", "pspp-goto-variable"},
198 {PKGDATADIR "/insert-variable.png", "pspp-insert-variable"},
199 {PKGDATADIR "/insert-case.png", "pspp-insert-case"},
200 {PKGDATADIR "/split-file.png", "pspp-split-file"},
201 {PKGDATADIR "/select-cases.png", "pspp-select-cases"},
202 {PKGDATADIR "/recent-dialogs.png", "pspp-recent-dialogs"},
203 {PKGDATADIR "/nominal.png", "var-nominal"},
204 {PKGDATADIR "/ordinal.png", "var-ordinal"},
205 {PKGDATADIR "/scale.png", "var-scale"},
206 {PKGDATADIR "/string.png", "var-string"},
207 {PKGDATADIR "/date-scale.png", "var-date-scale"}
211 create_icon_factory (void)
214 GtkIconFactory *factory = gtk_icon_factory_new ();
216 for (i = 0 ; i < sizeof (icons) / sizeof(icons[0]); ++i)
220 gdk_pixbuf_new_from_file (relocate (icons[i].file_name), &err);
224 GtkIconSet *icon_set = gtk_icon_set_new_from_pixbuf (pixbuf);
225 g_object_unref (pixbuf);
226 gtk_icon_factory_add ( factory, icons[i].id, icon_set);
230 g_warning ("Cannot create icon: %s", err->message);
231 g_clear_error (&err);
236 /* Create our own "pspp-stock-reset" item, using the
237 GTK_STOCK_REFRESH icon set */
239 GtkStockItem items[] = {
240 {"pspp-stock-reset", N_("_Reset"), 0, 0, PACKAGE},
241 {"pspp-stock-select", N_("_Select"), 0, 0, PACKAGE}
245 gtk_stock_add (items, 2);
246 gtk_icon_factory_add (factory, "pspp-stock-reset",
247 gtk_icon_factory_lookup_default (GTK_STOCK_REFRESH)
250 gtk_icon_factory_add (factory, "pspp-stock-select",
251 gtk_icon_factory_lookup_default (GTK_STOCK_INDEX)
255 gtk_icon_factory_add_default (factory);
259 Convert a filename from the local encoding into "filename" encoding.
260 The return value will be allocated on the heap. It is the responsibility
261 of the caller to free it.
264 local_to_filename_encoding (const char *fn)
266 gchar *filename = NULL;
268 const gchar *local_encoding = NULL;
270 const gboolean local_is_utf8 = g_get_charset (&local_encoding);
272 /* There seems to be no Glib function to convert from local encoding
273 to filename encoding. Therefore it has to be done in two steps:
274 the intermediate encoding is UTF8.
276 Either step could fail. However, in many cases the file can still
277 be loaded even if the conversion fails. So in those cases, after showing
278 a warning, we simply copy the locally encoded filename to the destination
279 and hope for the best.
289 utf8 = g_locale_to_utf8 (fn, -1, NULL, &written, &err);
292 g_warning ("Cannot convert filename from local encoding `%s' to UTF-8: %s",
295 g_clear_error (&err);
302 filename = g_filename_from_utf8 (utf8, written, NULL, NULL, &err);
303 if ( NULL == filename)
305 g_warning ("Cannot convert filename from UTF8 to filename encoding: %s",
307 g_clear_error (&err);
313 if ( filename == NULL)
314 filename = xstrdup (fn);
320 handle_msg (const struct msg *m_, void *lexer_)
322 struct lexer *lexer = lexer_;
325 if (lexer != NULL && m.file_name == NULL)
327 m.file_name = CONST_CAST (char *, lex_get_file_name (lexer));
328 m.first_line = lex_get_first_line_number (lexer, 0);
329 m.last_line = lex_get_last_line_number (lexer, 0);
330 m.first_column = lex_get_first_column (lexer, 0);
331 m.last_column = lex_get_last_column (lexer, 0);
334 message_item_submit (message_item_create (&m));
338 psppire_set_lexer (struct lexer *lexer)
340 msg_set_handler (handle_msg, lexer);