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-window-register.h"
57 #include "ui/gui/widgets.h"
58 #include "ui/source-init-opts.h"
59 #include "ui/syntax-gen.h"
61 #include "ui/gui/icons/icon-names.h"
64 #include "gl/configmake.h"
65 #include "gl/xalloc.h"
66 #include "gl/relocatable.h"
68 static void create_icon_factory (void);
69 static gchar *local_to_filename_encoding (const char *fn);
72 #define _(msgid) gettext (msgid)
73 #define N_(msgid) msgid
77 initialize (const char *data_file)
81 preregister_widgets ();
83 gsl_set_error_handler_off ();
87 psppire_set_lexer (NULL);
89 bind_textdomain_codeset (PACKAGE, "UTF-8");
91 create_icon_factory ();
93 psppire_output_window_setup ();
98 psppire_selector_set_default_selection_func (GTK_TYPE_ENTRY, insert_source_row_into_entry);
99 psppire_selector_set_default_selection_func (PSPPIRE_VAR_VIEW_TYPE, insert_source_row_into_tree_view);
100 psppire_selector_set_default_selection_func (GTK_TYPE_TREE_VIEW, insert_source_row_into_tree_view);
104 gchar *filename = local_to_filename_encoding (data_file);
106 enum detect_result res = any_reader_may_open (filename);
108 /* Check to see if the file is a .sav or a .por file. If not
109 assume that it is a syntax file */
111 open_data_window (NULL, filename, NULL, NULL);
112 else if (res == ANY_NO)
114 create_data_window ();
115 open_syntax_window (filename, NULL);
121 create_data_window ();
134 func (gpointer key, gpointer value, gpointer data)
137 PsppireWindow *window = PSPPIRE_WINDOW (value);
139 g_signal_emit_by_name (window, "delete-event", 0, &rv);
145 PsppireWindowRegister *reg = psppire_window_register_new ();
146 psppire_window_register_foreach (reg, func, NULL);
153 int resolution; /* The dimension of the images which will be used */
154 size_t n_sizes; /* The number of items in the array below.
155 This may be zero, in which case the iconset will be wildcarded
156 (used by default when no non-wildcarded set is available) */
157 const GtkIconSize *usage; /* An array determining for what the icon set is used */
160 static const GtkIconSize menus[] = {GTK_ICON_SIZE_MENU};
161 static const GtkIconSize toolbar[] = {GTK_ICON_SIZE_LARGE_TOOLBAR};
164 /* We currently have three icon sets viz: 16x16, 24x24 and 32x32
165 We use the 16x16 for menus, the 32x32 for the toolbar and
166 the 24x24 for everything else.
168 Exactly one element of the following array should have its 2nd and 3rd
171 static const struct icon_size sizemap[] =
173 {16, sizeof (menus) / sizeof (GtkIconSize), menus},
175 {32, sizeof (toolbar) / sizeof (GtkIconSize), toolbar}
180 create_icon_factory (void)
183 GtkIconFactory *factory = gtk_icon_factory_new ();
184 struct icon_context ctx[2];
185 ctx[0] = action_icon_context;
186 ctx[1] = category_icon_context;
187 for (c = 0 ; c < 2 ; ++c)
189 const struct icon_context *ic = &ctx[c];
191 for (i = 0 ; i < ic->n_icons ; ++i)
193 GtkIconSet *icon_set = gtk_icon_set_new ();
195 for (r = 0 ; r < sizeof (sizemap) / sizeof (sizemap[0]); ++r)
198 GtkIconSource *source = gtk_icon_source_new ();
199 gchar *filename = g_strdup_printf ("%s/%s/%dx%d/%s.png", PKGDATADIR,
201 sizemap[r].resolution, sizemap[r].resolution,
203 const char *relocated_filename = relocate (filename);
205 gtk_icon_source_set_filename (source, relocated_filename);
206 gtk_icon_source_set_size_wildcarded (source, sizemap[r].n_sizes <= 0);
207 for (s = 0 ; s < sizemap[r].n_sizes ; ++s)
208 gtk_icon_source_set_size (source, sizemap[r].usage[s]);
209 if (filename != relocated_filename)
210 free (CONST_CAST (char *, relocated_filename));
212 gtk_icon_set_add_source (icon_set, source);
215 gtk_icon_factory_add (factory, ic->icon_name[i], icon_set);
226 /* We have our own icons for some things.
227 But we want the Stock Item to be identical to the Gtk standard
228 ones in all other respects.
230 const struct iconmap map[] = {
231 {GTK_STOCK_NEW, "file-new-document"},
232 {GTK_STOCK_QUIT, "file-quit"},
233 {GTK_STOCK_SAVE, "file-save-document"},
234 {GTK_STOCK_CUT, "edit-cut"},
235 {GTK_STOCK_COPY, "edit-copy"},
236 {GTK_STOCK_PASTE, "edit-paste"},
237 {GTK_STOCK_UNDO, "edit-undo"},
238 {GTK_STOCK_REDO, "edit-redo"},
239 {GTK_STOCK_DELETE, "edit-delete"},
240 {GTK_STOCK_ABOUT, "help-about"},
241 {GTK_STOCK_PRINT, "file-print-document"}
244 GtkStockItem customised[sizeof (map) / sizeof (map[0])];
247 for (i = 0; i < sizeof (map) / sizeof (map[0]); ++i)
249 gtk_stock_lookup (map[i].gtk_id, &customised[i]);
250 customised[i].stock_id = map[i].pspp_id;
255 gtk_stock_add (customised, sizeof (map) / sizeof (map[0]));
259 /* Create our own "pspp-stock-reset" item, using the
260 GTK_STOCK_REFRESH icon set */
261 GtkStockItem items[2] = {
262 {"pspp-stock-reset", N_("_Reset"), 0, 0, PACKAGE},
263 {"pspp-stock-select", N_("_Select"), 0, 0, PACKAGE}
266 gtk_stock_add (items, 2);
268 gtk_icon_factory_add (factory, "pspp-stock-reset",
269 gtk_icon_factory_lookup_default (GTK_STOCK_REFRESH)
272 gtk_icon_factory_add (factory, "pspp-stock-select",
273 gtk_icon_factory_lookup_default (GTK_STOCK_INDEX)
277 gtk_icon_factory_add_default (factory);
281 Convert a filename from the local encoding into "filename" encoding.
282 The return value will be allocated on the heap. It is the responsibility
283 of the caller to free it.
286 local_to_filename_encoding (const char *fn)
288 gchar *filename = NULL;
290 const gchar *local_encoding = NULL;
292 const gboolean local_is_utf8 = g_get_charset (&local_encoding);
294 /* There seems to be no Glib function to convert from local encoding
295 to filename encoding. Therefore it has to be done in two steps:
296 the intermediate encoding is UTF8.
298 Either step could fail. However, in many cases the file can still
299 be loaded even if the conversion fails. So in those cases, after showing
300 a warning, we simply copy the locally encoded filename to the destination
301 and hope for the best.
311 utf8 = g_locale_to_utf8 (fn, -1, NULL, &written, &err);
314 g_warning ("Cannot convert filename from local encoding `%s' to UTF-8: %s",
317 g_clear_error (&err);
324 filename = g_filename_from_utf8 (utf8, written, NULL, NULL, &err);
325 if ( NULL == filename)
327 g_warning ("Cannot convert filename from UTF8 to filename encoding: %s",
329 g_clear_error (&err);
335 if ( filename == NULL)
336 filename = xstrdup (fn);
342 handle_msg (const struct msg *m_, void *lexer_)
344 struct lexer *lexer = lexer_;
347 if (lexer != NULL && m.file_name == NULL)
349 m.file_name = CONST_CAST (char *, lex_get_file_name (lexer));
350 m.first_line = lex_get_first_line_number (lexer, 0);
351 m.last_line = lex_get_last_line_number (lexer, 0);
352 m.first_column = lex_get_first_column (lexer, 0);
353 m.last_column = lex_get_last_column (lexer, 0);
356 message_item_submit (message_item_create (&m));
360 psppire_set_lexer (struct lexer *lexer)
362 msg_set_handler (handle_msg, lexer);