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);
266 gtk_icon_factory_add (factory, ic->icon_name[i], icon_set);
277 /* We have our own icons for some things.
278 But we want the Stock Item to be identical to the Gtk standard
279 ones in all other respects.
281 const struct iconmap map[] = {
282 {GTK_STOCK_NEW, "file-new-document"},
283 {GTK_STOCK_QUIT, "file-quit"},
284 {GTK_STOCK_SAVE, "file-save-document"},
285 {GTK_STOCK_CUT, "edit-cut"},
286 {GTK_STOCK_COPY, "edit-copy"},
287 {GTK_STOCK_PASTE, "edit-paste"},
288 {GTK_STOCK_UNDO, "edit-undo"},
289 {GTK_STOCK_REDO, "edit-redo"},
290 {GTK_STOCK_DELETE, "edit-delete"},
291 {GTK_STOCK_ABOUT, "help-about"},
292 {GTK_STOCK_PRINT, "file-print-document"}
295 GtkStockItem customised[sizeof (map) / sizeof (map[0])];
298 for (i = 0; i < sizeof (map) / sizeof (map[0]); ++i)
300 gtk_stock_lookup (map[i].gtk_id, &customised[i]);
301 customised[i].stock_id = map[i].pspp_id;
306 gtk_stock_add (customised, sizeof (map) / sizeof (map[0]));
310 /* Create our own "pspp-stock-reset" item, using the
311 GTK_STOCK_REFRESH icon set */
312 GtkStockItem items[2] = {
313 {"pspp-stock-reset", N_("_Reset"), 0, 0, PACKAGE},
314 {"pspp-stock-select", N_("_Select"), 0, 0, PACKAGE}
317 gtk_stock_add (items, 2);
319 gtk_icon_factory_add (factory, "pspp-stock-reset",
320 gtk_icon_factory_lookup_default (GTK_STOCK_REFRESH)
323 gtk_icon_factory_add (factory, "pspp-stock-select",
324 gtk_icon_factory_lookup_default (GTK_STOCK_INDEX)
328 gtk_icon_factory_add_default (factory);
332 Convert a filename from the local encoding into "filename" encoding.
333 The return value will be allocated on the heap. It is the responsibility
334 of the caller to free it.
337 local_to_filename_encoding (const char *fn)
339 gchar *filename = NULL;
341 const gchar *local_encoding = NULL;
343 const gboolean local_is_utf8 = g_get_charset (&local_encoding);
345 /* There seems to be no Glib function to convert from local encoding
346 to filename encoding. Therefore it has to be done in two steps:
347 the intermediate encoding is UTF8.
349 Either step could fail. However, in many cases the file can still
350 be loaded even if the conversion fails. So in those cases, after showing
351 a warning, we simply copy the locally encoded filename to the destination
352 and hope for the best.
362 utf8 = g_locale_to_utf8 (fn, -1, NULL, &written, &err);
365 g_warning ("Cannot convert filename from local encoding `%s' to UTF-8: %s",
368 g_clear_error (&err);
375 filename = g_filename_from_utf8 (utf8, written, NULL, NULL, &err);
376 if ( NULL == filename)
378 g_warning ("Cannot convert filename from UTF8 to filename encoding: %s",
380 g_clear_error (&err);
386 if ( filename == NULL)
387 filename = xstrdup (fn);
393 handle_msg (const struct msg *m_, void *lexer_)
395 struct lexer *lexer = lexer_;
398 if (lexer != NULL && m.file_name == NULL)
400 m.file_name = CONST_CAST (char *, lex_get_file_name (lexer));
401 m.first_line = lex_get_first_line_number (lexer, 0);
402 m.last_line = lex_get_last_line_number (lexer, 0);
403 m.first_column = lex_get_first_column (lexer, 0);
404 m.last_column = lex_get_last_column (lexer, 0);
407 message_item_submit (message_item_create (&m));
411 psppire_set_lexer (struct lexer *lexer)
413 msg_set_handler (handle_msg, lexer);