gui: Merge File|Open|Syntax and File|Open|Data into File|Open.
authorBen Pfaff <blp@cs.stanford.edu>
Wed, 10 Mar 2010 05:48:42 +0000 (21:48 -0800)
committerBen Pfaff <blp@cs.stanford.edu>
Wed, 10 Mar 2010 05:49:03 +0000 (21:49 -0800)
In playing with the GUI, I've found it increasingly annoying to have to
click an extra time to tell PSPPIRE whether I want to open a data file or
a syntax file.  There's no need for that--it can easily figure out what
kind of file it's being asked to read.  This commit implements that
behavior.

src/data/any-reader.c
src/data/any-reader.h
src/ui/gui/data-editor.glade
src/ui/gui/psppire-data-window.c
src/ui/gui/psppire-syntax-window.c
src/ui/gui/psppire-syntax-window.h

index 1c1b519b2dce7c289d8cb11d340582cbc199dcf3..731f552a9f9021bf05ffd524c5fbebad11946405 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 2006 Free Software Foundation, Inc.
+   Copyright (C) 2006, 2010 Free Software Foundation, Inc.
 
    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
@@ -42,30 +42,38 @@ enum detect_result
     IO_ERROR                    /* File couldn't be opened. */
   };
 
-/* Tries to detect whether HANDLE represents a given type of
-   file, by opening the file and passing it to DETECT, and
-   returns a detect_result. */
+/* Tries to detect whether FILE is a given type of file, by opening the file
+   and passing it to DETECT, and returns a detect_result. */
 static enum detect_result
-try_detect (struct file_handle *handle, bool (*detect) (FILE *))
+try_detect (const char *file_name, bool (*detect) (FILE *))
 {
   FILE *file;
   bool is_type;
 
-  file = fn_open (fh_get_file_name (handle), "rb");
+  file = fn_open (file_name, "rb");
   if (file == NULL)
     {
       msg (ME, _("An error occurred while opening \"%s\": %s."),
-           fh_get_file_name (handle), strerror (errno));
+           file_name, strerror (errno));
       return IO_ERROR;
     }
 
   is_type = detect (file);
 
-  fn_close (fh_get_file_name (handle), file);
+  fn_close (file_name, file);
 
   return is_type ? YES : NO;
 }
 
+/* Returns true if any_reader_open() would be able to open FILE as a data
+   file, false otherwise. */
+bool
+any_reader_may_open (const char *file)
+{
+  return (try_detect (file, sfm_detect) == YES
+          || try_detect (file, pfm_detect) == YES);
+}
+
 /* Returns a casereader for HANDLE.  On success, returns the new
    casereader and stores the file's dictionary into *DICT.  On
    failure, returns a null pointer. */
