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 ();
85 output_engine_push ();
89 psppire_set_lexer (NULL);
91 bind_textdomain_codeset (PACKAGE, "UTF-8");
93 create_icon_factory ();
95 psppire_output_window_setup ();
100 /* FIXME: This should be implemented with a GtkInterface */
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);
104 psppire_selector_set_default_selection_func (PSPPIRE_TYPE_MEANS_LAYER, insert_source_row_into_layers);
108 gchar *filename = local_to_filename_encoding (data_file);
110 enum detect_result res = any_reader_may_open (filename);
112 /* Check to see if the file is a .sav or a .por file. If not
113 assume that it is a syntax file */
115 open_data_window (NULL, filename, NULL, NULL);
116 else if (res == ANY_NO)
118 create_data_window ();
119 open_syntax_window (filename, NULL);
125 create_data_window ();
133 output_engine_pop ();
138 func (gpointer key, gpointer value, gpointer data)
141 PsppireWindow *window = PSPPIRE_WINDOW (value);
143 g_signal_emit_by_name (window, "delete-event", 0, &rv);
149 PsppireWindowRegister *reg = psppire_window_register_new ();
150 psppire_window_register_foreach (reg, func, NULL);
157 int resolution; /* The dimension of the images which will be used */
158 size_t n_sizes; /* The number of items in the array below. */
159 const GtkIconSize *usage; /* An array determining for what the icon set is used */
162 static const GtkIconSize menus[] = {GTK_ICON_SIZE_MENU};
163 static const GtkIconSize large_toolbar[] = {GTK_ICON_SIZE_LARGE_TOOLBAR};
164 static const GtkIconSize small_toolbar[] = {GTK_ICON_SIZE_SMALL_TOOLBAR};
167 /* We currently have three icon sets viz: 16x16, 24x24 and 32x32
168 We use the 16x16 for menus, the 32x32 for the large_toolbars and
169 the 24x24 for small_toolbars.
171 The order of this array is pertinent. The icons in the sets occuring
172 earlier in the array will be used a the wildcard (default) icon size,
173 if such an icon exists.
175 static const struct icon_size sizemap[] =
177 {24, sizeof (small_toolbar) / sizeof (GtkIconSize), small_toolbar},
178 {16, sizeof (menus) / sizeof (GtkIconSize), menus},
179 {32, sizeof (large_toolbar) / sizeof (GtkIconSize), large_toolbar}
184 create_icon_factory (void)
187 GtkIconFactory *factory = gtk_icon_factory_new ();
188 struct icon_context ctx[2];
189 ctx[0] = action_icon_context;
190 ctx[1] = category_icon_context;
191 for (c = 0 ; c < 2 ; ++c)
193 const struct icon_context *ic = &ctx[c];
195 for (i = 0 ; i < ic->n_icons ; ++i)
197 gboolean wildcarded = FALSE;
198 GtkIconSet *icon_set = gtk_icon_set_new ();
200 for (r = 0 ; r < sizeof (sizemap) / sizeof (sizemap[0]); ++r)
203 GtkIconSource *source = gtk_icon_source_new ();
204 gchar *filename = g_strdup_printf ("%s/%s/%dx%d/%s.png", PKGDATADIR,
206 sizemap[r].resolution, sizemap[r].resolution,
208 const char *relocated_filename = relocate (filename);
209 GFile *gf = g_file_new_for_path (relocated_filename);
210 if (g_file_query_exists (gf, NULL))
212 gtk_icon_source_set_filename (source, relocated_filename);
215 gtk_icon_source_set_size_wildcarded (source, TRUE);
221 for (s = 0 ; s < sizemap[r].n_sizes ; ++s)
222 gtk_icon_source_set_size (source, sizemap[r].usage[s]);
223 if (filename != relocated_filename)
224 free (CONST_CAST (char *, relocated_filename));
227 if ( gtk_icon_source_get_filename (source))
228 gtk_icon_set_add_source (icon_set, source);
231 gtk_icon_factory_add (factory, ic->icon_name[i], icon_set);
242 /* We have our own icons for some things.
243 But we want the Stock Item to be identical to the Gtk standard
244 ones in all other respects.
246 const struct iconmap map[] = {
247 {GTK_STOCK_NEW, "file-new-document"},
248 {GTK_STOCK_QUIT, "file-quit"},
249 {GTK_STOCK_SAVE, "file-save-document"},
250 {GTK_STOCK_CUT, "edit-cut"},
251 {GTK_STOCK_COPY, "edit-copy"},
252 {GTK_STOCK_PASTE, "edit-paste"},
253 {GTK_STOCK_UNDO, "edit-undo"},
254 {GTK_STOCK_REDO, "edit-redo"},
255 {GTK_STOCK_DELETE, "edit-delete"},
256 {GTK_STOCK_ABOUT, "help-about"},
257 {GTK_STOCK_PRINT, "file-print-document"}
260 GtkStockItem customised[sizeof (map) / sizeof (map[0])];
263 for (i = 0; i < sizeof (map) / sizeof (map[0]); ++i)
265 gtk_stock_lookup (map[i].gtk_id, &customised[i]);
266 customised[i].stock_id = map[i].pspp_id;
271 gtk_stock_add (customised, sizeof (map) / sizeof (map[0]));
275 /* Create our own "pspp-stock-reset" item, using the
276 GTK_STOCK_REFRESH icon set */
277 GtkStockItem items[2] = {
278 {"pspp-stock-reset", N_("_Reset"), 0, 0, PACKAGE},
279 {"pspp-stock-select", N_("_Select"), 0, 0, PACKAGE}
282 gtk_stock_add (items, 2);
284 gtk_icon_factory_add (factory, "pspp-stock-reset",
285 gtk_icon_factory_lookup_default (GTK_STOCK_REFRESH)
288 gtk_icon_factory_add (factory, "pspp-stock-select",
289 gtk_icon_factory_lookup_default (GTK_STOCK_INDEX)
293 gtk_icon_factory_add_default (factory);
297 Convert a filename from the local encoding into "filename" encoding.
298 The return value will be allocated on the heap. It is the responsibility
299 of the caller to free it.
302 local_to_filename_encoding (const char *fn)
304 gchar *filename = NULL;
306 const gchar *local_encoding = NULL;
308 const gboolean local_is_utf8 = g_get_charset (&local_encoding);
310 /* There seems to be no Glib function to convert from local encoding
311 to filename encoding. Therefore it has to be done in two steps:
312 the intermediate encoding is UTF8.
314 Either step could fail. However, in many cases the file can still
315 be loaded even if the conversion fails. So in those cases, after showing
316 a warning, we simply copy the locally encoded filename to the destination
317 and hope for the best.
327 utf8 = g_locale_to_utf8 (fn, -1, NULL, &written, &err);
330 g_warning ("Cannot convert filename from local encoding `%s' to UTF-8: %s",
333 g_clear_error (&err);
340 filename = g_filename_from_utf8 (utf8, written, NULL, NULL, &err);
341 if ( NULL == filename)
343 g_warning ("Cannot convert filename from UTF8 to filename encoding: %s",
345 g_clear_error (&err);
351 if ( filename == NULL)
352 filename = xstrdup (fn);
358 handle_msg (const struct msg *m_, void *lexer_)
360 struct lexer *lexer = lexer_;
363 if (lexer != NULL && m.file_name == NULL)
365 m.file_name = CONST_CAST (char *, lex_get_file_name (lexer));
366 m.first_line = lex_get_first_line_number (lexer, 0);
367 m.last_line = lex_get_last_line_number (lexer, 0);
368 m.first_column = lex_get_first_column (lexer, 0);
369 m.last_column = lex_get_last_column (lexer, 0);
372 message_item_submit (message_item_create (&m));
376 psppire_set_lexer (struct lexer *lexer)
378 msg_set_handler (handle_msg, lexer);