Merge remote-tracking branch 'origin/master' into sheet
authorJohn Darrington <john@darrington.wattle.id.au>
Thu, 18 May 2017 16:28:21 +0000 (18:28 +0200)
committerJohn Darrington <john@darrington.wattle.id.au>
Thu, 18 May 2017 16:28:21 +0000 (18:28 +0200)
1  2 
src/ui/gui/automake.mk
src/ui/gui/psppire-data-window.c
src/ui/gui/widgets.c

diff --combined src/ui/gui/automake.mk
index 224ef749fba668c2d41108d7e47fae393ef6c6ee,b19cccfe61ed8c133500240010c44d50b806c2f4..4338deb5b0ed006521054648f12ec76927745726
@@@ -20,6 -20,7 +20,7 @@@ UI_FILES = 
        src/ui/gui/frequencies.ui \
        src/ui/gui/histogram.ui \
        src/ui/gui/indep-samples.ui \
+       src/ui/gui/k-independent.ui \
        src/ui/gui/k-means.ui \
        src/ui/gui/k-related.ui \
        src/ui/gui/ks-one-sample.ui \
@@@ -68,14 -69,13 +69,14 @@@ EXTRA_DIST += 
        src/ui/gui/marshaller-list \
        src/ui/gui/pspplogo.svg
  
 +src_ui_gui_psppire_CPPFLAGS=
  
  if HAVE_GUI
 -bin_PROGRAMS += src/ui/gui/psppire 
 -noinst_PROGRAMS += src/ui/gui/spreadsheet-test 
 +bin_PROGRAMS += src/ui/gui/psppire
 +noinst_PROGRAMS += src/ui/gui/spreadsheet-test
  
 -src_ui_gui_psppire_CFLAGS = $(GTK_CFLAGS) $(GTKSOURCEVIEW_CFLAGS) -Wall -DGDK_MULTIHEAD_SAFE=1 
 -src_ui_gui_spreadsheet_test_CFLAGS = $(GTK_CFLAGS) -Wall -DGDK_MULTIHEAD_SAFE=1 
 +src_ui_gui_psppire_CFLAGS = $(GTK_CFLAGS) $(GTKSOURCEVIEW_CFLAGS) -Wall -DGDK_MULTIHEAD_SAFE=1
 +src_ui_gui_spreadsheet_test_CFLAGS = $(GTK_CFLAGS) -Wall -DGDK_MULTIHEAD_SAFE=1
  
  
  src_ui_gui_psppire_LDFLAGS = \
@@@ -121,9 -121,23 +122,9 @@@ INSTALL_DATA_HOOKS += install-lan
  
  dist_src_ui_gui_psppire_DATA = \
        $(UI_FILES) \
 -      $(top_srcdir)/src/ui/gui/pspp.lang \
 -      $(top_srcdir)/src/ui/gui/psppire.gtkrc
 +      $(top_srcdir)/src/ui/gui/pspp.lang
  
  src_ui_gui_psppire_SOURCES = \
 -      src/ui/gui/pspp-sheet-private.h \
 -      src/ui/gui/pspp-sheet-selection.c \
 -      src/ui/gui/pspp-sheet-selection.h \
 -      src/ui/gui/pspp-sheet-view-column.c \
 -      src/ui/gui/pspp-sheet-view-column.h \
 -      src/ui/gui/pspp-sheet-view.c \
 -      src/ui/gui/pspp-sheet-view.h \
 -      src/ui/gui/pspp-widget-facade.c \
 -      src/ui/gui/pspp-widget-facade.h \
 -      src/ui/gui/psppire-button-editable.c \
 -      src/ui/gui/psppire-button-editable.h \
 -      src/ui/gui/psppire-cell-renderer-button.c \
 -      src/ui/gui/psppire-cell-renderer-button.h \
        src/ui/gui/psppire-dialog.c \
        src/ui/gui/psppire-keypad.c \
        src/ui/gui/psppire-selector.c \
        src/ui/gui/psppire-conf.h \
        src/ui/gui/psppire-data-editor.c \
        src/ui/gui/psppire-data-editor.h \
 -      src/ui/gui/psppire-data-sheet.c \
 -      src/ui/gui/psppire-data-sheet.h \
        src/ui/gui/psppire-data-store.c \
        src/ui/gui/psppire-data-store.h \
        src/ui/gui/psppire-data-window.c \
        src/ui/gui/psppire-dialog-action-kmeans.h \
        src/ui/gui/psppire-dialog-action-logistic.c \
        src/ui/gui/psppire-dialog-action-logistic.h \