@@ -78,13 +86,13 @@ any_reader_open (struct file_handle *handle, struct dictionary **dict)
       {
         enum detect_result result;
 
-        result = try_detect (handle, sfm_detect);
+        result = try_detect (fh_get_file_name (handle), sfm_detect);
         if (result == IO_ERROR)
           return NULL;
         else if (result == YES)
           return sfm_open_reader (handle, dict, NULL);
 
-        result = try_detect (handle, pfm_detect);
+        result = try_detect (fh_get_file_name (handle), pfm_detect);
         if (result == IO_ERROR)
           return NULL;
         else if (result == YES)
index 18707fa8416ad79c5ca71d6967d354d03399d358..e999aa33f5be28543d18c1f0b120d47ded4264d0 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 2006 Free Software Foundation, Inc.
+   Copyright (C) 2006, 2010 Free Software Foundation, Inc.
 
    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
@@ -21,6 +21,7 @@
 
 struct file_handle;
 struct dictionary;
+bool any_reader_may_open (const char *file_name);
 struct casereader *any_reader_open (struct file_handle *,
                                     struct dictionary **);
 
index 6c32014f0ae325da15b31c7665ece923f93d978c..9e9bb6baba30d7129df09a25e64ab9e81acba520 100644 (file)
               </widget>
             </child>
             <child>
-              <widget class="GtkImageMenuItem" id="open1">
+              <widget class="GtkImageMenuItem" id="file_open">
                 <property name="label">gtk-open</property>
                 <property name="visible">True</property>
                 <property name="use_underline">True</property>
                 <property name="use_stock">True</property>
-                <child>
-                  <widget class="GtkMenu" id="open1_menu">
-                    <child>
-                      <widget class="GtkMenuItem" id="file_open_syntax">
-                        <property name="visible">True</property>
-                        <property name="label" translatable="yes">_Syntax</property>
-                        <property name="use_underline">True</property>
-                      </widget>
-                    </child>
-                    <child>
-                      <widget class="GtkMenuItem" id="file_open_data">
-                        <property name="visible">True</property>
-                        <property name="label" translatable="yes">_Data</property>
-                        <property name="use_underline">True</property>
-                      </widget>
-                    </child>
-                  </widget>
-                </child>
               </widget>
             </child>
             <child>
index c7631c9da42440beed850a6991fe6e62104eb76c..00dba993ce3991ca5537edfd49dadacc6cc6cdcd 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPPIRE - a graphical user interface for PSPP.
-   Copyright (C) 2008, 2009  Free Software Foundation
+   Copyright (C) 2008, 2009, 2010  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 <gtk/gtksignal.h>
 #include <gtk/gtkbox.h>
-#include "executor.h"
-#include "helper.h"
-
-#include "text-data-import-dialog.h"
-
-
-#include <ui/syntax-gen.h>
-#include <language/syntax-string-source.h>
-#include <libpspp/message.h>
 #include <stdlib.h>
 
-#include <data/procedure.h>
-
-#include "psppire.h"
-#include "psppire-window.h"
-#include "psppire-data-window.h"
-#include "psppire-syntax-window.h"
-
-#include "about.h"
-
-#include "goto-case-dialog.h"
-#include "weight-cases-dialog.h"
-#include "split-file-dialog.h"
-#include "transpose-dialog.h"
-#include "sort-cases-dialog.h"
-#include "select-cases-dialog.h"
-#include "compute-dialog.h"
-#include "find-dialog.h"
-#include "rank-dialog.h"
-#include "recode-dialog.h"
-#include "comments-dialog.h"
-#include "variable-info-dialog.h"
-#include "descriptives-dialog.h"
-#include "crosstabs-dialog.h"
-#include "frequencies-dialog.h"
-#include "examine-dialog.h"
-#include "regression-dialog.h"
-#include "reliability-dialog.h"
-#include "roc-dialog.h"
-#include "correlation-dialog.h"
-#include "factor-dialog.h"
-#include "oneway-anova-dialog.h"
-#include "t-test-independent-samples-dialog.h"
-#include "t-test-one-sample.h"
-#include "t-test-paired-samples.h"
-
+#include "data/any-reader.h"
+#include "data/procedure.h"
+#include "language/syntax-string-source.h"
+#include "libpspp/message.h"
+#include "ui/gui/about.h"
+#include "ui/gui/comments-dialog.h"
+#include "ui/gui/compute-dialog.h"
+#include "ui/gui/correlation-dialog.h"
+#include "ui/gui/crosstabs-dialog.h"
+#include "ui/gui/descriptives-dialog.h"
+#include "ui/gui/examine-dialog.h"
+#include "ui/gui/executor.h"
+#include "ui/gui/factor-dialog.h"
+#include "ui/gui/find-dialog.h"
+#include "ui/gui/frequencies-dialog.h"
+#include "ui/gui/goto-case-dialog.h"
+#include "ui/gui/helper.h"
+#include "ui/gui/oneway-anova-dialog.h"
+#include "ui/gui/psppire-data-window.h"
+#include "ui/gui/psppire-syntax-window.h"
+#include "ui/gui/psppire-window.h"
+#include "ui/gui/psppire.h"
+#include "ui/gui/rank-dialog.h"
+#include "ui/gui/recode-dialog.h"
+#include "ui/gui/regression-dialog.h"
+#include "ui/gui/reliability-dialog.h"
+#include "ui/gui/roc-dialog.h"
+#include "ui/gui/select-cases-dialog.h"
+#include "ui/gui/sort-cases-dialog.h"
+#include "ui/gui/split-file-dialog.h"
+#include "ui/gui/t-test-independent-samples-dialog.h"
+#include "ui/gui/t-test-one-sample.h"
+#include "ui/gui/t-test-paired-samples.h"
+#include "ui/gui/text-data-import-dialog.h"
+#include "ui/gui/transpose-dialog.h"
+#include "ui/gui/variable-info-dialog.h"
+#include "ui/gui/weight-cases-dialog.h"
+#include "ui/syntax-gen.h"
 
 #include <gettext.h>
 #define _(msgid) gettext (msgid)
@@ -390,7 +384,19 @@ sysfile_chooser_dialog (PsppireWindow *toplevel)
                                 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
                                 NULL);
 
