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 const GtkIconSize *usage; /* An array determining for what the icon set is used */
161 static const GtkIconSize menus[] = {GTK_ICON_SIZE_MENU};
162 static const GtkIconSize large_toolbar[] = {GTK_ICON_SIZE_LARGE_TOOLBAR};
163 static const GtkIconSize small_toolbar[] = {GTK_ICON_SIZE_SMALL_TOOLBAR};
166 /* We currently have three icon sets viz: 16x16, 24x24 and 32x32
167 We use the 16x16 for menus, the 32x32 for the large_toolbars and
168 the 24x24 for small_toolbars.
170 The order of this array is pertinent. The icons in the sets occuring
171 earlier in the array will be used a the wildcard (default) icon size,
172 if such an icon exists.
174 static const struct icon_size sizemap[] =
176 {24, sizeof (small_toolbar) / sizeof (GtkIconSize), small_toolbar},
177 {16, sizeof (menus) / sizeof (GtkIconSize), menus},
178 {32, sizeof (large_toolbar) / sizeof (GtkIconSize), large_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 gboolean wildcarded = FALSE;
197 GtkIconSet *icon_set = gtk_icon_set_new ();
199 for (r = 0 ; r < sizeof (sizemap) / sizeof (sizemap[0]); ++r)
202 GtkIconSource *source = gtk_icon_source_new ();
203 gchar *filename = g_strdup_printf ("%s/%s/%dx%d/%s.png", PKGDATADIR,
205 sizemap[r].resolution, sizemap[r].resolution,
207 const char *relocated_filename = relocate (filename);
208 GFile *gf = g_file_new_for_path (relocated_filename);
209 if (g_file_query_exists (gf, NULL))
211 gtk_icon_source_set_filename (source, relocated_filename);
214 gtk_icon_source_set_size_wildcarded (source, TRUE);
220 for (s = 0 ; s < sizemap[r].n_sizes ; ++s)
221 gtk_icon_source_set_size (source, sizemap[r].usage[s]);
222 if (filename != relocated_filename)
223 free (CONST_CAST (char *, relocated_filename));
226 if ( gtk_icon_source_get_filename (source))
227 gtk_icon_set_add_source (icon_set, source);
230 gtk_icon_factory_add (factory, ic->icon_name[i], icon_set);
241 /* We have our own icons for some things.
242 But we want the Stock Item to be identical to the Gtk standard
243 ones in all other respects.
245 const struct iconmap map[] = {
246 {GTK_STOCK_NEW, "file-new-document"},
247 {GTK_STOCK_QUIT, "file-quit"},
248 {GTK_STOCK_SAVE, "file-save-document"},
249 {GTK_STOCK_CUT, "edit-cut"},
250 {GTK_STOCK_COPY, "edit-copy"},
251 {GTK_STOCK_PASTE, "edit-paste"},
252 {GTK_STOCK_UNDO, "edit-undo"},
253 {GTK_STOCK_REDO, "edit-redo"},
254 {GTK_STOCK_DELETE, "edit-delete"},
255 {GTK_STOCK_ABOUT, "help-about"},
256 {GTK_STOCK_PRINT, "file-print-document"}
259 GtkStockItem customised[sizeof (map) / sizeof (map[0])];
262 for (i = 0; i < sizeof (map) / sizeof (map[0]); ++i)
264 gtk_stock_lookup (map[i].gtk_id, &customised[i]);
265 customised[i].stock_id = map[i].pspp_id;
270 gtk_stock_add (customised, sizeof (map) / sizeof (map[0]));
274 /* Create our own "pspp-stock-reset" item, using the
275 GTK_STOCK_REFRESH icon set */
276 GtkStockItem items[2] = {
277 {"pspp-stock-reset", N_("_Reset"), 0, 0, PACKAGE},
278 {"pspp-stock-select", N_("_Select"), 0, 0, PACKAGE}
281 gtk_stock_add (items, 2);
283 gtk_icon_factory_add (factory, "pspp-stock-reset",
284 gtk_icon_factory_lookup_default (GTK_STOCK_REFRESH)
287 gtk_icon_factory_add (factory, "pspp-stock-select",
288 gtk_icon_factory_lookup_default (GTK_STOCK_INDEX)
292 gtk_icon_factory_add_default (factory);
296 Convert a filename from the local encoding into "filename" encoding.
297 The return value will be allocated on the heap. It is the responsibility
298 of the caller to free it.
301 local_to_filename_encoding (const char *fn)
303 gchar *filename = NULL;
305 const gchar *local_encoding = NULL;
307 const gboolean local_is_utf8 = g_get_charset (&local_encoding);
309 /* There seems to be no Glib function to convert from local encoding
310 to filename encoding. Therefore it has to be done in two steps:
311 the intermediate encoding is UTF8.
313 Either step could fail. However, in many cases the file can still
314 be loaded even if the conversion fails. So in those cases, after showing
315 a warning, we simply copy the locally encoded filename to the destination
316 and hope for the best.
326 utf8 = g_locale_to_utf8 (fn, -1, NULL, &written, &err);
329 g_warning ("Cannot convert filename from local encoding `%s' to UTF-8: %s",
332 g_clear_error (&err);
339 filename = g_filename_from_utf8 (utf8, written, NULL, NULL, &err);
340 if ( NULL == filename)
342 g_warning ("Cannot convert filename from UTF8 to filename encoding: %s",
344 g_clear_error (&err);
350 if ( filename == NULL)
351 filename = xstrdup (fn);
357 handle_msg (const struct msg *m_, void *lexer_)
359 struct lexer *lexer = lexer_;
362 if (lexer != NULL && m.file_name == NULL)
364 m.file_name = CONST_CAST (char *, lex_get_file_name (lexer));
365 m.first_line = lex_get_first_line_number (lexer, 0);
366 m.last_line = lex_get_last_line_number (lexer, 0);
367 m.first_column = lex_get_first_column (lexer, 0);
368 m.last_column = lex_get_last_column (lexer, 0);
371 message_item_submit (message_item_create (&m));
375 psppire_set_lexer (struct lexer *lexer)
377 msg_set_handler (handle_msg, lexer);