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/session.h"
33 #include "data/settings.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-syntax-window.h"
52 #include "ui/gui/psppire-selector.h"
53 #include "ui/gui/psppire-var-view.h"
54 #include "ui/gui/psppire-means-layer.h"
55 #include "ui/gui/psppire-window-register.h"
56 #include "ui/gui/widgets.h"
57 #include "ui/source-init-opts.h"
58 #include "ui/syntax-gen.h"
60 #include "ui/gui/icons/icon-names.h"
63 #include "gl/configmake.h"
64 #include "gl/xalloc.h"
65 #include "gl/relocatable.h"
67 static void create_icon_factory (void);
68 static gchar *local_to_filename_encoding (const char *fn);
71 #define _(msgid) gettext (msgid)
72 #define N_(msgid) msgid
76 initialize (const struct init_source *is)
84 preregister_widgets ();
87 gsl_set_error_handler_off ();
90 output_engine_push ();
99 psppire_set_lexer (NULL);
102 bind_textdomain_codeset (PACKAGE, "UTF-8");
105 if ( ! gtk_parse_args (is->argc, is->argv) )
107 perror ("Error parsing arguments");
112 create_icon_factory ();
115 psppire_output_window_setup ();
121 textdomain (PACKAGE);
124 /* FIXME: This should be implemented with a GtkInterface */
125 psppire_selector_set_default_selection_func (GTK_TYPE_ENTRY, insert_source_row_into_entry);
126 psppire_selector_set_default_selection_func (PSPPIRE_VAR_VIEW_TYPE, insert_source_row_into_tree_view);
127 psppire_selector_set_default_selection_func (GTK_TYPE_TREE_VIEW, insert_source_row_into_tree_view);
128 psppire_selector_set_default_selection_func (PSPPIRE_TYPE_MEANS_LAYER, insert_source_row_into_layers);
134 gchar *filename = local_to_filename_encoding (is->file);
136 int retval = any_reader_detect (filename, NULL);
138 /* Check to see if the file is a .sav or a .por file. If not
139 assume that it is a syntax file */
141 open_data_window (NULL, filename, NULL, NULL);
142 else if (retval == 0)
144 create_data_window ();
145 open_syntax_window (filename, NULL);
151 create_data_window ();
168 output_engine_pop ();
173 func (gpointer key, gpointer value, gpointer data)
176 PsppireWindow *window = PSPPIRE_WINDOW (value);
178 g_signal_emit_by_name (window, "delete-event", 0, &rv);
184 PsppireWindowRegister *reg = psppire_window_register_new ();
185 psppire_window_register_foreach (reg, func, NULL);
192 int resolution; /* The dimension of the images which will be used */
193 size_t n_sizes; /* The number of items in the array below. */
194 const GtkIconSize *usage; /* An array determining for what the icon set is used */
197 static const GtkIconSize menus[] = {GTK_ICON_SIZE_MENU};
198 static const GtkIconSize large_toolbar[] = {GTK_ICON_SIZE_LARGE_TOOLBAR};
199 static const GtkIconSize small_toolbar[] = {GTK_ICON_SIZE_SMALL_TOOLBAR};
202 /* We currently have three icon sets viz: 16x16, 24x24 and 32x32
203 We use the 16x16 for menus, the 32x32 for the large_toolbars and
204 the 24x24 for small_toolbars.
206 The order of this array is pertinent. The icons in the sets occuring
207 earlier in the array will be used a the wildcard (default) icon size,
208 if such an icon exists.
210 static const struct icon_size sizemap[] =
212 {24, sizeof (small_toolbar) / sizeof (GtkIconSize), small_toolbar},
213 {16, sizeof (menus) / sizeof (GtkIconSize), menus},
214 {32, sizeof (large_toolbar) / sizeof (GtkIconSize), large_toolbar}
219 create_icon_factory (void)
222 GtkIconFactory *factory = gtk_icon_factory_new ();
223 struct icon_context ctx[2];
224 ctx[0] = action_icon_context;
225 ctx[1] = category_icon_context;
226 for (c = 0 ; c < 2 ; ++c)
228 const struct icon_context *ic = &ctx[c];
230 for (i = 0 ; i < ic->n_icons ; ++i)
232 gboolean wildcarded = FALSE;
233 GtkIconSet *icon_set = gtk_icon_set_new ();
235 for (r = 0 ; r < sizeof (sizemap) / sizeof (sizemap[0]); ++r)
238 GtkIconSource *source = gtk_icon_source_new ();
239 gchar *filename = g_strdup_printf ("%s/%s/%dx%d/%s.png", PKGDATADIR,
241 sizemap[r].resolution, sizemap[r].resolution,
243 const char *relocated_filename = relocate (filename);
244 GFile *gf = g_file_new_for_path (relocated_filename);
245 if (g_file_query_exists (gf, NULL))
247 gtk_icon_source_set_filename (source, relocated_filename);
250 gtk_icon_source_set_size_wildcarded (source, TRUE);
256 for (s = 0 ; s < sizemap[r].n_sizes ; ++s)
257 gtk_icon_source_set_size (source, sizemap[r].usage[s]);
258 if (filename != relocated_filename)
259 free (CONST_CAST (char *, relocated_filename));
262 if ( gtk_icon_source_get_filename (source))
263 gtk_icon_set_add_source (icon_set, source);
265 gtk_icon_source_free (source);
268 gtk_icon_factory_add (factory, ic->icon_name[i], icon_set);
279 /* We have our own icons for some things.
280 But we want the Stock Item to be identical to the Gtk standard
281 ones in all other respects.
283 const struct iconmap map[] = {
284 {GTK_STOCK_NEW, "file-new-document"},
285 {GTK_STOCK_QUIT, "file-quit"},
286 {GTK_STOCK_SAVE, "file-save-document"},
287 {GTK_STOCK_CUT, "edit-cut"},
288 {GTK_STOCK_COPY, "edit-copy"},
289 {GTK_STOCK_PASTE, "edit-paste"},
290 {GTK_STOCK_UNDO, "edit-undo"},
291 {GTK_STOCK_REDO, "edit-redo"},
292 {GTK_STOCK_DELETE, "edit-delete"},
293 {GTK_STOCK_ABOUT, "help-about"},
294 {GTK_STOCK_PRINT, "file-print-document"}
297 GtkStockItem customised[sizeof (map) / sizeof (map[0])];
300 for (i = 0; i < sizeof (map) / sizeof (map[0]); ++i)
302 gtk_stock_lookup (map[i].gtk_id, &customised[i]);
303 customised[i].stock_id = map[i].pspp_id;
308 gtk_stock_add (customised, sizeof (map) / sizeof (map[0]));
312 /* Create our own "pspp-stock-reset" item, using the
313 GTK_STOCK_REFRESH icon set */
314 GtkStockItem items[2] = {
315 {"pspp-stock-reset", N_("_Reset"), 0, 0, PACKAGE},
316 {"pspp-stock-select", N_("_Select"), 0, 0, PACKAGE}
319 gtk_stock_add (items, 2);
321 gtk_icon_factory_add (factory, "pspp-stock-reset",
322 gtk_icon_factory_lookup_default (GTK_STOCK_REFRESH)
325 gtk_icon_factory_add (factory, "pspp-stock-select",
326 gtk_icon_factory_lookup_default (GTK_STOCK_INDEX)
330 gtk_icon_factory_add_default (factory);
334 Convert a filename from the local encoding into "filename" encoding.
335 The return value will be allocated on the heap. It is the responsibility
336 of the caller to free it.
339 local_to_filename_encoding (const char *fn)
341 gchar *filename = NULL;
343 const gchar *local_encoding = NULL;
345 const gboolean local_is_utf8 = g_get_charset (&local_encoding);
347 /* There seems to be no Glib function to convert from local encoding
348 to filename encoding. Therefore it has to be done in two steps:
349 the intermediate encoding is UTF8.
351 Either step could fail. However, in many cases the file can still
352 be loaded even if the conversion fails. So in those cases, after showing
353 a warning, we simply copy the locally encoded filename to the destination
354 and hope for the best.
364 utf8 = g_locale_to_utf8 (fn, -1, NULL, &written, &err);
367 g_warning ("Cannot convert filename from local encoding `%s' to UTF-8: %s",
370 g_clear_error (&err);
377 filename = g_filename_from_utf8 (utf8, written, NULL, NULL, &err);
378 if ( NULL == filename)
380 g_warning ("Cannot convert filename from UTF8 to filename encoding: %s",
382 g_clear_error (&err);
388 if ( filename == NULL)
389 filename = xstrdup (fn);
395 handle_msg (const struct msg *m_, void *lexer_)
397 struct lexer *lexer = lexer_;
400 if (lexer != NULL && m.file_name == NULL)
402 m.file_name = CONST_CAST (char *, lex_get_file_name (lexer));
403 m.first_line = lex_get_first_line_number (lexer, 0);
404 m.last_line = lex_get_last_line_number (lexer, 0);
405 m.first_column = lex_get_first_column (lexer, 0);
406 m.last_column = lex_get_last_column (lexer, 0);
409 message_item_submit (message_item_create (&m));
413 psppire_set_lexer (struct lexer *lexer)
415 msg_set_handler (handle_msg, lexer);