Revert "adding osx application bundler scripts"
[pspp] / src / ui / gui / psppire.c
index f0041eba4ec07b0f57ff072226a8695f54338600..1532cbd316fca466ad9f6ef5169db23f353cfb39 100644 (file)
@@ -1,10 +1,9 @@
-/* 
-   PSPPIRE --- A Graphical User Interface for PSPP
-   Copyright (C) 2004, 2005, 2006  Free Software Foundation
+/* PSPPIRE - a graphical user interface for PSPP.
+   Copyright (C) 2004, 2005, 2006, 2009, 2010, 2011, 2012, 2013, 2014, 2016  Free Software Foundation
 
-   This program is free software; you can redistribute it and/or modify
+   This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-   02110-1301, USA. */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
 
 #include <config.h>
 
-#include <assert.h>
-#include <libintl.h>
-
 
-#include "data-editor.h"
-#include <libpspp/version.h>
-#include <libpspp/copyleft.h>
-#include <data/file-handle-def.h>
-#include <data/format.h>
-#include <data/settings.h>
-#include <data/file-name.h>
-#include <data/procedure.h>
-#include <libpspp/getl.h>
-#include <language/lexer/lexer.h>
-
-#include <getopt.h>
-#include <gtk/gtk.h>
+#include <assert.h>
+#include <gsl/gsl_errno.h>
 #include <gtk/gtk.h>
-#include <glade/glade.h>
-#include "psppire-dict.h"
-#include "psppire-var-store.h"
-#include "psppire-data-store.h"
-#include "helper.h"
-#include "data-sheet.h"
-#include "var-sheet.h"
-#include "message-dialog.h"
-#include "flexifile-factory.h"
-
-PsppireDataStore *the_data_store = 0;
-
-
-static bool parse_command_line (int *argc, char ***argv, 
-                               gchar **filename, GError **err);
-
+#include <libintl.h>
+#include <unistd.h>
+
+#include "data/any-reader.h"
+#include "data/casereader.h"
+#include "data/dataset.h"
+#include "data/datasheet.h"
+#include "data/file-handle-def.h"
+#include "data/session.h"
+#include "data/settings.h"
+
+#include "language/lexer/lexer.h"
+#include "libpspp/i18n.h"
+#include "libpspp/message.h"
+#include "libpspp/version.h"
+
+#include "output/driver.h"
+#include "output/journal.h"
+#include "output/message-item.h"
+
+#include "ui/gui/dict-display.h"
+#include "ui/gui/executor.h"
+#include "ui/gui/psppire-data-store.h"
+#include "ui/gui/psppire-data-window.h"
+#include "ui/gui/psppire-dict.h"
+#include "ui/gui/psppire.h"
+#include "ui/gui/psppire-output-window.h"
+#include "ui/gui/psppire-syntax-window.h"
+#include "ui/gui/psppire-selector.h"
+#include "ui/gui/psppire-var-view.h"
+#include "ui/gui/psppire-means-layer.h"
+#include "ui/gui/psppire-window-register.h"
+#include "ui/gui/widgets.h"
+#include "ui/source-init-opts.h"
+#include "ui/syntax-gen.h"
+
+#include "ui/gui/icons/icon-names.h"
+
+
+#include "gl/configmake.h"
+#include "gl/xalloc.h"
+#include "gl/relocatable.h"
+
+static void create_icon_factory (void);
 
 #define _(msgid) gettext (msgid)
 #define N_(msgid) msgid
 