-  GtkFileFilter *filter = gtk_file_filter_new ();
+  GtkFileFilter *filter;
+
+  filter = gtk_file_filter_new ();
+  gtk_file_filter_set_name (filter, _("Data and Syntax Files"));
+  gtk_file_filter_add_pattern (filter, "*.sav");
+  gtk_file_filter_add_pattern (filter, "*.SAV");
+  gtk_file_filter_add_pattern (filter, "*.por");
+  gtk_file_filter_add_pattern (filter, "*.POR");
+  gtk_file_filter_add_pattern (filter, "*.sps");
+  gtk_file_filter_add_pattern (filter, "*.SPS");
+  gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
+
+  filter = gtk_file_filter_new ();
   gtk_file_filter_set_name (filter, _("System Files (*.sav)"));
   gtk_file_filter_add_pattern (filter, "*.sav");
   gtk_file_filter_add_pattern (filter, "*.SAV");
@@ -402,6 +408,12 @@ sysfile_chooser_dialog (PsppireWindow *toplevel)
   gtk_file_filter_add_pattern (filter, "*.POR");
   gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
 
+  filter = gtk_file_filter_new ();
+  gtk_file_filter_set_name (filter, _("Syntax Files (*.sps) "));
+  gtk_file_filter_add_pattern (filter, "*.sps");
+  gtk_file_filter_add_pattern (filter, "*.SPS");
+  gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
+
   filter = gtk_file_filter_new ();
   gtk_file_filter_set_name (filter, _("All Files"));
   gtk_file_filter_add_pattern (filter, "*");
@@ -434,7 +446,7 @@ sysfile_chooser_dialog (PsppireWindow *toplevel)
 /* Callback for the data_open action.
    Prompts for a filename and opens it */
 static void
-open_data_dialog (GtkAction *action, PsppireWindow *de)
+open_window (GtkAction *action, PsppireWindow *de)
 {
   GtkWidget *dialog = sysfile_chooser_dialog (de);
 
@@ -445,7 +457,10 @@ open_data_dialog (GtkAction *action, PsppireWindow *de)
        gchar *name =
          gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
 
-       psppire_window_load (de, name);
+        if (any_reader_may_open (name))
+          psppire_window_load (de, name);
+        else
+          open_syntax_window (name);
 
        g_free (name);
       }
@@ -1182,15 +1197,15 @@ psppire_data_window_init (PsppireDataWindow *de)
     GtkWidget *toolbarbutton = get_widget_assert (de->builder, "button-open");
 
     GtkAction *action_data_open =
-      resolve_action (de->builder, "file_open_data", NULL);
+      resolve_action (de->builder, "file_open", NULL);
 
     g_object_set (action_data_open,
-                 "tooltip",  _("Open a data file"),
+                 "tooltip",  _("Open a data or syntax file"),
                  "stock-id", "gtk-open",
                  NULL);
 
     g_signal_connect (action_data_open, "activate",
-                     G_CALLBACK (open_data_dialog), de);
+                     G_CALLBACK (open_window), de);
 
     g_signal_connect_swapped (toolbarbutton, "clicked",
                      G_CALLBACK (gtk_action_activate), action_data_open);
@@ -1798,10 +1813,6 @@ psppire_data_window_init (PsppireDataWindow *de)
                    G_CALLBACK (create_syntax_window),
                    NULL);
 
