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/session.h"
32 #include "data/settings.h"
34 #include "language/lexer/lexer.h"
35 #include "libpspp/i18n.h"
36 #include "libpspp/message.h"
37 #include "libpspp/version.h"
39 #include "output/driver.h"
40 #include "output/journal.h"
41 #include "output/message-item.h"
43 #include "ui/gui/dict-display.h"
44 #include "ui/gui/executor.h"
45 #include "ui/gui/psppire-data-store.h"
46 #include "ui/gui/psppire-data-window.h"
47 #include "ui/gui/psppire-dict.h"
48 #include "ui/gui/psppire.h"
49 #include "ui/gui/psppire-output-window.h"
50 #include "ui/gui/psppire-syntax-window.h"
51 #include "ui/gui/psppire-selector.h"
52 #include "ui/gui/psppire-var-view.h"
53 #include "ui/gui/psppire-means-layer.h"
54 #include "ui/gui/psppire-window-register.h"
55 #include "ui/gui/widgets.h"
56 #include "ui/source-init-opts.h"
57 #include "ui/syntax-gen.h"
59 #include "ui/gui/icons/icon-names.h"
62 #include "gl/configmake.h"
63 #include "gl/xalloc.h"
64 #include "gl/relocatable.h"
66 static void create_icon_factory (void);
67 static gchar *local_to_filename_encoding (const char *fn);
70 #define _(msgid) gettext (msgid)
71 #define N_(msgid) msgid
75 initialize (const struct init_source *is)
83 preregister_widgets ();
86 gsl_set_error_handler_off ();
89 output_engine_push ();
98 psppire_set_lexer (NULL);
101 bind_textdomain_codeset (PACKAGE, "UTF-8");
104 if ( ! gtk_parse_args (is->argc, is->argv) )
106 perror ("Error parsing arguments");
111 create_icon_factory ();
114 psppire_output_window_setup ();
120 textdomain (PACKAGE);
123 /* FIXME: This should be implemented with a GtkInterface */
124 psppire_selector_set_default_selection_func (GTK_TYPE_ENTRY, insert_source_row_into_entry);
125 psppire_selector_set_default_selection_func (PSPPIRE_VAR_VIEW_TYPE, insert_source_row_into_tree_view);
126 psppire_selector_set_default_selection_func (GTK_TYPE_TREE_VIEW, insert_source_row_into_tree_view);
127 psppire_selector_set_default_selection_func (PSPPIRE_TYPE_MEANS_LAYER, insert_source_row_into_layers);
133 gchar *filename = local_to_filename_encoding (is->file);
135 int retval = any_reader_detect (filename, NULL);
137 /* Check to see if the file is a .sav or a .por file. If not
138 assume that it is a syntax file */
140 open_data_window (NULL, filename, NULL, NULL);
141 else if (retval == 0)
143 create_data_window ();
144 open_syntax_window (filename, NULL);
150 create_data_window ();
167 output_engine_pop ();
172 func (gpointer key, gpointer value, gpointer data)
175 PsppireWindow *window = PSPPIRE_WINDOW (value);
177 g_signal_emit_by_name (window, "delete-event", 0, &rv);
183 PsppireWindowRegister *reg = psppire_window_register_new ();
184 psppire_window_register_foreach (reg, func, NULL);
191 int resolution; /* The dimension of the images which will be used */
192 size_t n_sizes; /* The number of items in the array below. */
193 const GtkIconSize *usage; /* An array determining for what the icon set is used */
196 static const GtkIconSize menus[] = {GTK_ICON_SIZE_MENU};
197 static const GtkIconSize large_toolbar[] = {GTK_ICON_SIZE_LARGE_TOOLBAR};
198 static const GtkIconSize small_toolbar[] = {GTK_ICON_SIZE_SMALL_TOOLBAR};
201 /* We currently have three icon sets viz: 16x16, 24x24 and 32x32
202 We use the 16x16 for menus, the 32x32 for the large_toolbars and
203 the 24x24 for small_toolbars.
205 The order of this array is pertinent. The icons in the sets occuring
206 earlier in the array will be used a the wildcard (default) icon size,
207 if such an icon exists.
209 static const struct icon_size sizemap[] =
211 {24, sizeof (small_toolbar) / sizeof (GtkIconSize), small_toolbar},
212 {16, sizeof (menus) / sizeof (GtkIconSize), menus},
213 {32, sizeof (large_toolbar) / sizeof (GtkIconSize), large_toolbar}
218 create_icon_factory (void)
221 GtkIconFactory *factory = gtk_icon_factory_new ();
222 struct icon_context ctx[2];
223 ctx[0] = action_icon_context;
224 ctx[1] = category_icon_context;
225 for (c = 0 ; c < 2 ; ++c)
227 const struct icon_context *ic = &ctx[c];
229 for (i = 0 ; i < ic->n_icons ; ++i)
231 gboolean wildcarded = FALSE;
232 GtkIconSet *icon_set = gtk_icon_set_new ();
234 for (r = 0 ; r < sizeof (sizemap) / sizeof (sizemap[0]); ++r)
237 GtkIconSource *source = gtk_icon_source_new ();
238 gchar *filename = g_strdup_printf ("%s/%s/%dx%d/%s.png", PKGDATADIR,
240 sizemap[r].resolution, sizemap[r].resolution,
242 const char *relocated_filename = relocate (filename);
243 GFile *gf = g_file_new_for_path (relocated_filename);
244 if (g_file_query_exists (gf, NULL))
246 gtk_icon_source_set_filename (source, relocated_filename);
249 gtk_icon_source_set_size_wildcarded (source, TRUE);
255 for (s = 0 ; s < sizemap[r].n_sizes ; ++s)
256 gtk_icon_source_set_size (source, sizemap[r].usage[s]);
257 if (filename != relocated_filename)
258 free (CONST_CAST (char *, relocated_filename));
261 if ( gtk_icon_source_get_filename (source))
262 gtk_icon_set_add_source (icon_set, source);
264 gtk_icon_source_free (source);
267 gtk_icon_factory_add (factory, ic->icon_name[i], icon_set);
278 /* We have our own icons for some things.
279 But we want the Stock Item to be identical to the Gtk standard
280 ones in all other respects.
282 const struct iconmap map[] = {
283 {GTK_STOCK_NEW, "file-new-document"},
284 {GTK_STOCK_QUIT, "file-quit"},
285 {GTK_STOCK_SAVE, "file-save-document"},
286 {GTK_STOCK_CUT, "edit-cut"},
287 {GTK_STOCK_COPY, "edit-copy"},
288 {GTK_STOCK_PASTE, "edit-paste"},
289 {GTK_STOCK_UNDO, "edit-undo"},
290 {GTK_STOCK_REDO, "edit-redo"},
291 {GTK_STOCK_DELETE, "edit-delete"},
292 {GTK_STOCK_ABOUT, "help-about"},
293 {GTK_STOCK_PRINT, "file-print-document"}
296 GtkStockItem customised[sizeof (map) / sizeof (map[0])];
299 for (i = 0; i < sizeof (map) / sizeof (map[0]); ++i)
301 gtk_stock_lookup (map[i].gtk_id, &customised[i]);
302 customised[i].stock_id = map[i].pspp_id;
307 gtk_stock_add (customised, sizeof (map) / sizeof (map[0]));
311 /* Create our own "pspp-stock-reset" item, using the
312 GTK_STOCK_REFRESH icon set */
313 GtkStockItem items[2] = {
314 {"pspp-stock-reset", N_("_Reset"), 0, 0, PACKAGE},
315 {"pspp-stock-select", N_("_Select"), 0, 0, PACKAGE}
318 gtk_stock_add (items, 2);
320 gtk_icon_factory_add (factory, "pspp-stock-reset",
321 gtk_icon_factory_lookup_default (GTK_STOCK_REFRESH)
324 gtk_icon_factory_add (factory, "pspp-stock-select",
325 gtk_icon_factory_lookup_default (GTK_STOCK_INDEX)
329 gtk_icon_factory_add_default (factory);
333 Convert a filename from the local encoding into "filename" encoding.
334 The return value will be allocated on the heap. It is the responsibility
335 of the caller to free it.
338 local_to_filename_encoding (const char *fn)
340 gchar *filename = NULL;
342 const gchar *local_encoding = NULL;
344 const gboolean local_is_utf8 = g_get_charset (&local_encoding);
346 /* There seems to be no Glib function to convert from local encoding
347 to filename encoding. Therefore it has to be done in two steps:
348 the intermediate encoding is UTF8.
350 Either step could fail. However, in many cases the file can still
351 be loaded even if the conversion fails. So in those cases, after showing
352 a warning, we simply copy the locally encoded filename to the destination
353 and hope for the best.
363 utf8 = g_locale_to_utf8 (fn, -1, NULL, &written, &err);
366 g_warning ("Cannot convert filename from local encoding `%s' to UTF-8: %s",
369 g_clear_error (&err);
376 filename = g_filename_from_utf8 (utf8, written, NULL, NULL, &err);
377 if ( NULL == filename)
379 g_warning ("Cannot convert filename from UTF8 to filename encoding: %s",
381 g_clear_error (&err);
387 if ( filename == NULL)
388 filename = xstrdup (fn);
394 handle_msg (const struct msg *m_, void *lexer_)
396 struct lexer *lexer = lexer_;
399 if (lexer != NULL && m.file_name == NULL)
401 m.file_name = CONST_CAST (char *, lex_get_file_name (lexer));
402 m.first_line = lex_get_first_line_number (lexer, 0);
403 m.last_line = lex_get_last_line_number (lexer, 0);
404 m.first_column = lex_get_first_column (lexer, 0);
405 m.last_column = lex_get_last_column (lexer, 0);
408 message_item_submit (message_item_create (&m));
412 psppire_set_lexer (struct lexer *lexer)
414 msg_set_handler (handle_msg, lexer);