-static void
-give_help(void)
+
+bool
+initialize (const struct init_source *is)
 {
-  static struct msg m = {
-    MSG_GENERAL, 
-    MSG_NOTE,
-    {0, -1},
-    0, 
-  };
+  switch (is->state)
+    {
+    case 0:
+      i18n_init ();
+      break;
+    case 1:
+      preregister_widgets ();
+      break;
+    case 2:
+      gsl_set_error_handler_off ();
+      break;
+    case 3:
+      output_engine_push ();
+      break;
+    case 4:
+      settings_init ();
+      break;
+    case 5:
+      fh_init ();
+      break;
+    case 6:
+      psppire_set_lexer (NULL);
+      break;
+    case 7:
+      bind_textdomain_codeset (PACKAGE, "UTF-8");
+      break;
+    case 8:
+      if ( ! gtk_parse_args (is->argc, is->argv) )
+       {
+         perror ("Error parsing arguments");
+         exit (1);
+       }
+      break;
+    case 9:
+      create_icon_factory ();
+      break;
+    case 10:
+      psppire_output_window_setup ();
+      break;
+    case 11:
+      journal_init ();
+      break;
+    case 12:
+      textdomain (PACKAGE);
+      break;
+    case 13:
+      /* FIXME: This should be implemented with a GtkInterface */
+      psppire_selector_set_default_selection_func (GTK_TYPE_ENTRY, insert_source_row_into_entry);
+      psppire_selector_set_default_selection_func (PSPPIRE_VAR_VIEW_TYPE, insert_source_row_into_tree_view);
+      psppire_selector_set_default_selection_func (GTK_TYPE_TREE_VIEW, insert_source_row_into_tree_view);
+      psppire_selector_set_default_selection_func (PSPPIRE_TYPE_MEANS_LAYER, insert_source_row_into_layers);
+      break;
+    case 14:
+      {
+      if (is->filename_arg != -1)
+       {
+#ifndef G_OS_WIN32
+         const char *file = (*is->argv)[is->filename_arg];
+         const gchar *local_encoding = NULL;
+         g_get_charset (&local_encoding);
+#else
+         char **as = g_win32_get_command_line ();
+         const char *file = as[is->filename_arg];
+         const gchar *local_encoding = "UTF-8";
+#endif   
+
+         struct file_handle *fh = fh_create_file (NULL,
+                                                  file,
+                                                  local_encoding,
+                                                  fh_default_properties ());
+         
+         const char *filename = fh_get_file_name (fh);
+
+         int retval = any_reader_detect (fh, NULL);
+
+         /* Check to see if the file is a .sav or a .por file.  If not
+            assume that it is a syntax file */
+         if (retval == 1)
+           open_data_window (NULL, filename, NULL, NULL);
+         else if (retval == 0)
+           {
+             create_data_window ();
+             open_syntax_window (filename, NULL);
+           }
+
+         fh_unref (fh);
+       }
+      else
+       {
+         create_data_window ();
+       }
+      return TRUE;
+      }
+      break;
+    default:
+      return TRUE;
+      break;
+    }
+  return FALSE;
+}
 
-  if (! m.text) 
-    m.text=g_strdup(_("Sorry. The help system hasn't yet been implemented."));
 
-  popup_message(&m);
+void
+de_initialize (void)
+{
+  settings_done ();
+  output_engine_pop ();
+  i18n_done ();
 }
 
-PsppireVarStore *the_var_store = 0;
-
-void create_icon_factory (void);
+void
+psppire_quit (void)
+{
+  gtk_main_quit ();
+}
 
-struct source_stream *the_source_stream ;
-struct dataset * the_dataset = NULL;
+struct icon_size
+{
+  int resolution;  /* The dimension of the images which will be used */
+  size_t n_sizes;  /* The number of items in the array below. */
+  const GtkIconSize *usage; /* An array determining for what the icon set is used */
+};
 
+static const GtkIconSize menus[] = {GTK_ICON_SIZE_MENU};
+static const GtkIconSize large_toolbar[] = {GTK_ICON_SIZE_LARGE_TOOLBAR};
+static const GtkIconSize small_toolbar[] = {GTK_ICON_SIZE_SMALL_TOOLBAR};
 