-  g_signal_connect (get_action_assert (de->builder,"file_open_syntax"),
-                   "activate",
-                   G_CALLBACK (open_syntax_window),
-                   de);
 
   {
     GtkAction *abt = get_action_assert (de->builder, "help_about");
index 0110fb905d9a8b6b1a0ebffbf2ab7f68b4a82598..48e1ea44fe73d3873c4631d6e5b4bc06311e4636 100644 (file)
@@ -360,51 +360,17 @@ create_syntax_window (void)
   gtk_widget_show (w);
 }
 
-/* Callback for the File->Open->Syntax menuitem */
 void
-open_syntax_window (GtkMenuItem *menuitem, gpointer parent)
+open_syntax_window (const char *file_name)
 {
-  GtkFileFilter *filter;
-  gint response;
-
-  GtkWidget *dialog =
-    gtk_file_chooser_dialog_new (_("Open Syntax"),
-                                GTK_WINDOW (parent),
-                                GTK_FILE_CHOOSER_ACTION_OPEN,
-                                GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
-                                GTK_STOCK_OPEN,   GTK_RESPONSE_ACCEPT,
-                                NULL);
-
-  filter = gtk_file_filter_new ();
-  gtk_file_filter_set_name (filter, _("Syntax Files (*.sps) "));
-  gtk_file_filter_add_pattern (filter, "*.sps");
-  gtk_file_filter_add_pattern (filter, "*.SPS");
-  gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
+  GtkWidget *se = psppire_syntax_window_new ();
 
-  filter = gtk_file_filter_new ();
-  gtk_file_filter_set_name (filter, _("All Files"));
-  gtk_file_filter_add_pattern (filter, "*");
-  gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
-
-  response = gtk_dialog_run (GTK_DIALOG (dialog));
-
-  if (response == GTK_RESPONSE_ACCEPT)
-    {
-      const char *file_name = gtk_file_chooser_get_filename
-       (GTK_FILE_CHOOSER (dialog));
-
-      GtkWidget *se = psppire_syntax_window_new ();
-
-      if ( psppire_window_load (PSPPIRE_WINDOW (se), file_name) ) 
-       gtk_widget_show (se);
-      else
-       gtk_widget_destroy (se);
-    }
-
-  gtk_widget_destroy (dialog);
+  if ( psppire_window_load (PSPPIRE_WINDOW (se), file_name) )
+    gtk_widget_show (se);
+  else
+    gtk_widget_destroy (se);
 }
 
-
 static void
 on_text_changed (GtkTextBuffer *buffer, PsppireSyntaxWindow *window)
 {
@@ -464,11 +430,6 @@ psppire_syntax_window_init (PsppireSyntaxWindow *window)
                    G_CALLBACK (create_syntax_window),
                    NULL);
 
-  g_signal_connect (get_action_assert (xml,"file_open_syntax"),
-                   "activate",
-                   G_CALLBACK (open_syntax_window),
-                   window);
-
 #if 0
   g_signal_connect (get_action_assert (xml,"file_new_data"),
                    "activate",
@@ -580,7 +541,7 @@ error_dialog (GtkWindow *w, const gchar *filename,  GError *err)
 /*
   Loads the buffer from the file called FILENAME
 */
-static gboolean
+gboolean
 syntax_load (PsppireWindow *window, const gchar *filename)
 {
   GError *err = NULL;
index c863a92f1a24e335439c43721a2c0c11da215ace..3816a1319f8d6d57b0ee11fcc03823b0bbcf4860 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPPIRE - a graphical user interface for PSPP.
-   Copyright (C) 2008  Free Software Foundation
+   Copyright (C) 2008, 2010  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
@@ -62,9 +62,8 @@ struct _PsppireSyntaxWindowClass
 GType      psppire_syntax_window_get_type        (void);
 GtkWidget* psppire_syntax_window_new             (void);
 
-void open_syntax_window (GtkMenuItem *menuitem, gpointer parent);
 void create_syntax_window (void);
-
+void open_syntax_window (const char *file_name);
 
 G_END_DECLS