1 /* PSPPIRE - a graphical user interface for PSPP.
2 Copyright (C) 2004, 2005, 2006, 2009, 2010, 2011, 2012, 2013, 2014 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/>. */
21 #include <gsl/gsl_errno.h>
26 #include "data/any-reader.h"
27 #include "data/casereader.h"
28 #include "data/dataset.h"
29 #include "data/datasheet.h"
30 #include "data/file-handle-def.h"
31 #include "data/file-name.h"
32 #include "data/por-file-reader.h"
33 #include "data/session.h"
34 #include "data/settings.h"
35 #include "data/sys-file-reader.h"
37 #include "language/lexer/lexer.h"
38 #include "libpspp/i18n.h"
39 #include "libpspp/message.h"
40 #include "libpspp/version.h"
42 #include "output/driver.h"
43 #include "output/journal.h"
44 #include "output/message-item.h"
46 #include "ui/gui/dict-display.h"
47 #include "ui/gui/executor.h"
48 #include "ui/gui/psppire-data-store.h"
49 #include "ui/gui/psppire-data-window.h"
50 #include "ui/gui/psppire-dict.h"
51 #include "ui/gui/psppire.h"
52 #include "ui/gui/psppire-output-window.h"
53 #include "ui/gui/psppire-syntax-window.h"
54 #include "ui/gui/psppire-selector.h"
55 #include "ui/gui/psppire-var-view.h"
56 #include "ui/gui/psppire-means-layer.h"
57 #include "ui/gui/psppire-window-register.h"
58 #include "ui/gui/widgets.h"
59 #include "ui/source-init-opts.h"
60 #include "ui/syntax-gen.h"
62 #include "ui/gui/icons/icon-names.h"
65 #include "gl/configmake.h"
66 #include "gl/xalloc.h"
67 #include "gl/relocatable.h"
69 static void create_icon_factory (void);
70 static gchar *local_to_filename_encoding (const char *fn);
73 #define _(msgid) gettext (msgid)
74 #define N_(msgid) msgid
78 initialize (const char *data_file)
82 preregister_widgets ();
84 gsl_set_error_handler_off ();
88 psppire_set_lexer (NULL);
90 bind_textdomain_codeset (PACKAGE, "UTF-8");
92 create_icon_factory ();
94 psppire_output_window_setup ();
99 /* FIXME: This should be implemented with a GtkInterface */
100 psppire_selector_set_default_selection_func (GTK_TYPE_ENTRY, insert_source_row_into_entry);
101 psppire_selector_set_default_selection_func (PSPPIRE_VAR_VIEW_TYPE, insert_source_row_into_tree_view);
102 psppire_selector_set_default_selection_func (GTK_TYPE_TREE_VIEW, insert_source_row_into_tree_view);
103 psppire_selector_set_default_selection_func (PSPPIRE_TYPE_MEANS_LAYER, insert_source_row_into_layers);
107 gchar *filename = local_to_filename_encoding (data_file);
109 enum detect_result res = any_reader_may_open (filename);
111 /* Check to see if the file is a .sav or a .por file. If not
112 assume that it is a syntax file */
114 open_data_window (NULL, filename, NULL, NULL);
115 else if (res == ANY_NO)
117 create_data_window ();
118 open_syntax_window (filename, NULL);
124 create_data_window ();
137 func (gpointer key, gpointer value, gpointer data)
140 PsppireWindow *window = PSPPIRE_WINDOW (value);
142 g_signal_emit_by_name (window, "delete-event", 0, &rv);
148 PsppireWindowRegister *reg = psppire_window_register_new ();
149 psppire_window_register_foreach (reg, func, NULL);
156 int resolution; /* The dimension of the images which will be used */
157 size_t n_sizes; /* The number of items in the array below.
158 This may be zero, in which case the iconset will be wildcarded
159 (used by default when no non-wildcarded set is available) */
160 const GtkIconSize *usage; /* An array determining for what the icon set is used */
163 static const GtkIconSize menus[] = {GTK_ICON_SIZE_MENU};
164 static const GtkIconSize toolbar[] = {GTK_ICON_SIZE_LARGE_TOOLBAR};
167 /* We currently have three icon sets viz: 16x16, 24x24 and 32x32
168 We use the 16x16 for menus, the 32x32 for the toolbar and
169 the 24x24 for everything else.
171 Exactly one element of the following array should have its 2nd and 3rd
174 static const struct icon_size sizemap[] =
176 {16, sizeof (menus) / sizeof (GtkIconSize), menus},
178 {32, sizeof (toolbar) / sizeof (GtkIconSize), toolbar}
183 create_icon_factory (void)
186 GtkIconFactory *factory = gtk_icon_factory_new ();
187 struct icon_context ctx[2];
188 ctx[0] = action_icon_context;
189 ctx[1] = category_icon_context;
190 for (c = 0 ; c < 2 ; ++c)
192 const struct icon_context *ic = &ctx[c];
194 for (i = 0 ; i < ic->n_icons ; ++i)
196 GtkIconSet *icon_set = gtk_icon_set_new ();
198 for (r = 0 ; r < sizeof (sizemap) / sizeof (sizemap[0]); ++r)
201 GtkIconSource *source = gtk_icon_source_new ();
202 gchar *filename = g_strdup_printf ("%s/%s/%dx%d/%s.png", PKGDATADIR,
204 sizemap[r].resolution, sizemap[r].resolution,
206 const char *relocated_filename = relocate (filename);
208 gtk_icon_source_set_filename (source, relocated_filename);
209 gtk_icon_source_set_size_wildcarded (source, sizemap[r].n_sizes <= 0);
210 for (s = 0 ; s < sizemap[r].n_sizes ; ++s)
211 gtk_icon_source_set_size (source, sizemap[r].usage[s]);
212 if (filename != relocated_filename)
213 free (CONST_CAST (char *, relocated_filename));
215 gtk_icon_set_add_source (icon_set, source);
218 gtk_icon_factory_add (factory, ic->icon_name[i], icon_set);
229 /* We have our own icons for some things.
230 But we want the Stock Item to be identical to the Gtk standard
231 ones in all other respects.
233 const struct iconmap map[] = {
234 {GTK_STOCK_NEW, "file-new-document"},
235 {GTK_STOCK_QUIT, "file-quit"},
236 {GTK_STOCK_SAVE, "file-save-document"},
237 {GTK_STOCK_CUT, "edit-cut"},
238 {GTK_STOCK_COPY, "edit-copy"},
239 {GTK_STOCK_PASTE, "edit-paste"},
240 {GTK_STOCK_UNDO, "edit-undo"},
241 {GTK_STOCK_REDO, "edit-redo"},
242 {GTK_STOCK_DELETE, "edit-delete"},
243 {GTK_STOCK_ABOUT, "help-about"},
244 {GTK_STOCK_PRINT, "file-print-document"}
247 GtkStockItem customised[sizeof (map) / sizeof (map[0])];
250 for (i = 0; i < sizeof (map) / sizeof (map[0]); ++i)
252 gtk_stock_lookup (map[i].gtk_id, &customised[i]);
253 customised[i].stock_id = map[i].pspp_id;
258 gtk_stock_add (customised, sizeof (map) / sizeof (map[0]));
262 /* Create our own "pspp-stock-reset" item, using the
263 GTK_STOCK_REFRESH icon set */
264 GtkStockItem items[2] = {
265 {"pspp-stock-reset", N_("_Reset"), 0, 0, PACKAGE},
266 {"pspp-stock-select", N_("_Select"), 0, 0, PACKAGE}
269 gtk_stock_add (items, 2);
271 gtk_icon_factory_add (factory, "pspp-stock-reset",
272 gtk_icon_factory_lookup_default (GTK_STOCK_REFRESH)
275 gtk_icon_factory_add (factory, "pspp-stock-select",
276 gtk_icon_factory_lookup_default (GTK_STOCK_INDEX)
280 gtk_icon_factory_add_default (factory);
284 Convert a filename from the local encoding into "filename" encoding.
285 The return value will be allocated on the heap. It is the responsibility
286 of the caller to free it.
289 local_to_filename_encoding (const char *fn)
291 gchar *filename = NULL;
293 const gchar *local_encoding = NULL;
295 const gboolean local_is_utf8 = g_get_charset (&local_encoding);
297 /* There seems to be no Glib function to convert from local encoding
298 to filename encoding. Therefore it has to be done in two steps:
299 the intermediate encoding is UTF8.
301 Either step could fail. However, in many cases the file can still
302 be loaded even if the conversion fails. So in those cases, after showing
303 a warning, we simply copy the locally encoded filename to the destination
304 and hope for the best.
314 utf8 = g_locale_to_utf8 (fn, -1, NULL, &written, &err);
317 g_warning ("Cannot convert filename from local encoding `%s' to UTF-8: %s",
320 g_clear_error (&err);
327 filename = g_filename_from_utf8 (utf8, written, NULL, NULL, &err);
328 if ( NULL == filename)
330 g_warning ("Cannot convert filename from UTF8 to filename encoding: %s",
332 g_clear_error (&err);
338 if ( filename == NULL)
339 filename = xstrdup (fn);
345 handle_msg (const struct msg *m_, void *lexer_)
347 struct lexer *lexer = lexer_;
350 if (lexer != NULL && m.file_name == NULL)
352 m.file_name = CONST_CAST (char *, lex_get_file_name (lexer));
353 m.first_line = lex_get_first_line_number (lexer, 0);
354 m.last_line = lex_get_last_line_number (lexer, 0);
355 m.first_column = lex_get_first_column (lexer, 0);
356 m.last_column = lex_get_last_column (lexer, 0);
359 message_item_submit (message_item_create (&m));
363 psppire_set_lexer (struct lexer *lexer)
365 msg_set_handler (handle_msg, lexer);