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);
120 func (gpointer key, gpointer value, gpointer data)
123 PsppireWindow *window = PSPPIRE_WINDOW (value);
125 g_signal_emit_by_name (window, "delete-event", 0, &rv);
131 PsppireWindowRegister *reg = psppire_window_register_new ();
132 psppire_window_register_foreach (reg, func, NULL);
138 inject_renamed_icon (const char *icon, const char *substitute)
140 GtkIconTheme *theme = gtk_icon_theme_get_default ();
141 if (!gtk_icon_theme_has_icon (theme, icon)
142 && gtk_icon_theme_has_icon (theme, substitute))
144 gint *sizes = gtk_icon_theme_get_icon_sizes (theme, substitute);
147 for (p = sizes; *p != 0; p++)
152 pb = gtk_icon_theme_load_icon (theme, substitute, size, 0, NULL);
155 GdkPixbuf *copy = gdk_pixbuf_copy (pb);
157 gtk_icon_theme_add_builtin_icon (icon, size, copy);
163 /* Avoid a bug in GTK+ 2.22 that can cause a segfault at startup time. Earlier
164 and later versions of GTK+ do not have the bug. Bug #31511.
166 Based on this patch against Inkscape:
167 https://launchpadlibrarian.net/60175914/copy_renamed_icons.patch */
169 inject_renamed_icons (void)
171 if (gtk_major_version == 2 && gtk_minor_version == 22)
173 inject_renamed_icon ("gtk-file", "document-x-generic");
174 inject_renamed_icon ("gtk-directory", "folder");
180 const char *file_name;
185 static const struct icon_info icons[] =
187 {PKGDATADIR "/value-labels.png", "pspp-value-labels"},
188 {PKGDATADIR "/weight-cases.png", "pspp-weight-cases"},
189 {PKGDATADIR "/goto-variable.png", "pspp-goto-variable"},
190 {PKGDATADIR "/insert-variable.png", "pspp-insert-variable"},
191 {PKGDATADIR "/insert-case.png", "pspp-insert-case"},
192 {PKGDATADIR "/split-file.png", "pspp-split-file"},
193 {PKGDATADIR "/select-cases.png", "pspp-select-cases"},
194 {PKGDATADIR "/recent-dialogs.png", "pspp-recent-dialogs"},
195 {PKGDATADIR "/nominal.png", "var-nominal"},
196 {PKGDATADIR "/ordinal.png", "var-ordinal"},
197 {PKGDATADIR "/scale.png", "var-scale"},
198 {PKGDATADIR "/string.png", "var-string"},
199 {PKGDATADIR "/date-scale.png", "var-date-scale"}
203 create_icon_factory (void)
206 GtkIconFactory *factory = gtk_icon_factory_new ();
208 for (i = 0 ; i < sizeof (icons) / sizeof(icons[0]); ++i)
212 gdk_pixbuf_new_from_file (relocate (icons[i].file_name), &err);
216 GtkIconSet *icon_set = gtk_icon_set_new_from_pixbuf (pixbuf);
217 g_object_unref (pixbuf);
218 gtk_icon_factory_add ( factory, icons[i].id, icon_set);
222 g_warning ("Cannot create icon: %s", err->message);
223 g_clear_error (&err);
228 /* Create our own "pspp-stock-reset" item, using the
229 GTK_STOCK_REFRESH icon set */
231 GtkStockItem items[] = {
232 {"pspp-stock-reset", N_("_Reset"), 0, 0, PACKAGE},
233 {"pspp-stock-select", N_("_Select"), 0, 0, PACKAGE}
237 gtk_stock_add (items, 2);
238 gtk_icon_factory_add (factory, "pspp-stock-reset",
239 gtk_icon_factory_lookup_default (GTK_STOCK_REFRESH)
242 gtk_icon_factory_add (factory, "pspp-stock-select",
243 gtk_icon_factory_lookup_default (GTK_STOCK_INDEX)
247 gtk_icon_factory_add_default (factory);
251 load_data_file (PsppireDataWindow *window, const char *arg)
253 gchar *filename = NULL;
255 const gchar *local_encoding = NULL;
257 const gboolean local_is_utf8 = g_get_charset (&local_encoding);
259 /* There seems to be no Glib function to convert from local encoding
260 to filename encoding. Therefore it has to be done in two steps:
261 the intermediate encoding is UTF8.
263 Either step could fail. However, in many cases the file can still
264 be loaded even if the conversion fails. So in those cases, after showing
265 a warning, we simply copy the locally encoded filename to the destination
266 and hope for the best.
271 utf8 = xstrdup (arg);
276 utf8 = g_locale_to_utf8 (arg, -1, NULL, &written, &err);
279 g_warning ("Cannot convert filename from local encoding `%s' to UTF-8: %s",
282 g_clear_error (&err);
289 filename = g_filename_from_utf8 (utf8, written, NULL, NULL, &err);
290 if ( NULL == filename)
292 g_warning ("Cannot convert filename from UTF8 to filename encoding: %s",
294 g_clear_error (&err);
300 if ( filename == NULL)
301 filename = xstrdup (arg);
303 psppire_window_load (PSPPIRE_WINDOW (window), filename);
309 handle_msg (const struct msg *m_, void *lexer_)
311 struct lexer *lexer = lexer_;
314 if (lexer != NULL && m.file_name == NULL)
316 m.file_name = CONST_CAST (char *, lex_get_file_name (lexer));
317 m.first_line = lex_get_first_line_number (lexer, 0);
318 m.last_line = lex_get_last_line_number (lexer, 0);
319 m.first_column = lex_get_first_column (lexer, 0);
320 m.last_column = lex_get_last_column (lexer, 0);
323 message_item_submit (message_item_create (&m));
327 psppire_set_lexer (struct lexer *lexer)
329 msg_set_handler (handle_msg, lexer);