+       src/ui/gui/psppire-dialog-action-k-independent.c \
+       src/ui/gui/psppire-dialog-action-k-independent.h \
        src/ui/gui/psppire-dialog-action-k-related.c \
        src/ui/gui/psppire-dialog-action-k-related.h \
        src/ui/gui/psppire-dialog-action-means.c \
        src/ui/gui/psppire-select-dest.h \
        src/ui/gui/psppire-syntax-window.c \
        src/ui/gui/psppire-syntax-window.h \
 +      src/ui/gui/psppire-delimited-text.c \
 +      src/ui/gui/psppire-delimited-text.h \
 +      src/ui/gui/psppire-text-file.c \
 +      src/ui/gui/psppire-text-file.h \
        src/ui/gui/psppire-val-chooser.c \
        src/ui/gui/psppire-val-chooser.h \
        src/ui/gui/psppire-value-entry.c \
        src/ui/gui/psppire-value-entry.h \
        src/ui/gui/psppire-var-ptr.c \
        src/ui/gui/psppire-var-ptr.h \
 -      src/ui/gui/psppire-var-sheet.c \
 -      src/ui/gui/psppire-var-sheet.h \
 +      src/ui/gui/psppire-data-sheet.c \
 +      src/ui/gui/psppire-data-sheet.h \
 +      src/ui/gui/psppire-variable-sheet.c \
 +      src/ui/gui/psppire-variable-sheet.h \
 +      src/ui/gui/psppire-var-sheet-header.h \
 +      src/ui/gui/psppire-var-sheet-header.c \
        src/ui/gui/psppire-window.c \
        src/ui/gui/psppire-window.h \
        src/ui/gui/psppire-window-base.c \
        src/ui/gui/var-display.h \
        src/ui/gui/var-type-dialog.c \
        src/ui/gui/var-type-dialog.h \
 +      src/ui/gui/value-variant.c \
 +      src/ui/gui/value-variant.h \
        src/ui/gui/widget-io.c \
        src/ui/gui/widget-io.h \
        src/ui/gui/widgets.c \
@@@ -388,8 -396,6 +391,8 @@@ BUILT_SOURCES += src/ui/gui/psppire-mar
  
  CLEANFILES += src/ui/gui/psppire-marshal.c src/ui/gui/psppire-marshal.h \
        src/ui/gui/resources.c $(nodist_src_ui_gui_psppire_DATA)
 +
 +include $(top_srcdir)/src/ui/gui/efficient-sheet.mk
  endif HAVE_GUI
  
  #ensure the installcheck passes even if there is no X server available
@@@ -397,7 -403,7 +400,7 @@@ installcheck-local
        DISPLAY=/invalid/port $(MAKE) $(AM_MAKEFLAGS) installcheck-binPROGRAMS
  
  # <gtk/gtk.h> wrapper
 -src_ui_gui_psppire_CPPFLAGS = $(AM_CPPFLAGS) -Isrc/ui/gui/include
 +src_ui_gui_psppire_CPPFLAGS += $(AM_CPPFLAGS) -Isrc/ui/gui/include
  BUILT_SOURCES += src/ui/gui/include/gtk/gtk.h
  src/ui/gui/include/gtk/gtk.h: src/ui/gui/include/gtk/gtk.in.h
        @$(MKDIR_P) src/ui/gui/include/gtk