-int 
-main(int argc, char *argv[]) 
-{
-  struct casefile_factory *factory;
-  PsppireDict *dictionary = 0;
 
+/* We currently have three icon sets viz: 16x16, 24x24 and 32x32
+   We use the 16x16 for menus, the 32x32 for the large_toolbars and 
+   the 24x24 for small_toolbars.
 
-  GtkWidget *data_editor ;
-  GtkSheet *var_sheet ; 
-  GtkSheet *data_sheet ;
+   The order of this array is pertinent.  The icons in the sets occuring
+   earlier in the array will be used a the wildcard (default) icon size,
+   if such an icon exists.
+*/
+static const struct icon_size sizemap[] = 
+{
+  {24,  sizeof (small_toolbar) / sizeof (GtkIconSize), small_toolbar},
+  {16,  sizeof (menus) / sizeof (GtkIconSize), menus},
+  {32,  sizeof (large_toolbar) / sizeof (GtkIconSize), large_toolbar}
+};
 
-  gchar *filename=0;
-  GError *err = 0;
-  gchar *vers;
 
-  gtk_init(&argc, &argv);
-  if ( (vers = gtk_check_version(GTK_MAJOR_VERSION, 
-                                GTK_MINOR_VERSION, 
-                                GTK_MICRO_VERSION)) )
-    {
-      g_critical(vers);
+static void
+create_icon_factory (void)
+{
+  gint c;
+  GtkIconFactory *factory = gtk_icon_factory_new ();
+  struct icon_context ctx[2];
+  ctx[0] = action_icon_context;
+  ctx[1] = category_icon_context;
+  for (c = 0 ; c < 2 ; ++c)
+  {
+    const struct icon_context *ic = &ctx[c];
+    gint i;
+    for (i = 0 ; i < ic->n_icons ; ++i)
+      {
+       gboolean wildcarded = FALSE;
+       GtkIconSet *icon_set = gtk_icon_set_new ();
+       int r;
+       for (r = 0 ; r < sizeof (sizemap) / sizeof (sizemap[0]); ++r)
+         {
+           int s;
+           GtkIconSource *source = gtk_icon_source_new ();
+           gchar *filename = g_strdup_printf ("%s/%s/%dx%d/%s.png", PKGDATADIR,
+                                              ic->context_name,
+                                              sizemap[r].resolution, sizemap[r].resolution,
+                                              ic->icon_name[i]);
+           const char *relocated_filename = relocate (filename);
+           GFile *gf = g_file_new_for_path (relocated_filename);
+           if (g_file_query_exists (gf, NULL))
+             {
+               gtk_icon_source_set_filename (source, relocated_filename);
+               if (!wildcarded)
+                 {
+                   gtk_icon_source_set_size_wildcarded (source, TRUE);
+                   wildcarded = TRUE;
+                 }
+             }
+           g_object_unref (gf);
+
+           for (s = 0 ; s < sizemap[r].n_sizes ; ++s)
+             gtk_icon_source_set_size (source, sizemap[r].usage[s]);
+           if (filename != relocated_filename)
+             free (CONST_CAST (char *, relocated_filename));
+           g_free (filename);
+
+           if ( gtk_icon_source_get_filename (source))
+             gtk_icon_set_add_source (icon_set, source);
+
+           gtk_icon_source_free (source);
+         }
+      
+       gtk_icon_factory_add (factory, ic->icon_name[i], icon_set);
     }
-       
+  }
 
-  /* gtk_init messes with the locale. 
-     So unset the bits we want to control ourselves */
-  setlocale (LC_NUMERIC, "C");
+  {
+    struct iconmap
+    {
+      const gchar *gtk_id;
+      gchar *pspp_id;
+    };
 
-  bindtextdomain (PACKAGE, locale_dir);
+    /* We have our own icons for some things.
+       But we want the Stock Item to be identical to the Gtk standard
+       ones in all other respects.
+    */
+    const struct iconmap map[] = {
+      {GTK_STOCK_NEW,    "file-new-document"},
+      {GTK_STOCK_QUIT,   "file-quit"},
+      {GTK_STOCK_SAVE,   "file-save-document"},
+      {GTK_STOCK_CUT,    "edit-cut"},
+      {GTK_STOCK_COPY,   "edit-copy"},
+      {GTK_STOCK_PASTE,  "edit-paste"},
+      {GTK_STOCK_UNDO,   "edit-undo"},
+      {GTK_STOCK_REDO,   "edit-redo"},
+      {GTK_STOCK_DELETE, "edit-delete"},
+      {GTK_STOCK_ABOUT,  "help-about"},
+      {GTK_STOCK_PRINT,  "file-print-document"}
+    };
 
-  textdomain (PACKAGE);
+    GtkStockItem customised[sizeof (map) / sizeof (map[0])];
+    int i;
 
-  if ( ! parse_command_line(&argc, &argv, &filename, &err) ) 
+    for (i = 0; i < sizeof (map) / sizeof (map[0]); ++i)
     {
-      g_clear_error(&err);
-      return 0;
+      gtk_stock_lookup (map[i].gtk_id, &customised[i]);
+      customised[i].stock_id =  map[i].pspp_id;
     }
 
-  glade_init();
-
-  fmt_init();
-  settings_init();
-  fh_init ();
-  factory = flexifile_factory_create ();
-  the_source_stream = create_source_stream (
-                         fn_getenv_default ("STAT_INCLUDE_PATH", include_path)
-                         );
-
-  the_dataset = create_dataset (factory);
-
-  message_dialog_init (the_source_stream);
-
-  dictionary =
-    psppire_dict_new_from_dict (
-                               dataset_dict (the_dataset)
-                               );
-
-  bind_textdomain_codeset(PACKAGE, "UTF-8");
-
-  /* Create the model for the var_sheet */
-  the_var_store = psppire_var_store_new(dictionary);
-
-
-  the_data_store = psppire_data_store_new (dictionary);
-
-  create_icon_factory();
-
-#if 0
-  /* load the interface */
-  data_editor_xml = glade_xml_new(PKGDATADIR "/data-editor.glade", NULL, NULL);
 
-  if ( !data_editor_xml ) return 1;
 
-  data_editor = get_widget_assert(data_editor_xml, "data_editor");
-
-  /* connect the signals in the interface */
-  glade_xml_signal_autoconnect(data_editor_xml);
-
-  var_sheet  = GTK_SHEET(get_widget_assert(data_editor_xml, "variable_sheet"));
-  data_sheet = GTK_SHEET(get_widget_assert(data_editor_xml, "data_sheet"));
-
-  gtk_sheet_set_model(var_sheet, G_SHEET_MODEL(the_var_store));
-
-  gtk_sheet_set_model(data_sheet, G_SHEET_MODEL(the_data_store));
-
-  var_data_selection_init();
-
-  {
-  GList *helps = glade_xml_get_widget_prefix(data_editor_xml, "help_button_");
-
-  GList *i;
-  for ( i = g_list_first(helps); i ; i = g_list_next(i))
-      g_signal_connect(GTK_WIDGET(i->data), "clicked", give_help, 0);
+    gtk_stock_add (customised, sizeof (map) / sizeof (map[0]));
   }
 
-#endif
-
-  new_data_window (NULL, NULL);
+  {
+    /* Create our own "pspp-stock-reset" item, using the
+       GTK_STOCK_REFRESH icon set */
+    GtkStockItem items[2] = {
+      {"pspp-stock-reset", N_("_Reset"), 0, 0, PACKAGE},
+      {"pspp-stock-select", N_("_Select"), 0, 0, PACKAGE}
+    };
 
-  /* start the event loop */
-  gtk_main();
+    gtk_stock_add (items, 2);
 
-  destroy_source_stream (the_source_stream);
-  message_dialog_done();
+    gtk_icon_factory_add (factory, "pspp-stock-reset",
+                         gtk_icon_factory_lookup_default (GTK_STOCK_REFRESH)
+                         );
 
-  settings_done();
+    gtk_icon_factory_add (factory, "pspp-stock-select",
+                         gtk_icon_factory_lookup_default (GTK_STOCK_INDEX)
+                         );
+  }
 
-  return 0;
+  gtk_icon_factory_add_default (factory);
 }
 
+\f
 
-/* Parses the command line specified by ARGC and ARGV as received by
-   main().  Returns true if normal execution should proceed,
-   false if the command-line indicates that PSPP should exit. */
-static bool
-parse_command_line (int *argc, char ***argv, gchar **filename, GError **err)
+static void
+handle_msg (const struct msg *m_, void *lexer_)
 {
-  static struct option long_options[] =
-    {
-      {"help", no_argument, NULL, 'h'},
-      {"version", no_argument, NULL, 'V'},
-      {0, 0, 0, 0},
-    };
-
-  int c;
-
-  for (;;)
-    {
-      c = getopt_long (*argc, *argv, "hV", long_options, NULL);
-      if (c == -1)
-       break;
-
-      switch (c)
-       {
-       case 'h':
-         g_print ("Usage: psppire {|--help|--version}\n");
-          return false;
-       case 'V':
-         g_print (version);
-         g_print ("\n");
-         g_print (legal);
-         return false;
-       default:
-         return false;
-       }
-    }
+  struct lexer *lexer = lexer_;
+  struct msg m = *m_;
 
-  if ( optind < *argc) 
+  if (lexer != NULL && m.file_name == NULL)
     {
-      *filename = (*argv)[optind];
+      m.file_name = CONST_CAST (char *, lex_get_file_name (lexer));
+      m.first_line = lex_get_first_line_number (lexer, 0);
+      m.last_line = lex_get_last_line_number (lexer, 0);
+      m.first_column = lex_get_first_column (lexer, 0);
+      m.last_column = lex_get_last_column (lexer, 0);
     }
 
-  return true;
+  message_item_submit (message_item_create (&m));
 }
 
-
-
-void 
-create_icon_factory (void)
+void
+psppire_set_lexer (struct lexer *lexer)
 {
-  GtkIconFactory *factory = gtk_icon_factory_new();
-
-  GtkIconSet *icon_set;
-  
-  GdkPixbuf *pixbuf;
-
-  pixbuf = gdk_pixbuf_new_from_file (PKGDATADIR "/value-labels.png", 0);
-  icon_set = gtk_icon_set_new_from_pixbuf (pixbuf);
-  g_object_unref (pixbuf);
-  gtk_icon_factory_add ( factory, "pspp-value-labels", icon_set);
-
-  pixbuf = gdk_pixbuf_new_from_file (PKGDATADIR "/weight-cases.png", 0);
-  icon_set = gtk_icon_set_new_from_pixbuf (pixbuf);
-  g_object_unref (pixbuf);
-  gtk_icon_factory_add ( factory, "pspp-weight-cases", icon_set);
-
-  pixbuf = gdk_pixbuf_new_from_file (PKGDATADIR "/goto-variable.png", 0);
-  icon_set = gtk_icon_set_new_from_pixbuf (pixbuf);
-  g_object_unref (pixbuf);
-  gtk_icon_factory_add ( factory, "pspp-goto-variable", icon_set);
-
-  pixbuf = gdk_pixbuf_new_from_file (PKGDATADIR "/insert-variable.png", 0);
-  icon_set = gtk_icon_set_new_from_pixbuf (pixbuf);
-  g_object_unref (pixbuf);
-  gtk_icon_factory_add ( factory, "pspp-insert-variable", icon_set);
-
-  pixbuf = gdk_pixbuf_new_from_file (PKGDATADIR "/insert-case.png", 0);
-  icon_set = gtk_icon_set_new_from_pixbuf (pixbuf);
-  g_object_unref (pixbuf);
-  gtk_icon_factory_add ( factory, "pspp-insert-case", icon_set);
-
-  pixbuf = gdk_pixbuf_new_from_file (PKGDATADIR "/split-file.png", 0);
-  icon_set = gtk_icon_set_new_from_pixbuf (pixbuf);
-  g_object_unref (pixbuf);
-  gtk_icon_factory_add ( factory, "pspp-split-file", icon_set);
-
-  pixbuf = gdk_pixbuf_new_from_file (PKGDATADIR "/select-cases.png", 0);
-  icon_set = gtk_icon_set_new_from_pixbuf (pixbuf);
-  g_object_unref (pixbuf);
-  gtk_icon_factory_add ( factory, "pspp-select-cases", icon_set);
-
-  gtk_icon_factory_add_default (factory);
+  msg_set_handler (handle_msg, lexer);
 }