index 8af85b946b590e233417451317d6afd0f6809219,15fe2e9fe956616965ef5c5f98adeca2b1c37b51..a6a9b241cdefb7271e894a6ba379324437fb906c
@@@ -1,6 -1,5 +1,6 @@@
  /* PSPPIRE - a graphical user interface for PSPP.
 -   Copyright (C) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2016  Free Software Foundation
 +   Copyright (C) 2008, 2009, 2010, 2011, 2012, 2013, 2014,
 +   2016, 2017  Free Software Foundation
  
     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
  #include "ui/gui/helper.h"
  #include "ui/gui/psppire-import-assistant.h"
  #include "ui/gui/psppire-data-window.h"
 +#include "ui/gui/psppire-data-editor.h"
  #include "ui/gui/psppire-dialog-action.h"
  #include "ui/gui/psppire-encoding-selector.h"
  #include "ui/gui/psppire-syntax-window.h"
  #include "ui/gui/psppire-window.h"
 -#include "ui/gui/psppire-data-sheet.h"
 -#include "ui/gui/psppire-var-sheet.h"
  #include "ui/gui/windows-menu.h"
  #include "ui/gui/goto-case-dialog.h"
  #include "ui/gui/psppire.h"
@@@ -47,8 -47,6 +47,8 @@@
  #include "gl/c-strcasestr.h"
  #include "gl/xvasprintf.h"
  
 +#include "ui/gui/efficient-sheet/src/jmd-sheet.h"
 +
  #include "find-dialog.h"
  #include "options-dialog.h"
  #include "psppire-dialog-action-1sks.h"
@@@ -69,6 -67,7 +69,7 @@@
  #include "psppire-dialog-action-frequencies.h"
  #include "psppire-dialog-action-histogram.h"
  #include "psppire-dialog-action-indep-samps.h"
+ #include "psppire-dialog-action-k-independent.h"
  #include "psppire-dialog-action-k-related.h"
  #include "psppire-dialog-action-kmeans.h"
  #include "psppire-dialog-action-logistic.h"
@@@ -1069,52 -1068,10 +1070,52 @@@ static voi
  on_cut (PsppireDataWindow *dw)
  {
    int p = gtk_notebook_get_current_page (GTK_NOTEBOOK (dw->data_editor));
 -  if (p == 0)
 -    {
 -      PsppireDataSheet *ds = psppire_data_editor_get_active_data_sheet (dw->data_editor);
 -      psppire_data_sheet_edit_cut (ds);
 +  if (p == PSPPIRE_DATA_EDITOR_DATA_VIEW)
 +  {
 +      PsppireDict *dict = NULL;
 +      g_object_get (dw->data_editor, "dictionary", &dict, NULL);
 +
 +      gint x, y;
 +      JmdSheet *sheet = JMD_SHEET (dw->data_editor->data_sheet);
 +      JmdRange sel = *sheet->selection;
 +
 +      GtkClipboard *clip =
 +      gtk_clipboard_get_for_display (gtk_widget_get_display (GTK_WIDGET (dw)),
 +                                     GDK_SELECTION_CLIPBOARD);
 +
 +      /* Save the selected area to a string */
 +      GString *str = g_string_new ("");
 +      for (y = sel.start_y ; y <= sel.end_y; ++y)
 +      {
 +        for (x = sel.start_x ; x <= sel.end_x; ++x)
 +          {
 +            const struct variable * var = psppire_dict_get_variable (dict, x);
 +            gchar *s = psppire_data_store_get_string (dw->data_editor->data_store,
 +                                                        y, var, FALSE);
 +            g_string_append (str, s);
 +            g_string_append (str, "\t");
 +            g_free (s);
 +          }
 +        g_string_append (str, "\n");
 +      }
 +
 +      gtk_clipboard_set_text (clip, str->str, str->len);
 +      g_string_free (str, TRUE);
 +
 +      /* Now fill the selected area with SYSMIS */
 +      union value sm ;
 +      sm.f = SYSMIS;
 +      for (x = sel.start_x ; x <= sel.end_x; ++x)
 +      {
 +        const struct variable * var = psppire_dict_get_variable (dict, x);
 +        for (y = sel.start_y ; y <= sel.end_y; ++y)
 +          {
 +            psppire_data_store_set_value (dw->data_editor->data_store,
 +                                          y,
 +                                          var, &sm);
 +          }
 +      }
 +
      }
  }
  
@@@ -1122,13 -1079,10 +1123,13 @@@ static voi
  on_copy (PsppireDataWindow *dw)
  {
    int p = gtk_notebook_get_current_page (GTK_NOTEBOOK (dw->data_editor));
 -  if (p == 0)
 +  if (p == PSPPIRE_DATA_EDITOR_DATA_VIEW)
      {
 -      PsppireDataSheet *ds = psppire_data_editor_get_active_data_sheet (dw->data_editor);
 -      psppire_data_sheet_edit_copy (ds);
 +      GtkClipboard *clip =
 +      gtk_clipboard_get_for_display (gtk_widget_get_display (GTK_WIDGET (dw)),
 +                                 GDK_SELECTION_CLIPBOARD);
 +
 +      jmd_sheet_set_clip (JMD_SHEET (dw->data_editor->data_sheet), clip);
      }
  }
  
@@@ -1136,78 -1090,75 +1137,78 @@@ static voi
  on_paste (PsppireDataWindow *dw)
  {
    int p = gtk_notebook_get_current_page (GTK_NOTEBOOK (dw->data_editor));
 -  if (p == 0)
 +  if (p == PSPPIRE_DATA_EDITOR_DATA_VIEW)
      {
 -      PsppireDataSheet *ds = psppire_data_editor_get_active_data_sheet (dw->data_editor);
 -      psppire_data_sheet_edit_paste (ds);
 +      psppire_data_editor_paste (dw->data_editor);
      }
  }
  
 -
  static void
  on_clear_cases (PsppireDataWindow *dw)
  {
 -  int p = gtk_notebook_get_current_page (GTK_NOTEBOOK (dw->data_editor));
 -  if (p == 0)
 +  PsppireDataEditor *de = dw->data_editor;
 +  int p = gtk_notebook_get_current_page (GTK_NOTEBOOK (de));
 +  if (p == PSPPIRE_DATA_EDITOR_DATA_VIEW)
      {
 -      PsppireDataSheet *ds = psppire_data_editor_get_active_data_sheet (dw->data_editor);
 -      psppire_data_sheet_edit_clear_cases (ds);
 +      JmdRange *range = JMD_SHEET(de->data_sheet)->selection;
 +      psppire_data_store_delete_cases (de->data_store, range->start_y,
 +                                     range->end_y - range->start_y + 1);
 +      gtk_widget_queue_draw (GTK_WIDGET (de->data_sheet));
      }
  }
  
  static void
  on_clear_variables (PsppireDataWindow *dw)
  {
 -  int p = gtk_notebook_get_current_page (GTK_NOTEBOOK (dw->data_editor));
 -  if (p == 0)
 +  PsppireDataEditor *de = dw->data_editor;
 +  int p = gtk_notebook_get_current_page (GTK_NOTEBOOK (de));
 +  if (p == PSPPIRE_DATA_EDITOR_DATA_VIEW)
      {
 -      PsppireDataSheet *ds = psppire_data_editor_get_active_data_sheet (dw->data_editor);
 -      psppire_data_sheet_edit_clear_variables (ds);
 +      psppire_data_editor_data_delete_variables (de);
      }
    else
      {
 -      psppire_var_sheet_clear_variables (PSPPIRE_VAR_SHEET (dw->data_editor->var_sheet));
 +      psppire_data_editor_var_delete_variables (de);
      }
  }
  
 -
  static void
  insert_variable (PsppireDataWindow *dw)
  {
 -  int p = gtk_notebook_get_current_page (GTK_NOTEBOOK (dw->data_editor));
 -  if (p == 0)
 +  PsppireDataEditor *de = dw->data_editor;
 +  int p = gtk_notebook_get_current_page (GTK_NOTEBOOK (de));
 +
 +  if (p == PSPPIRE_DATA_EDITOR_DATA_VIEW)
      {
 -      PsppireDataSheet *ds = psppire_data_editor_get_active_data_sheet (dw->data_editor);
 -      psppire_data_sheet_insert_variable (ds);
 +      JmdRange *range = JMD_SHEET(de->data_sheet)->selection;
 +      psppire_data_editor_insert_new_variable_at_posn (de, range->start_x);
      }
    else
      {
 -      psppire_var_sheet_insert_variable (PSPPIRE_VAR_SHEET (dw->data_editor->var_sheet));
 +      JmdRange *range = JMD_SHEET(de->var_sheet)->selection;
 +      psppire_data_editor_insert_new_variable_at_posn (de, range->start_y);
      }
  }
  
 -
  static void
  insert_case_at_row (PsppireDataWindow *dw)
  {
 -  PsppireDataSheet *ds = psppire_data_editor_get_active_data_sheet (dw->data_editor);
 -
 -  psppire_data_sheet_insert_case (ds);
 +  PsppireDataEditor *de = dw->data_editor;
 +  JmdRange *range = JMD_SHEET(de->data_sheet)->selection;
 +  psppire_data_editor_insert_new_case_at_posn (de, range->start_y);
  }
  
  static void
  goto_case (PsppireDataWindow *dw)
  {
 -  PsppireDataSheet *ds = psppire_data_editor_get_active_data_sheet (dw->data_editor);
 -
 -  goto_case_dialog (ds);
 +  PsppireDataEditor *de = dw->data_editor;
 +  int p = gtk_notebook_get_current_page (GTK_NOTEBOOK (de));
 +  if (p == PSPPIRE_DATA_EDITOR_DATA_VIEW)
 +    {
 +      goto_case_dialog (PSPPIRE_DATA_SHEET (de->data_sheet));
 +    }
  }
  
 -
 -
  static GtkWidget *
  create_file_menu (PsppireDataWindow *dw)
  {
    return menuitem;
  }
  
 +
  static GtkWidget *
  create_edit_menu (PsppireDataWindow *dw)
  {
    return menuitem;
  }
  
 -
  static void
  psppire_data_window_finish_init (PsppireDataWindow *de,
                                   struct dataset *ds)
    g_signal_connect_swapped (de->data_store, "case-changed",
                            G_CALLBACK (set_unsaved), de);
  
 -  g_signal_connect_swapped (de->data_store, "case-inserted",
 -                          G_CALLBACK (set_unsaved), de);
 -
 -  g_signal_connect_swapped (de->data_store, "cases-deleted",
 -                          G_CALLBACK (set_unsaved), de);
 -
    dataset_set_callbacks (de->dataset, &cbs, de);
  
    connect_help (de->builder);
                    G_CALLBACK (on_split_change),
                    de);
  
 -  g_signal_connect_swapped (de->dict, "backend-changed",
 +  g_signal_connect_swapped (de->dict, "items-changed",
                              G_CALLBACK (enable_save), de);
    g_signal_connect_swapped (de->dict, "variable-inserted",
                              G_CALLBACK (enable_save), de);
    connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_1SKS, de);
    connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_TWO_SAMPLE, de);
    connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_K_RELATED, de);
+   connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_K_INDEPENDENT, de);
  
    {
      GSimpleAction *file_import_action = g_simple_action_new ("file-import", NULL);
    ll_push_head (&all_data_windows, &de->ll);
  }
  
 +
  static void
  psppire_data_window_dispose (GObject *object)
  {
@@@ -1896,7 -1853,6 +1898,7 @@@ psppire_data_window_get_property (GObje
  }
  
  
 +
  GtkWidget*
  psppire_data_window_new (struct dataset *ds)
  {
    return dw;
  }
  
 +
 +
  bool
  psppire_data_window_is_empty (PsppireDataWindow *dw)
  {
    return psppire_dict_get_var_cnt (dw->dict) == 0;
  }
  
 +
  static void
  psppire_data_window_iface_init (PsppireWindowIface *iface)
  {
  
  \f
  
 +
  PsppireDataWindow *
  psppire_default_data_window (void)
  {
    return ll_data (ll_head (&all_data_windows), PsppireDataWindow, ll);
  }
  
 +
 +
  void
  psppire_data_window_set_default (PsppireDataWindow *pdw)
  {
@@@ -1974,8 -1924,6 +1976,8 @@@ psppire_data_window_undefault (PsppireD
    ll_push_tail (&all_data_windows, &pdw->ll);
  }
  
 +
 +
  PsppireDataWindow *
  psppire_data_window_for_dataset (struct dataset *ds)
  {
diff --combined src/ui/gui/widgets.c
index bbbc5a728a1204e394ec7102e92106ea48c7edac,01496cf7970339d78ec918fc884dc7085613f620..6878fa0fe547ee0db128cd1cc85aeecd38d08b07
@@@ -4,7 -4,6 +4,7 @@@
  
  #include "widgets.h"
  
 +#include "gettext.h"
  
  #include "psppire-dialog.h"
  #include "psppire-selector.h"
@@@ -34,6 -33,7 +34,7 @@@
  #include "psppire-dialog-action-histogram.h"
  #include "psppire-dialog-action-indep-samps.h"
  #include "psppire-dialog-action-k-related.h"
+ #include "psppire-dialog-action-k-independent.h"
  #include "psppire-dialog-action-1sks.h"
  #include "psppire-dialog-action-kmeans.h"
  #include "psppire-dialog-action-logistic.h"
@@@ -85,6 -85,7 +86,7 @@@ static const get_type_func dialog_actio
    psppire_dialog_action_histogram_get_type,
    psppire_dialog_action_logistic_get_type,
    psppire_dialog_action_kmeans_get_type,
+   psppire_dialog_action_k_independent_get_type,
    psppire_dialog_action_k_related_get_type,
    psppire_dialog_action_means_get_type,
    psppire_dialog_action_oneway_get_type,
@@@ -121,62 -122,6 +123,62 @@@ preregister_actions (void
  }
  
  
 +static void
 +tx_string_to_double (const GValue *src, GValue *dest)
 +{
 +  const gchar *str = g_value_get_string (src);
 +  gdouble dble = g_strtod (str, NULL);
 +  g_value_set_double (dest, dble);
 +}
 +
 +
 +static void
 +tx_string_to_int (const GValue *src, GValue *dest)
 +{
 +  const gchar *str = g_value_get_string (src);
 +  gint x = atoi (str);
 +  g_value_set_int (dest, x);
 +}
 +
 +static void
 +enum_to_string (const GValue *src, GValue *dest)
 +{
 +  gint n = g_value_get_enum (src);
 +  GType t = G_VALUE_TYPE (src);
 +  GEnumClass *ec = g_type_class_ref (t);
 +  GEnumValue *ev = g_enum_get_value (ec, n);
 +
 +  g_value_set_string (dest, gettext (ev->value_nick));
 +}
 +
 +
 +
 +GType align_enum_type;
 +GType measure_enum_type;
 +GType role_enum_type;
 +
 +
 +extern const GEnumValue align[];
 +extern const GEnumValue measure[];
 +extern const GEnumValue role[];
 +
 +
 +
 +static void
 +preregister_misc (void)
 +{
 +  align_enum_type = g_enum_register_static ("PsppAlignment", align);
 +  measure_enum_type = g_enum_register_static ("PsppMeasure", measure);
 +  role_enum_type = g_enum_register_static ("PsppRole", role);
 +
 +  g_value_register_transform_func (G_TYPE_STRING, G_TYPE_DOUBLE, tx_string_to_double);
 +  g_value_register_transform_func (G_TYPE_STRING, G_TYPE_INT, tx_string_to_int);
 +
 +  g_value_register_transform_func (measure_enum_type, G_TYPE_STRING, enum_to_string);
 +  g_value_register_transform_func (align_enum_type, G_TYPE_STRING, enum_to_string);
 +  g_value_register_transform_func (role_enum_type, G_TYPE_STRING, enum_to_string);
 +}
 +
  
  /* Any custom widgets which are to be used in GtkBuilder ui files
     need to be preregistered, otherwise GtkBuilder refuses to
@@@ -197,7 -142,6 +199,7 @@@ preregister_widgets (void
    psppire_means_layer_get_type ();
  
    preregister_actions ();
 +  preregister_misc ();
  
    /* This seems to be necessary on Cygwin.
       It ought not to be necessary.  Having it here can't do any harm. */