From: John Darrington Date: Fri, 20 Feb 2009 01:22:49 +0000 (+0900) Subject: Merge commit 'HEAD'; commit 'savannah/master' X-Git-Tag: v0.7.3~296^2~9 X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8953baa61127d6d3b91f763663ea647bf3e4e793;hp=dff7c7a05e6da0de78544fa97c6882bd4a40d977;p=pspp-builds.git Merge commit 'HEAD'; commit 'savannah/master' Conflicts: src/ui/gui/crosstabs-dialog.c src/ui/gui/goto-case-dialog.c src/ui/gui/helper.c src/ui/gui/output-viewer.c src/ui/gui/output-viewer.h src/ui/gui/psppire.c src/ui/gui/regression-dialog.c --- diff --git a/src/ui/gui/automake.mk b/src/ui/gui/automake.mk index 1549da47..6440215a 100644 --- a/src/ui/gui/automake.mk +++ b/src/ui/gui/automake.mk @@ -131,8 +131,6 @@ src_ui_gui_psppire_SOURCES = \ src/ui/gui/frequencies-dialog.h \ src/ui/gui/goto-case-dialog.c \ src/ui/gui/goto-case-dialog.h \ - src/ui/gui/data-editor.c \ - src/ui/gui/data-editor.h \ src/ui/gui/descriptives-dialog.c \ src/ui/gui/descriptives-dialog.h \ src/ui/gui/examine-dialog.c \ @@ -154,8 +152,6 @@ src_ui_gui_psppire_SOURCES = \ src/ui/gui/missing-val-dialog.h \ src/ui/gui/oneway-anova-dialog.c \ src/ui/gui/oneway-anova-dialog.h \ - src/ui/gui/output-viewer.c \ - src/ui/gui/output-viewer.h \ src/ui/gui/psppire-acr.h \ src/ui/gui/psppire-buttonbox.h \ src/ui/gui/psppire-hbuttonbox.h \ @@ -187,8 +183,6 @@ src_ui_gui_psppire_SOURCES = \ src/ui/gui/sort-cases-dialog.h \ src/ui/gui/split-file-dialog.c \ src/ui/gui/split-file-dialog.h \ - src/ui/gui/syntax-editor.c \ - src/ui/gui/syntax-editor.h \ src/ui/gui/syntax-editor-source.c \ src/ui/gui/syntax-editor-source.h \ src/ui/gui/text-data-import-dialog.c \ @@ -215,8 +209,16 @@ src_ui_gui_psppire_SOURCES = \ src/ui/gui/weight-cases-dialog.h \ src/ui/gui/widget-io.c \ src/ui/gui/widget-io.h \ - src/ui/gui/window-manager.c \ - src/ui/gui/window-manager.h + src/ui/gui/psppire-data-window.c \ + src/ui/gui/psppire-data-window.h \ + src/ui/gui/psppire-output-window.c \ + src/ui/gui/psppire-output-window.h \ + src/ui/gui/psppire-window.c \ + src/ui/gui/psppire-window.h \ + src/ui/gui/psppire-window-register.c \ + src/ui/gui/psppire-window-register.h \ + src/ui/gui/psppire-syntax-window.c \ + src/ui/gui/psppire-syntax-window.h nodist_src_ui_gui_psppire_SOURCES = \ src/ui/gui/psppire-marshal.c \ diff --git a/src/ui/gui/comments-dialog.c b/src/ui/gui/comments-dialog.c index f425fac2..49d143cb 100644 --- a/src/ui/gui/comments-dialog.c +++ b/src/ui/gui/comments-dialog.c @@ -18,9 +18,10 @@ #include "psppire-dialog.h" #include "helper.h" -#include "data-editor.h" +#include "psppire-data-window.h" +#include "psppire-data-editor.h" #include -#include "syntax-editor.h" +#include "helper.h" #include "psppire-var-store.h" #include @@ -94,7 +95,7 @@ comments_dialog (GObject *o, gpointer data) { GtkTextIter iter; gint response ; - struct data_editor *de = data; + PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data); struct comment_dialog cd; GtkBuilder *xml = builder_new ("psppire.ui"); @@ -108,7 +109,7 @@ comments_dialog (GObject *o, gpointer data) g_object_get (de->data_editor, "var-store", &vs, NULL); - gtk_window_set_transient_for (GTK_WINDOW (dialog), de->parent.window); + gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (de)); { PangoContext * context ; @@ -166,6 +167,7 @@ comments_dialog (GObject *o, gpointer data) case GTK_RESPONSE_OK: { gchar *syntax = generate_syntax (&cd); + struct getl_interface *sss = create_syntax_string_source (syntax); execute_syntax (sss); @@ -176,10 +178,7 @@ comments_dialog (GObject *o, gpointer data) { gchar *syntax = generate_syntax (&cd); - struct syntax_editor *se = - (struct syntax_editor *) window_create (WINDOW_SYNTAX, NULL); - - gtk_text_buffer_insert_at_cursor (se->buffer, syntax, -1); + paste_syntax_in_new_window (syntax); g_free (syntax); } diff --git a/src/ui/gui/compute-dialog.c b/src/ui/gui/compute-dialog.c index 76b9a7d1..7269ab79 100644 --- a/src/ui/gui/compute-dialog.c +++ b/src/ui/gui/compute-dialog.c @@ -20,14 +20,14 @@ #include "helper.h" #include "psppire-dialog.h" #include "psppire-keypad.h" -#include "data-editor.h" +#include "psppire-data-window.h" #include "psppire-var-store.h" #include "dialog-common.h" #include "dict-display.h" #include #include -#include "syntax-editor.h" +#include "helper.h" static void function_list_populate (GtkTreeView *tv); @@ -365,7 +365,7 @@ void compute_dialog (GObject *o, gpointer data) { gint response; - struct data_editor *de = data; + PsppireDataWindow *de = data; PsppireVarStore *vs = NULL; struct compute_dialog scd; @@ -394,7 +394,7 @@ compute_dialog (GObject *o, gpointer data) g_signal_connect (expression, "toggled", G_CALLBACK(on_expression_toggle), &scd); - gtk_window_set_transient_for (GTK_WINDOW (dialog), de->parent.window); + gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (de)); attach_dictionary_to_treeview (GTK_TREE_VIEW (dict_view), @@ -447,6 +447,7 @@ compute_dialog (GObject *o, gpointer data) case GTK_RESPONSE_OK: { gchar *syntax = generate_syntax (&scd); + struct getl_interface *sss = create_syntax_string_source (syntax); execute_syntax (sss); @@ -457,10 +458,7 @@ compute_dialog (GObject *o, gpointer data) { gchar *syntax = generate_syntax (&scd); - struct syntax_editor *se = - (struct syntax_editor *) window_create (WINDOW_SYNTAX, NULL); - - gtk_text_buffer_insert_at_cursor (se->buffer, syntax, -1); + paste_syntax_in_new_window (syntax); g_free (syntax); } diff --git a/src/ui/gui/crosstabs-dialog.c b/src/ui/gui/crosstabs-dialog.c index 2c50b461..a3498d1f 100644 --- a/src/ui/gui/crosstabs-dialog.c +++ b/src/ui/gui/crosstabs-dialog.c @@ -23,13 +23,13 @@ #include #include -#include +#include #include #include #include "helper.h" #include #include -#include +#include #include "gettext.h" #define _(msgid) gettext (msgid) @@ -385,13 +385,15 @@ void crosstabs_dialog (GObject *o, gpointer data) { gint response; - struct data_editor *de = data; - struct crosstabs_dialog cd; GtkBuilder *xml = builder_new ("crosstabs.ui"); + PsppireVarStore *vs = NULL; + PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data); + + GtkWidget *dialog = get_widget_assert (xml, "crosstabs-dialog"); GtkWidget *source = get_widget_assert (xml, "dict-treeview"); GtkWidget *dest_rows = get_widget_assert (xml, "rows"); @@ -419,7 +421,7 @@ crosstabs_dialog (GObject *o, gpointer data) cells ); - gtk_window_set_transient_for (GTK_WINDOW (dialog), de->parent.window); + gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (de)); attach_dictionary_to_treeview (GTK_TREE_VIEW (source), vs->dict, @@ -461,9 +463,9 @@ crosstabs_dialog (GObject *o, gpointer data) cd.current_opts.table = TRUE; cd.current_opts.pivot = TRUE; - gtk_window_set_transient_for (GTK_WINDOW (cd.format_dialog), de->parent.window); - gtk_window_set_transient_for (GTK_WINDOW (cd.cell_dialog), de->parent.window); - gtk_window_set_transient_for (GTK_WINDOW (cd.stat_dialog), de->parent.window); + gtk_window_set_transient_for (GTK_WINDOW (cd.format_dialog), GTK_WINDOW (de)); + gtk_window_set_transient_for (GTK_WINDOW (cd.cell_dialog), GTK_WINDOW (de)); + gtk_window_set_transient_for (GTK_WINDOW (cd.stat_dialog), GTK_WINDOW (de)); g_signal_connect (dialog, "refresh", G_CALLBACK (refresh), &cd); @@ -485,6 +487,7 @@ crosstabs_dialog (GObject *o, gpointer data) case GTK_RESPONSE_OK: { gchar *syntax = generate_syntax (&cd); + struct getl_interface *sss = create_syntax_string_source (syntax); execute_syntax (sss); @@ -495,10 +498,7 @@ crosstabs_dialog (GObject *o, gpointer data) { gchar *syntax = generate_syntax (&cd); - struct syntax_editor *se = - (struct syntax_editor *) window_create (WINDOW_SYNTAX, NULL); - - gtk_text_buffer_insert_at_cursor (se->buffer, syntax, -1); + paste_syntax_in_new_window (syntax); g_free (syntax); } diff --git a/src/ui/gui/data-editor.c b/src/ui/gui/data-editor.c deleted file mode 100644 index 13cc29a9..00000000 --- a/src/ui/gui/data-editor.c +++ /dev/null @@ -1,1699 +0,0 @@ -/* PSPPIRE - a graphical user interface for PSPP. - Copyright (C) 2006, 2007, 2008 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 - 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, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - 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, see . */ - -#include -#include -#include - -#include -#include - -#include "window-manager.h" - -#include "psppire-data-editor.h" - -#include "helper.h" -#include "about.h" -#include -#include "psppire-dialog.h" -#include "psppire-selector.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 "goto-case-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 "dict-display.h" -#include "regression-dialog.h" -#include "text-data-import-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" - -#define _(msgid) gettext (msgid) -#define N_(msgid) msgid - -#include "data-editor.h" -#include "syntax-editor.h" -#include -#include -#include -#include "window-manager.h" - -#include "psppire-data-store.h" -#include "psppire-var-store.h" - -static void on_edit_copy (GtkMenuItem *, gpointer); -static void on_edit_cut (GtkMenuItem *, gpointer); -static void on_edit_paste (GtkAction *a, gpointer data); - - -static GtkWidget * create_data_sheet_variable_popup_menu (struct data_editor *); - -static GtkWidget * create_var_sheet_variable_popup_menu (struct data_editor *); - -static GtkWidget * create_data_sheet_cases_popup_menu (struct data_editor *); - -static void register_data_editor_actions (struct data_editor *de); -static void on_insert_variable (GtkAction *, gpointer data); -static void insert_case (GtkAction *a, gpointer data); - -static void toggle_value_labels (GtkToggleAction *a, gpointer data); -static void toggle_split_window (GtkToggleAction *ta, gpointer data); - - -/* Callback for when the dictionary changes properties*/ -static void on_weight_change (GObject *, gint, gpointer); -static void on_filter_change (GObject *, gint, gpointer); -static void on_split_change (PsppireDict *, gpointer); - -static void on_switch_sheet (GtkNotebook *notebook, - GtkNotebookPage *page, - guint page_num, - gpointer user_data); - -static void status_bar_activate (GtkCheckMenuItem *, gpointer); - -static void grid_lines_activate (GtkCheckMenuItem *, gpointer); - -static void data_view_activate (GtkCheckMenuItem *, gpointer); - -static void variable_view_activate (GtkCheckMenuItem *, gpointer ); - -static void fonts_activate (GtkMenuItem *, gpointer); - -static void file_quit (GtkCheckMenuItem *, gpointer ); - -static void -enable_delete_cases (GtkWidget *w, gint case_num, gpointer data) -{ - struct data_editor *de = data; - - gtk_action_set_visible (de->delete_cases, case_num != -1); -} - - -static void -enable_delete_variables (GtkWidget *w, gint var, gpointer data) -{ - struct data_editor *de = data; - - gtk_action_set_visible (de->delete_variables, var != -1); -} - - - -/* Run the EXECUTE command. */ -static void -execute (GtkMenuItem *mi, gpointer data) -{ - struct getl_interface *sss = create_syntax_string_source ("EXECUTE."); - - execute_syntax (sss); -} - -static void -transformation_change_callback (bool transformations_pending, - gpointer data) -{ - struct data_editor *de = data; - GtkWidget *menuitem = - get_widget_assert (de->xml, "transform_run-pending"); - GtkWidget *status_label = - get_widget_assert (de->xml, "case-counter-area"); - - gtk_widget_set_sensitive (menuitem, transformations_pending); - - - if ( transformations_pending) - gtk_label_set_text (GTK_LABEL (status_label), - _("Transformations Pending")); - else - gtk_label_set_text (GTK_LABEL (status_label), ""); -} - - -static void open_data_file (const gchar *, struct data_editor *); - - -/* Puts FILE_NAME into the recent list. - If it's already in the list, it moves it to the top -*/ -static void -add_most_recent (const char *file_name) -{ -#if RECENT_LISTS_AVAILABLE - - GtkRecentManager *manager = gtk_recent_manager_get_default(); - gchar *uri = g_filename_to_uri (file_name, NULL, NULL); - - gtk_recent_manager_remove_item (manager, uri, NULL); - - if ( ! gtk_recent_manager_add_item (manager, uri)) - g_warning ("Could not add item %s to recent list\n",uri); - - g_free (uri); -#endif -} - - - -#if RECENT_LISTS_AVAILABLE - -static void -on_recent_data_select (GtkMenuShell *menushell, gpointer user_data) -{ - gchar *file; - struct data_editor *de = user_data; - - gchar *uri = - gtk_recent_chooser_get_current_uri (GTK_RECENT_CHOOSER (menushell)); - - file = g_filename_from_uri (uri, NULL, NULL); - - g_free (uri); - - open_data_file (file, de); - - g_free (file); -} - -static void -on_recent_files_select (GtkMenuShell *menushell, gpointer user_data) -{ - gchar *file; - - struct syntax_editor *se ; - - gchar *uri = - gtk_recent_chooser_get_current_uri (GTK_RECENT_CHOOSER (menushell)); - - file = g_filename_from_uri (uri, NULL, NULL); - - g_free (uri); - - se = (struct syntax_editor *) - window_create (WINDOW_SYNTAX, file); - - load_editor_from_file (se, file, NULL); - - g_free (file); -} - -#endif - - -static void -update_paste_menuitems (GtkWidget *w, gboolean x, gpointer data) -{ - struct data_editor *de = data; - - GtkWidget * edit_paste = get_widget_assert (de->xml, "edit_paste"); - - gtk_widget_set_sensitive (edit_paste, x); -} - -static void -update_cut_copy_menuitems (GtkWidget *w, gboolean x, gpointer data) -{ - struct data_editor *de = data; - - GtkWidget * edit_copy = get_widget_assert (de->xml, "edit_copy"); - GtkWidget * edit_cut = get_widget_assert (de->xml, "edit_cut"); - - gtk_widget_set_sensitive (edit_copy, x); - gtk_widget_set_sensitive (edit_cut, x); -} - -extern PsppireVarStore *the_var_store; -extern struct dataset *the_dataset; -extern PsppireDataStore *the_data_store ; - - -/* - Create a new data editor. -*/ -struct data_editor * -new_data_editor (void) -{ - struct data_editor *de ; - struct editor_window *e; - PsppireVarStore *vs; - GtkWidget *vbox ; - - de = g_malloc0 (sizeof (*de)); - - e = (struct editor_window *) de; - - de->xml = XML_NEW ("data-editor.glade"); - - - vbox = get_widget_assert (de->xml, "vbox1"); - - de->data_editor = PSPPIRE_DATA_EDITOR (psppire_data_editor_new (the_var_store, the_data_store)); - - g_signal_connect (de->data_editor, "data-selection-changed", - G_CALLBACK (update_cut_copy_menuitems), de); - - g_signal_connect (de->data_editor, "data-available-changed", - G_CALLBACK (update_paste_menuitems), de); - - - gtk_widget_show (GTK_WIDGET (de->data_editor)); - - gtk_container_add (GTK_CONTAINER (vbox), GTK_WIDGET (de->data_editor)); - gtk_box_reorder_child (GTK_BOX (vbox) , GTK_WIDGET (de->data_editor), 2); - dataset_add_transform_change_callback (the_dataset, - transformation_change_callback, - de); - - vs = the_var_store; - - g_assert(vs); /* Traps a possible bug in w32 build */ - - g_signal_connect (vs->dict, "weight-changed", - G_CALLBACK (on_weight_change), - de); - - g_signal_connect (vs->dict, "filter-changed", - G_CALLBACK (on_filter_change), - de); - - g_signal_connect (vs->dict, "split-changed", - G_CALLBACK (on_split_change), - de); - - connect_help (de->xml); - - - - g_signal_connect (get_widget_assert (de->xml, "edit_copy"), - "activate", - G_CALLBACK (on_edit_copy), de); - - g_signal_connect (get_widget_assert (de->xml, "edit_cut"), - "activate", - G_CALLBACK (on_edit_cut), de); - - - register_data_editor_actions (de); - - de->toggle_value_labels = - gtk_toggle_action_new ("toggle-value-labels", - _("_Labels"), - _("Show/hide value labels"), - "pspp-value-labels"); - - g_signal_connect (de->toggle_value_labels, "toggled", - G_CALLBACK (toggle_value_labels), de); - - - gtk_action_connect_proxy (GTK_ACTION (de->toggle_value_labels), - get_widget_assert (de->xml, - "togglebutton-value-labels")); - - - gtk_action_connect_proxy (GTK_ACTION (de->toggle_value_labels), - get_widget_assert (de->xml, - "view_value-labels")); - - de->delete_cases = - gtk_action_new ("clear-cases", - _("Clear"), - _("Delete the cases at the selected position(s)"), - "pspp-clear-cases"); - - g_signal_connect_swapped (de->delete_cases, "activate", - G_CALLBACK (psppire_data_editor_delete_cases), - de->data_editor); - - gtk_action_connect_proxy (de->delete_cases, - get_widget_assert (de->xml, "edit_clear-cases")); - - g_signal_connect (get_widget_assert (de->xml, "edit_paste"), "activate", - G_CALLBACK (on_edit_paste), - de); - - gtk_action_set_visible (de->delete_cases, FALSE); - - de->delete_variables = - gtk_action_new ("clear-variables", - _("Clear"), - _("Delete the variables at the selected position(s)"), - "pspp-clear-variables"); - - g_signal_connect_swapped (de->delete_variables, "activate", - G_CALLBACK (psppire_data_editor_delete_variables), - de->data_editor); - - gtk_action_connect_proxy (de->delete_variables, - get_widget_assert (de->xml, "edit_clear-variables") - ); - - gtk_action_set_visible (de->delete_variables, FALSE); - - de->insert_variable = - gtk_action_new ("insert-variable", - _("Insert _Variable"), - _("Create a new variable at the current position"), - "pspp-insert-variable"); - - g_signal_connect (de->insert_variable, "activate", - G_CALLBACK (on_insert_variable), de->data_editor); - - - gtk_action_connect_proxy (de->insert_variable, - get_widget_assert (de->xml, "button-insert-variable") - ); - - gtk_action_connect_proxy (de->insert_variable, - get_widget_assert (de->xml, "edit_insert-variable") - ); - - - de->insert_case = - gtk_action_new ("insert-case", - _("Insert Ca_se"), - _("Create a new case at the current position"), - "pspp-insert-case"); - - g_signal_connect (de->insert_case, "activate", - G_CALLBACK (insert_case), de); - - - gtk_action_connect_proxy (de->insert_case, - get_widget_assert (de->xml, "button-insert-case") - ); - - - gtk_action_connect_proxy (de->insert_case, - get_widget_assert (de->xml, "edit_insert-case") - ); - - - - de->invoke_goto_dialog = - gtk_action_new ("goto-case-dialog", - _("_Goto Case"), - _("Jump to a Case in the Data Sheet"), - "gtk-jump-to"); - - - gtk_action_connect_proxy (de->invoke_goto_dialog, - get_widget_assert (de->xml, "button-goto-case") - ); - - gtk_action_connect_proxy (de->invoke_goto_dialog, - get_widget_assert (de->xml, "edit_goto-case") - ); - - - g_signal_connect (de->invoke_goto_dialog, "activate", - G_CALLBACK (goto_case_dialog), de); - - - de->invoke_weight_cases_dialog = - gtk_action_new ("weight-cases-dialog", - _("_Weights"), - _("Weight cases by variable"), - "pspp-weight-cases"); - - g_signal_connect (de->invoke_weight_cases_dialog, "activate", - G_CALLBACK (weight_cases_dialog), de); - - - de->invoke_transpose_dialog = - gtk_action_new ("transpose-dialog", - _("_Transpose"), - _("Transpose the cases with the variables"), - NULL); - - - g_signal_connect (de->invoke_transpose_dialog, "activate", - G_CALLBACK (transpose_dialog), de); - - - - de->invoke_split_file_dialog = - gtk_action_new ("split-file-dialog", - _("S_plit"), - _("Split the active file"), - "pspp-split-file"); - - g_signal_connect (de->invoke_split_file_dialog, "activate", - G_CALLBACK (split_file_dialog), de); - - - - de->invoke_sort_cases_dialog = - gtk_action_new ("sort-cases-dialog", - _("_Sort"), - _("Sort cases in the active file"), - "pspp-sort-cases"); - - g_signal_connect (de->invoke_sort_cases_dialog, "activate", - G_CALLBACK (sort_cases_dialog), de); - - de->invoke_select_cases_dialog = - gtk_action_new ("select-cases-dialog", - _("Select _Cases"), - _("Select cases from the active file"), - "pspp-select-cases"); - - g_signal_connect (de->invoke_select_cases_dialog, "activate", - G_CALLBACK (select_cases_dialog), de); - - - de->invoke_compute_dialog = - gtk_action_new ("compute-dialog", - _("_Compute"), - _("Compute new values for a variable"), - "pspp-compute"); - - g_signal_connect (de->invoke_compute_dialog, "activate", - G_CALLBACK (compute_dialog), de); - - de->invoke_oneway_anova_dialog = - gtk_action_new ("oneway-anova", - _("Oneway _ANOVA"), - _("Perform one way analysis of variance"), - NULL); - - g_signal_connect (de->invoke_oneway_anova_dialog, "activate", - G_CALLBACK (oneway_anova_dialog), de); - - de->invoke_t_test_independent_samples_dialog = - gtk_action_new ("t-test-independent-samples", - _("_Independent Samples T Test"), - _("Calculate T Test for samples from independent groups"), - NULL); - - g_signal_connect (de->invoke_t_test_independent_samples_dialog, "activate", - G_CALLBACK (t_test_independent_samples_dialog), de); - - - de->invoke_t_test_paired_samples_dialog = - gtk_action_new ("t-test-paired-samples", - _("_Paired Samples T Test"), - _("Calculate T Test for paired samples"), - NULL); - - g_signal_connect (de->invoke_t_test_paired_samples_dialog, "activate", - G_CALLBACK (t_test_paired_samples_dialog), de); - - - de->invoke_t_test_one_sample_dialog = - gtk_action_new ("t-test-one-sample", - _("One _Sample T Test"), - _("Calculate T Test for sample from a single distribution"), - NULL); - - g_signal_connect (de->invoke_t_test_one_sample_dialog, "activate", - G_CALLBACK (t_test_one_sample_dialog), de); - - - de->invoke_comments_dialog = - gtk_action_new ("commments-dialog", - _("Data File _Comments"), - _("Commentary text for the data file"), - NULL); - - g_signal_connect (de->invoke_comments_dialog, "activate", - G_CALLBACK (comments_dialog), de); - - de->invoke_find_dialog = - gtk_action_new ("find-dialog", - _("_Find"), - _("Find Case"), - "gtk-find"); - - g_signal_connect (de->invoke_find_dialog, "activate", - G_CALLBACK (find_dialog), de); - - - de->invoke_rank_dialog = - gtk_action_new ("rank-dialog", - _("Ran_k Cases"), - _("Rank Cases"), - "pspp-rank-cases"); - - g_signal_connect (de->invoke_rank_dialog, "activate", - G_CALLBACK (rank_dialog), de); - - - de->invoke_recode_same_dialog = - gtk_action_new ("recode-same-dialog", - _("Recode into _Same Variables"), - _("Recode values into the same Variables"), - "pspp-recode-same"); - - g_signal_connect (de->invoke_recode_same_dialog, "activate", - G_CALLBACK (recode_same_dialog), de); - - - de->invoke_recode_different_dialog = - gtk_action_new ("recode-different-dialog", - _("Recode into _Different Variables"), - _("Recode values into different Variables"), - "pspp-recode-different"); - - g_signal_connect (de->invoke_recode_different_dialog, "activate", - G_CALLBACK (recode_different_dialog), de); - - - de->invoke_variable_info_dialog = - gtk_action_new ("variable-info-dialog", - _("_Variables"), - _("Jump to Variable"), - "pspp-goto-variable"); - - g_signal_connect (de->invoke_variable_info_dialog, "activate", - G_CALLBACK (variable_info_dialog), de); - - de->invoke_descriptives_dialog = - gtk_action_new ("descriptives-dialog", - _("_Descriptives"), - _("Calculate descriptive statistics (mean, variance, ...)"), - "pspp-descriptives"); - - g_signal_connect (de->invoke_descriptives_dialog, "activate", - G_CALLBACK (descriptives_dialog), de); - - - de->invoke_frequencies_dialog = - gtk_action_new ("frequencies-dialog", - _("_Frequencies"), - _("Generate frequency statistics"), - "pspp-frequencies"); - - g_signal_connect (de->invoke_frequencies_dialog, "activate", - G_CALLBACK (frequencies_dialog), de); - - de->invoke_crosstabs_dialog = - gtk_action_new ("crosstabs-dialog", - _("_Crosstabs"), - _("Generate crosstabulations"), - "pspp-crosstabs"); - - g_signal_connect (de->invoke_crosstabs_dialog, "activate", - G_CALLBACK (crosstabs_dialog), de); - - - de->invoke_examine_dialog = - gtk_action_new ("examine-dialog", - _("_Explore"), - _("Examine Data by Factors"), - "pspp-examine"); - - g_signal_connect (de->invoke_examine_dialog, "activate", - G_CALLBACK (examine_dialog), de); - - - de->invoke_regression_dialog = - gtk_action_new ("regression-dialog", - _("Linear _Regression"), - _("Estimate parameters of the linear model"), - "pspp-regression"); - - g_signal_connect (de->invoke_regression_dialog, "activate", - G_CALLBACK (regression_dialog), de); - - e->window = GTK_WINDOW (get_widget_assert (de->xml, "data_editor")); - - g_signal_connect_swapped (get_widget_assert (de->xml,"file_new_data"), - "activate", - G_CALLBACK (gtk_action_activate), - de->action_data_new); - - g_signal_connect_swapped (get_widget_assert (de->xml,"file_open_data"), - "activate", - G_CALLBACK (gtk_action_activate), - de->action_data_open); - -#if RECENT_LISTS_AVAILABLE - { - GtkRecentManager *rm = gtk_recent_manager_get_default (); - GtkWidget *recent_data = get_widget_assert (de->xml, "file_recent-data"); - GtkWidget *recent_files = get_widget_assert (de->xml, "file_recent-files"); - GtkWidget *recent_separator = get_widget_assert (de->xml, "file_separator1"); - - GtkWidget *menu = gtk_recent_chooser_menu_new_for_manager (rm); - - GtkRecentFilter *filter = gtk_recent_filter_new (); - - gtk_widget_show (recent_data); - gtk_widget_show (recent_files); - gtk_widget_show (recent_separator); - - gtk_recent_filter_add_pattern (filter, "*.sav"); - gtk_recent_filter_add_pattern (filter, "*.SAV"); - - gtk_recent_chooser_add_filter (GTK_RECENT_CHOOSER (menu), filter); - - gtk_widget_set_sensitive (recent_data, TRUE); - g_signal_connect (menu, "selection-done", - G_CALLBACK (on_recent_data_select), de); - - gtk_menu_item_set_submenu (GTK_MENU_ITEM (recent_data), menu); - - - filter = gtk_recent_filter_new (); - menu = gtk_recent_chooser_menu_new_for_manager (rm); - - gtk_recent_filter_add_pattern (filter, "*.sps"); - gtk_recent_filter_add_pattern (filter, "*.SPS"); - - gtk_recent_chooser_add_filter (GTK_RECENT_CHOOSER (menu), filter); - - gtk_widget_set_sensitive (recent_files, TRUE); - g_signal_connect (menu, "selection-done", - G_CALLBACK (on_recent_files_select), de); - - gtk_menu_item_set_submenu (GTK_MENU_ITEM (recent_files), menu); - } -#endif - - g_signal_connect (get_widget_assert (de->xml,"file_new_syntax"), - "activate", - G_CALLBACK (new_syntax_window), - e->window); - - g_signal_connect (get_widget_assert (de->xml,"file_open_syntax"), - "activate", - G_CALLBACK (open_syntax_window), - e->window); - - g_signal_connect_swapped (get_widget_assert (de->xml,"file_import-text"), - "activate", - G_CALLBACK (gtk_action_activate), - de->invoke_text_import_assistant); - - g_signal_connect_swapped (get_widget_assert (de->xml,"file_save"), - "activate", - G_CALLBACK (gtk_action_activate), - de->action_data_save); - - g_signal_connect_swapped (get_widget_assert (de->xml,"file_save_as"), - "activate", - G_CALLBACK (gtk_action_activate), - de->action_data_save_as); - - gtk_action_connect_proxy (de->invoke_find_dialog, - get_widget_assert (de->xml, "edit_find") - ); - - gtk_action_connect_proxy (de->invoke_find_dialog, - get_widget_assert (de->xml, "button-find") - ); - - gtk_action_connect_proxy (de->invoke_rank_dialog, - get_widget_assert (de->xml, "transform_rank") - ); - - gtk_action_connect_proxy (de->invoke_recode_same_dialog, - get_widget_assert (de->xml, - "transform_recode-same") - ); - - gtk_action_connect_proxy (de->invoke_recode_different_dialog, - get_widget_assert (de->xml, - "transform_recode-different") - ); - - gtk_action_connect_proxy (de->invoke_weight_cases_dialog, - get_widget_assert (de->xml, "data_weight-cases") - ); - - gtk_action_connect_proxy (de->invoke_transpose_dialog, - get_widget_assert (de->xml, "data_transpose") - ); - - gtk_action_connect_proxy (de->invoke_split_file_dialog, - get_widget_assert (de->xml, "data_split-file") - ); - - gtk_action_connect_proxy (de->invoke_sort_cases_dialog, - get_widget_assert (de->xml, "data_sort-cases") - ); - - gtk_action_connect_proxy (de->invoke_select_cases_dialog, - get_widget_assert (de->xml, "data_select-cases") - ); - - gtk_action_connect_proxy (de->invoke_compute_dialog, - get_widget_assert (de->xml, "transform_compute") - ); - - gtk_action_connect_proxy (de->invoke_t_test_independent_samples_dialog, - get_widget_assert (de->xml, - "indep-t-test") - ); - - - gtk_action_connect_proxy (de->invoke_t_test_paired_samples_dialog, - get_widget_assert (de->xml, - "paired-t-test") - ); - - - gtk_action_connect_proxy (de->invoke_t_test_one_sample_dialog, - get_widget_assert (de->xml, - "one-sample-t-test") - ); - - - gtk_action_connect_proxy (de->invoke_oneway_anova_dialog, - get_widget_assert (de->xml, - "oneway-anova") - ); - - - gtk_action_connect_proxy (de->invoke_comments_dialog, - get_widget_assert (de->xml, "utilities_comments") - ); - - gtk_action_connect_proxy (de->invoke_variable_info_dialog, - get_widget_assert (de->xml, "utilities_variables") - ); - - gtk_action_connect_proxy (de->invoke_descriptives_dialog, - get_widget_assert (de->xml, "analyze_descriptives") - ); - - gtk_action_connect_proxy (de->invoke_crosstabs_dialog, - get_widget_assert (de->xml, "crosstabs") - ); - - gtk_action_connect_proxy (de->invoke_frequencies_dialog, - get_widget_assert (de->xml, "analyze_frequencies") - ); - - - gtk_action_connect_proxy (de->invoke_examine_dialog, - get_widget_assert (de->xml, "analyze_explore") - ); - - gtk_action_connect_proxy (de->invoke_regression_dialog, - get_widget_assert (de->xml, "linear-regression") - ); - - g_signal_connect (get_widget_assert (de->xml,"help_about"), - "activate", - G_CALLBACK (about_new), - e->window); - - - g_signal_connect (get_widget_assert (de->xml,"help_reference"), - "activate", - G_CALLBACK (reference_manual), - e->window); - - - g_signal_connect (de->data_editor, - "cases-selected", - G_CALLBACK (enable_delete_cases), - de); - - - g_signal_connect (de->data_editor, - "variables-selected", - G_CALLBACK (enable_delete_variables), - de); - - - g_signal_connect (GTK_NOTEBOOK (de->data_editor), - "switch-page", - G_CALLBACK (on_switch_sheet), de); - - gtk_notebook_set_current_page (GTK_NOTEBOOK (de->data_editor), PSPPIRE_DATA_EDITOR_VARIABLE_VIEW); - gtk_notebook_set_current_page (GTK_NOTEBOOK (de->data_editor), PSPPIRE_DATA_EDITOR_DATA_VIEW); - - g_signal_connect (get_widget_assert (de->xml, "view_statusbar"), - "activate", - G_CALLBACK (status_bar_activate), de); - - - g_signal_connect (get_widget_assert (de->xml, "view_gridlines"), - "activate", - G_CALLBACK (grid_lines_activate), de); - - - - g_signal_connect (get_widget_assert (de->xml, "view_data"), - "activate", - G_CALLBACK (data_view_activate), de); - - g_signal_connect (get_widget_assert (de->xml, "view_variables"), - "activate", - G_CALLBACK (variable_view_activate), de); - - - - g_signal_connect (get_widget_assert (de->xml, "view_fonts"), - "activate", - G_CALLBACK (fonts_activate), de); - - - - - gtk_action_connect_proxy (de->action_data_open, - get_widget_assert (de->xml, "button-open") - ); - - gtk_action_connect_proxy (de->action_data_save, - get_widget_assert (de->xml, "button-save") - ); - - gtk_action_connect_proxy (de->invoke_variable_info_dialog, - get_widget_assert (de->xml, "button-goto-variable") - ); - - gtk_action_connect_proxy (de->invoke_weight_cases_dialog, - get_widget_assert (de->xml, "button-weight-cases") - ); - - gtk_action_connect_proxy (de->invoke_split_file_dialog, - get_widget_assert (de->xml, "button-split-file") - ); - - gtk_action_connect_proxy (de->invoke_select_cases_dialog, - get_widget_assert (de->xml, "button-select-cases") - ); - - - g_signal_connect (get_widget_assert (de->xml, "file_quit"), - "activate", - G_CALLBACK (file_quit), de); - - g_signal_connect (get_widget_assert (de->xml, "transform_run-pending"), - "activate", - G_CALLBACK (execute), de); - - - g_signal_connect (get_widget_assert (de->xml, "windows_minimise_all"), - "activate", - G_CALLBACK (minimise_all_windows), NULL); - - de->toggle_split_window = - gtk_toggle_action_new ("toggle-split-window", - _("_Split Window"), - _("Split the window vertically and horizontally"), - "pspp-split-window"); - - g_signal_connect (de->toggle_split_window, "toggled", - G_CALLBACK (toggle_split_window), - de); - - gtk_action_connect_proxy (GTK_ACTION (de->toggle_split_window), - get_widget_assert (de->xml, - "windows_split")); - - de->data_sheet_variable_popup_menu = - GTK_MENU (create_data_sheet_variable_popup_menu (de)); - - de->var_sheet_variable_popup_menu = - GTK_MENU (create_var_sheet_variable_popup_menu (de)); - - de->data_sheet_cases_popup_menu = - GTK_MENU (create_data_sheet_cases_popup_menu (de)); - - - g_object_set (de->data_editor, - "datasheet-column-menu", de->data_sheet_variable_popup_menu, - "datasheet-row-menu", de->data_sheet_cases_popup_menu, - "varsheet-row-menu", de->var_sheet_variable_popup_menu, - NULL); - - - return de; -} - - -void -new_data_window (GtkMenuItem *menuitem, gpointer parent) -{ - window_create (WINDOW_DATA, NULL); -} - -/* Callback for when the datasheet/varsheet is selected */ -static void -on_switch_sheet (GtkNotebook *notebook, - GtkNotebookPage *page, - guint page_num, - gpointer user_data) -{ - struct data_editor *de = user_data; - - GtkWidget *view_data = get_widget_assert (de->xml, "view_data"); - GtkWidget *view_variables = get_widget_assert (de->xml, "view_variables"); - - switch (page_num) - { - case PSPPIRE_DATA_EDITOR_VARIABLE_VIEW: - gtk_widget_hide (view_variables); - gtk_widget_show (view_data); - gtk_action_set_sensitive (de->insert_variable, TRUE); - gtk_action_set_sensitive (de->insert_case, FALSE); - gtk_action_set_sensitive (de->invoke_goto_dialog, FALSE); - break; - case PSPPIRE_DATA_EDITOR_DATA_VIEW: - gtk_widget_show (view_variables); - gtk_widget_hide (view_data); - gtk_action_set_sensitive (de->invoke_goto_dialog, TRUE); - gtk_action_set_sensitive (de->insert_case, TRUE); - break; - default: - g_assert_not_reached (); - break; - } - -#if 0 - update_paste_menuitem (de, page_num); -#endif -} - - -static void -status_bar_activate (GtkCheckMenuItem *menuitem, gpointer data) -{ - struct data_editor *de = data; - GtkWidget *statusbar = get_widget_assert (de->xml, "status-bar"); - - if ( gtk_check_menu_item_get_active (menuitem) ) - gtk_widget_show (statusbar); - else - gtk_widget_hide (statusbar); -} - - -static void -grid_lines_activate (GtkCheckMenuItem *menuitem, gpointer data) -{ - struct data_editor *de = data; - const gboolean grid_visible = gtk_check_menu_item_get_active (menuitem); - - psppire_data_editor_show_grid (de->data_editor, grid_visible); -} - - - -static void -data_view_activate (GtkCheckMenuItem *menuitem, gpointer data) -{ - struct data_editor *de = data; - - gtk_notebook_set_current_page (GTK_NOTEBOOK (de->data_editor), PSPPIRE_DATA_EDITOR_DATA_VIEW); -} - - -static void -variable_view_activate (GtkCheckMenuItem *menuitem, gpointer data) -{ - struct data_editor *de = data; - - gtk_notebook_set_current_page (GTK_NOTEBOOK (de->data_editor), PSPPIRE_DATA_EDITOR_VARIABLE_VIEW); -} - - -static void -fonts_activate (GtkMenuItem *menuitem, gpointer data) -{ - struct data_editor *de = data; - PangoFontDescription *current_font; - gchar *font_name; - GtkWidget *dialog = - gtk_font_selection_dialog_new (_("Font Selection")); - - - current_font = GTK_WIDGET(de->data_editor)->style->font_desc; - font_name = pango_font_description_to_string (current_font); - - gtk_font_selection_dialog_set_font_name (GTK_FONT_SELECTION_DIALOG (dialog), font_name); - - g_free (font_name); - - gtk_window_set_transient_for (GTK_WINDOW (dialog), - GTK_WINDOW (get_widget_assert (de->xml, - "data_editor"))); - if ( GTK_RESPONSE_OK == gtk_dialog_run (GTK_DIALOG (dialog)) ) - { - const gchar *font = gtk_font_selection_dialog_get_font_name - (GTK_FONT_SELECTION_DIALOG (dialog)); - - PangoFontDescription* font_desc = - pango_font_description_from_string (font); - - psppire_data_editor_set_font (de->data_editor, font_desc); - } - - gtk_widget_hide (dialog); -} - - - -/* Callback for the value labels action */ -static void -toggle_value_labels (GtkToggleAction *ta, gpointer data) -{ - struct data_editor *de = data; - - g_object_set (de->data_editor, "value-labels", gtk_toggle_action_get_active (ta), NULL); -} - - - -static void -toggle_split_window (GtkToggleAction *ta, gpointer data) -{ - struct data_editor *de = data; - - psppire_data_editor_split_window (de->data_editor, - gtk_toggle_action_get_active (ta)); -} - - - - -static void -file_quit (GtkCheckMenuItem *menuitem, gpointer data) -{ - /* FIXME: Need to be more intelligent here. - Give the user the opportunity to save any unsaved data. - */ - g_object_unref (the_data_store); - gtk_main_quit (); -} - - -static void -insert_case (GtkAction *action, gpointer data) -{ - struct data_editor *de = data; - - psppire_data_editor_insert_case (de->data_editor); -} - -static void -on_insert_variable (GtkAction *action, gpointer data) -{ - PsppireDataEditor *de = PSPPIRE_DATA_EDITOR (data); - psppire_data_editor_insert_variable (de); -} - - -/* Callback for when the dictionary changes its split variables */ -static void -on_split_change (PsppireDict *dict, gpointer data) -{ - struct data_editor *de = data; - - size_t n_split_vars = dict_get_split_cnt (dict->dict); - - GtkWidget *split_status_area = - get_widget_assert (de->xml, "split-file-status-area"); - - if ( n_split_vars == 0 ) - { - gtk_label_set_text (GTK_LABEL (split_status_area), _("No Split")); - } - else - { - gint i; - GString *text; - const struct variable *const * split_vars = - dict_get_split_vars (dict->dict); - - text = g_string_new (_("Split by ")); - - for (i = 0 ; i < n_split_vars - 1; ++i ) - { - g_string_append_printf (text, "%s, ", var_get_name (split_vars[i])); - } - g_string_append (text, var_get_name (split_vars[i])); - - gtk_label_set_text (GTK_LABEL (split_status_area), text->str); - - g_string_free (text, TRUE); - } -} - - -/* Callback for when the dictionary changes its filter variable */ -static void -on_filter_change (GObject *o, gint filter_index, gpointer data) -{ - struct data_editor *de = data; - GtkWidget *filter_status_area = - get_widget_assert (de->xml, "filter-use-status-area"); - - if ( filter_index == -1 ) - { - gtk_label_set_text (GTK_LABEL (filter_status_area), _("Filter off")); - } - else - { - PsppireVarStore *vs = NULL; - struct variable *var ; - gchar *text ; - - g_object_get (de->data_editor, "var-store", &vs, NULL); - - var = psppire_dict_get_variable (vs->dict, filter_index); - - text = g_strdup_printf (_("Filter by %s"), var_get_name (var)); - - gtk_label_set_text (GTK_LABEL (filter_status_area), text); - - g_free (text); - } -} - -/* Callback for when the dictionary changes its weights */ -static void -on_weight_change (GObject *o, gint weight_index, gpointer data) -{ - struct data_editor *de = data; - GtkWidget *weight_status_area = - get_widget_assert (de->xml, "weight-status-area"); - - if ( weight_index == -1 ) - { - gtk_label_set_text (GTK_LABEL (weight_status_area), _("Weights off")); - } - else - { - struct variable *var ; - PsppireVarStore *vs = NULL; - gchar *text; - - g_object_get (de->data_editor, "var-store", &vs, NULL); - - var = psppire_dict_get_variable (vs->dict, weight_index); - - text = g_strdup_printf (_("Weight by %s"), var_get_name (var)); - - gtk_label_set_text (GTK_LABEL (weight_status_area), text); - - g_free (text); - } -} - - - - -static void data_save_as_dialog (GtkAction *, struct data_editor *de); -static void new_file (GtkAction *, struct editor_window *de); -static void open_data_dialog (GtkAction *, struct data_editor *de); -static void data_save (GtkAction *action, struct data_editor *e); - - -/* Create the GtkActions and connect to their signals */ -static void -register_data_editor_actions (struct data_editor *de) -{ - de->action_data_open = - gtk_action_new ("data-open-dialog", - _("Open"), - _("Open a data file"), - "gtk-open"); - - g_signal_connect (de->action_data_open, "activate", - G_CALLBACK (open_data_dialog), de); - - - de->action_data_save = gtk_action_new ("data-save", - _("Save"), - _("Save data to file"), - "gtk-save"); - - g_signal_connect (de->action_data_save, "activate", - G_CALLBACK (data_save), de); - - - - de->action_data_save_as = gtk_action_new ("data-save-as-dialog", - _("Save As"), - _("Save data to file"), - "gtk-save"); - - g_signal_connect (de->action_data_save_as, "activate", - G_CALLBACK (data_save_as_dialog), de); - - de->action_data_new = - gtk_action_new ("data-new", - _("New"), - _("New data file"), - NULL); - - g_signal_connect (de->action_data_new, "activate", - G_CALLBACK (new_file), de); - - de->invoke_text_import_assistant = - gtk_action_new ("file_import-text", - _("_Import Text Data"), - _("Import text data file"), - ""); - - g_signal_connect (de->invoke_text_import_assistant, "activate", - G_CALLBACK (text_data_import_assistant), de); -} - -/* Returns true if NAME has a suffix which might denote a PSPP file */ -static gboolean -name_has_suffix (const gchar *name) -{ - if ( g_str_has_suffix (name, ".sav")) - return TRUE; - if ( g_str_has_suffix (name, ".SAV")) - return TRUE; - if ( g_str_has_suffix (name, ".por")) - return TRUE; - if ( g_str_has_suffix (name, ".POR")) - return TRUE; - - return FALSE; -} - -/* Append SUFFIX to the filename of DE */ -static void -append_filename_suffix (struct data_editor *de, const gchar *suffix) -{ - if ( ! name_has_suffix (de->file_name)) - { - gchar *s = de->file_name; - de->file_name = g_strconcat (de->file_name, suffix, NULL); - g_free (s); - } -} - -/* Save DE to file */ -static void -save_file (struct data_editor *de) -{ - struct getl_interface *sss; - struct string file_name ; - - g_assert (de->file_name); - - ds_init_empty (&file_name); - syntax_gen_string (&file_name, ss_cstr (de->file_name)); - - if ( de->save_as_portable ) - { - append_filename_suffix (de, ".por"); - sss = create_syntax_string_source ("EXPORT OUTFILE=%s.", - ds_cstr (&file_name)); - } - else - { - append_filename_suffix (de, ".sav"); - sss = create_syntax_string_source ("SAVE OUTFILE=%s.", - ds_cstr (&file_name)); - } - - ds_destroy (&file_name); - - execute_syntax (sss); -} - - -/* Callback for data_save action. - If there's an existing file name, then just save, - otherwise prompt for a file name, then save */ -static void -data_save (GtkAction *action, struct data_editor *de) -{ - if ( de->file_name) - save_file (de); - else - data_save_as_dialog (action, de); -} - - -/* Callback for data_save_as action. Prompt for a filename and save */ -static void -data_save_as_dialog (GtkAction *action, struct data_editor *de) -{ - struct editor_window *e = (struct editor_window *) de; - - GtkWidget *button_sys; - GtkWidget *dialog = - gtk_file_chooser_dialog_new (_("Save"), - GTK_WINDOW (e->window), - GTK_FILE_CHOOSER_ACTION_SAVE, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, - NULL); - - GtkFileFilter *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"); - gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter); - - filter = gtk_file_filter_new (); - gtk_file_filter_set_name (filter, _("Portable Files (*.por) ")); - gtk_file_filter_add_pattern (filter, "*.por"); - 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, _("All Files")); - gtk_file_filter_add_pattern (filter, "*"); - gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter); - - { - GtkWidget *button_por; - GtkWidget *vbox = gtk_vbox_new (TRUE, 5); - button_sys = - gtk_radio_button_new_with_label (NULL, _("System File")); - - button_por = - gtk_radio_button_new_with_label - (gtk_radio_button_get_group (GTK_RADIO_BUTTON(button_sys)), - _("Portable File")); - - gtk_box_pack_start_defaults (GTK_BOX (vbox), button_sys); - gtk_box_pack_start_defaults (GTK_BOX (vbox), button_por); - - gtk_widget_show_all (vbox); - - gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER(dialog), vbox); - } - - switch (gtk_dialog_run (GTK_DIALOG (dialog))) - { - case GTK_RESPONSE_ACCEPT: - { - g_free (de->file_name); - - de->file_name = - gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); - - de->save_as_portable = - ! gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button_sys)); - - if ( de->save_as_portable) - append_filename_suffix (de, ".por"); - else - append_filename_suffix (de, ".sav"); - - save_file (de); - - window_set_name_from_filename (e, de->file_name); - } - break; - default: - break; - } - - gtk_widget_destroy (dialog); -} - - -/* Callback for data_new action. - Performs the NEW FILE command */ -static void -new_file (GtkAction *action, struct editor_window *e) -{ - struct data_editor *de = (struct data_editor *) e; - - struct getl_interface *sss = - create_syntax_string_source ("NEW FILE."); - - execute_syntax (sss); - - g_free (de->file_name); - de->file_name = NULL; - - default_window_name (e); -} - - -static void -open_data_file (const gchar *file_name, struct data_editor *de) -{ - struct getl_interface *sss; - struct string filename; - - ds_init_empty (&filename); - syntax_gen_string (&filename, ss_cstr (file_name)); - - sss = create_syntax_string_source ("GET FILE=%s.", - ds_cstr (&filename)); - ds_destroy (&filename); - - if (execute_syntax (sss) ) - { - window_set_name_from_filename ((struct editor_window *) de, file_name); - add_most_recent (file_name); - } -} - - - -/* Callback for the data_open action. - Prompts for a filename and opens it */ -static void -open_data_dialog (GtkAction *action, struct data_editor *de) -{ - struct editor_window *e = (struct editor_window *) de; - - GtkWidget *dialog = - gtk_file_chooser_dialog_new (_("Open"), - GTK_WINDOW (e->window), - GTK_FILE_CHOOSER_ACTION_OPEN, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, - NULL); - - GtkFileFilter *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"); - gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter); - - filter = gtk_file_filter_new (); - gtk_file_filter_set_name (filter, _("Portable Files (*.por) ")); - gtk_file_filter_add_pattern (filter, "*.por"); - 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, _("All Files")); - gtk_file_filter_add_pattern (filter, "*"); - gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter); - - - if ( de->file_name) - { - gchar *dir_name = g_path_get_dirname (de->file_name); - gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), - dir_name); - free (dir_name); - } - - switch (gtk_dialog_run (GTK_DIALOG (dialog))) - { - case GTK_RESPONSE_ACCEPT: - { - g_free (de->file_name); - de->file_name = - gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); - - open_data_file (de->file_name, de); - } - break; - default: - break; - } - - gtk_widget_destroy (dialog); -} - - -static GtkWidget * -create_data_sheet_variable_popup_menu (struct data_editor *de) -{ - GtkWidget *menu = gtk_menu_new (); - - GtkWidget *sort_ascending = - gtk_menu_item_new_with_label (_("Sort Ascending")); - - GtkWidget *sort_descending = - gtk_menu_item_new_with_label (_("Sort Descending")); - - GtkWidget *insert_variable = - gtk_menu_item_new_with_label (_("Insert Variable")); - - GtkWidget *clear_variable = - gtk_menu_item_new_with_label (_("Clear")); - - - gtk_action_connect_proxy (de->delete_variables, - clear_variable ); - - - gtk_menu_shell_append (GTK_MENU_SHELL (menu), insert_variable); - - - gtk_menu_shell_append (GTK_MENU_SHELL (menu), - gtk_separator_menu_item_new ()); - - - gtk_menu_shell_append (GTK_MENU_SHELL (menu), clear_variable); - - - gtk_menu_shell_append (GTK_MENU_SHELL (menu), - gtk_separator_menu_item_new ()); - - - gtk_menu_shell_append (GTK_MENU_SHELL (menu), sort_ascending); - - - g_signal_connect_swapped (G_OBJECT (sort_ascending), "activate", - G_CALLBACK (psppire_data_editor_sort_ascending), - de->data_editor); - - g_signal_connect_swapped (G_OBJECT (sort_descending), "activate", - G_CALLBACK (psppire_data_editor_sort_descending), - de->data_editor); - - g_signal_connect_swapped (G_OBJECT (insert_variable), "activate", - G_CALLBACK (gtk_action_activate), - de->insert_variable); - - - gtk_menu_shell_append (GTK_MENU_SHELL (menu), sort_descending); - - gtk_widget_show_all (menu); - - return menu; -} - - -static GtkWidget * -create_data_sheet_cases_popup_menu (struct data_editor *de) -{ - GtkWidget *menu = gtk_menu_new (); - - GtkWidget *insert_case = - gtk_menu_item_new_with_label (_("Insert Case")); - - GtkWidget *delete_case = - gtk_menu_item_new_with_label (_("Clear")); - - - gtk_action_connect_proxy (de->delete_cases, - delete_case); - - - gtk_menu_shell_append (GTK_MENU_SHELL (menu), insert_case); - - g_signal_connect_swapped (G_OBJECT (insert_case), "activate", - G_CALLBACK (gtk_action_activate), - de->insert_case); - - - gtk_menu_shell_append (GTK_MENU_SHELL (menu), - gtk_separator_menu_item_new ()); - - - gtk_menu_shell_append (GTK_MENU_SHELL (menu), delete_case); - - - gtk_widget_show_all (menu); - - return menu; -} - - -static GtkWidget * -create_var_sheet_variable_popup_menu (struct data_editor *de) -{ - GtkWidget *menu = gtk_menu_new (); - - GtkWidget *insert_variable = - gtk_menu_item_new_with_label (_("Insert Variable")); - - GtkWidget *delete_variable = - gtk_menu_item_new_with_label (_("Clear")); - - - gtk_action_connect_proxy (de->delete_variables, - delete_variable); - - - gtk_menu_shell_append (GTK_MENU_SHELL (menu), insert_variable); - - g_signal_connect_swapped (G_OBJECT (insert_variable), "activate", - G_CALLBACK (gtk_action_activate), - de->insert_variable); - - - gtk_menu_shell_append (GTK_MENU_SHELL (menu), - gtk_separator_menu_item_new ()); - - - gtk_menu_shell_append (GTK_MENU_SHELL (menu), delete_variable); - - - gtk_widget_show_all (menu); - - return menu; -} - - - - - -static void -on_edit_paste (GtkAction *a, gpointer data) -{ - struct data_editor *de = data; - - psppire_data_editor_clip_paste (de->data_editor); -} - -static void -on_edit_copy (GtkMenuItem *m, gpointer data) -{ - struct data_editor *de = data; - - psppire_data_editor_clip_copy (de->data_editor); -} - - - -static void -on_edit_cut (GtkMenuItem *m, gpointer data) -{ - struct data_editor *de = data; - - psppire_data_editor_clip_cut (de->data_editor); -} diff --git a/src/ui/gui/data-editor.h b/src/ui/gui/data-editor.h deleted file mode 100644 index af282e26..00000000 --- a/src/ui/gui/data-editor.h +++ /dev/null @@ -1,99 +0,0 @@ -/* PSPPIRE - a graphical user interface for PSPP. - Copyright (C) 2006, 2007 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 - 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, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - 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, see . */ - - -#ifndef DATA_EDITOR_H -#define DATA_EDITOR_H - -#include -#include -#include "window-manager.h" -#include "psppire-data-editor.h" - -struct data_editor -{ - struct editor_window parent; - - GtkAction *action_data_new; - GtkAction *action_data_open; - GtkAction *action_data_save_as; - GtkAction *action_data_save; - - - GtkAction *invoke_text_import_assistant; - - /* Actions which invoke dialog boxes */ - GtkAction *invoke_weight_cases_dialog; - GtkAction *invoke_transpose_dialog; - GtkAction *invoke_split_file_dialog; - GtkAction *invoke_sort_cases_dialog; - GtkAction *invoke_compute_dialog; - GtkAction *invoke_comments_dialog; - GtkAction *invoke_select_cases_dialog; - GtkAction *invoke_goto_dialog; - GtkAction *invoke_variable_info_dialog; - GtkAction *invoke_find_dialog; - GtkAction *invoke_rank_dialog; - GtkAction *invoke_recode_same_dialog; - GtkAction *invoke_recode_different_dialog; - - GtkAction *invoke_crosstabs_dialog; - GtkAction *invoke_descriptives_dialog; - GtkAction *invoke_frequencies_dialog; - GtkAction *invoke_examine_dialog; - GtkAction *invoke_regression_dialog; - - GtkAction *invoke_t_test_independent_samples_dialog; - GtkAction *invoke_t_test_paired_samples_dialog; - GtkAction *invoke_oneway_anova_dialog; - GtkAction *invoke_t_test_one_sample_dialog; - - GtkToggleAction *toggle_split_window; - - - /* Actions which do things */ - GtkAction *insert_variable; - GtkAction *insert_case; - GtkAction *delete_variables; - GtkAction *delete_cases; - - GtkToggleAction *toggle_value_labels; - - GladeXML *xml; - - GtkMenu *data_sheet_variable_popup_menu; - GtkMenu *data_sheet_cases_popup_menu; - - GtkMenu *var_sheet_variable_popup_menu; - - PsppireDataEditor *data_editor; - - gboolean save_as_portable; - - /* Name of the file this data is associated with (ie, was loaded from or - has been saved to), in "filename encoding", or NULL, if it's not - associated with any file */ - gchar *file_name; -}; - - -struct data_editor * new_data_editor (void); - -void new_data_window (GtkMenuItem *, gpointer); - -void data_editor_select_sheet (struct data_editor *de, gint page); - -#endif diff --git a/src/ui/gui/descriptives-dialog.c b/src/ui/gui/descriptives-dialog.c index 7b33eae2..aaed7eee 100644 --- a/src/ui/gui/descriptives-dialog.c +++ b/src/ui/gui/descriptives-dialog.c @@ -23,13 +23,13 @@ #include #include -#include +#include #include #include #include #include #include -#include +#include #include "gettext.h" #define _(msgid) gettext (msgid) @@ -202,7 +202,7 @@ void descriptives_dialog (GObject *o, gpointer data) { gint response; - struct data_editor *de = data; + PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data); struct descriptives_dialog scd; @@ -221,7 +221,7 @@ descriptives_dialog (GObject *o, gpointer data) g_object_get (de->data_editor, "var-store", &vs, NULL); - gtk_window_set_transient_for (GTK_WINDOW (dialog), de->parent.window); + gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (de)); attach_dictionary_to_treeview (GTK_TREE_VIEW (source), vs->dict, @@ -263,6 +263,7 @@ descriptives_dialog (GObject *o, gpointer data) case GTK_RESPONSE_OK: { gchar *syntax = generate_syntax (&scd); + struct getl_interface *sss = create_syntax_string_source (syntax); execute_syntax (sss); @@ -272,12 +273,7 @@ descriptives_dialog (GObject *o, gpointer data) case PSPPIRE_RESPONSE_PASTE: { gchar *syntax = generate_syntax (&scd); - - struct syntax_editor *se = - (struct syntax_editor *) window_create (WINDOW_SYNTAX, NULL); - - gtk_text_buffer_insert_at_cursor (se->buffer, syntax, -1); - + paste_syntax_in_new_window (syntax); g_free (syntax); } break; diff --git a/src/ui/gui/examine-dialog.c b/src/ui/gui/examine-dialog.c index 682af46b..171d88cf 100644 --- a/src/ui/gui/examine-dialog.c +++ b/src/ui/gui/examine-dialog.c @@ -22,13 +22,13 @@ #include #include -#include +#include #include #include #include #include #include -#include +#include #include "gettext.h" #define _(msgid) gettext (msgid) @@ -236,7 +236,7 @@ void examine_dialog (GObject *o, gpointer data) { gint response; - struct data_editor *de = data; + PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data); struct examine_dialog ex_d; @@ -275,9 +275,9 @@ examine_dialog (GObject *o, gpointer data) ex_d.percentiles_button = GTK_TOGGLE_BUTTON (get_widget_assert (xml, "percentiles-button")); - gtk_window_set_transient_for (GTK_WINDOW (dialog), de->parent.window); - gtk_window_set_transient_for (GTK_WINDOW (ex_d.stats_dialog), de->parent.window); - gtk_window_set_transient_for (GTK_WINDOW (ex_d.opts_dialog), de->parent.window); + gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (de)); + gtk_window_set_transient_for (GTK_WINDOW (ex_d.stats_dialog), GTK_WINDOW (de)); + gtk_window_set_transient_for (GTK_WINDOW (ex_d.opts_dialog), GTK_WINDOW (de)); attach_dictionary_to_treeview (GTK_TREE_VIEW (source), vs->dict, @@ -344,12 +344,7 @@ examine_dialog (GObject *o, gpointer data) case PSPPIRE_RESPONSE_PASTE: { gchar *syntax = generate_syntax (&ex_d); - - struct syntax_editor *se = - (struct syntax_editor *) window_create (WINDOW_SYNTAX, NULL); - - gtk_text_buffer_insert_at_cursor (se->buffer, syntax, -1); - + paste_syntax_in_new_window (syntax); g_free (syntax); } break; diff --git a/src/ui/gui/find-dialog.c b/src/ui/gui/find-dialog.c index 985e73fb..130b25cf 100644 --- a/src/ui/gui/find-dialog.c +++ b/src/ui/gui/find-dialog.c @@ -24,7 +24,7 @@ which match particular strings */ #include "psppire-selector.h" #include "psppire-dialog.h" #include "helper.h" -#include "data-editor.h" +#include "psppire-data-window.h" #include "dict-display.h" #include #include @@ -54,7 +54,7 @@ struct find_dialog GtkBuilder *xml; PsppireDict *dict; struct datasheet *data; - struct data_editor *de; + PsppireDataWindow *de; GtkWidget *variable_entry; GtkWidget *value_entry; GtkWidget *value_labels_checkbox; @@ -185,7 +185,7 @@ value_labels_toggled (GtkToggleButton *tb, gpointer data) void find_dialog (GObject *o, gpointer data) { - struct data_editor *de = data; + PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data); struct find_dialog fd; @@ -238,7 +238,7 @@ find_dialog (GObject *o, gpointer data) - gtk_window_set_transient_for (GTK_WINDOW (dialog), de->parent.window); + gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (de)); attach_dictionary_to_treeview (GTK_TREE_VIEW (source), diff --git a/src/ui/gui/frequencies-dialog.c b/src/ui/gui/frequencies-dialog.c index 89cf7683..37e301b8 100644 --- a/src/ui/gui/frequencies-dialog.c +++ b/src/ui/gui/frequencies-dialog.c @@ -23,13 +23,13 @@ #include #include -#include +#include #include #include #include #include #include -#include +#include #include "gettext.h" #define _(msgid) gettext (msgid) @@ -307,7 +307,7 @@ void frequencies_dialog (GObject *o, gpointer data) { gint response; - struct data_editor *de = data; + PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data); struct frequencies_dialog fd; @@ -331,7 +331,7 @@ frequencies_dialog (GObject *o, gpointer data) ); - gtk_window_set_transient_for (GTK_WINDOW (dialog), de->parent.window); + gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (de)); attach_dictionary_to_treeview (GTK_TREE_VIEW (source), vs->dict, @@ -369,7 +369,7 @@ frequencies_dialog (GObject *o, gpointer data) fd.current_opts.limit = 50; - gtk_window_set_transient_for (GTK_WINDOW (fd.format_dialog), de->parent.window); + gtk_window_set_transient_for (GTK_WINDOW (fd.format_dialog), GTK_WINDOW (de)); g_signal_connect (dialog, "refresh", G_CALLBACK (refresh), &fd); @@ -393,6 +393,7 @@ frequencies_dialog (GObject *o, gpointer data) case GTK_RESPONSE_OK: { gchar *syntax = generate_syntax (&fd); + struct getl_interface *sss = create_syntax_string_source (syntax); execute_syntax (sss); @@ -402,12 +403,7 @@ frequencies_dialog (GObject *o, gpointer data) case PSPPIRE_RESPONSE_PASTE: { gchar *syntax = generate_syntax (&fd); - - struct syntax_editor *se = - (struct syntax_editor *) window_create (WINDOW_SYNTAX, NULL); - - gtk_text_buffer_insert_at_cursor (se->buffer, syntax, -1); - + paste_syntax_in_new_window (syntax); g_free (syntax); } break; diff --git a/src/ui/gui/goto-case-dialog.c b/src/ui/gui/goto-case-dialog.c index a22b5cb0..9a523943 100644 --- a/src/ui/gui/goto-case-dialog.c +++ b/src/ui/gui/goto-case-dialog.c @@ -19,12 +19,12 @@ #include "goto-case-dialog.h" #include "helper.h" #include "psppire-dialog.h" -#include "data-editor.h" +#include "psppire-data-window.h" #include "psppire-data-store.h" static void -refresh (const struct data_editor *de, GtkBuilder *xml) +refresh (const PsppireDataWindow *de, GtkBuilder *xml) { PsppireDataStore *ds = NULL; casenumber case_count ; @@ -44,12 +44,12 @@ goto_case_dialog (GObject *o, gpointer data) { gint response; GtkBuilder *xml = builder_new ("psppire.ui"); - struct data_editor *de = data; + PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data); GtkWidget *dialog = get_widget_assert (xml, "goto-case-dialog"); - gtk_window_set_transient_for (GTK_WINDOW (dialog), de->parent.window); + gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (de)); refresh (de, xml); diff --git a/src/ui/gui/helper.c b/src/ui/gui/helper.c index fc9105d7..6a3a0f9e 100644 --- a/src/ui/gui/helper.c +++ b/src/ui/gui/helper.c @@ -20,6 +20,8 @@ */ #include +#include "psppire-syntax-window.h" + #include #include @@ -46,7 +48,7 @@ #include #include "psppire-data-store.h" #include -#include "output-viewer.h" +#include "psppire-output-window.h" #include "xalloc.h" @@ -268,7 +270,7 @@ execute_syntax (struct getl_interface *sss) som_flush (); - reload_the_viewer (); + psppire_output_window_reload (); return retval; } @@ -320,3 +322,12 @@ clone_list_store (const GtkListStore *src) +void +paste_syntax_in_new_window (const gchar *syntax) +{ + GtkWidget *se = psppire_syntax_window_new (); + + gtk_text_buffer_insert_at_cursor (PSPPIRE_SYNTAX_WINDOW (se)->buffer, syntax, -1); + + gtk_widget_show (se); +} diff --git a/src/ui/gui/helper.h b/src/ui/gui/helper.h index d08a1752..d388ccb4 100644 --- a/src/ui/gui/helper.h +++ b/src/ui/gui/helper.h @@ -26,6 +26,10 @@ #include #include + + +void paste_syntax_in_new_window (const gchar *syntax); + /* GtkRecentChooserMenu was added in 2.10.0 but it didn't support GtkRecentFilters until diff --git a/src/ui/gui/oneway-anova-dialog.c b/src/ui/gui/oneway-anova-dialog.c index 59b65b4a..d41b2760 100644 --- a/src/ui/gui/oneway-anova-dialog.c +++ b/src/ui/gui/oneway-anova-dialog.c @@ -22,7 +22,7 @@ #include "psppire-dict.h" #include "psppire-var-store.h" #include "helper.h" -#include "data-editor.h" +#include "psppire-data-window.h" #include "psppire-dialog.h" #include "dialog-common.h" #include "dict-display.h" @@ -30,7 +30,7 @@ #include -#include "syntax-editor.h" +#include "helper.h" #include "gettext.h" @@ -126,7 +126,7 @@ void oneway_anova_dialog (GObject *o, gpointer data) { gint response; - struct data_editor *de = data; + PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data); PsppireVarStore *vs = NULL; @@ -168,7 +168,7 @@ oneway_anova_dialog (GObject *o, gpointer data) ow.dialog = GTK_WINDOW (get_widget_assert (builder, "oneway-anova-dialog")); - gtk_window_set_transient_for (ow.dialog, de->parent.window); + gtk_window_set_transient_for (ow.dialog, GTK_WINDOW (de)); attach_dictionary_to_treeview (GTK_TREE_VIEW (dict_view), vs->dict, @@ -222,7 +222,7 @@ oneway_anova_dialog (GObject *o, gpointer data) psppire_acr_set_entry (cd->acr, entry); gtk_window_set_transient_for (GTK_WINDOW (cd->contrasts_dialog), - de->parent.window); + GTK_WINDOW (de)); } response = psppire_dialog_run (PSPPIRE_DIALOG (ow.dialog)); @@ -232,6 +232,7 @@ oneway_anova_dialog (GObject *o, gpointer data) case GTK_RESPONSE_OK: { gchar *syntax = generate_syntax (&ow); + struct getl_interface *sss = create_syntax_string_source (syntax); execute_syntax (sss); @@ -241,11 +242,7 @@ oneway_anova_dialog (GObject *o, gpointer data) case PSPPIRE_RESPONSE_PASTE: { gchar *syntax = generate_syntax (&ow); - - struct syntax_editor *se = - (struct syntax_editor *) window_create (WINDOW_SYNTAX, NULL); - - gtk_text_buffer_insert_at_cursor (se->buffer, syntax, -1); + paste_syntax_in_new_window (syntax); g_free (syntax); } diff --git a/src/ui/gui/output-viewer.c b/src/ui/gui/output-viewer.c deleted file mode 100644 index 2b0c4af8..00000000 --- a/src/ui/gui/output-viewer.c +++ /dev/null @@ -1,294 +0,0 @@ -/* PSPPIRE - a graphical user interface for PSPP. - Copyright (C) 2007 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 - 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, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - 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, see . */ - -#include -#include -#include -#include "window-manager.h" -#include "output-viewer.h" -#include "helper.h" -#include "about.h" - -#include -#include -#include - -#include -#include - -#include "xalloc.h" - -struct output_viewer -{ - struct editor_window parent; - GtkTextBuffer *buffer; /* The buffer which contains the text */ - GtkWidget *textview ; - FILE *fp; /* The file it's viewing */ -}; - - -static void -cancel_urgency (GtkWindow *window, gpointer data) -{ - gtk_window_set_urgency_hint (window, FALSE); -} - - -static struct output_viewer *the_output_viewer = NULL; - -int viewer_length = 16; -int viewer_width = 59; - -/* Callback for the "delete" action (clicking the x on the top right - hand corner of the window) */ -static gboolean -on_delete (GtkWidget *w, GdkEvent *event, gpointer user_data) -{ - struct output_viewer *ov = user_data; - - g_free (ov); - - the_output_viewer = NULL; - - unlink (output_file_name ()); - - return FALSE; -} - - -/* Sets width and length according to the new size - of the output window */ -static void -on_textview_resize (GtkWidget *widget, - GtkAllocation *allocation, - gpointer user_data) -{ - PangoContext * context ; - PangoLayout *layout ; - PangoRectangle logical; - GtkStyle *style; - gint right_margin, left_margin; - GtkTextView *text_view = GTK_TEXT_VIEW (widget); - - context = gtk_widget_create_pango_context (widget); - layout = pango_layout_new (context); - - style = gtk_widget_get_style (widget); - - pango_layout_set_font_description (layout, style->font_desc); - - /* Find the width of one character. We can use any character, because - the textview has a monospaced font */ - pango_layout_set_text (layout, "M", 1); - - pango_layout_get_extents (layout, NULL, &logical); - - left_margin = gtk_text_view_get_left_margin (text_view); - right_margin = gtk_text_view_get_right_margin (text_view); - - viewer_length = allocation->height / PANGO_PIXELS (logical.height); - viewer_width = (allocation->width - right_margin - left_margin) - / PANGO_PIXELS (logical.width); - - g_object_unref (G_OBJECT (layout)); - g_object_unref (G_OBJECT (context)); -} - - - -/* - Create a new output viewer -*/ -struct output_viewer * -new_output_viewer (void) -{ - GladeXML *xml = XML_NEW ("output-viewer.glade"); - - struct output_viewer *ov ; - struct editor_window *e; - - connect_help (xml); - - ov = g_malloc (sizeof (*ov)); - - e = (struct editor_window *)ov; - - - e->window = GTK_WINDOW (get_widget_assert (xml, "output-viewer-window")); - ov->textview = get_widget_assert (xml, "output-viewer-textview"); - ov->buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (ov->textview)); - - g_signal_connect (e->window, - "focus-in-event", - G_CALLBACK (cancel_urgency), - NULL); - - { - /* Output uses ascii characters for tabular material. - So we need a monospaced font otherwise it'll look silly */ - PangoFontDescription *font_desc = - pango_font_description_from_string ("monospace"); - - gtk_widget_modify_font (ov->textview, font_desc); - pango_font_description_free (font_desc); - } - - g_signal_connect (ov->textview, "size-allocate", - G_CALLBACK (on_textview_resize), NULL); - - ov->fp = NULL; - - g_signal_connect (get_widget_assert (xml,"help_about"), - "activate", - G_CALLBACK (about_new), - e->window); - - g_signal_connect (get_widget_assert (xml,"help_reference"), - "activate", - G_CALLBACK (reference_manual), - NULL); - - g_signal_connect (get_widget_assert (xml,"windows_minimise-all"), - "activate", - G_CALLBACK (minimise_all_windows), - NULL); - - g_object_unref (xml); - - - g_signal_connect (e->window, "delete-event", - G_CALLBACK (on_delete), ov); - - return ov; -} - - -void -reload_the_viewer (void) -{ - struct stat buf; - - /* If there is no output, then don't do anything */ - if (0 != stat (output_file_name (), &buf)) - return ; - - if ( NULL == the_output_viewer ) - { - the_output_viewer = - (struct output_viewer *) window_create (WINDOW_OUTPUT, NULL); - } - - reload_viewer (the_output_viewer); -} - -#define OUTPUT_FILE_NAME "psppire.txt" - -void -reload_viewer (struct output_viewer *ov) -{ - GtkTextIter end_iter; - GtkTextMark *mark ; - - static char *line = NULL; - - gboolean chars_inserted = FALSE; - - gtk_text_buffer_get_end_iter (ov->buffer, &end_iter); - - line = xrealloc (line, sizeof (char) * (viewer_width + 1)); - - - mark = gtk_text_buffer_create_mark (ov->buffer, NULL, &end_iter, TRUE); - -#ifdef __CYGWIN__ - /* - Apparently Windoze is not capabale of writing to a file whilst - another (or the same) process is reading from it. Therefore, we - must close the file after reading it, and clear the entire buffer - before writing to it. - This will be slower for large buffers, but should work - (in so far as anything ever works on windows). - */ - { - GtkTextIter start_iter; - FILE *fp = fopen (OUTPUT_FILE_NAME, "r"); - if ( !fp) - { - g_print ("Cannot open %s\n", OUTPUT_FILE_NAME); - return; - } - - /* Delete all the entire buffer */ - gtk_text_buffer_get_start_iter (ov->buffer, &start_iter); - gtk_text_buffer_delete (ov->buffer, &start_iter, &end_iter); - - - gtk_text_buffer_get_start_iter (ov->buffer, &start_iter); - /* Read in the next lot of text */ - while (fgets (line, viewer_width + 1, fp) != NULL) - { - chars_inserted = TRUE; - gtk_text_buffer_insert (ov->buffer, &start_iter, line, -1); - } - - fclose (fp); - } -#else - { - if ( ov->fp == NULL) - { - ov->fp = fopen (output_file_name (), "r"); - if ( ov->fp == NULL) - { - g_print ("Cannot open %s\n", output_file_name ()); - return; - } - } - - /* Read in the next lot of text */ - while (fgets (line, viewer_width + 1, ov->fp) != NULL) - { - chars_inserted = TRUE; - gtk_text_buffer_insert (ov->buffer, &end_iter, line, -1); - } - } -#endif - - /* Scroll to where the start of this lot of text begins */ - gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (ov->textview), - mark, - 0.1, TRUE, 0.0, 0.0); - - - if ( chars_inserted ) - gtk_window_set_urgency_hint ( ((struct editor_window *)ov)->window, TRUE); -} - - - - -const char * -output_file_name (void) -{ - const char *dir = default_output_path (); - static char *filename = NULL; - - if ( NULL == filename ) - filename = xasprintf ("%s%s", dir, OUTPUT_FILE_NAME); - - - return filename; -} diff --git a/src/ui/gui/output-viewer.glade b/src/ui/gui/output-viewer.glade index 0bcf5f3e..aeb88793 100644 --- a/src/ui/gui/output-viewer.glade +++ b/src/ui/gui/output-viewer.glade @@ -78,7 +78,7 @@ _Windows True - + True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK diff --git a/src/ui/gui/output-viewer.h b/src/ui/gui/output-viewer.h deleted file mode 100644 index e5bf5c1c..00000000 --- a/src/ui/gui/output-viewer.h +++ /dev/null @@ -1,38 +0,0 @@ -/* PSPPIRE - a graphical user interface for PSPP. - Copyright (C) 2007 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 - 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, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - 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, see . */ - - -#ifndef OUTPUT_VIEWER_H -#define OUTPUT_VIEWER_H - -#include - -#include "window-manager.h" - - -extern int viewer_length ; -extern int viewer_width ; - -struct output_viewer * new_output_viewer (void); - -void reload_viewer (struct output_viewer *); - -void reload_the_viewer (void); - - -const char * output_file_name (void); - -#endif diff --git a/src/ui/gui/psppire-data-store.c b/src/ui/gui/psppire-data-store.c index 71d7d5f5..1bbd2bb8 100644 --- a/src/ui/gui/psppire-data-store.c +++ b/src/ui/gui/psppire-data-store.c @@ -308,8 +308,6 @@ delete_variable_callback (GObject *obj, gint dict_index, #endif } - - static void variable_changed_callback (GObject *obj, gint var_num, gpointer data) { @@ -319,7 +317,6 @@ variable_changed_callback (GObject *obj, gint var_num, gpointer data) psppire_sheet_column_columns_changed (PSPPIRE_SHEET_COLUMN (store), var_num, 1); - psppire_sheet_model_range_changed (PSPPIRE_SHEET_MODEL (store), -1, var_num, -1, var_num); diff --git a/src/ui/gui/psppire-data-window.c b/src/ui/gui/psppire-data-window.c new file mode 100644 index 00000000..90e749d3 --- /dev/null +++ b/src/ui/gui/psppire-data-window.c @@ -0,0 +1,1720 @@ +/* PSPPIRE - a graphical user interface for PSPP. + Copyright (C) 2008 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 + 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, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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, see . */ + +#include + +#include +#include +#include +#include "helper.h" + +#include "text-data-import-dialog.h" + + +#include +#include +#include +#include + +#include + +#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 "dict-display.h" +#include "regression-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 +#define _(msgid) gettext (msgid) +#define N_(msgid) msgid + + + +static void psppire_data_window_base_finalize (PsppireDataWindowClass *, gpointer); +static void psppire_data_window_base_init (PsppireDataWindowClass *class); +static void psppire_data_window_class_init (PsppireDataWindowClass *class); +static void psppire_data_window_init (PsppireDataWindow *data_editor); + + +GType +psppire_data_window_get_type (void) +{ + static GType psppire_data_window_type = 0; + + if (!psppire_data_window_type) + { + static const GTypeInfo psppire_data_window_info = + { + sizeof (PsppireDataWindowClass), + (GBaseInitFunc) psppire_data_window_base_init, + (GBaseFinalizeFunc) psppire_data_window_base_finalize, + (GClassInitFunc)psppire_data_window_class_init, + (GClassFinalizeFunc) NULL, + NULL, + sizeof (PsppireDataWindow), + 0, + (GInstanceInitFunc) psppire_data_window_init, + }; + + psppire_data_window_type = + g_type_register_static (PSPPIRE_WINDOW_TYPE, "PsppireDataWindow", + &psppire_data_window_info, 0); + } + + return psppire_data_window_type; +} + + +static void +psppire_data_window_finalize (GObject *object) +{ + PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (object); + + GObjectClass *class = G_OBJECT_GET_CLASS (object); + + GObjectClass *parent_class = g_type_class_peek_parent (class); + + g_object_unref (de->xml); + + + if (G_OBJECT_CLASS (parent_class)->finalize) + (*G_OBJECT_CLASS (parent_class)->finalize) (object); +} + + +static void +psppire_data_window_class_init (PsppireDataWindowClass *class) +{ +} + + +static void +psppire_data_window_base_init (PsppireDataWindowClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + + object_class->finalize = psppire_data_window_finalize; +} + + + +static void +psppire_data_window_base_finalize (PsppireDataWindowClass *class, + gpointer class_data) +{ +} + + + + + +extern PsppireVarStore *the_var_store; +extern struct dataset *the_dataset; +extern PsppireDataStore *the_data_store ; + + +static void +update_paste_menuitems (GtkWidget *w, gboolean x, gpointer data) +{ + PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data); + + GtkWidget * edit_paste = get_widget_assert (de->xml, "edit_paste"); + + gtk_widget_set_sensitive (edit_paste, x); +} + +static void +update_cut_copy_menuitems (GtkWidget *w, gboolean x, gpointer data) +{ + PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data); + + GtkWidget * edit_copy = get_widget_assert (de->xml, "edit_copy"); + GtkWidget * edit_cut = get_widget_assert (de->xml, "edit_cut"); + + gtk_widget_set_sensitive (edit_copy, x); + gtk_widget_set_sensitive (edit_cut, x); +} + +/* Run the EXECUTE command. */ +static void +execute (GtkMenuItem *mi, gpointer data) +{ + struct getl_interface *sss = create_syntax_string_source ("EXECUTE."); + + execute_syntax (sss); +} + +static void +transformation_change_callback (bool transformations_pending, + gpointer data) +{ + PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data); + + GtkWidget *menuitem = + get_widget_assert (de->xml, "transform_run-pending"); + GtkWidget *status_label = + get_widget_assert (de->xml, "case-counter-area"); + + gtk_widget_set_sensitive (menuitem, transformations_pending); + + + if ( transformations_pending) + gtk_label_set_text (GTK_LABEL (status_label), + _("Transformations Pending")); + else + gtk_label_set_text (GTK_LABEL (status_label), ""); +} + +/* Callback for when the dictionary changes its filter variable */ +static void +on_filter_change (GObject *o, gint filter_index, gpointer data) +{ + PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data); + + GtkWidget *filter_status_area = + get_widget_assert (de->xml, "filter-use-status-area"); + + if ( filter_index == -1 ) + { + gtk_label_set_text (GTK_LABEL (filter_status_area), _("Filter off")); + } + else + { + PsppireVarStore *vs = NULL; + struct variable *var ; + gchar *text ; + + g_object_get (de->data_editor, "var-store", &vs, NULL); + + var = psppire_dict_get_variable (vs->dict, filter_index); + + text = g_strdup_printf (_("Filter by %s"), var_get_name (var)); + + gtk_label_set_text (GTK_LABEL (filter_status_area), text); + + g_free (text); + } +} + +/* Callback for when the dictionary changes its split variables */ +static void +on_split_change (PsppireDict *dict, gpointer data) +{ + PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data); + + size_t n_split_vars = dict_get_split_cnt (dict->dict); + + GtkWidget *split_status_area = + get_widget_assert (de->xml, "split-file-status-area"); + + if ( n_split_vars == 0 ) + { + gtk_label_set_text (GTK_LABEL (split_status_area), _("No Split")); + } + else + { + gint i; + GString *text; + const struct variable *const * split_vars = + dict_get_split_vars (dict->dict); + + text = g_string_new (_("Split by ")); + + for (i = 0 ; i < n_split_vars - 1; ++i ) + { + g_string_append_printf (text, "%s, ", var_get_name (split_vars[i])); + } + g_string_append (text, var_get_name (split_vars[i])); + + gtk_label_set_text (GTK_LABEL (split_status_area), text->str); + + g_string_free (text, TRUE); + } +} + + + + +/* Callback for when the dictionary changes its weights */ +static void +on_weight_change (GObject *o, gint weight_index, gpointer data) +{ + PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data); + + GtkWidget *weight_status_area = + get_widget_assert (de->xml, "weight-status-area"); + + if ( weight_index == -1 ) + { + gtk_label_set_text (GTK_LABEL (weight_status_area), _("Weights off")); + } + else + { + struct variable *var ; + PsppireVarStore *vs = NULL; + gchar *text; + + g_object_get (de->data_editor, "var-store", &vs, NULL); + + var = psppire_dict_get_variable (vs->dict, weight_index); + + text = g_strdup_printf (_("Weight by %s"), var_get_name (var)); + + gtk_label_set_text (GTK_LABEL (weight_status_area), text); + + g_free (text); + } +} + +/* Puts FILE_NAME into the recent list. + If it's already in the list, it moves it to the top +*/ +static void +add_most_recent (const char *file_name) +{ +#if RECENT_LISTS_AVAILABLE + + GtkRecentManager *manager = gtk_recent_manager_get_default(); + gchar *uri = g_filename_to_uri (file_name, NULL, NULL); + + gtk_recent_manager_remove_item (manager, uri, NULL); + + if ( ! gtk_recent_manager_add_item (manager, uri)) + g_warning ("Could not add item %s to recent list\n",uri); + + g_free (uri); +#endif +} + +static void +open_data_file (const gchar *file_name, PsppireDataWindow *de) +{ + struct getl_interface *sss; + struct string filename; + + ds_init_empty (&filename); + syntax_gen_string (&filename, ss_cstr (file_name)); + + sss = create_syntax_string_source ("GET FILE=%s.", + ds_cstr (&filename)); + ds_destroy (&filename); + + if (execute_syntax (sss) ) + { + psppire_window_set_filename (PSPPIRE_WINDOW (de), file_name); + add_most_recent (file_name); + } +} + + +/* Callback for the data_open action. + Prompts for a filename and opens it */ +static void +open_data_dialog (GtkAction *action, PsppireDataWindow *de) +{ + GtkWidget *dialog = + gtk_file_chooser_dialog_new (_("Open"), + GTK_WINDOW (de), + GTK_FILE_CHOOSER_ACTION_OPEN, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, + NULL); + + GtkFileFilter *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"); + gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter); + + filter = gtk_file_filter_new (); + gtk_file_filter_set_name (filter, _("Portable Files (*.por) ")); + gtk_file_filter_add_pattern (filter, "*.por"); + 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, _("All Files")); + gtk_file_filter_add_pattern (filter, "*"); + gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter); + + + if (de->file_name) + { + gchar *dir_name = g_path_get_dirname (de->file_name); + gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), + dir_name); + free (dir_name); + } + + switch (gtk_dialog_run (GTK_DIALOG (dialog))) + { + case GTK_RESPONSE_ACCEPT: + { + g_free (de->file_name); + de->file_name = + gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); + + open_data_file (de->file_name, de); + } + break; + default: + break; + } + + gtk_widget_destroy (dialog); +} + +/* Returns true if NAME has a suffix which might denote a PSPP file */ +static gboolean +name_has_suffix (const gchar *name) +{ + if ( g_str_has_suffix (name, ".sav")) + return TRUE; + if ( g_str_has_suffix (name, ".SAV")) + return TRUE; + if ( g_str_has_suffix (name, ".por")) + return TRUE; + if ( g_str_has_suffix (name, ".POR")) + return TRUE; + + return FALSE; +} + + +/* Append SUFFIX to the filename of DE */ +static void +append_filename_suffix (PsppireDataWindow *de, const gchar *suffix) +{ + if ( ! name_has_suffix (de->file_name)) + { + gchar *s = de->file_name; + de->file_name = g_strconcat (de->file_name, suffix, NULL); + g_free (s); + } +} + +/* Save DE to file */ +static void +save_file (PsppireDataWindow *de) +{ + struct getl_interface *sss; + struct string file_name ; + + g_assert (de->file_name); + + ds_init_empty (&file_name); + syntax_gen_string (&file_name, ss_cstr (de->file_name)); + + if ( de->save_as_portable ) + { + append_filename_suffix (de, ".por"); + sss = create_syntax_string_source ("EXPORT OUTFILE=%s.", + ds_cstr (&file_name)); + } + else + { + append_filename_suffix (de, ".sav"); + sss = create_syntax_string_source ("SAVE OUTFILE=%s.", + ds_cstr (&file_name)); + } + + ds_destroy (&file_name); + + execute_syntax (sss); +} + + +static void +insert_case (GtkAction *action, gpointer data) +{ + PsppireDataWindow *dw = PSPPIRE_DATA_WINDOW (data); + + psppire_data_editor_insert_case (dw->data_editor); +} + +static void +on_insert_variable (GtkAction *action, gpointer data) +{ + PsppireDataEditor *de = PSPPIRE_DATA_EDITOR (data); + psppire_data_editor_insert_variable (de); +} + + +/* Callback for data_save_as action. Prompt for a filename and save */ +static void +data_save_as_dialog (GtkAction *action, PsppireDataWindow *de) +{ + GtkWidget *button_sys; + GtkWidget *dialog = + gtk_file_chooser_dialog_new (_("Save"), + GTK_WINDOW (de), + GTK_FILE_CHOOSER_ACTION_SAVE, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, + NULL); + + GtkFileFilter *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"); + gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter); + + filter = gtk_file_filter_new (); + gtk_file_filter_set_name (filter, _("Portable Files (*.por) ")); + gtk_file_filter_add_pattern (filter, "*.por"); + 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, _("All Files")); + gtk_file_filter_add_pattern (filter, "*"); + gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter); + + { + GtkWidget *button_por; + GtkWidget *vbox = gtk_vbox_new (TRUE, 5); + button_sys = + gtk_radio_button_new_with_label (NULL, _("System File")); + + button_por = + gtk_radio_button_new_with_label + (gtk_radio_button_get_group (GTK_RADIO_BUTTON(button_sys)), + _("Portable File")); + + gtk_box_pack_start_defaults (GTK_BOX (vbox), button_sys); + gtk_box_pack_start_defaults (GTK_BOX (vbox), button_por); + + gtk_widget_show_all (vbox); + + gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER(dialog), vbox); + } + + switch (gtk_dialog_run (GTK_DIALOG (dialog))) + { + case GTK_RESPONSE_ACCEPT: + { + g_free (de->file_name); + + de->file_name = + gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); + + de->save_as_portable = + ! gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button_sys)); + + if ( de->save_as_portable) + append_filename_suffix (de, ".por"); + else + append_filename_suffix (de, ".sav"); + + save_file (de); + + psppire_window_set_filename (PSPPIRE_WINDOW (de), de->file_name); + } + break; + default: + break; + } + + gtk_widget_destroy (dialog); +} + + +/* Callback for data_save action. + If there's an existing file name, then just save, + otherwise prompt for a file name, then save */ +static void +data_save (GtkAction *action, PsppireDataWindow *de) +{ + if ( de->file_name) + save_file (de); + else + data_save_as_dialog (action, de); +} + + +/* Callback for data_new action. + Performs the NEW FILE command */ +static void +new_file (GtkAction *action, PsppireDataWindow *de) +{ + struct getl_interface *sss = + create_syntax_string_source ("NEW FILE."); + + execute_syntax (sss); + + g_free (de->file_name); + de->file_name = NULL; + + psppire_window_set_filename (PSPPIRE_WINDOW (de), NULL); +} + + + +/* Create the GtkActions and connect to their signals */ +static void +register_data_editor_actions (PsppireDataWindow *de) +{ + de->action_data_open = + gtk_action_new ("data-open-dialog", + _("Open"), + _("Open a data file"), + "gtk-open"); + + g_signal_connect (de->action_data_open, "activate", + G_CALLBACK (open_data_dialog), de); + + + de->action_data_save = gtk_action_new ("data-save", + _("Save"), + _("Save data to file"), + "gtk-save"); + + g_signal_connect (de->action_data_save, "activate", + G_CALLBACK (data_save), de); + + + de->action_data_save_as = gtk_action_new ("data-save-as-dialog", + _("Save As"), + _("Save data to file"), + "gtk-save"); + + g_signal_connect (de->action_data_save_as, "activate", + G_CALLBACK (data_save_as_dialog), de); + + de->action_data_new = + gtk_action_new ("data-new", + _("New"), + _("New data file"), + NULL); + + g_signal_connect (de->action_data_new, "activate", + G_CALLBACK (new_file), de); + + de->invoke_text_import_assistant = + gtk_action_new ("file_import-text", + _("_Import Text Data"), + _("Import text data file"), + ""); + + g_signal_connect (de->invoke_text_import_assistant, "activate", + G_CALLBACK (text_data_import_assistant), de); +} + +static void +on_edit_paste (GtkAction *a, gpointer data) +{ + PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data); + + psppire_data_editor_clip_paste (de->data_editor); +} + +static void +on_edit_copy (GtkMenuItem *m, gpointer data) +{ + PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data); + + psppire_data_editor_clip_copy (de->data_editor); +} + + + +static void +on_edit_cut (GtkMenuItem *m, gpointer data) +{ + PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data); + + psppire_data_editor_clip_cut (de->data_editor); +} + + +static void +status_bar_activate (GtkCheckMenuItem *menuitem, gpointer data) +{ + PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data); + GtkWidget *statusbar = get_widget_assert (de->xml, "status-bar"); + + if ( gtk_check_menu_item_get_active (menuitem) ) + gtk_widget_show (statusbar); + else + gtk_widget_hide (statusbar); +} + + +static void +grid_lines_activate (GtkCheckMenuItem *menuitem, gpointer data) +{ + PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data); + const gboolean grid_visible = gtk_check_menu_item_get_active (menuitem); + + psppire_data_editor_show_grid (de->data_editor, grid_visible); +} + + + +static void +data_view_activate (GtkCheckMenuItem *menuitem, gpointer data) +{ + PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data); + + gtk_notebook_set_current_page (GTK_NOTEBOOK (de->data_editor), PSPPIRE_DATA_EDITOR_DATA_VIEW); +} + + +static void +variable_view_activate (GtkCheckMenuItem *menuitem, gpointer data) +{ + PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data); + + gtk_notebook_set_current_page (GTK_NOTEBOOK (de->data_editor), PSPPIRE_DATA_EDITOR_VARIABLE_VIEW); +} + + +static void +fonts_activate (GtkMenuItem *menuitem, gpointer data) +{ + PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data); + PangoFontDescription *current_font; + gchar *font_name; + GtkWidget *dialog = + gtk_font_selection_dialog_new (_("Font Selection")); + + + current_font = GTK_WIDGET(de->data_editor)->style->font_desc; + font_name = pango_font_description_to_string (current_font); + + gtk_font_selection_dialog_set_font_name (GTK_FONT_SELECTION_DIALOG (dialog), font_name); + + g_free (font_name); + + gtk_window_set_transient_for (GTK_WINDOW (dialog), + GTK_WINDOW (get_widget_assert (de->xml, + "data_editor"))); + if ( GTK_RESPONSE_OK == gtk_dialog_run (GTK_DIALOG (dialog)) ) + { + const gchar *font = gtk_font_selection_dialog_get_font_name + (GTK_FONT_SELECTION_DIALOG (dialog)); + + PangoFontDescription* font_desc = + pango_font_description_from_string (font); + + psppire_data_editor_set_font (de->data_editor, font_desc); + } + + gtk_widget_hide (dialog); +} + + + +/* Callback for the value labels action */ +static void +toggle_value_labels (GtkToggleAction *ta, gpointer data) +{ + PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data); + + g_object_set (de->data_editor, "value-labels", gtk_toggle_action_get_active (ta), NULL); +} + +static void +toggle_split_window (GtkToggleAction *ta, gpointer data) +{ + PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data); + + psppire_data_editor_split_window (de->data_editor, + gtk_toggle_action_get_active (ta)); +} + + +static void +file_quit (GtkCheckMenuItem *menuitem, gpointer data) +{ + /* FIXME: Need to be more intelligent here. + Give the user the opportunity to save any unsaved data. + */ + g_object_unref (the_data_store); + gtk_main_quit (); +} + + + +static GtkWidget * +create_data_sheet_variable_popup_menu (PsppireDataWindow *de) +{ + GtkWidget *menu = gtk_menu_new (); + + GtkWidget *sort_ascending = + gtk_menu_item_new_with_label (_("Sort Ascending")); + + GtkWidget *sort_descending = + gtk_menu_item_new_with_label (_("Sort Descending")); + + GtkWidget *insert_variable = + gtk_menu_item_new_with_label (_("Insert Variable")); + + GtkWidget *clear_variable = + gtk_menu_item_new_with_label (_("Clear")); + + + gtk_action_connect_proxy (de->delete_variables, + clear_variable ); + + + gtk_menu_shell_append (GTK_MENU_SHELL (menu), insert_variable); + + + gtk_menu_shell_append (GTK_MENU_SHELL (menu), + gtk_separator_menu_item_new ()); + + + gtk_menu_shell_append (GTK_MENU_SHELL (menu), clear_variable); + + + gtk_menu_shell_append (GTK_MENU_SHELL (menu), + gtk_separator_menu_item_new ()); + + + gtk_menu_shell_append (GTK_MENU_SHELL (menu), sort_ascending); + + + g_signal_connect_swapped (G_OBJECT (sort_ascending), "activate", + G_CALLBACK (psppire_data_editor_sort_ascending), + de->data_editor); + + g_signal_connect_swapped (G_OBJECT (sort_descending), "activate", + G_CALLBACK (psppire_data_editor_sort_descending), + de->data_editor); + + g_signal_connect_swapped (G_OBJECT (insert_variable), "activate", + G_CALLBACK (gtk_action_activate), + de->insert_variable); + + + gtk_menu_shell_append (GTK_MENU_SHELL (menu), sort_descending); + + gtk_widget_show_all (menu); + + return menu; +} + + +static GtkWidget * +create_data_sheet_cases_popup_menu (PsppireDataWindow *de) +{ + GtkWidget *menu = gtk_menu_new (); + + GtkWidget *insert_case = + gtk_menu_item_new_with_label (_("Insert Case")); + + GtkWidget *delete_case = + gtk_menu_item_new_with_label (_("Clear")); + + + gtk_action_connect_proxy (de->delete_cases, + delete_case); + + + gtk_menu_shell_append (GTK_MENU_SHELL (menu), insert_case); + + g_signal_connect_swapped (G_OBJECT (insert_case), "activate", + G_CALLBACK (gtk_action_activate), + de->insert_case); + + + gtk_menu_shell_append (GTK_MENU_SHELL (menu), + gtk_separator_menu_item_new ()); + + + gtk_menu_shell_append (GTK_MENU_SHELL (menu), delete_case); + + + gtk_widget_show_all (menu); + + return menu; +} + + +static GtkWidget * +create_var_sheet_variable_popup_menu (PsppireDataWindow *de) +{ + GtkWidget *menu = gtk_menu_new (); + + GtkWidget *insert_variable = + gtk_menu_item_new_with_label (_("Insert Variable")); + + GtkWidget *delete_variable = + gtk_menu_item_new_with_label (_("Clear")); + + + gtk_action_connect_proxy (de->delete_variables, + delete_variable); + + + gtk_menu_shell_append (GTK_MENU_SHELL (menu), insert_variable); + + g_signal_connect_swapped (G_OBJECT (insert_variable), "activate", + G_CALLBACK (gtk_action_activate), + de->insert_variable); + + + gtk_menu_shell_append (GTK_MENU_SHELL (menu), + gtk_separator_menu_item_new ()); + + + gtk_menu_shell_append (GTK_MENU_SHELL (menu), delete_variable); + + + gtk_widget_show_all (menu); + + return menu; +} + + +#if RECENT_LISTS_AVAILABLE + +static void +on_recent_data_select (GtkMenuShell *menushell, gpointer user_data) +{ + gchar *file; + PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (user_data); + + gchar *uri = + gtk_recent_chooser_get_current_uri (GTK_RECENT_CHOOSER (menushell)); + + file = g_filename_from_uri (uri, NULL, NULL); + + g_free (uri); + + open_data_file (file, de); + + g_free (file); +} + +static void +on_recent_files_select (GtkMenuShell *menushell, gpointer user_data) +{ + gchar *file; + + GtkWidget *se ; + + gchar *uri = + gtk_recent_chooser_get_current_uri (GTK_RECENT_CHOOSER (menushell)); + + file = g_filename_from_uri (uri, NULL, NULL); + + g_free (uri); + + se = psppire_syntax_window_new (); + + psppire_syntax_window_load_from_file (PSPPIRE_SYNTAX_WINDOW (se), file, NULL); + gtk_widget_show (se); + + g_free (file); +} + +#endif + +static void +enable_delete_cases (GtkWidget *w, gint case_num, gpointer data) +{ + PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data); + + gtk_action_set_visible (de->delete_cases, case_num != -1); +} + + +static void +enable_delete_variables (GtkWidget *w, gint var, gpointer data) +{ + PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data); + + gtk_action_set_visible (de->delete_variables, var != -1); +} + +/* Callback for when the datasheet/varsheet is selected */ +static void +on_switch_sheet (GtkNotebook *notebook, + GtkNotebookPage *page, + guint page_num, + gpointer user_data) +{ + PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (user_data); + + GtkWidget *view_data = get_widget_assert (de->xml, "view_data"); + GtkWidget *view_variables = get_widget_assert (de->xml, "view_variables"); + + switch (page_num) + { + case PSPPIRE_DATA_EDITOR_VARIABLE_VIEW: + gtk_widget_hide (view_variables); + gtk_widget_show (view_data); + gtk_action_set_sensitive (de->insert_variable, TRUE); + gtk_action_set_sensitive (de->insert_case, FALSE); + gtk_action_set_sensitive (de->invoke_goto_dialog, FALSE); + break; + case PSPPIRE_DATA_EDITOR_DATA_VIEW: + gtk_widget_show (view_variables); + gtk_widget_hide (view_data); + gtk_action_set_sensitive (de->invoke_goto_dialog, TRUE); + gtk_action_set_sensitive (de->insert_case, TRUE); + break; + default: + g_assert_not_reached (); + break; + } + +#if 0 + update_paste_menuitem (de, page_num); +#endif +} + + + + +static void +psppire_data_window_init (PsppireDataWindow *de) +{ + PsppireVarStore *vs; + + GtkWidget *menubar; + GtkWidget *hb ; + GtkWidget *sb ; + + GtkWidget *box = gtk_vbox_new (FALSE, 0); + de->xml = XML_NEW ("data-editor.glade"); + + menubar = get_widget_assert (de->xml, "menubar"); + hb = get_widget_assert (de->xml, "handlebox1"); + sb = get_widget_assert (de->xml, "status-bar"); + + de->data_editor = + PSPPIRE_DATA_EDITOR (psppire_data_editor_new (the_var_store, the_data_store)); + + connect_help (de->xml); + + g_object_ref (menubar); + gtk_widget_unparent (menubar); + + g_object_ref (hb); + gtk_widget_unparent (hb); + + g_object_ref (sb); + gtk_widget_unparent (sb); + + gtk_box_pack_start (GTK_BOX (box), menubar, FALSE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (box), hb, FALSE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (box), GTK_WIDGET (de->data_editor), TRUE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (box), sb, FALSE, TRUE, 0); + + gtk_container_add (GTK_CONTAINER (de), box); + + g_signal_connect (de->data_editor, "data-selection-changed", + G_CALLBACK (update_cut_copy_menuitems), de); + + g_signal_connect (de->data_editor, "data-available-changed", + G_CALLBACK (update_paste_menuitems), de); + + dataset_add_transform_change_callback (the_dataset, + transformation_change_callback, + de); + + + vs = the_var_store; + + g_assert(vs); /* Traps a possible bug in w32 build */ + + g_signal_connect (vs->dict, "weight-changed", + G_CALLBACK (on_weight_change), + de); + + g_signal_connect (vs->dict, "filter-changed", + G_CALLBACK (on_filter_change), + de); + + g_signal_connect (vs->dict, "split-changed", + G_CALLBACK (on_split_change), + de); + + + g_signal_connect (get_widget_assert (de->xml, "edit_copy"), + "activate", + G_CALLBACK (on_edit_copy), de); + + g_signal_connect (get_widget_assert (de->xml, "edit_cut"), + "activate", + G_CALLBACK (on_edit_cut), de); + + + register_data_editor_actions (de); + + de->toggle_value_labels = + gtk_toggle_action_new ("toggle-value-labels", + _("_Labels"), + _("Show/hide value labels"), + "pspp-value-labels"); + + g_signal_connect (de->toggle_value_labels, "toggled", + G_CALLBACK (toggle_value_labels), de); + + + gtk_action_connect_proxy (GTK_ACTION (de->toggle_value_labels), + get_widget_assert (de->xml, + "togglebutton-value-labels")); + + + gtk_action_connect_proxy (GTK_ACTION (de->toggle_value_labels), + get_widget_assert (de->xml, + "view_value-labels")); + + + + de->delete_cases = + gtk_action_new ("clear-cases", + _("Clear"), + _("Delete the cases at the selected position(s)"), + "pspp-clear-cases"); + + g_signal_connect_swapped (de->delete_cases, "activate", + G_CALLBACK (psppire_data_editor_delete_cases), + de->data_editor); + + gtk_action_connect_proxy (de->delete_cases, + get_widget_assert (de->xml, "edit_clear-cases")); + + g_signal_connect (get_widget_assert (de->xml, "edit_paste"), "activate", + G_CALLBACK (on_edit_paste), + de); + + gtk_action_set_visible (de->delete_cases, FALSE); + + de->delete_variables = + gtk_action_new ("clear-variables", + _("Clear"), + _("Delete the variables at the selected position(s)"), + "pspp-clear-variables"); + + g_signal_connect_swapped (de->delete_variables, "activate", + G_CALLBACK (psppire_data_editor_delete_variables), + de->data_editor); + + gtk_action_connect_proxy (de->delete_variables, + get_widget_assert (de->xml, "edit_clear-variables") + ); + + gtk_action_set_visible (de->delete_variables, FALSE); + + de->insert_variable = + gtk_action_new ("insert-variable", + _("Insert _Variable"), + _("Create a new variable at the current position"), + "pspp-insert-variable"); + + g_signal_connect (de->insert_variable, "activate", + G_CALLBACK (on_insert_variable), de->data_editor); + + + gtk_action_connect_proxy (de->insert_variable, + get_widget_assert (de->xml, "button-insert-variable") + ); + + gtk_action_connect_proxy (de->insert_variable, + get_widget_assert (de->xml, "edit_insert-variable") + ); + + + de->insert_case = + gtk_action_new ("insert-case", + _("Insert Ca_se"), + _("Create a new case at the current position"), + "pspp-insert-case"); + + g_signal_connect (de->insert_case, "activate", + G_CALLBACK (insert_case), de); + + + gtk_action_connect_proxy (de->insert_case, + get_widget_assert (de->xml, "button-insert-case") + ); + + + gtk_action_connect_proxy (de->insert_case, + get_widget_assert (de->xml, "edit_insert-case") + ); + + + de->invoke_goto_dialog = + gtk_action_new ("goto-case-dialog", + _("_Goto Case"), + _("Jump to a Case in the Data Sheet"), + "gtk-jump-to"); + + + gtk_action_connect_proxy (de->invoke_goto_dialog, + get_widget_assert (de->xml, "button-goto-case") + ); + + gtk_action_connect_proxy (de->invoke_goto_dialog, + get_widget_assert (de->xml, "edit_goto-case") + ); + + + g_signal_connect (de->invoke_goto_dialog, "activate", + G_CALLBACK (goto_case_dialog), de); + + de->invoke_weight_cases_dialog = + gtk_action_new ("weight-cases-dialog", + _("_Weights"), + _("Weight cases by variable"), + "pspp-weight-cases"); + + g_signal_connect (de->invoke_weight_cases_dialog, "activate", + G_CALLBACK (weight_cases_dialog), de); + + + de->invoke_transpose_dialog = + gtk_action_new ("transpose-dialog", + _("_Transpose"), + _("Transpose the cases with the variables"), + NULL); + + + g_signal_connect (de->invoke_transpose_dialog, "activate", + G_CALLBACK (transpose_dialog), de); + + + + de->invoke_split_file_dialog = + gtk_action_new ("split-file-dialog", + _("S_plit"), + _("Split the active file"), + "pspp-split-file"); + + g_signal_connect (de->invoke_split_file_dialog, "activate", + G_CALLBACK (split_file_dialog), de); + + + + de->invoke_sort_cases_dialog = + gtk_action_new ("sort-cases-dialog", + _("_Sort"), + _("Sort cases in the active file"), + "pspp-sort-cases"); + + g_signal_connect (de->invoke_sort_cases_dialog, "activate", + G_CALLBACK (sort_cases_dialog), de); + + de->invoke_select_cases_dialog = + gtk_action_new ("select-cases-dialog", + _("Select _Cases"), + _("Select cases from the active file"), + "pspp-select-cases"); + + g_signal_connect (de->invoke_select_cases_dialog, "activate", + G_CALLBACK (select_cases_dialog), de); + + + de->invoke_compute_dialog = + gtk_action_new ("compute-dialog", + _("_Compute"), + _("Compute new values for a variable"), + "pspp-compute"); + + g_signal_connect (de->invoke_compute_dialog, "activate", + G_CALLBACK (compute_dialog), de); + + de->invoke_oneway_anova_dialog = + gtk_action_new ("oneway-anova", + _("Oneway _ANOVA"), + _("Perform one way analysis of variance"), + NULL); + + g_signal_connect (de->invoke_oneway_anova_dialog, "activate", + G_CALLBACK (oneway_anova_dialog), de); + + de->invoke_t_test_independent_samples_dialog = + gtk_action_new ("t-test-independent-samples", + _("_Independent Samples T Test"), + _("Calculate T Test for samples from independent groups"), + NULL); + + g_signal_connect (de->invoke_t_test_independent_samples_dialog, "activate", + G_CALLBACK (t_test_independent_samples_dialog), de); + + + de->invoke_t_test_paired_samples_dialog = + gtk_action_new ("t-test-paired-samples", + _("_Paired Samples T Test"), + _("Calculate T Test for paired samples"), + NULL); + + g_signal_connect (de->invoke_t_test_paired_samples_dialog, "activate", + G_CALLBACK (t_test_paired_samples_dialog), de); + + + de->invoke_t_test_one_sample_dialog = + gtk_action_new ("t-test-one-sample", + _("One _Sample T Test"), + _("Calculate T Test for sample from a single distribution"), + NULL); + + g_signal_connect (de->invoke_t_test_one_sample_dialog, "activate", + G_CALLBACK (t_test_one_sample_dialog), de); + + + de->invoke_comments_dialog = + gtk_action_new ("commments-dialog", + _("Data File _Comments"), + _("Commentary text for the data file"), + NULL); + + g_signal_connect (de->invoke_comments_dialog, "activate", + G_CALLBACK (comments_dialog), de); + + de->invoke_find_dialog = + gtk_action_new ("find-dialog", + _("_Find"), + _("Find Case"), + "gtk-find"); + + g_signal_connect (de->invoke_find_dialog, "activate", + G_CALLBACK (find_dialog), de); + + + de->invoke_rank_dialog = + gtk_action_new ("rank-dialog", + _("Ran_k Cases"), + _("Rank Cases"), + "pspp-rank-cases"); + + g_signal_connect (de->invoke_rank_dialog, "activate", + G_CALLBACK (rank_dialog), de); + + + de->invoke_recode_same_dialog = + gtk_action_new ("recode-same-dialog", + _("Recode into _Same Variables"), + _("Recode values into the same Variables"), + "pspp-recode-same"); + + g_signal_connect (de->invoke_recode_same_dialog, "activate", + G_CALLBACK (recode_same_dialog), de); + + + de->invoke_recode_different_dialog = + gtk_action_new ("recode-different-dialog", + _("Recode into _Different Variables"), + _("Recode values into different Variables"), + "pspp-recode-different"); + + g_signal_connect (de->invoke_recode_different_dialog, "activate", + G_CALLBACK (recode_different_dialog), de); + + + de->invoke_variable_info_dialog = + gtk_action_new ("variable-info-dialog", + _("_Variables"), + _("Jump to Variable"), + "pspp-goto-variable"); + + g_signal_connect (de->invoke_variable_info_dialog, "activate", + G_CALLBACK (variable_info_dialog), de); + + de->invoke_descriptives_dialog = + gtk_action_new ("descriptives-dialog", + _("_Descriptives"), + _("Calculate descriptive statistics (mean, variance, ...)"), + "pspp-descriptives"); + + g_signal_connect (de->invoke_descriptives_dialog, "activate", + G_CALLBACK (descriptives_dialog), de); + + + de->invoke_frequencies_dialog = + gtk_action_new ("frequencies-dialog", + _("_Frequencies"), + _("Generate frequency statistics"), + "pspp-frequencies"); + + g_signal_connect (de->invoke_frequencies_dialog, "activate", + G_CALLBACK (frequencies_dialog), de); + + de->invoke_crosstabs_dialog = + gtk_action_new ("crosstabs-dialog", + _("_Crosstabs"), + _("Generate crosstabulations"), + "pspp-crosstabs"); + + g_signal_connect (de->invoke_crosstabs_dialog, "activate", + G_CALLBACK (crosstabs_dialog), de); + + + de->invoke_examine_dialog = + gtk_action_new ("examine-dialog", + _("_Explore"), + _("Examine Data by Factors"), + "pspp-examine"); + + g_signal_connect (de->invoke_examine_dialog, "activate", + G_CALLBACK (examine_dialog), de); + + + de->invoke_regression_dialog = + gtk_action_new ("regression-dialog", + _("Linear _Regression"), + _("Estimate parameters of the linear model"), + "pspp-regression"); + + g_signal_connect (de->invoke_regression_dialog, "activate", + G_CALLBACK (regression_dialog), de); + + g_signal_connect_swapped (get_widget_assert (de->xml,"file_new_data"), + "activate", + G_CALLBACK (gtk_action_activate), + de->action_data_new); + + g_signal_connect_swapped (get_widget_assert (de->xml,"file_open_data"), + "activate", + G_CALLBACK (gtk_action_activate), + de->action_data_open); + +#if RECENT_LISTS_AVAILABLE + { + GtkRecentManager *rm = gtk_recent_manager_get_default (); + GtkWidget *recent_data = get_widget_assert (de->xml, "file_recent-data"); + GtkWidget *recent_files = get_widget_assert (de->xml, "file_recent-files"); + GtkWidget *recent_separator = get_widget_assert (de->xml, "file_separator1"); + + GtkWidget *menu = gtk_recent_chooser_menu_new_for_manager (rm); + + GtkRecentFilter *filter = gtk_recent_filter_new (); + + gtk_widget_show (recent_data); + gtk_widget_show (recent_files); + gtk_widget_show (recent_separator); + + gtk_recent_filter_add_pattern (filter, "*.sav"); + gtk_recent_filter_add_pattern (filter, "*.SAV"); + + gtk_recent_chooser_add_filter (GTK_RECENT_CHOOSER (menu), filter); + + gtk_widget_set_sensitive (recent_data, TRUE); + g_signal_connect (menu, "selection-done", + G_CALLBACK (on_recent_data_select), de); + + gtk_menu_item_set_submenu (GTK_MENU_ITEM (recent_data), menu); + + + filter = gtk_recent_filter_new (); + menu = gtk_recent_chooser_menu_new_for_manager (rm); + + gtk_recent_filter_add_pattern (filter, "*.sps"); + gtk_recent_filter_add_pattern (filter, "*.SPS"); + + gtk_recent_chooser_add_filter (GTK_RECENT_CHOOSER (menu), filter); + + gtk_widget_set_sensitive (recent_files, TRUE); + g_signal_connect (menu, "selection-done", + G_CALLBACK (on_recent_files_select), de); + + gtk_menu_item_set_submenu (GTK_MENU_ITEM (recent_files), menu); + } +#endif + + g_signal_connect (get_widget_assert (de->xml,"file_new_syntax"), + "activate", + G_CALLBACK (create_syntax_window), + NULL); + + g_signal_connect (get_widget_assert (de->xml,"file_open_syntax"), + "activate", + G_CALLBACK (open_syntax_window), + de); + + g_signal_connect_swapped (get_widget_assert (de->xml,"file_import-text"), + "activate", + G_CALLBACK (gtk_action_activate), + de->invoke_text_import_assistant); + + g_signal_connect_swapped (get_widget_assert (de->xml,"file_save"), + "activate", + G_CALLBACK (gtk_action_activate), + de->action_data_save); + + g_signal_connect_swapped (get_widget_assert (de->xml,"file_save_as"), + "activate", + G_CALLBACK (gtk_action_activate), + de->action_data_save_as); + + gtk_action_connect_proxy (de->invoke_find_dialog, + get_widget_assert (de->xml, "edit_find") + ); + + gtk_action_connect_proxy (de->invoke_find_dialog, + get_widget_assert (de->xml, "button-find") + ); + + gtk_action_connect_proxy (de->invoke_rank_dialog, + get_widget_assert (de->xml, "transform_rank") + ); + + gtk_action_connect_proxy (de->invoke_recode_same_dialog, + get_widget_assert (de->xml, + "transform_recode-same") + ); + + gtk_action_connect_proxy (de->invoke_recode_different_dialog, + get_widget_assert (de->xml, + "transform_recode-different") + ); + + gtk_action_connect_proxy (de->invoke_weight_cases_dialog, + get_widget_assert (de->xml, "data_weight-cases") + ); + + gtk_action_connect_proxy (de->invoke_transpose_dialog, + get_widget_assert (de->xml, "data_transpose") + ); + + gtk_action_connect_proxy (de->invoke_split_file_dialog, + get_widget_assert (de->xml, "data_split-file") + ); + + gtk_action_connect_proxy (de->invoke_sort_cases_dialog, + get_widget_assert (de->xml, "data_sort-cases") + ); + + gtk_action_connect_proxy (de->invoke_select_cases_dialog, + get_widget_assert (de->xml, "data_select-cases") + ); + + gtk_action_connect_proxy (de->invoke_compute_dialog, + get_widget_assert (de->xml, "transform_compute") + ); + + gtk_action_connect_proxy (de->invoke_t_test_independent_samples_dialog, + get_widget_assert (de->xml, + "indep-t-test") + ); + + + gtk_action_connect_proxy (de->invoke_t_test_paired_samples_dialog, + get_widget_assert (de->xml, + "paired-t-test") + ); + + + gtk_action_connect_proxy (de->invoke_t_test_one_sample_dialog, + get_widget_assert (de->xml, + "one-sample-t-test") + ); + + + gtk_action_connect_proxy (de->invoke_oneway_anova_dialog, + get_widget_assert (de->xml, + "oneway-anova") + ); + + + gtk_action_connect_proxy (de->invoke_comments_dialog, + get_widget_assert (de->xml, "utilities_comments") + ); + + gtk_action_connect_proxy (de->invoke_variable_info_dialog, + get_widget_assert (de->xml, "utilities_variables") + ); + + gtk_action_connect_proxy (de->invoke_descriptives_dialog, + get_widget_assert (de->xml, "analyze_descriptives") + ); + + gtk_action_connect_proxy (de->invoke_crosstabs_dialog, + get_widget_assert (de->xml, "crosstabs") + ); + + gtk_action_connect_proxy (de->invoke_frequencies_dialog, + get_widget_assert (de->xml, "analyze_frequencies") + ); + + + gtk_action_connect_proxy (de->invoke_examine_dialog, + get_widget_assert (de->xml, "analyze_explore") + ); + + gtk_action_connect_proxy (de->invoke_regression_dialog, + get_widget_assert (de->xml, "linear-regression") + ); + + g_signal_connect (get_widget_assert (de->xml,"help_about"), + "activate", + G_CALLBACK (about_new), + de); + + + g_signal_connect (get_widget_assert (de->xml,"help_reference"), + "activate", + G_CALLBACK (reference_manual), + de); + + + g_signal_connect (de->data_editor, + "cases-selected", + G_CALLBACK (enable_delete_cases), + de); + + g_signal_connect (de->data_editor, + "variables-selected", + G_CALLBACK (enable_delete_variables), + de); + + + g_signal_connect (GTK_NOTEBOOK (de->data_editor), + "switch-page", + G_CALLBACK (on_switch_sheet), de); + + gtk_notebook_set_current_page (GTK_NOTEBOOK (de->data_editor), PSPPIRE_DATA_EDITOR_VARIABLE_VIEW); + gtk_notebook_set_current_page (GTK_NOTEBOOK (de->data_editor), PSPPIRE_DATA_EDITOR_DATA_VIEW); + + g_signal_connect (get_widget_assert (de->xml, "view_statusbar"), + "activate", + G_CALLBACK (status_bar_activate), de); + + + g_signal_connect (get_widget_assert (de->xml, "view_gridlines"), + "activate", + G_CALLBACK (grid_lines_activate), de); + + + + g_signal_connect (get_widget_assert (de->xml, "view_data"), + "activate", + G_CALLBACK (data_view_activate), de); + + g_signal_connect (get_widget_assert (de->xml, "view_variables"), + "activate", + G_CALLBACK (variable_view_activate), de); + + + + g_signal_connect (get_widget_assert (de->xml, "view_fonts"), + "activate", + G_CALLBACK (fonts_activate), de); + + + + + gtk_action_connect_proxy (de->action_data_open, + get_widget_assert (de->xml, "button-open") + ); + + gtk_action_connect_proxy (de->action_data_save, + get_widget_assert (de->xml, "button-save") + ); + + gtk_action_connect_proxy (de->invoke_variable_info_dialog, + get_widget_assert (de->xml, "button-goto-variable") + ); + + gtk_action_connect_proxy (de->invoke_weight_cases_dialog, + get_widget_assert (de->xml, "button-weight-cases") + ); + + gtk_action_connect_proxy (de->invoke_split_file_dialog, + get_widget_assert (de->xml, "button-split-file") + ); + + gtk_action_connect_proxy (de->invoke_select_cases_dialog, + get_widget_assert (de->xml, "button-select-cases") + ); + + + g_signal_connect (get_widget_assert (de->xml, "file_quit"), + "activate", + G_CALLBACK (file_quit), de); + + g_signal_connect (get_widget_assert (de->xml, "transform_run-pending"), + "activate", + G_CALLBACK (execute), de); + + + g_signal_connect (get_widget_assert (de->xml, "windows_minimise_all"), + "activate", + G_CALLBACK (psppire_window_minimise_all), NULL); + + de->toggle_split_window = + gtk_toggle_action_new ("toggle-split-window", + _("_Split Window"), + _("Split the window vertically and horizontally"), + "pspp-split-window"); + + g_signal_connect (de->toggle_split_window, "toggled", + G_CALLBACK (toggle_split_window), + de); + + gtk_action_connect_proxy (GTK_ACTION (de->toggle_split_window), + get_widget_assert (de->xml, + "windows_split")); + + de->data_sheet_variable_popup_menu = + GTK_MENU (create_data_sheet_variable_popup_menu (de)); + + de->var_sheet_variable_popup_menu = + GTK_MENU (create_var_sheet_variable_popup_menu (de)); + + de->data_sheet_cases_popup_menu = + GTK_MENU (create_data_sheet_cases_popup_menu (de)); + + PSPPIRE_WINDOW (de)->menu = GTK_MENU_SHELL (get_widget_assert (de->xml,"Windows_menu")); + + g_object_set (de->data_editor, + "datasheet-column-menu", de->data_sheet_variable_popup_menu, + "datasheet-row-menu", de->data_sheet_cases_popup_menu, + "varsheet-row-menu", de->var_sheet_variable_popup_menu, + NULL); + + gtk_widget_show (GTK_WIDGET (de->data_editor)); + gtk_widget_show (box); +} + + +GtkWidget* +psppire_data_window_new (void) +{ + return GTK_WIDGET (g_object_new (psppire_data_window_get_type (), + "usage", PSPPIRE_WINDOW_USAGE_DATA, + NULL)); +} + diff --git a/src/ui/gui/psppire-data-window.h b/src/ui/gui/psppire-data-window.h new file mode 100644 index 00000000..77687dc9 --- /dev/null +++ b/src/ui/gui/psppire-data-window.h @@ -0,0 +1,120 @@ +/* PSPPIRE - a graphical user interface for PSPP. + Copyright (C) 2008 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 + 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, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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, see . */ + + +#ifndef __PSPPIRE_DATA_WINDOW_H__ +#define __PSPPIRE_DATA_WINDOW_H__ + + +#include +#include +#include +#include "psppire-window.h" +#include "psppire-data-editor.h" +#include +#include + +G_BEGIN_DECLS + +#define PSPPIRE_DATA_WINDOW_TYPE (psppire_data_window_get_type ()) +#define PSPPIRE_DATA_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PSPPIRE_DATA_WINDOW_TYPE, PsppireDataWindow)) +#define PSPPIRE_DATA_WINDOW_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), \ + PSPPIRE_DATA_WINDOW_TYPE, PsppireData_WindowClass)) +#define PSPPIRE_IS_DATA_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + PSPPIRE_DATA_WINDOW_TYPE)) +#define PSPPIRE_IS_DATA_WINDOW_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), \ + PSPPIRE_DATA_WINDOW_TYPE)) + + +typedef struct _PsppireDataWindow PsppireDataWindow; +typedef struct _PsppireDataWindowClass PsppireDataWindowClass; + + +struct _PsppireDataWindow +{ + PsppireWindow parent; + + /* */ + PsppireDataEditor *data_editor; + GladeXML *xml; + GtkAction *action_data_new; + GtkAction *action_data_open; + GtkAction *action_data_save_as; + GtkAction *action_data_save; + + GtkAction *invoke_text_import_assistant; + + /* Actions which invoke dialog boxes */ + GtkAction *invoke_weight_cases_dialog; + GtkAction *invoke_transpose_dialog; + GtkAction *invoke_split_file_dialog; + GtkAction *invoke_sort_cases_dialog; + GtkAction *invoke_compute_dialog; + GtkAction *invoke_comments_dialog; + GtkAction *invoke_select_cases_dialog; + GtkAction *invoke_goto_dialog; + GtkAction *invoke_variable_info_dialog; + GtkAction *invoke_find_dialog; + GtkAction *invoke_rank_dialog; + GtkAction *invoke_recode_same_dialog; + GtkAction *invoke_recode_different_dialog; + + GtkAction *invoke_crosstabs_dialog; + GtkAction *invoke_descriptives_dialog; + GtkAction *invoke_frequencies_dialog; + GtkAction *invoke_examine_dialog; + GtkAction *invoke_regression_dialog; + + GtkAction *invoke_t_test_independent_samples_dialog; + GtkAction *invoke_t_test_paired_samples_dialog; + GtkAction *invoke_oneway_anova_dialog; + GtkAction *invoke_t_test_one_sample_dialog; + + GtkToggleAction *toggle_split_window; + GtkToggleAction *toggle_value_labels; + + + GtkAction *insert_variable; + GtkAction *insert_case; + GtkAction *delete_variables; + GtkAction *delete_cases; + + + GtkMenu *data_sheet_variable_popup_menu; + GtkMenu *data_sheet_cases_popup_menu; + GtkMenu *var_sheet_variable_popup_menu; + + + gboolean save_as_portable; + + /* Name of the file this data is associated with (ie, was loaded from or + has been saved to), in "filename encoding", or NULL, if it's not + associated with any file */ + gchar *file_name; +}; + +struct _PsppireDataWindowClass +{ + PsppireWindowClass parent_class; +}; + +GType psppire_data_window_get_type (void); +GtkWidget* psppire_data_window_new (void); + + +G_END_DECLS + +#endif /* __PSPPIRE_DATA_WINDOW_H__ */ diff --git a/src/ui/gui/psppire-output-window.c b/src/ui/gui/psppire-output-window.c new file mode 100644 index 00000000..5fc52e9b --- /dev/null +++ b/src/ui/gui/psppire-output-window.c @@ -0,0 +1,376 @@ +/* PSPPIRE - a graphical user interface for PSPP. + Copyright (C) 2008 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 + 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, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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, see . */ + +#include + +#include +#include +#include +#include "helper.h" + +#include +#include + +#include "about.h" + +#include "psppire-output-window.h" + + +#include "xalloc.h" + +#include +#include +#include + +#include +#define _(msgid) gettext (msgid) +#define N_(msgid) msgid + + + +static void psppire_output_window_base_finalize (PsppireOutputWindowClass *, gpointer); +static void psppire_output_window_base_init (PsppireOutputWindowClass *class); +static void psppire_output_window_class_init (PsppireOutputWindowClass *class); +static void psppire_output_window_init (PsppireOutputWindow *window); + + +GType +psppire_output_window_get_type (void) +{ + static GType psppire_output_window_type = 0; + + if (!psppire_output_window_type) + { + static const GTypeInfo psppire_output_window_info = + { + sizeof (PsppireOutputWindowClass), + (GBaseInitFunc) psppire_output_window_base_init, + (GBaseFinalizeFunc) psppire_output_window_base_finalize, + (GClassInitFunc)psppire_output_window_class_init, + (GClassFinalizeFunc) NULL, + NULL, + sizeof (PsppireOutputWindow), + 0, + (GInstanceInitFunc) psppire_output_window_init, + }; + + psppire_output_window_type = + g_type_register_static (PSPPIRE_WINDOW_TYPE, "PsppireOutputWindow", + &psppire_output_window_info, 0); + } + + return psppire_output_window_type; +} + + +static void +psppire_output_window_finalize (GObject *object) +{ + GObjectClass *class = G_OBJECT_GET_CLASS (object); + + GObjectClass *parent_class = g_type_class_peek_parent (class); + + + if (G_OBJECT_CLASS (parent_class)->finalize) + (*G_OBJECT_CLASS (parent_class)->finalize) (object); + +} + + +static void +psppire_output_window_class_init (PsppireOutputWindowClass *class) +{ +} + + +static void +psppire_output_window_base_init (PsppireOutputWindowClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + + object_class->finalize = psppire_output_window_finalize; +} + + + +static void +psppire_output_window_base_finalize (PsppireOutputWindowClass *class, + gpointer class_data) +{ +} + + + + +static PsppireOutputWindow *the_output_viewer = NULL; + + +int viewer_length = 16; +int viewer_width = 59; + +/* Callback for the "delete" action (clicking the x on the top right + hand corner of the window) */ +static gboolean +on_delete (GtkWidget *w, GdkEvent *event, gpointer user_data) +{ + PsppireOutputWindow *ow = PSPPIRE_OUTPUT_WINDOW (user_data); + + gtk_widget_destroy (GTK_WIDGET (ow)); + + the_output_viewer = NULL; + + unlink (OUTPUT_FILE_NAME); + + return FALSE; +} + + + +static void +cancel_urgency (GtkWindow *window, gpointer data) +{ + gtk_window_set_urgency_hint (window, FALSE); +} +/* Sets width and length according to the new size + of the output window */ +static void +on_textview_resize (GtkWidget *widget, + GtkAllocation *allocation, + gpointer user_data) +{ + PangoContext * context ; + PangoLayout *layout ; + PangoRectangle logical; + GtkStyle *style; + gint right_margin, left_margin; + GtkTextView *text_view = GTK_TEXT_VIEW (widget); + + context = gtk_widget_create_pango_context (widget); + layout = pango_layout_new (context); + + style = gtk_widget_get_style (widget); + + pango_layout_set_font_description (layout, style->font_desc); + + /* Find the width of one character. We can use any character, because + the textview has a monospaced font */ + pango_layout_set_text (layout, "M", 1); + + pango_layout_get_extents (layout, NULL, &logical); + + left_margin = gtk_text_view_get_left_margin (text_view); + right_margin = gtk_text_view_get_right_margin (text_view); + + viewer_length = allocation->height / PANGO_PIXELS (logical.height); + viewer_width = (allocation->width - right_margin - left_margin) + / PANGO_PIXELS (logical.width); + + g_object_unref (G_OBJECT (layout)); + g_object_unref (G_OBJECT (context)); +} + + +static void +psppire_output_window_init (PsppireOutputWindow *window) +{ + GladeXML *xml = XML_NEW ("output-viewer.glade"); + + GtkWidget *box = gtk_vbox_new (FALSE, 0); + + GtkWidget *sw = get_widget_assert (xml, "scrolledwindow1"); + + GtkWidget *menubar = get_widget_assert (xml, "menubar1"); + + window->textview = get_widget_assert (xml, "output-viewer-textview"); + + + gtk_container_add (GTK_CONTAINER (window), box); + + + g_object_ref (menubar); + gtk_widget_unparent (menubar); + + g_object_ref (sw); + gtk_widget_unparent (sw); + + + gtk_box_pack_start (GTK_BOX (box), menubar, FALSE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (box), sw, TRUE, TRUE, 0); + + + gtk_widget_show_all (box); + + connect_help (xml); + + window->buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (window->textview)); + + g_signal_connect (window, + "focus-in-event", + G_CALLBACK (cancel_urgency), + NULL); + + { + /* Output uses ascii characters for tabular material. + So we need a monospaced font otherwise it'll look silly */ + PangoFontDescription *font_desc = + pango_font_description_from_string ("monospace"); + + gtk_widget_modify_font (window->textview, font_desc); + pango_font_description_free (font_desc); + } + + g_signal_connect (window->textview, "size-allocate", + G_CALLBACK (on_textview_resize), NULL); + + window->fp = NULL; + + g_signal_connect (get_widget_assert (xml,"help_about"), + "activate", + G_CALLBACK (about_new), + window); + + g_signal_connect (get_widget_assert (xml,"help_reference"), + "activate", + G_CALLBACK (reference_manual), + NULL); + + g_signal_connect (get_widget_assert (xml,"windows_minimise-all"), + "activate", + G_CALLBACK (psppire_window_minimise_all), + NULL); + + PSPPIRE_WINDOW (window)->menu = GTK_MENU_SHELL (get_widget_assert (xml,"windows_menu")); + + + g_object_unref (xml); + + g_signal_connect (window, "delete-event", + G_CALLBACK (on_delete), window); +} + + +GtkWidget* +psppire_output_window_new (void) +{ + return GTK_WIDGET (g_object_new (psppire_output_window_get_type (), + "usage", PSPPIRE_WINDOW_USAGE_OUTPUT, + NULL)); +} + +static void reload_viewer (PsppireOutputWindow *ow); + +void +psppire_output_window_reload (void) +{ + struct stat buf; + + /* If there is no output, then don't do anything */ + if (0 != stat (OUTPUT_FILE_NAME, &buf)) + return ; + + if ( NULL == the_output_viewer ) + { + the_output_viewer = PSPPIRE_OUTPUT_WINDOW (psppire_output_window_new ()); + gtk_widget_show (GTK_WIDGET (the_output_viewer)); + } + + reload_viewer (the_output_viewer); + +} + + +static void +reload_viewer (PsppireOutputWindow *ow) +{ + GtkTextIter end_iter; + GtkTextMark *mark ; + + static char *line = NULL; + + gboolean chars_inserted = FALSE; + + gtk_text_buffer_get_end_iter (ow->buffer, &end_iter); + + line = xrealloc (line, sizeof (char) * (viewer_width + 1)); + + mark = gtk_text_buffer_create_mark (ow->buffer, NULL, &end_iter, TRUE); + +#ifdef __CYGWIN__ + /* + Apparently Windoze is not capabale of writing to a file whilst + another (or the same) process is reading from it. Therefore, we + must close the file after reading it, and clear the entire buffer + before writing to it. + This will be slower for large buffers, but should work + (in so far as anything ever works on windows). + */ + { + GtkTextIter start_iter; + FILE *fp = fopen (OUTPUT_FILE_NAME, "r"); + if ( !fp) + { + g_print ("Cannot open %s\n", OUTPUT_FILE_NAME); + return; + } + + /* Delete all the entire buffer */ + gtk_text_buffer_get_start_iter (ov->buffer, &start_iter); + gtk_text_buffer_delete (ov->buffer, &start_iter, &end_iter); + + + gtk_text_buffer_get_start_iter (ov->buffer, &start_iter); + /* Read in the next lot of text */ + while (fgets (line, viewer_width + 1, fp) != NULL) + { + chars_inserted = TRUE; + gtk_text_buffer_insert (ov->buffer, &start_iter, line, -1); + } + + fclose (fp); + } +#else + { + if ( ow->fp == NULL) + { + ow->fp = fopen (OUTPUT_FILE_NAME, "r"); + if ( ow->fp == NULL) + { + g_print ("Cannot open %s\n", OUTPUT_FILE_NAME); + return; + } + } + + /* Read in the next lot of text */ + while (fgets (line, viewer_width + 1, ow->fp) != NULL) + { + chars_inserted = TRUE; + gtk_text_buffer_insert (ow->buffer, &end_iter, line, -1); + } + } +#endif + + /* Scroll to where the start of this lot of text begins */ + gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (ow->textview), + mark, + 0.1, TRUE, 0.0, 0.0); + + + if ( chars_inserted ) + gtk_window_set_urgency_hint ( GTK_WINDOW (ow), TRUE); +} + + + diff --git a/src/ui/gui/psppire-output-window.h b/src/ui/gui/psppire-output-window.h new file mode 100644 index 00000000..621a9e24 --- /dev/null +++ b/src/ui/gui/psppire-output-window.h @@ -0,0 +1,78 @@ +/* PSPPIRE - a graphical user interface for PSPP. + Copyright (C) 2008 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 + 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, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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, see . */ + + +#ifndef __PSPPIRE_OUTPUT_WINDOW_H__ +#define __PSPPIRE_OUTPUT_WINDOW_H__ + + +#include +#include +#include +#include +#include "psppire-window.h" +#include + +extern int viewer_length; +extern int viewer_width ; + + +#define OUTPUT_FILE_NAME "psppire.txt" + + + +G_BEGIN_DECLS + +#define PSPPIRE_OUTPUT_WINDOW_TYPE (psppire_output_window_get_type ()) +#define PSPPIRE_OUTPUT_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PSPPIRE_OUTPUT_WINDOW_TYPE, PsppireOutputWindow)) +#define PSPPIRE_OUTPUT_WINDOW_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), \ + PSPPIRE_OUTPUT_WINDOW_TYPE, PsppireOutput_WindowClass)) +#define PSPPIRE_IS_OUTPUT_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + PSPPIRE_OUTPUT_WINDOW_TYPE)) +#define PSPPIRE_IS_OUTPUT_WINDOW_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), \ + PSPPIRE_OUTPUT_WINDOW_TYPE)) + + +typedef struct _PsppireOutputWindow PsppireOutputWindow; +typedef struct _PsppireOutputWindowClass PsppireOutputWindowClass; + + +struct _PsppireOutputWindow +{ + PsppireWindow parent; + + /* */ + GtkTextBuffer *buffer; /* The buffer which contains the text */ + GtkWidget *textview ; + FILE *fp; /* The file it's viewing */ +}; + +struct _PsppireOutputWindowClass +{ + PsppireWindowClass parent_class; + +}; + +GType psppire_output_window_get_type (void); +GtkWidget* psppire_output_window_new (void); + + +void psppire_output_window_reload (void); + + +G_END_DECLS + +#endif /* __PSPPIRE_OUTPUT_WINDOW_H__ */ diff --git a/src/ui/gui/psppire-syntax-window.c b/src/ui/gui/psppire-syntax-window.c new file mode 100644 index 00000000..37bfd35c --- /dev/null +++ b/src/ui/gui/psppire-syntax-window.c @@ -0,0 +1,631 @@ +/* PSPPIRE - a graphical user interface for PSPP. + Copyright (C) 2008 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 + 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, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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, see . */ + +#include + +#include +#include +#include +#include "helper.h" + +#include +#include + +#include "psppire-syntax-window.h" + +#include "psppire-data-window.h" +#include "psppire-window-register.h" +#include "about.h" +#include "psppire-syntax-window.h" +#include "syntax-editor-source.h" +#include + +#include +#define _(msgid) gettext (msgid) +#define N_(msgid) msgid + +static void psppire_syntax_window_base_finalize (PsppireSyntaxWindowClass *, gpointer); +static void psppire_syntax_window_base_init (PsppireSyntaxWindowClass *class); +static void psppire_syntax_window_class_init (PsppireSyntaxWindowClass *class); +static void psppire_syntax_window_init (PsppireSyntaxWindow *syntax_editor); + +GType +psppire_syntax_window_get_type (void) +{ + static GType psppire_syntax_window_type = 0; + + if (!psppire_syntax_window_type) + { + static const GTypeInfo psppire_syntax_window_info = + { + sizeof (PsppireSyntaxWindowClass), + (GBaseInitFunc) psppire_syntax_window_base_init, + (GBaseFinalizeFunc) psppire_syntax_window_base_finalize, + (GClassInitFunc)psppire_syntax_window_class_init, + (GClassFinalizeFunc) NULL, + NULL, + sizeof (PsppireSyntaxWindow), + 0, + (GInstanceInitFunc) psppire_syntax_window_init, + }; + + psppire_syntax_window_type = + g_type_register_static (PSPPIRE_WINDOW_TYPE, "PsppireSyntaxWindow", + &psppire_syntax_window_info, 0); + } + + return psppire_syntax_window_type; +} + +static void +psppire_syntax_window_finalize (GObject *object) +{ + GObjectClass *class = G_OBJECT_GET_CLASS (object); + + GObjectClass *parent_class = g_type_class_peek_parent (class); + + if (G_OBJECT_CLASS (parent_class)->finalize) + (*G_OBJECT_CLASS (parent_class)->finalize) (object); +} + + +static void +psppire_syntax_window_class_init (PsppireSyntaxWindowClass *class) +{ +} + + +static void +psppire_syntax_window_base_init (PsppireSyntaxWindowClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + + object_class->finalize = psppire_syntax_window_finalize; +} + + + +static void +psppire_syntax_window_base_finalize (PsppireSyntaxWindowClass *class, + gpointer class_data) +{ +} + + +static void +editor_execute_syntax (const PsppireSyntaxWindow *sw, GtkTextIter start, + GtkTextIter stop) +{ + PsppireWindow *win = PSPPIRE_WINDOW (sw); + const gchar *name = psppire_window_get_filename (win); + execute_syntax (create_syntax_editor_source (sw->buffer, start, stop, name)); +} + + +/* Parse and execute all the text in the buffer */ +static void +on_run_all (GtkMenuItem *menuitem, gpointer user_data) +{ + GtkTextIter begin, end; + PsppireSyntaxWindow *se = PSPPIRE_SYNTAX_WINDOW (user_data); + + gtk_text_buffer_get_iter_at_offset (se->buffer, &begin, 0); + gtk_text_buffer_get_iter_at_offset (se->buffer, &end, -1); + + editor_execute_syntax (se, begin, end); +} + +/* Parse and execute the currently selected text */ +static void +on_run_selection (GtkMenuItem *menuitem, gpointer user_data) +{ + GtkTextIter begin, end; + PsppireSyntaxWindow *se = PSPPIRE_SYNTAX_WINDOW (user_data); + + if ( gtk_text_buffer_get_selection_bounds (se->buffer, &begin, &end) ) + editor_execute_syntax (se, begin, end); +} + + +/* Parse and execute the from the current line, to the end of the + buffer */ +static void +on_run_to_end (GtkMenuItem *menuitem, gpointer user_data) +{ + GtkTextIter begin, end; + GtkTextIter here; + gint line; + + PsppireSyntaxWindow *se = PSPPIRE_SYNTAX_WINDOW (user_data); + + /* Get the current line */ + gtk_text_buffer_get_iter_at_mark (se->buffer, + &here, + gtk_text_buffer_get_insert (se->buffer) + ); + + line = gtk_text_iter_get_line (&here) ; + + /* Now set begin and end to the start of this line, and end of buffer + respectively */ + gtk_text_buffer_get_iter_at_line (se->buffer, &begin, line); + gtk_text_buffer_get_iter_at_line (se->buffer, &end, -1); + + editor_execute_syntax (se, begin, end); +} + + + +/* Parse and execute the current line */ +static void +on_run_current_line (GtkMenuItem *menuitem, gpointer user_data) +{ + GtkTextIter begin, end; + GtkTextIter here; + gint line; + + PsppireSyntaxWindow *se = PSPPIRE_SYNTAX_WINDOW (user_data); + + /* Get the current line */ + gtk_text_buffer_get_iter_at_mark (se->buffer, + &here, + gtk_text_buffer_get_insert (se->buffer) + ); + + line = gtk_text_iter_get_line (&here) ; + + /* Now set begin and end to the start of this line, and start of + following line respectively */ + gtk_text_buffer_get_iter_at_line (se->buffer, &begin, line); + gtk_text_buffer_get_iter_at_line (se->buffer, &end, line + 1); + + editor_execute_syntax (se, begin, end); +} + + + +/* Append ".sps" to FILENAME if necessary. + The returned result must be freed when no longer required. + */ +static gchar * +append_suffix (const gchar *filename) +{ + if ( ! g_str_has_suffix (filename, ".sps" ) && + ! g_str_has_suffix (filename, ".SPS" ) ) + { + return g_strdup_printf ("%s.sps", filename); + } + + return strdup (filename); +} + +/* + Save BUFFER to the file called FILENAME. + If successful, clears the buffer's modified flag +*/ +static gboolean +save_editor_to_file (PsppireSyntaxWindow *se, + const gchar *filename, + GError **err) +{ + GtkTextBuffer *buffer = se->buffer; + gboolean result ; + GtkTextIter start, stop; + gchar *text; + + gchar *suffixedname; + gchar *glibfilename; + g_assert (filename); + + suffixedname = append_suffix (filename); + + glibfilename = g_filename_from_utf8 (suffixedname, -1, 0, 0, err); + + g_free ( suffixedname); + + if ( ! glibfilename ) + return FALSE; + + gtk_text_buffer_get_iter_at_line (buffer, &start, 0); + gtk_text_buffer_get_iter_at_offset (buffer, &stop, -1); + + text = gtk_text_buffer_get_text (buffer, &start, &stop, FALSE); + + result = g_file_set_contents (glibfilename, text, -1, err); + + if ( result ) + { + psppire_window_set_filename (PSPPIRE_WINDOW (se), filename); + gtk_text_buffer_set_modified (buffer, FALSE); + } + + return result; +} + +/* If the buffer's modified flag is set, then save it, and close the window. + Otherwise just close the window. +*/ +static void +save_if_modified (PsppireSyntaxWindow *se) +{ + + if ( TRUE == gtk_text_buffer_get_modified (se->buffer)) + { + gint response; + GtkWidget *dialog; + + const gchar *filename = psppire_window_get_filename (PSPPIRE_WINDOW (se)); + + g_return_if_fail (filename != NULL); + + dialog = + gtk_message_dialog_new (GTK_WINDOW (se), + GTK_DIALOG_MODAL, + GTK_MESSAGE_QUESTION, + GTK_BUTTONS_NONE, + _("Save contents of syntax editor to %s?"), + filename); + + gtk_dialog_add_button (GTK_DIALOG (dialog), + GTK_STOCK_YES, + GTK_RESPONSE_ACCEPT); + gtk_dialog_add_button (GTK_DIALOG (dialog), + GTK_STOCK_NO, + GTK_RESPONSE_REJECT); + gtk_dialog_add_button (GTK_DIALOG (dialog), + GTK_STOCK_CANCEL, + GTK_RESPONSE_CANCEL); + + + response = gtk_dialog_run (GTK_DIALOG (dialog)); + + gtk_widget_destroy (dialog); + + if ( response == GTK_RESPONSE_ACCEPT ) + { + GError *err = NULL; + + if ( ! save_editor_to_file (se, filename, &err) ) + { + msg (ME, err->message); + g_error_free (err); + } + } + + if ( response == GTK_RESPONSE_CANCEL ) + return ; + } + + gtk_widget_destroy (GTK_WIDGET (se)); +} + +/* Callback for the File->SaveAs menuitem */ +static void +on_syntax_save_as (GtkMenuItem *menuitem, gpointer user_data) +{ + GtkFileFilter *filter; + gint response; + + PsppireSyntaxWindow *se = PSPPIRE_SYNTAX_WINDOW (user_data); + + GtkWidget *dialog = + gtk_file_chooser_dialog_new (_("Save Syntax"), + GTK_WINDOW (se), + GTK_FILE_CHOOSER_ACTION_SAVE, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_SAVE, 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); + + 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); + + gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), + TRUE); + response = gtk_dialog_run (GTK_DIALOG (dialog)); + + if ( response == GTK_RESPONSE_ACCEPT ) + { + GError *err = NULL; + char *filename = + gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog) ); + + if ( ! save_editor_to_file (se, filename, &err) ) + { + msg ( ME, err->message ); + g_error_free (err); + } + + free (filename); + } + + gtk_widget_destroy (dialog); +} + + +/* Callback for the File->Save menuitem */ +static void +on_syntax_save (GtkMenuItem *menuitem, gpointer user_data) +{ + PsppireSyntaxWindow *se = PSPPIRE_SYNTAX_WINDOW (user_data); + const gchar *filename = psppire_window_get_filename (PSPPIRE_WINDOW (se)); + + + if ( filename == NULL ) + on_syntax_save_as (menuitem, se); + else + { + GError *err = NULL; + save_editor_to_file (se, filename, &err); + if ( err ) + { + msg (ME, err->message); + g_error_free (err); + } + } +} + + +/* Callback for the File->Quit menuitem */ +static gboolean +on_quit (GtkMenuItem *menuitem, gpointer user_data) +{ + PsppireSyntaxWindow *se = PSPPIRE_SYNTAX_WINDOW (user_data); + save_if_modified (se); + return FALSE; +} + + +/* Callback for the "delete" action (clicking the x on the top right + hand corner of the window) */ +static gboolean +on_delete (GtkWidget *w, GdkEvent *event, gpointer user_data) +{ + PsppireSyntaxWindow *se = PSPPIRE_SYNTAX_WINDOW (user_data); + + save_if_modified (se); + return TRUE; +} + + +void +create_syntax_window (void) +{ + GtkWidget *w = psppire_syntax_window_new (); + gtk_widget_show (w); +} + +/* Callback for the File->Open->Syntax menuitem */ +void +open_syntax_window (GtkMenuItem *menuitem, gpointer parent) +{ + 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); + + 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_syntax_window_load_from_file (PSPPIRE_SYNTAX_WINDOW (se), file_name, NULL) ) +#if RECENT_LISTS_AVAILABLE + { + GtkRecentManager *manager = gtk_recent_manager_get_default(); + gchar *uri = g_filename_to_uri (file_name, NULL, NULL); + + gtk_recent_manager_remove_item (manager, uri, NULL); + if ( ! gtk_recent_manager_add_item (manager, uri)) + g_warning ("Could not add item %s to recent list\n",uri); + + g_free (uri); + } +#else + ; +#endif + gtk_widget_show (se); + } + + gtk_widget_destroy (dialog); +} + + + +extern struct source_stream *the_source_stream ; + +static void +psppire_syntax_window_init (PsppireSyntaxWindow *window) +{ + GladeXML *xml = XML_NEW ("syntax-editor.glade"); + GtkWidget *box = gtk_vbox_new (FALSE, 0); + + GtkWidget *menubar = get_widget_assert (xml, "menubar2"); + GtkWidget *sw = get_widget_assert (xml, "scrolledwindow8"); + GtkWidget *sb = get_widget_assert (xml, "statusbar2"); + + GtkWidget *text_view = get_widget_assert (xml, "syntax_text_view"); + window->buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view)); + window->lexer = lex_create (the_source_stream); + + connect_help (xml); + + gtk_container_add (GTK_CONTAINER (window), box); + + g_object_ref (menubar); + gtk_widget_unparent (menubar); + + g_object_ref (sw); + gtk_widget_unparent (sw); + + g_object_ref (sb); + gtk_widget_unparent (sb); + + + gtk_box_pack_start (GTK_BOX (box), menubar, FALSE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (box), sw, TRUE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (box), sb, FALSE, TRUE, 0); + + gtk_widget_show_all (box); + + g_signal_connect (get_widget_assert (xml,"file_new_syntax"), + "activate", + G_CALLBACK (create_syntax_window), + NULL); + + g_signal_connect (get_widget_assert (xml,"file_open_syntax"), + "activate", + G_CALLBACK (open_syntax_window), + window); + +#if 0 + g_signal_connect (get_widget_assert (xml,"file_new_data"), + "activate", + G_CALLBACK (create_data_window), + window); +#endif + + g_signal_connect (get_widget_assert (xml,"help_about"), + "activate", + G_CALLBACK (about_new), + window); + + g_signal_connect (get_widget_assert (xml,"help_reference"), + "activate", + G_CALLBACK (reference_manual), + NULL); + + g_signal_connect (get_widget_assert (xml, "file_save"), + "activate", + G_CALLBACK (on_syntax_save), + window); + + g_signal_connect (get_widget_assert (xml, "file_save_as"), + "activate", + G_CALLBACK (on_syntax_save_as), + window); + + g_signal_connect (get_widget_assert (xml,"file_quit"), + "activate", + G_CALLBACK (on_quit), + window); + + g_signal_connect (get_widget_assert (xml,"run_all"), + "activate", + G_CALLBACK (on_run_all), + window); + + + g_signal_connect (get_widget_assert (xml,"run_selection"), + "activate", + G_CALLBACK (on_run_selection), + window); + + g_signal_connect (get_widget_assert (xml,"run_current_line"), + "activate", + G_CALLBACK (on_run_current_line), + window); + + g_signal_connect (get_widget_assert (xml,"run_to_end"), + "activate", + G_CALLBACK (on_run_to_end), + window); + + g_signal_connect (get_widget_assert (xml,"windows_minimise_all"), + "activate", + G_CALLBACK (psppire_window_minimise_all), NULL); + + PSPPIRE_WINDOW (window)->menu = GTK_MENU_SHELL (get_widget_assert (xml,"windows_menu")); + + g_object_unref (xml); + + g_signal_connect (window, "delete-event", + G_CALLBACK (on_delete), window); +} + + +GtkWidget* +psppire_syntax_window_new (void) +{ + return GTK_WIDGET (g_object_new (psppire_syntax_window_get_type (), + "usage", PSPPIRE_WINDOW_USAGE_SYNTAX, + NULL)); +} + + +/* + Loads the buffer from the file called FILENAME +*/ +gboolean +psppire_syntax_window_load_from_file (PsppireSyntaxWindow *se, + const gchar *filename, + GError **err) +{ + gchar *text; + GtkTextIter iter; + + gchar *glibfilename = g_filename_from_utf8 (filename, -1, 0, 0, err); + + if ( ! glibfilename ) + return FALSE; + + /* FIXME: What if it's a very big file ? */ + if ( ! g_file_get_contents (glibfilename, &text, NULL, err) ) + { + g_free (glibfilename); + return FALSE; + } + g_free (glibfilename); + + gtk_text_buffer_get_iter_at_line (se->buffer, &iter, 0); + + gtk_text_buffer_insert (se->buffer, &iter, text, -1); + + psppire_window_set_filename (PSPPIRE_WINDOW (se), filename); + + gtk_text_buffer_set_modified (se->buffer, FALSE); + + return TRUE; +} + diff --git a/src/ui/gui/psppire-syntax-window.h b/src/ui/gui/psppire-syntax-window.h new file mode 100644 index 00000000..c434e07f --- /dev/null +++ b/src/ui/gui/psppire-syntax-window.h @@ -0,0 +1,73 @@ +/* PSPPIRE - a graphical user interface for PSPP. + Copyright (C) 2008 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 + 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, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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, see . */ + + +#ifndef __PSPPIRE_SYNTAX_WINDOW_H__ +#define __PSPPIRE_SYNTAX_WINDOW_H__ + +#include +#include +#include +#include +#include "psppire-window.h" +#include + +G_BEGIN_DECLS + +#define PSPPIRE_SYNTAX_WINDOW_TYPE (psppire_syntax_window_get_type ()) +#define PSPPIRE_SYNTAX_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PSPPIRE_SYNTAX_WINDOW_TYPE, PsppireSyntaxWindow)) +#define PSPPIRE_SYNTAX_WINDOW_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), \ + PSPPIRE_SYNTAX_WINDOW_TYPE, PsppireSyntax_WindowClass)) +#define PSPPIRE_IS_SYNTAX_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + PSPPIRE_SYNTAX_WINDOW_TYPE)) +#define PSPPIRE_IS_SYNTAX_WINDOW_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), \ + PSPPIRE_SYNTAX_WINDOW_TYPE)) + + +typedef struct _PsppireSyntaxWindow PsppireSyntaxWindow; +typedef struct _PsppireSyntaxWindowClass PsppireSyntaxWindowClass; + + +struct _PsppireSyntaxWindow +{ + PsppireWindow parent; + + /* */ + + GtkTextBuffer *buffer; /* The buffer which contains the text */ + struct lexer *lexer; /* Lexer to parse syntax */ +}; + +struct _PsppireSyntaxWindowClass +{ + PsppireWindowClass parent_class; + +}; + +GType psppire_syntax_window_get_type (void); +GtkWidget* psppire_syntax_window_new (void); + +gboolean psppire_syntax_window_load_from_file (PsppireSyntaxWindow *se, + const gchar *filename, + GError **err); + +void open_syntax_window (GtkMenuItem *menuitem, gpointer parent); +void create_syntax_window (void); + + +G_END_DECLS + +#endif /* __PSPPIRE_SYNTAX_WINDOW_H__ */ diff --git a/src/ui/gui/psppire-window-register.c b/src/ui/gui/psppire-window-register.c new file mode 100644 index 00000000..dfa46c65 --- /dev/null +++ b/src/ui/gui/psppire-window-register.c @@ -0,0 +1,189 @@ +/* PSPPIRE - a graphical user interface for PSPP. + Copyright (C) 2008 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 + 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, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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, see . */ + +#include + +#include "psppire-window-register.h" + +static void psppire_window_register_init (PsppireWindowRegister *window_register); +static void psppire_window_register_class_init (PsppireWindowRegisterClass *class); + +static void psppire_window_register_finalize (GObject *object); +static void psppire_window_register_dispose (GObject *object); + +static GObjectClass *parent_class = NULL; + + +enum { + INSERTED, + REMOVED, + n_SIGNALS +}; + +static guint signals [n_SIGNALS]; + +GType +psppire_window_register_get_type (void) +{ + static GType window_register_type = 0; + + if (!window_register_type) + { + static const GTypeInfo window_register_info = + { + sizeof (PsppireWindowRegisterClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) psppire_window_register_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (PsppireWindowRegister), + 0, + (GInstanceInitFunc) psppire_window_register_init, + }; + + window_register_type = g_type_register_static (G_TYPE_OBJECT, + "PsppireWindowRegister", + &window_register_info, 0); + } + + return window_register_type; +} + + +static void +psppire_window_register_finalize (GObject *object) +{ +} + +static void +psppire_window_register_dispose (GObject *object) +{ +} + +static PsppireWindowRegister *the_instance = NULL; + +static GObject* +psppire_window_register_construct (GType type, + guint n_construct_params, + GObjectConstructParam *construct_params) +{ + GObject *object; + + if (!the_instance) + { + object = G_OBJECT_CLASS (parent_class)->constructor (type, + n_construct_params, + construct_params); + the_instance = PSPPIRE_WINDOW_REGISTER (object); + } + else + object = g_object_ref (G_OBJECT (the_instance)); + + return object; +} + +static void +psppire_window_register_class_init (PsppireWindowRegisterClass *class) +{ + GObjectClass *object_class; + + parent_class = g_type_class_peek_parent (class); + object_class = (GObjectClass*) class; + + object_class->finalize = psppire_window_register_finalize; + object_class->dispose = psppire_window_register_dispose; + object_class->constructor = psppire_window_register_construct; + + signals [INSERTED] = + g_signal_new ("inserted", + G_TYPE_FROM_CLASS (class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, NULL, + g_cclosure_marshal_VOID__POINTER, + G_TYPE_NONE, + 1, + G_TYPE_POINTER); + + signals [REMOVED] = + g_signal_new ("removed", + G_TYPE_FROM_CLASS (class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, NULL, + g_cclosure_marshal_VOID__POINTER, + G_TYPE_NONE, + 1, + G_TYPE_POINTER); +} + +static void +psppire_window_register_init (PsppireWindowRegister *window_register) +{ + window_register->dispose_has_run = FALSE; + window_register->name_table = g_hash_table_new (g_str_hash, g_str_equal); +} + +void +psppire_window_register_insert (PsppireWindowRegister *wr, PsppireWindow *window, const gchar *name) +{ + g_hash_table_insert (wr->name_table, (gpointer) name, window); + + g_signal_emit (wr, signals[INSERTED], 0, name); +} + + +void +psppire_window_register_remove (PsppireWindowRegister *wr, const gchar *name) +{ + g_signal_emit (wr, signals[REMOVED], 0, name); + + g_hash_table_remove (wr->name_table, (gpointer) name); +} + +PsppireWindow * +psppire_window_register_lookup (PsppireWindowRegister *wr, const gchar *name) +{ + return g_hash_table_lookup (wr->name_table, name); +} + +void +psppire_window_register_foreach (PsppireWindowRegister *wr, GHFunc func, PsppireWindow *win) +{ + g_hash_table_foreach (wr->name_table, func, win); +} + +static void +minimise_window (gpointer key, gpointer value, gpointer data) +{ + gtk_window_iconify (GTK_WINDOW (value)); +} + + +void +psppire_window_register_minimise_all (PsppireWindowRegister *wr) +{ + g_hash_table_foreach (wr->name_table, minimise_window, wr); +} + + + +PsppireWindowRegister * +psppire_window_register_new (void) +{ + return g_object_new (psppire_window_register_get_type (), NULL); +} diff --git a/src/ui/gui/psppire-window-register.h b/src/ui/gui/psppire-window-register.h new file mode 100644 index 00000000..cc24f4ef --- /dev/null +++ b/src/ui/gui/psppire-window-register.h @@ -0,0 +1,92 @@ +/* PSPPIRE - a graphical user interface for PSPP. + Copyright (C) 2008 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 + 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, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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, see . */ + + +#include +#include + +#include "psppire-window.h" + +#ifndef __PSPPIRE_WINDOW_REGISTER_H__ +#define __PSPPIRE_WINDOW_REGISTER_H__ + +G_BEGIN_DECLS + + +#define PSPPIRE_TYPE_WINDOW_REGISTER (psppire_window_register_get_type ()) + +#define PSPPIRE_WINDOW_REGISTER(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + PSPPIRE_TYPE_WINDOW_REGISTER, PsppireWindowRegister)) + +#define PSPPIRE_WINDOW_REGISTER_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), \ + PSPPIRE_TYPE_WINDOW_REGISTER, \ + PsppireWindowRegisterClass)) + + +#define PSPPIRE_IS_WINDOW_REGISTER(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PSPPIRE_TYPE_WINDOW_REGISTER)) + +#define PSPPIRE_IS_WINDOW_REGISTER_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), PSPPIRE_TYPE_WINDOW_REGISTER)) + + +#define PSPPIRE_WINDOW_REGISTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + PSPPIRE_TYPE_WINDOW_REGISTER, \ + PsppireWindowRegisterClass)) + +typedef struct _PsppireWindowRegister PsppireWindowRegister; +typedef struct _PsppireWindowRegisterClass PsppireWindowRegisterClass; + + +struct _PsppireWindowRegister +{ + GObject parent; + + /*< private >*/ + gboolean dispose_has_run ; + GHashTable *name_table; +}; + + +struct _PsppireWindowRegisterClass +{ + GObjectClass parent_class; +}; + + +GType psppire_window_register_get_type (void) G_GNUC_CONST; + +PsppireWindowRegister * psppire_window_register_new (void); + +void psppire_window_register_insert (PsppireWindowRegister *wr, PsppireWindow *window, + const gchar *name); + +void psppire_window_register_remove (PsppireWindowRegister *wr, const gchar *name); + + +PsppireWindow *psppire_window_register_lookup (PsppireWindowRegister *wr, const gchar *name); + + +void psppire_window_register_foreach (PsppireWindowRegister *wr, GHFunc func, PsppireWindow *); + +void psppire_window_register_minimise_all (PsppireWindowRegister *wr); + + +G_END_DECLS + +#endif /* __PSPPIRE_WINDOW_REGISTER_H__ */ diff --git a/src/ui/gui/psppire-window.c b/src/ui/gui/psppire-window.c new file mode 100644 index 00000000..ebced6d7 --- /dev/null +++ b/src/ui/gui/psppire-window.c @@ -0,0 +1,444 @@ +/* PSPPIRE - a graphical user interface for PSPP. + Copyright (C) 2008 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 + 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, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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, see . */ + +#include + +#include +#include +#include + +#include + +#include +#define _(msgid) gettext (msgid) +#define N_(msgid) msgid + +#include "psppire-window.h" +#include "psppire-window-register.h" + +static void psppire_window_base_finalize (PsppireWindowClass *, gpointer); +static void psppire_window_base_init (PsppireWindowClass *class); +static void psppire_window_class_init (PsppireWindowClass *class); +static void psppire_window_init (PsppireWindow *window); + + +static PsppireWindowClass *the_class; +static GObjectClass *parent_class; + +GType +psppire_window_get_type (void) +{ + static GType psppire_window_type = 0; + + if (!psppire_window_type) + { + static const GTypeInfo psppire_window_info = + { + sizeof (PsppireWindowClass), + (GBaseInitFunc) psppire_window_base_init, + (GBaseFinalizeFunc) psppire_window_base_finalize, + (GClassInitFunc) psppire_window_class_init, + (GClassFinalizeFunc) NULL, + NULL, + sizeof (PsppireWindow), + 0, + (GInstanceInitFunc) psppire_window_init, + }; + + psppire_window_type = + g_type_register_static (GTK_TYPE_WINDOW, "PsppireWindow", + &psppire_window_info, 0); + } + + return psppire_window_type; +} + + +/* Properties */ +enum +{ + PROP_0, + PROP_FILENAME, + PROP_USAGE +}; + + +gchar * +uniquify (const gchar *str, int *x) +{ + return g_strdup_printf ("%s%d", str, (*x)++); +} + + + +static void +psppire_window_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + PsppireWindow *window = PSPPIRE_WINDOW (object); + + switch (prop_id) + { + case PROP_USAGE: + window->usage = g_value_get_enum (value); + break; + case PROP_FILENAME: + { + PsppireWindowRegister *reg = psppire_window_register_new (); + gchar mdash[6] = {0,0,0,0,0,0}; + gchar *basename, *title; + const gchar *name = g_value_get_string (value); + int x = 0; + gchar *candidate_name ; + GValue def = {0}; + g_value_init (&def, pspec->value_type); + + if ( NULL == name) + { + g_param_value_set_default (pspec, &def); + name = g_value_get_string (&def); + } + + candidate_name = strdup (name); + + while ( psppire_window_register_lookup (reg, candidate_name)) + { + free (candidate_name); + candidate_name = uniquify (name, &x); + } + + basename = g_path_get_basename (candidate_name); + g_unichar_to_utf8 (0x2014, mdash); + + g_value_unset (&def); + + switch (window->usage) + { + case PSPPIRE_WINDOW_USAGE_SYNTAX: + title = g_strdup_printf ( _("%s %s PSPPIRE Syntax Editor"), + basename, mdash); + break; + case PSPPIRE_WINDOW_USAGE_OUTPUT: + title = g_strdup_printf ( _("%s %s PSPPIRE Output"), + basename, mdash); + case PSPPIRE_WINDOW_USAGE_DATA: + title = g_strdup_printf ( _("%s %s PSPPIRE Data Editor"), + basename, mdash); + break; + default: + g_assert_not_reached (); + break; + } + + gtk_window_set_title (GTK_WINDOW (window), title); + + if ( window->name) + psppire_window_register_remove (reg, window->name); + + free (window->name); + window->name = candidate_name; + + psppire_window_register_insert (reg, window, window->name); + + free (basename); + free (title); + } + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + }; +} + + +static void +psppire_window_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + PsppireWindow *window = PSPPIRE_WINDOW (object); + + switch (prop_id) + { + case PROP_USAGE: + g_value_set_enum (value, window->usage); + break; + case PROP_FILENAME: + g_value_set_string (value, window->name); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + }; +} + + + +static void +psppire_window_finalize (GObject *object) +{ + PsppireWindow *window = PSPPIRE_WINDOW (object); + + PsppireWindowRegister *reg = psppire_window_register_new (); + + psppire_window_register_remove (reg, window->name); + free (window->name); + + g_signal_handler_disconnect (psppire_window_register_new (), + window->remove_handler); + + g_signal_handler_disconnect (psppire_window_register_new (), + window->insert_handler); + + g_hash_table_destroy (window->menuitem_table); + + if (G_OBJECT_CLASS (parent_class)->finalize) + G_OBJECT_CLASS (parent_class)->finalize (object); +} + + +static void +psppire_window_class_init (PsppireWindowClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + + GParamSpec *use_class_spec = + g_param_spec_enum ("usage", + "Usage", + "What the window is used for", + G_TYPE_PSPPIRE_WINDOW_USAGE, + PSPPIRE_WINDOW_USAGE_SYNTAX /* default value */, + G_PARAM_CONSTRUCT_ONLY |G_PARAM_READABLE | G_PARAM_WRITABLE); + + + GParamSpec *filename_spec = + g_param_spec_string ("filename", + "File name", + "The name of the file associated with this window, if any", + "Untitled", + G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT + ); + + + object_class->set_property = psppire_window_set_property; + object_class->get_property = psppire_window_get_property; + + g_object_class_install_property (object_class, + PROP_FILENAME, + filename_spec); + + g_object_class_install_property (object_class, + PROP_USAGE, + use_class_spec); + + + the_class = class; + parent_class = g_type_class_peek_parent (class); +} + + +static void +psppire_window_base_init (PsppireWindowClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + + object_class->finalize = psppire_window_finalize; +} + + + +static void +psppire_window_base_finalize (PsppireWindowClass *class, + gpointer class_data) +{ +} + +static void +menu_toggled (GtkCheckMenuItem *mi, gpointer data) +{ + /* Prohibit changes to the state */ + mi->active = !mi->active; +} + + +/* Look up the window associated with this menuitem and present it to the user */ +static void +menu_activate (GtkMenuItem *mi, gpointer data) +{ + const gchar *key = data; + + PsppireWindowRegister *reg = psppire_window_register_new (); + + PsppireWindow *window = psppire_window_register_lookup (reg, key); + + gtk_window_present (GTK_WINDOW (window)); +} + +static void +insert_menuitem_into_menu (PsppireWindow *window, gpointer key) +{ + GtkWidget *item = gtk_check_menu_item_new_with_label (key); + + g_signal_connect (item, "toggled", G_CALLBACK (menu_toggled), NULL); + g_signal_connect (item, "activate", G_CALLBACK (menu_activate), key); + + gtk_widget_show (item); + + gtk_menu_shell_append (window->menu, item); + + /* Set the state without emitting a signal */ + GTK_CHECK_MENU_ITEM (item)->active = + (psppire_window_register_lookup (psppire_window_register_new (), key) == window); + + g_hash_table_insert (window->menuitem_table, key, item); +} + +static void +insert_item (gpointer key, gpointer value, gpointer data) +{ + PsppireWindow *window = PSPPIRE_WINDOW (data); + + if ( NULL != g_hash_table_lookup (window->menuitem_table, key)) + return; + + insert_menuitem_into_menu (window, key); +} + +/* Insert a new item into the window menu */ +static void +insert_menuitem (GObject *reg, const gchar *key, gpointer data) +{ + PsppireWindow *window = PSPPIRE_WINDOW (data); + + insert_menuitem_into_menu (window, (gpointer) key); +} + + +static void +remove_menuitem (PsppireWindowRegister *reg, const gchar *key, gpointer data) +{ + PsppireWindow *window = PSPPIRE_WINDOW (data); + GtkWidget *item ; + + item = g_hash_table_lookup (window->menuitem_table, key); + + g_hash_table_remove (window->menuitem_table, key); + + if (GTK_IS_CONTAINER (window->menu)) + gtk_container_remove (GTK_CONTAINER (window->menu), item); +} + +static void +insert_existing_items (PsppireWindow *window) +{ + psppire_window_register_foreach (psppire_window_register_new (), insert_item, window); +} + +static void +psppire_window_init (PsppireWindow *window) +{ + window->name = NULL; + window->menu = NULL; + + window->menuitem_table = g_hash_table_new (g_str_hash, g_str_equal); + + + g_signal_connect (window, "realize", G_CALLBACK (insert_existing_items), NULL); + + window->insert_handler = g_signal_connect (psppire_window_register_new (), + "inserted", + G_CALLBACK (insert_menuitem), + window); + + window->remove_handler = g_signal_connect (psppire_window_register_new (), + "removed", + G_CALLBACK (remove_menuitem), + window); +} + + +GtkWidget* +psppire_window_new (PsppireWindowUsage usage) +{ + return GTK_WIDGET (g_object_new (psppire_window_get_type (), + "type", GTK_WINDOW_TOPLEVEL, + "usage", usage, + NULL)); +} + + +const gchar * +psppire_window_get_filename (PsppireWindow *w) +{ + const gchar *name = NULL; + g_object_get (w, "filename", &name, NULL); + return name; +} + + +void +psppire_window_set_filename (PsppireWindow *w, const gchar *filename) +{ + g_object_set (w, "filename", filename, NULL); +} + + + +GType +psppire_window_usage_get_type (void) +{ + static GType etype = 0; + if (etype == 0) + { + static const GEnumValue values[] = { + { PSPPIRE_WINDOW_USAGE_SYNTAX, "PSPPIRE_WINDOW_USAGE_SYNTAX", + "Syntax" }, + + { PSPPIRE_WINDOW_USAGE_OUTPUT, "PSPPIRE_WINDOW_USAGE_OUTPUT", + "Output" }, + + { PSPPIRE_WINDOW_USAGE_DATA, "PSPPIRE_WINDOW_USAGE_DATA", + "Data" }, + + { 0, NULL, NULL } + }; + + etype = g_enum_register_static (g_intern_static_string ("PsppireWindowUsage"), + values); + } + + return etype; +} + + + +static void +minimise_window (gpointer key, gpointer value, gpointer data) +{ + gtk_window_iconify (GTK_WINDOW (value)); +} + + +void +psppire_window_minimise_all (void) +{ + PsppireWindowRegister *reg = psppire_window_register_new (); + + g_hash_table_foreach (reg->name_table, minimise_window, NULL); +} diff --git a/src/ui/gui/psppire-window.h b/src/ui/gui/psppire-window.h new file mode 100644 index 00000000..ef7feb23 --- /dev/null +++ b/src/ui/gui/psppire-window.h @@ -0,0 +1,92 @@ +/* PSPPIRE - a graphical user interface for PSPP. + Copyright (C) 2008 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 + 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, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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, see . */ + + +#ifndef __PSPPIRE_WINDOW_H__ +#define __PSPPIRE_WINDOW_H__ + + +#include +#include +#include +#include +#include + +G_BEGIN_DECLS + +typedef enum { + PSPPIRE_WINDOW_USAGE_SYNTAX, + PSPPIRE_WINDOW_USAGE_OUTPUT, + PSPPIRE_WINDOW_USAGE_DATA +} PsppireWindowUsage; + + +GType psppire_window_usage_get_type (void); + + +#define G_TYPE_PSPPIRE_WINDOW_USAGE \ + (psppire_window_usage_get_type()) + + + + +#define PSPPIRE_WINDOW_TYPE (psppire_window_get_type ()) +#define PSPPIRE_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PSPPIRE_WINDOW_TYPE, PsppireWindow)) +#define PSPPIRE_WINDOW_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), \ + PSPPIRE_WINDOW_TYPE, PsppireWindowClass)) +#define PSPPIRE_IS_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + PSPPIRE_WINDOW_TYPE)) +#define PSPPIRE_IS_WINDOW_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), \ + PSPPIRE_WINDOW_TYPE)) + + +typedef struct _PsppireWindow PsppireWindow; +typedef struct _PsppireWindowClass PsppireWindowClass; + + +struct _PsppireWindow +{ + GtkWindow parent; + + /* */ + gchar *name; + PsppireWindowUsage usage; + + GHashTable *menuitem_table; + GtkMenuShell *menu; + + guint insert_handler; + guint remove_handler; +}; + +struct _PsppireWindowClass +{ + GtkWindowClass parent_class; +}; + +GType psppire_window_get_type (void); +GtkWidget* psppire_window_new (PsppireWindowUsage usage); + +const gchar * psppire_window_get_filename (PsppireWindow *); + +void psppire_window_set_filename (PsppireWindow *w, const gchar *filename); + +void psppire_window_minimise_all (void); + + +G_END_DECLS + +#endif /* __PSPPIRE_WINDOW_H__ */ diff --git a/src/ui/gui/psppire.c b/src/ui/gui/psppire.c index 9dd3b713..bdd5ad53 100644 --- a/src/ui/gui/psppire.c +++ b/src/ui/gui/psppire.c @@ -25,7 +25,7 @@ #include #include "relocatable.h" -#include "data-editor.h" +#include "psppire-data-window.h" #include "psppire.h" #include @@ -52,7 +52,8 @@ #include "message-dialog.h" #include -#include "output-viewer.h" + +#include "psppire-output-window.h" #include #include @@ -67,6 +68,7 @@ static void create_icon_factory (void); struct source_stream *the_source_stream ; struct dataset * the_dataset = NULL; +static GtkWidget *the_data_window; static void replace_casereader (struct casereader *s) @@ -77,6 +79,10 @@ replace_casereader (struct casereader *s) #define _(msgid) gettext (msgid) #define N_(msgid) msgid + +const char * output_file_name (void); + + void initialize (struct command_line_processor *clp, int argc, char **argv) { @@ -116,8 +122,6 @@ initialize (struct command_line_processor *clp, int argc, char **argv) the_data_store = psppire_data_store_new (dictionary); replace_casereader (NULL); - - create_icon_factory (); { @@ -143,14 +147,16 @@ initialize (struct command_line_processor *clp, int argc, char **argv) journal_enable (); textdomain (PACKAGE); + the_data_window = psppire_data_window_new (); + command_line_processor_replace_aux (clp, &post_init_argp, the_source_stream); command_line_processor_replace_aux (clp, &non_option_argp, the_source_stream); command_line_processor_parse (clp, argc, argv); - new_data_window (NULL, NULL); - execute_syntax (create_syntax_string_source ("")); + + gtk_widget_show (the_data_window); } @@ -288,6 +294,9 @@ parse_non_options (int key, char *arg, struct argp_state *state) ERRMODE_CONTINUE); ds_destroy (&syntax); + + psppire_window_set_filename (the_data_window, arg); + break; } default: @@ -298,3 +307,17 @@ parse_non_options (int key, char *arg, struct argp_state *state) const struct argp non_option_argp = {NULL, parse_non_options, 0, 0, 0, 0, 0}; + + +const char * +output_file_name (void) +{ + const char *dir = default_output_path (); + static char *filename = NULL; + + if ( NULL == filename ) + filename = xasprintf ("%s%s", dir, OUTPUT_FILE_NAME); + + + return filename; +} diff --git a/src/ui/gui/rank-dialog.c b/src/ui/gui/rank-dialog.c index bf44dced..8ea25a1d 100644 --- a/src/ui/gui/rank-dialog.c +++ b/src/ui/gui/rank-dialog.c @@ -22,13 +22,13 @@ #include #include -#include +#include #include #include #include #include #include -#include +#include #include "gettext.h" #define _(msgid) gettext (msgid) @@ -220,7 +220,7 @@ void rank_dialog (GObject *o, gpointer data) { gint response; - struct data_editor *de = data; + PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data); struct rank_dialog rd; @@ -304,7 +304,7 @@ rank_dialog (GObject *o, gpointer data) G_CALLBACK (on_ntiles_toggle), rd.ntiles_entry); - gtk_window_set_transient_for (GTK_WINDOW (rd.dialog), de->parent.window); + gtk_window_set_transient_for (GTK_WINDOW (rd.dialog), GTK_WINDOW (de)); attach_dictionary_to_treeview (GTK_TREE_VIEW (vars), vs->dict, @@ -349,6 +349,7 @@ rank_dialog (GObject *o, gpointer data) case GTK_RESPONSE_OK: { gchar *syntax = generate_syntax (&rd); + struct getl_interface *sss = create_syntax_string_source (syntax); execute_syntax (sss); @@ -358,12 +359,7 @@ rank_dialog (GObject *o, gpointer data) case PSPPIRE_RESPONSE_PASTE: { gchar *syntax = generate_syntax (&rd); - - struct syntax_editor *se = - (struct syntax_editor *) window_create (WINDOW_SYNTAX, NULL); - - gtk_text_buffer_insert_at_cursor (se->buffer, syntax, -1); - + paste_syntax_in_new_window (syntax); g_free (syntax); } break; diff --git a/src/ui/gui/recode-dialog.c b/src/ui/gui/recode-dialog.c index 9d1ad79d..859737f6 100644 --- a/src/ui/gui/recode-dialog.c +++ b/src/ui/gui/recode-dialog.c @@ -27,13 +27,13 @@ #include #include -#include +#include #include #include #include #include #include -#include +#include #include #include "psppire-acr.h" @@ -470,14 +470,14 @@ toggle_sensitivity (GtkToggleButton *button, GtkWidget *target) gtk_widget_set_sensitive (target, state); } -static void recode_dialog (struct data_editor *de, gboolean diff); +static void recode_dialog (PsppireDataWindow *de, gboolean diff); /* Pops up the Recode Same version of the dialog box */ void recode_same_dialog (GObject *o, gpointer data) { - struct data_editor *de = data; + PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data); recode_dialog (de, FALSE); } @@ -486,7 +486,7 @@ recode_same_dialog (GObject *o, gpointer data) void recode_different_dialog (GObject *o, gpointer data) { - struct data_editor *de = data; + PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data); recode_dialog (de, TRUE); } @@ -836,7 +836,7 @@ set_acr (struct recode_dialog *rd) } static void -recode_dialog (struct data_editor *de, gboolean diff) +recode_dialog (PsppireDataWindow *de, gboolean diff) { gint response; @@ -882,7 +882,7 @@ recode_dialog (struct data_editor *de, gboolean diff) rd.different = diff; - gtk_window_set_transient_for (GTK_WINDOW (rd.dialog), de->parent.window); + gtk_window_set_transient_for (GTK_WINDOW (rd.dialog), GTK_WINDOW (de)); attach_dictionary_to_treeview (GTK_TREE_VIEW (rd.dict_treeview), @@ -993,7 +993,7 @@ recode_dialog (struct data_editor *de, gboolean diff) PSPPIRE_DIALOG (get_widget_assert (builder, "old-new-values-dialog")); gtk_window_set_transient_for (GTK_WINDOW (rd.old_and_new_dialog), - de->parent.window); + GTK_WINDOW (de)); rd.acr = PSPPIRE_ACR (get_widget_assert (builder, "psppire-acr1")); @@ -1084,6 +1084,7 @@ recode_dialog (struct data_editor *de, gboolean diff) case GTK_RESPONSE_OK: { gchar *syntax = generate_syntax (&rd); + struct getl_interface *sss = create_syntax_string_source (syntax); execute_syntax (sss); @@ -1093,11 +1094,7 @@ recode_dialog (struct data_editor *de, gboolean diff) case PSPPIRE_RESPONSE_PASTE: { gchar *syntax = generate_syntax (&rd); - - struct syntax_editor *se = - (struct syntax_editor *) window_create (WINDOW_SYNTAX, NULL); - - gtk_text_buffer_insert_at_cursor (se->buffer, syntax, -1); + paste_syntax_in_new_window (syntax); g_free (syntax); } diff --git a/src/ui/gui/regression-dialog.c b/src/ui/gui/regression-dialog.c index 3e0e0fbc..2d8aca3e 100644 --- a/src/ui/gui/regression-dialog.c +++ b/src/ui/gui/regression-dialog.c @@ -23,13 +23,13 @@ #include #include -#include +#include #include #include #include #include #include -#include +#include #include "gettext.h" #define _(msgid) gettext (msgid) @@ -223,11 +223,10 @@ void regression_dialog (GObject *o, gpointer data) { gint response; - struct data_editor *de = data; - struct regression_dialog rd; GtkBuilder *xml = builder_new ("regression.ui"); + PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data); PsppireVarStore *vs; GtkWidget *dialog = get_widget_assert (xml, "regression-dialog"); @@ -251,7 +250,7 @@ regression_dialog (GObject *o, gpointer data) stats ); - gtk_window_set_transient_for (GTK_WINDOW (dialog), de->parent.window); + gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (de)); attach_dictionary_to_treeview (GTK_TREE_VIEW (source), vs->dict, @@ -286,8 +285,8 @@ regression_dialog (GObject *o, gpointer data) rd.current_opts.pred = FALSE; rd.current_opts.resid = FALSE; - gtk_window_set_transient_for (GTK_WINDOW (rd.save_dialog), de->parent.window); - gtk_window_set_transient_for (GTK_WINDOW (rd.stat_dialog), de->parent.window); + gtk_window_set_transient_for (GTK_WINDOW (rd.save_dialog), GTK_WINDOW (de)); + gtk_window_set_transient_for (GTK_WINDOW (rd.stat_dialog), GTK_WINDOW (de)); g_signal_connect (dialog, "refresh", G_CALLBACK (refresh), &rd); @@ -307,6 +306,7 @@ regression_dialog (GObject *o, gpointer data) case GTK_RESPONSE_OK: { gchar *syntax = generate_syntax (&rd); + struct getl_interface *sss = create_syntax_string_source (syntax); execute_syntax (sss); @@ -316,11 +316,7 @@ regression_dialog (GObject *o, gpointer data) case PSPPIRE_RESPONSE_PASTE: { gchar *syntax = generate_syntax (&rd); - - struct syntax_editor *se = - (struct syntax_editor *) window_create (WINDOW_SYNTAX, NULL); - - gtk_text_buffer_insert_at_cursor (se->buffer, syntax, -1); + paste_syntax_in_new_window (syntax); g_free (syntax); } diff --git a/src/ui/gui/select-cases-dialog.c b/src/ui/gui/select-cases-dialog.c index 143f7a6d..d953308a 100644 --- a/src/ui/gui/select-cases-dialog.c +++ b/src/ui/gui/select-cases-dialog.c @@ -20,12 +20,12 @@ #include #include "helper.h" #include "psppire-dialog.h" -#include "data-editor.h" +#include "psppire-data-window.h" #include "dialog-common.h" #include "dict-display.h" #include "widget-io.h" #include -#include "syntax-editor.h" +#include "helper.h" #include @@ -240,7 +240,7 @@ select_cases_dialog (GObject *o, gpointer data) gint response; struct select_cases_dialog scd = {0,0,0,0,0,0}; GtkWidget *dialog ; - struct data_editor *de = data; + PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data); GtkWidget *entry = NULL; GtkWidget *selector ; GtkWidget *button_range; @@ -319,7 +319,7 @@ select_cases_dialog (GObject *o, gpointer data) dialog = get_widget_assert (scd.xml, "select-cases-dialog"); - gtk_window_set_transient_for (GTK_WINDOW (dialog), de->parent.window); + gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (de)); { GtkWidget *source = get_widget_assert (scd.xml, "select-cases-treeview"); @@ -353,6 +353,7 @@ select_cases_dialog (GObject *o, gpointer data) case GTK_RESPONSE_OK: { gchar *syntax = generate_syntax (&scd); + struct getl_interface *sss = create_syntax_string_source (syntax); execute_syntax (sss); @@ -362,11 +363,7 @@ select_cases_dialog (GObject *o, gpointer data) case PSPPIRE_RESPONSE_PASTE: { gchar *syntax = generate_syntax (&scd); - - struct syntax_editor *se = - (struct syntax_editor *) window_create (WINDOW_SYNTAX, NULL); - - gtk_text_buffer_insert_at_cursor (se->buffer, syntax, -1); + paste_syntax_in_new_window (syntax); g_free (syntax); } diff --git a/src/ui/gui/sort-cases-dialog.c b/src/ui/gui/sort-cases-dialog.c index dea226c7..d9c665e6 100644 --- a/src/ui/gui/sort-cases-dialog.c +++ b/src/ui/gui/sort-cases-dialog.c @@ -19,13 +19,13 @@ #include "sort-cases-dialog.h" #include "helper.h" #include "psppire-dialog.h" -#include "data-editor.h" +#include "psppire-data-window.h" #include "psppire-var-store.h" #include "dialog-common.h" #include "dict-display.h" #include -#include "syntax-editor.h" +#include "helper.h" static void refresh (PsppireDialog *dialog, GtkTreeView *dest) @@ -91,7 +91,7 @@ void sort_cases_dialog (GObject *o, gpointer data) { gint response; - struct data_editor *de = data; + PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data); struct sort_cases_dialog scd; @@ -108,7 +108,7 @@ sort_cases_dialog (GObject *o, gpointer data) g_object_get (de->data_editor, "var-store", &vs, NULL); - gtk_window_set_transient_for (GTK_WINDOW (dialog), de->parent.window); + gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (de)); attach_dictionary_to_treeview (GTK_TREE_VIEW (source), vs->dict, @@ -143,6 +143,7 @@ sort_cases_dialog (GObject *o, gpointer data) case GTK_RESPONSE_OK: { gchar *syntax = generate_syntax (&scd); + struct getl_interface *sss = create_syntax_string_source (syntax); execute_syntax (sss); @@ -152,11 +153,7 @@ sort_cases_dialog (GObject *o, gpointer data) case PSPPIRE_RESPONSE_PASTE: { gchar *syntax = generate_syntax (&scd); - - struct syntax_editor *se = - (struct syntax_editor *) window_create (WINDOW_SYNTAX, NULL); - - gtk_text_buffer_insert_at_cursor (se->buffer, syntax, -1); + paste_syntax_in_new_window (syntax); g_free (syntax); } diff --git a/src/ui/gui/split-file-dialog.c b/src/ui/gui/split-file-dialog.c index 00f30c62..8708b33f 100644 --- a/src/ui/gui/split-file-dialog.c +++ b/src/ui/gui/split-file-dialog.c @@ -20,10 +20,10 @@ #include "psppire-selector.h" #include "psppire-dialog.h" #include "helper.h" -#include "data-editor.h" +#include "psppire-data-window.h" #include "dict-display.h" #include -#include "syntax-editor.h" +#include "helper.h" #include #include @@ -166,7 +166,7 @@ void split_file_dialog (GObject *o, gpointer data) { gint response; - struct data_editor *de = data; + PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data); struct split_file_dialog sfd; PsppireVarStore *vs ; @@ -210,7 +210,7 @@ split_file_dialog (GObject *o, gpointer data) g_signal_connect (dialog, "refresh", G_CALLBACK (refresh), &sfd); - gtk_window_set_transient_for (GTK_WINDOW (dialog), de->parent.window); + gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (de)); response = psppire_dialog_run (PSPPIRE_DIALOG (dialog)); @@ -220,6 +220,7 @@ split_file_dialog (GObject *o, gpointer data) case GTK_RESPONSE_OK: { gchar *syntax = generate_syntax (&sfd); + struct getl_interface *sss = create_syntax_string_source (syntax); execute_syntax (sss); @@ -229,11 +230,7 @@ split_file_dialog (GObject *o, gpointer data) case PSPPIRE_RESPONSE_PASTE: { gchar *syntax = generate_syntax (&sfd); - - struct syntax_editor *se = - (struct syntax_editor *) window_create (WINDOW_SYNTAX, NULL); - - gtk_text_buffer_insert_at_cursor (se->buffer, syntax, -1); + paste_syntax_in_new_window (syntax); g_free (syntax); } diff --git a/src/ui/gui/syntax-editor-source.c b/src/ui/gui/syntax-editor-source.c index f7617a89..21437051 100644 --- a/src/ui/gui/syntax-editor-source.c +++ b/src/ui/gui/syntax-editor-source.c @@ -26,16 +26,17 @@ #include #include "syntax-editor-source.h" -#include "syntax-editor.h" +#include "psppire-syntax-window.h" #include "xalloc.h" struct syntax_editor_source { struct getl_interface parent; - const struct syntax_editor *se; + GtkTextBuffer *buffer; GtkTextIter i; GtkTextIter end; + const gchar *name; }; @@ -49,10 +50,8 @@ always_false (const struct getl_interface *i UNUSED) static const char * name (const struct getl_interface *i) { - const struct syntax_editor_source *ses = - (const struct syntax_editor_source *) i; - - return window_name ((const struct editor_window *) ses->se); + const struct syntax_editor_source *ses = (const struct syntax_editor_source *) i; + return ses->name; } @@ -81,7 +80,7 @@ read_line_from_buffer (struct getl_interface *i, next_line = ses->i; gtk_text_iter_forward_line (&next_line); - text = gtk_text_buffer_get_text (ses->se->buffer, + text = gtk_text_buffer_get_text (ses->buffer, &ses->i, &next_line, FALSE); g_strchomp (text); @@ -103,16 +102,18 @@ do_close (struct getl_interface *i ) } struct getl_interface * -create_syntax_editor_source (const struct syntax_editor *se, +create_syntax_editor_source (GtkTextBuffer *buffer, GtkTextIter start, - GtkTextIter stop + GtkTextIter stop, + const gchar *nm ) { struct syntax_editor_source *ses = xzalloc (sizeof *ses); - ses->se = se; + ses->buffer = buffer; ses->i = start; ses->end = stop; + ses->name = nm; ses->parent.interactive = always_false; diff --git a/src/ui/gui/syntax-editor-source.h b/src/ui/gui/syntax-editor-source.h index ca198393..f8d08eaa 100644 --- a/src/ui/gui/syntax-editor-source.h +++ b/src/ui/gui/syntax-editor-source.h @@ -23,9 +23,10 @@ struct getl_interface; struct syntax_editor; struct getl_interface * -create_syntax_editor_source (const struct syntax_editor *se, +create_syntax_editor_source (GtkTextBuffer *buffer, GtkTextIter start, - GtkTextIter stop + GtkTextIter stop, + const gchar *name ); diff --git a/src/ui/gui/syntax-editor.c b/src/ui/gui/syntax-editor.c deleted file mode 100644 index 35749fcd..00000000 --- a/src/ui/gui/syntax-editor.c +++ /dev/null @@ -1,556 +0,0 @@ -/* PSPPIRE - a graphical user interface for PSPP. - Copyright (C) 2006 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 - 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, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - 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, see . */ - -#include -#include -#include -#define _(msgid) gettext (msgid) -#define N_(msgid) msgid - -#include -#include -#include -#include -#include "helper.h" -#include "data-editor.h" -#include "about.h" - -#include "window-manager.h" - -#include -#include -#include -#include -#include "syntax-editor.h" -#include "syntax-editor-source.h" - -extern struct source_stream *the_source_stream ; -extern struct dataset *the_dataset; - -static gboolean save_editor_to_file (struct syntax_editor *se, - const gchar *filename, - GError **err); - -/* Append ".sps" to FILENAME if necessary. - The returned result must be freed when no longer required. - */ -static gchar * -append_suffix (const gchar *filename) -{ - if ( ! g_str_has_suffix (filename, ".sps" ) && - ! g_str_has_suffix (filename, ".SPS" ) ) - { - return g_strdup_printf ("%s.sps", filename); - } - - return strdup (filename); -} - -/* If the buffer's modified flag is set, then save it, and close the window. - Otherwise just close the window. -*/ -static void -save_if_modified (struct syntax_editor *se) -{ - struct editor_window *e = (struct editor_window *) se; - if ( TRUE == gtk_text_buffer_get_modified (se->buffer)) - { - gint response; - GtkWidget *dialog = - gtk_message_dialog_new (GTK_WINDOW (e->window), - GTK_DIALOG_MODAL, - GTK_MESSAGE_QUESTION, - GTK_BUTTONS_NONE, - _("Save contents of syntax editor to %s?"), - e->name - ); - - gtk_dialog_add_button (GTK_DIALOG (dialog), - GTK_STOCK_YES, - GTK_RESPONSE_ACCEPT); - gtk_dialog_add_button (GTK_DIALOG (dialog), - GTK_STOCK_NO, - GTK_RESPONSE_REJECT); - gtk_dialog_add_button (GTK_DIALOG (dialog), - GTK_STOCK_CANCEL, - GTK_RESPONSE_CANCEL); - - - response = gtk_dialog_run (GTK_DIALOG (dialog)); - - gtk_widget_destroy (dialog); - - if ( response == GTK_RESPONSE_ACCEPT ) - { - GError *err = NULL; - - if ( ! save_editor_to_file (se, e->name, &err) ) - { - msg (ME, err->message); - g_error_free (err); - } - } - - if ( response == GTK_RESPONSE_CANCEL ) - return ; - } - - gtk_widget_destroy (GTK_WIDGET (e->window)); -} - -/* Callback for the File->SaveAs menuitem */ -static void -on_syntax_save_as (GtkMenuItem *menuitem, gpointer user_data) -{ - GtkFileFilter *filter; - gint response; - struct syntax_editor *se = user_data; - struct editor_window *e = user_data; - - GtkWidget *dialog = - gtk_file_chooser_dialog_new (_("Save Syntax"), - GTK_WINDOW (e->window), - GTK_FILE_CHOOSER_ACTION_SAVE, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_SAVE, 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); - - 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); - - gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), - TRUE); - response = gtk_dialog_run (GTK_DIALOG (dialog)); - - if ( response == GTK_RESPONSE_ACCEPT ) - { - GError *err = NULL; - char *filename = - gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog) ); - - if ( save_editor_to_file (se, filename, &err) ) - { - g_free (e->name); - e->name = g_strdup (filename); - } - else - { - msg ( ME, err->message ); - g_error_free (err); - } - - free (filename); - } - - gtk_widget_destroy ( dialog ); -} - -/* Callback for the File->Save menuitem */ -static void -on_syntax_save (GtkMenuItem *menuitem, gpointer user_data) -{ - struct syntax_editor *se = user_data; - struct editor_window *e = user_data; - - if ( e->name == NULL ) - on_syntax_save_as (menuitem, user_data); - else - { - GError *err = NULL; - save_editor_to_file (se, e->name, &err); - if ( err ) - { - msg (ME, err->message); - g_error_free (err); - } - } -} - - -/* Callback for the "delete" action (clicking the x on the top right - hand corner of the window) */ -static gboolean -on_delete (GtkWidget *w, GdkEvent *event, gpointer user_data) -{ - struct syntax_editor *se = user_data; - save_if_modified (se); - return TRUE; -} - - -/* Callback for the File->Quit menuitem */ -static gboolean -on_quit (GtkMenuItem *menuitem, gpointer user_data) -{ - struct syntax_editor *se = user_data; - save_if_modified (se); - return FALSE; -} - -static void -editor_execute_syntax (const struct syntax_editor *se, GtkTextIter start, - GtkTextIter stop) -{ - execute_syntax (create_syntax_editor_source (se, start, stop)); -} - -/* Parse and execute all the text in the buffer */ -static void -on_run_all (GtkMenuItem *menuitem, gpointer user_data) -{ - GtkTextIter begin, end; - struct syntax_editor *se = user_data; - - gtk_text_buffer_get_iter_at_offset (se->buffer, &begin, 0); - gtk_text_buffer_get_iter_at_offset (se->buffer, &end, -1); - - editor_execute_syntax (se, begin, end); -} - -/* Parse and execute the currently selected text */ -static void -on_run_selection (GtkMenuItem *menuitem, gpointer user_data) -{ - GtkTextIter begin, end; - struct syntax_editor *se = user_data; - - if ( gtk_text_buffer_get_selection_bounds (se->buffer, &begin, &end) ) - editor_execute_syntax (se, begin, end); -} - - -/* Parse and execute the current line */ -static void -on_run_current_line (GtkMenuItem *menuitem, gpointer user_data) -{ - GtkTextIter begin, end; - GtkTextIter here; - gint line; - - struct syntax_editor *se = user_data; - - /* Get the current line */ - gtk_text_buffer_get_iter_at_mark (se->buffer, - &here, - gtk_text_buffer_get_insert (se->buffer) - ); - - line = gtk_text_iter_get_line (&here) ; - - /* Now set begin and end to the start of this line, and start of - following line respectively */ - gtk_text_buffer_get_iter_at_line (se->buffer, &begin, line); - gtk_text_buffer_get_iter_at_line (se->buffer, &end, line + 1); - - editor_execute_syntax (se, begin, end); -} - - - -/* Parse and execute the from the current line, to the end of the - buffer */ -static void -on_run_to_end (GtkMenuItem *menuitem, gpointer user_data) -{ - GtkTextIter begin, end; - GtkTextIter here; - gint line; - - struct syntax_editor *se = user_data; - - /* Get the current line */ - gtk_text_buffer_get_iter_at_mark (se->buffer, - &here, - gtk_text_buffer_get_insert (se->buffer) - ); - - line = gtk_text_iter_get_line (&here) ; - - /* Now set begin and end to the start of this line, and end of buffer - respectively */ - gtk_text_buffer_get_iter_at_line (se->buffer, &begin, line); - gtk_text_buffer_get_iter_at_line (se->buffer, &end, -1); - - editor_execute_syntax (se, begin, end); -} - - - - -/* - Create a new syntax editor with NAME. - If NAME is NULL, a name will be automatically assigned -*/ -struct syntax_editor * -new_syntax_editor (void) -{ - GladeXML *xml = XML_NEW ("syntax-editor.glade"); - - GtkWidget *text_view; - struct syntax_editor *se ; - struct editor_window *e; - - connect_help (xml); - - se = g_malloc (sizeof (*se)); - - e = (struct editor_window *)se; - - e->window = GTK_WINDOW (get_widget_assert (xml, "syntax_editor")); - text_view = get_widget_assert (xml, "syntax_text_view"); - se->buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view)); - se->lexer = lex_create (the_source_stream); - - g_signal_connect (get_widget_assert (xml,"file_new_syntax"), - "activate", - G_CALLBACK (new_syntax_window), - e->window); - - g_signal_connect (get_widget_assert (xml,"file_open_syntax"), - "activate", - G_CALLBACK (open_syntax_window), - e->window); - - g_signal_connect (get_widget_assert (xml,"file_new_data"), - "activate", - G_CALLBACK (new_data_window), - e->window); - - g_signal_connect (get_widget_assert (xml,"help_about"), - "activate", - G_CALLBACK (about_new), - e->window); - - g_signal_connect (get_widget_assert (xml,"help_reference"), - "activate", - G_CALLBACK (reference_manual), - NULL); - - - g_signal_connect (get_widget_assert (xml, "file_save"), - "activate", - G_CALLBACK (on_syntax_save), - se); - - g_signal_connect (get_widget_assert (xml, "file_save_as"), - "activate", - G_CALLBACK (on_syntax_save_as), - se); - - - g_signal_connect (get_widget_assert (xml,"file_quit"), - "activate", - G_CALLBACK (on_quit), - se); - - - g_signal_connect (get_widget_assert (xml,"run_all"), - "activate", - G_CALLBACK (on_run_all), - se); - - - g_signal_connect (get_widget_assert (xml,"run_selection"), - "activate", - G_CALLBACK (on_run_selection), - se); - - g_signal_connect (get_widget_assert (xml,"run_current_line"), - "activate", - G_CALLBACK (on_run_current_line), - se); - - - g_signal_connect (get_widget_assert (xml,"run_to_end"), - "activate", - G_CALLBACK (on_run_to_end), - se); - - - g_signal_connect (get_widget_assert (xml,"windows_minimise_all"), - "activate", - G_CALLBACK (minimise_all_windows), - NULL); - - - - g_object_unref (xml); - - g_signal_connect (e->window, "delete-event", - G_CALLBACK (on_delete), se); - - - - return se; -} - -/* - Callback for the File->New->Syntax menuitem -*/ -void -new_syntax_window (GtkMenuItem *menuitem, - gpointer user_data) -{ - window_create (WINDOW_SYNTAX, NULL); -} - - -/* - Save BUFFER to the file called FILENAME. - If successful, clears the buffer's modified flag -*/ -static gboolean -save_editor_to_file (struct syntax_editor *se, - const gchar *filename, - GError **err) -{ - GtkTextBuffer *buffer = se->buffer; - gboolean result ; - GtkTextIter start, stop; - gchar *text; - - gchar *suffixedname; - gchar *glibfilename; - g_assert (filename); - - suffixedname = append_suffix (filename); - - glibfilename = g_filename_from_utf8 (suffixedname, -1, 0, 0, err); - - g_free ( suffixedname); - - if ( ! glibfilename ) - return FALSE; - - gtk_text_buffer_get_iter_at_line (buffer, &start, 0); - gtk_text_buffer_get_iter_at_offset (buffer, &stop, -1); - - text = gtk_text_buffer_get_text (buffer, &start, &stop, FALSE); - - result = g_file_set_contents (glibfilename, text, -1, err); - - if ( result ) - { - window_set_name_from_filename ((struct editor_window *) se, filename); - gtk_text_buffer_set_modified (buffer, FALSE); - } - - return result; -} - - -/* - Loads the buffer from the file called FILENAME -*/ -gboolean -load_editor_from_file (struct syntax_editor *se, - const gchar *filename, - GError **err) -{ - GtkTextBuffer *buffer = se->buffer; - gchar *text; - GtkTextIter iter; - - gchar *glibfilename = g_filename_from_utf8 (filename, -1, 0, 0, err); - - if ( ! glibfilename ) - return FALSE; - - /* FIXME: What if it's a very big file ? */ - if ( ! g_file_get_contents (glibfilename, &text, NULL, err) ) - { - g_free (glibfilename); - return FALSE; - } - g_free (glibfilename); - - gtk_text_buffer_get_iter_at_line (buffer, &iter, 0); - - gtk_text_buffer_insert (buffer, &iter, text, -1); - - - window_set_name_from_filename ((struct editor_window *)se, filename); - gtk_text_buffer_set_modified (buffer, FALSE); - - return TRUE; -} - - -/* Callback for the File->Open->Syntax menuitem */ -void -open_syntax_window (GtkMenuItem *menuitem, gpointer parent) -{ - 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); - - 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)); - - struct syntax_editor *se = (struct syntax_editor *) - window_create (WINDOW_SYNTAX, file_name); - - if ( load_editor_from_file (se, file_name, NULL) ) -#if RECENT_LISTS_AVAILABLE - { - GtkRecentManager *manager = gtk_recent_manager_get_default(); - gchar *uri = g_filename_to_uri (file_name, NULL, NULL); - - gtk_recent_manager_remove_item (manager, uri, NULL); - if ( ! gtk_recent_manager_add_item (manager, uri)) - g_warning ("Could not add item %s to recent list\n",uri); - - g_free (uri); - } -#else - ; -#endif - - } - - gtk_widget_destroy (dialog); -} - diff --git a/src/ui/gui/syntax-editor.h b/src/ui/gui/syntax-editor.h deleted file mode 100644 index b3943ec8..00000000 --- a/src/ui/gui/syntax-editor.h +++ /dev/null @@ -1,44 +0,0 @@ -/* PSPPIRE - a graphical user interface for PSPP. - Copyright (C) 2006 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 - 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, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - 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, see . */ - - -#ifndef SYNTAX_EDITOR_H -#define SYNTAX_EDITOR_H - -#include - -#include "window-manager.h" - -struct lexer; - -struct syntax_editor -{ - struct editor_window parent; - GtkTextBuffer *buffer; /* The buffer which contains the text */ - struct lexer *lexer; /* Lexer to parse syntax */ -}; - - -struct syntax_editor * new_syntax_editor (void); - -void new_syntax_window (GtkMenuItem *, gpointer); - -void open_syntax_window (GtkMenuItem *, gpointer); - -gboolean load_editor_from_file (struct syntax_editor *se, - const gchar *filename, - GError **err); -#endif diff --git a/src/ui/gui/t-test-independent-samples-dialog.c b/src/ui/gui/t-test-independent-samples-dialog.c index 22b4526c..392867ad 100644 --- a/src/ui/gui/t-test-independent-samples-dialog.c +++ b/src/ui/gui/t-test-independent-samples-dialog.c @@ -22,7 +22,7 @@ #include "psppire-dict.h" #include "psppire-var-store.h" #include "helper.h" -#include "data-editor.h" +#include "psppire-data-window.h" #include "psppire-dialog.h" #include "dialog-common.h" #include "dict-display.h" @@ -31,7 +31,7 @@ #include #include -#include "syntax-editor.h" +#include "helper.h" #include @@ -391,7 +391,7 @@ t_test_independent_samples_dialog (GObject *o, gpointer data) { struct tt_indep_samples_dialog tt_d; gint response; - struct data_editor *de = data; + PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data); PsppireVarStore *vs = NULL; @@ -420,11 +420,11 @@ t_test_independent_samples_dialog (GObject *o, gpointer data) tt_d.define_groups_button = get_widget_assert (xml, "define-groups-button"); tt_d.groups_entry = get_widget_assert (xml, "indep-samples-t-test-entry"); - tt_d.opts = tt_options_dialog_create (xml, de->parent.window); - tt_d.grps = tt_groups_dialog_create (xml, de->parent.window); + tt_d.opts = tt_options_dialog_create (xml, GTK_WINDOW (de)); + tt_d.grps = tt_groups_dialog_create (xml, GTK_WINDOW (de)); - gtk_window_set_transient_for (GTK_WINDOW (tt_d.dialog), de->parent.window); + gtk_window_set_transient_for (GTK_WINDOW (tt_d.dialog), GTK_WINDOW (de)); attach_dictionary_to_treeview (GTK_TREE_VIEW (dict_view), vs->dict, @@ -474,6 +474,7 @@ t_test_independent_samples_dialog (GObject *o, gpointer data) case GTK_RESPONSE_OK: { gchar *syntax = generate_syntax (&tt_d); + struct getl_interface *sss = create_syntax_string_source (syntax); execute_syntax (sss); @@ -483,12 +484,7 @@ t_test_independent_samples_dialog (GObject *o, gpointer data) case PSPPIRE_RESPONSE_PASTE: { gchar *syntax = generate_syntax (&tt_d); - - struct syntax_editor *se = - (struct syntax_editor *) window_create (WINDOW_SYNTAX, NULL); - - gtk_text_buffer_insert_at_cursor (se->buffer, syntax, -1); - + paste_syntax_in_new_window (syntax); g_free (syntax); } break; diff --git a/src/ui/gui/t-test-one-sample.c b/src/ui/gui/t-test-one-sample.c index 98d9601b..3cdc91c3 100644 --- a/src/ui/gui/t-test-one-sample.c +++ b/src/ui/gui/t-test-one-sample.c @@ -22,7 +22,7 @@ #include "psppire-dict.h" #include "psppire-var-store.h" #include "helper.h" -#include "data-editor.h" +#include "psppire-data-window.h" #include "psppire-dialog.h" #include "dialog-common.h" #include "dict-display.h" @@ -30,7 +30,6 @@ #include "t-test-options.h" #include -#include "syntax-editor.h" #include #define _(msgid) gettext (msgid) @@ -123,7 +122,7 @@ t_test_one_sample_dialog (GObject *o, gpointer data) { struct tt_one_sample_dialog tt_d; gint response; - struct data_editor *de = data; + PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data); PsppireVarStore *vs = NULL; @@ -144,9 +143,9 @@ t_test_one_sample_dialog (GObject *o, gpointer data) tt_d.dict = vs->dict; tt_d.vars_treeview = get_widget_assert (xml, "one-sample-t-test-treeview1"); tt_d.test_value_entry = get_widget_assert (xml, "test-value-entry"); - tt_d.opt = tt_options_dialog_create (xml, de->parent.window); + tt_d.opt = tt_options_dialog_create (xml, GTK_WINDOW (de)); - gtk_window_set_transient_for (GTK_WINDOW (dialog), de->parent.window); + gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (de)); attach_dictionary_to_treeview (GTK_TREE_VIEW (dict_view), vs->dict, @@ -180,6 +179,7 @@ t_test_one_sample_dialog (GObject *o, gpointer data) case GTK_RESPONSE_OK: { gchar *syntax = generate_syntax (&tt_d); + struct getl_interface *sss = create_syntax_string_source (syntax); execute_syntax (sss); @@ -190,10 +190,7 @@ t_test_one_sample_dialog (GObject *o, gpointer data) { gchar *syntax = generate_syntax (&tt_d); - struct syntax_editor *se = - (struct syntax_editor *) window_create (WINDOW_SYNTAX, NULL); - - gtk_text_buffer_insert_at_cursor (se->buffer, syntax, -1); + paste_syntax_in_new_window (syntax); g_free (syntax); } diff --git a/src/ui/gui/t-test-paired-samples.c b/src/ui/gui/t-test-paired-samples.c index ec709603..ca1d776a 100644 --- a/src/ui/gui/t-test-paired-samples.c +++ b/src/ui/gui/t-test-paired-samples.c @@ -19,7 +19,7 @@ #include #include -#include "data-editor.h" +#include "psppire-data-window.h" #include "psppire-dict.h" #include "psppire-var-store.h" @@ -30,8 +30,6 @@ #include "dialog-common.h" #include "psppire-dialog.h" -#include "syntax-editor.h" - #include "helper.h" #include "psppire-var-ptr.h" @@ -182,7 +180,7 @@ t_test_paired_samples_dialog (GObject *o, gpointer data) { struct tt_paired_samples_dialog tt_d; gint response; - struct data_editor *de = data; + PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data); PsppireVarStore *vs = NULL; @@ -202,9 +200,9 @@ t_test_paired_samples_dialog (GObject *o, gpointer data) tt_d.dict = vs->dict; tt_d.pairs_treeview = get_widget_assert (xml, "paired-samples-t-test-treeview2"); - tt_d.opt = tt_options_dialog_create (xml, de->parent.window); + tt_d.opt = tt_options_dialog_create (xml, GTK_WINDOW (de)); - gtk_window_set_transient_for (GTK_WINDOW (dialog), de->parent.window); + gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (de)); attach_dictionary_to_treeview (GTK_TREE_VIEW (dict_view), @@ -254,6 +252,7 @@ t_test_paired_samples_dialog (GObject *o, gpointer data) case GTK_RESPONSE_OK: { gchar *syntax = generate_syntax (&tt_d); + struct getl_interface *sss = create_syntax_string_source (syntax); execute_syntax (sss); @@ -263,11 +262,7 @@ t_test_paired_samples_dialog (GObject *o, gpointer data) case PSPPIRE_RESPONSE_PASTE: { gchar *syntax = generate_syntax (&tt_d); - - struct syntax_editor *se = - (struct syntax_editor *) window_create (WINDOW_SYNTAX, NULL); - - gtk_text_buffer_insert_at_cursor (se->buffer, syntax, -1); + paste_syntax_in_new_window (syntax); g_free (syntax); } diff --git a/src/ui/gui/text-data-import-dialog.c b/src/ui/gui/text-data-import-dialog.c index a82a81a1..fa55bba5 100644 --- a/src/ui/gui/text-data-import-dialog.c +++ b/src/ui/gui/text-data-import-dialog.c @@ -39,13 +39,13 @@ #include #include #include -#include +#include #include #include #include #include #include -#include +#include #include "error.h" #include "xalloc.h" @@ -63,7 +63,7 @@ text_data_import_assistant (GObject *o, gpointer de_) struct data_editor *de = de_; GtkWidget *dialog = - gtk_message_dialog_new (de->parent.window, + gtk_message_dialog_new (GTK_WINDOW (de), GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_CLOSE, @@ -259,7 +259,7 @@ void text_data_import_assistant (GObject *o, gpointer de_) { struct data_editor *de = de_; - GtkWindow *parent_window = de->parent.window; + GtkWindow *parent_window = GTK_WINDOW (de); struct import_assistant *ia; ia = xzalloc (sizeof *ia); @@ -293,9 +293,7 @@ text_data_import_assistant (GObject *o, gpointer de_) case PSPPIRE_RESPONSE_PASTE: { char *syntax = generate_syntax (ia); - struct syntax_editor *se = - (struct syntax_editor *) window_create (WINDOW_SYNTAX, NULL); - gtk_text_buffer_insert_at_cursor (se->buffer, syntax, -1); + paste_syntax_in_new_window (syntax); free (syntax); } break; @@ -2305,7 +2303,7 @@ pop_watch_cursor (struct import_assistant *ia) { if (--ia->asst.watch_cursor == 0) { - GtkWidget *widget = GTK_WIDGET (ia->asst.assistant);; + GtkWidget *widget = GTK_WIDGET (ia->asst.assistant); gdk_window_set_cursor (widget->window, NULL); } } diff --git a/src/ui/gui/transpose-dialog.c b/src/ui/gui/transpose-dialog.c index 272ef1b3..09756d37 100644 --- a/src/ui/gui/transpose-dialog.c +++ b/src/ui/gui/transpose-dialog.c @@ -20,10 +20,10 @@ #include "psppire-selector.h" #include "psppire-dialog.h" #include "helper.h" -#include "data-editor.h" +#include "psppire-data-window.h" #include "dict-display.h" #include -#include "syntax-editor.h" +#include "helper.h" #include "dialog-common.h" @@ -79,7 +79,7 @@ void transpose_dialog (GObject *o, gpointer data) { gint response ; - struct data_editor *de = data; + PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data); GtkBuilder *xml = builder_new ("psppire.ui"); @@ -116,7 +116,7 @@ transpose_dialog (GObject *o, gpointer data) g_signal_connect (dialog, "refresh", G_CALLBACK (refresh), xml); - gtk_window_set_transient_for (GTK_WINDOW (dialog), de->parent.window); + gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (de)); psppire_dialog_set_valid_predicate (PSPPIRE_DIALOG (dialog), dialog_state_valid, xml); @@ -128,6 +128,7 @@ transpose_dialog (GObject *o, gpointer data) case GTK_RESPONSE_OK: { gchar *syntax = generate_syntax (vs->dict, xml); + struct getl_interface *sss = create_syntax_string_source (syntax); execute_syntax (sss); @@ -137,11 +138,7 @@ transpose_dialog (GObject *o, gpointer data) case PSPPIRE_RESPONSE_PASTE: { gchar *syntax = generate_syntax (vs->dict, xml); - - struct syntax_editor *se = - (struct syntax_editor *) window_create (WINDOW_SYNTAX, NULL); - - gtk_text_buffer_insert_at_cursor (se->buffer, syntax, -1); + paste_syntax_in_new_window (syntax); g_free (syntax); } diff --git a/src/ui/gui/variable-info-dialog.c b/src/ui/gui/variable-info-dialog.c index 22af89f0..2f5495f1 100644 --- a/src/ui/gui/variable-info-dialog.c +++ b/src/ui/gui/variable-info-dialog.c @@ -22,13 +22,13 @@ #include #include #include -#include "data-editor.h" +#include "psppire-data-window.h" #include "psppire-dialog.h" #include "psppire-var-store.h" #include "helper.h" #include -#include "syntax-editor.h" +#include "helper.h" #include @@ -163,7 +163,7 @@ static gchar * generate_syntax (GtkTreeView *treeview); void variable_info_dialog (GObject *o, gpointer data) { - struct data_editor *de = data; + PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data); gint response ; @@ -177,7 +177,7 @@ variable_info_dialog (GObject *o, gpointer data) g_object_get (de->data_editor, "var-store", &vs, NULL); - gtk_window_set_transient_for (GTK_WINDOW (dialog), de->parent.window); + gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (de)); attach_dictionary_to_treeview (GTK_TREE_VIEW (treeview), vs->dict, @@ -213,11 +213,7 @@ variable_info_dialog (GObject *o, gpointer data) case PSPPIRE_RESPONSE_PASTE: { gchar *syntax = generate_syntax (GTK_TREE_VIEW (treeview)); - - struct syntax_editor *se = - (struct syntax_editor *) window_create (WINDOW_SYNTAX, NULL); - - gtk_text_buffer_insert_at_cursor (se->buffer, syntax, -1); + paste_syntax_in_new_window (syntax); g_free (syntax); } diff --git a/src/ui/gui/weight-cases-dialog.c b/src/ui/gui/weight-cases-dialog.c index 8b46ca5e..a464646f 100644 --- a/src/ui/gui/weight-cases-dialog.c +++ b/src/ui/gui/weight-cases-dialog.c @@ -20,10 +20,10 @@ #include "psppire-selector.h" #include "psppire-dialog.h" #include "helper.h" -#include "data-editor.h" +#include "psppire-data-window.h" #include "dict-display.h" #include -#include "syntax-editor.h" +#include "helper.h" #include @@ -103,7 +103,7 @@ void weight_cases_dialog (GObject *o, gpointer data) { gint response; - struct data_editor *de = data; + PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data); struct weight_cases_dialog wcd; GtkBuilder *xml = builder_new ("psppire.ui"); @@ -121,7 +121,7 @@ weight_cases_dialog (GObject *o, gpointer data) g_object_get (de->data_editor, "var-store", &vs, NULL); - gtk_window_set_transient_for (GTK_WINDOW (dialog), de->parent.window); + gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (de)); g_signal_connect (radiobutton1, "toggled", G_CALLBACK (on_toggle), entry); g_signal_connect (selector, "selected", G_CALLBACK (on_select), @@ -171,12 +171,7 @@ weight_cases_dialog (GObject *o, gpointer data) case PSPPIRE_RESPONSE_PASTE: { gchar *syntax = generate_syntax (&wcd); - - struct syntax_editor *se = - (struct syntax_editor *) window_create (WINDOW_SYNTAX, NULL); - - gtk_text_buffer_insert_at_cursor (se->buffer, syntax, -1); - + paste_syntax_in_new_window (syntax); g_free (syntax); } break; diff --git a/src/ui/gui/window-manager.c b/src/ui/gui/window-manager.c deleted file mode 100644 index 91f44a59..00000000 --- a/src/ui/gui/window-manager.c +++ /dev/null @@ -1,198 +0,0 @@ -/* PSPPIRE - a graphical user interface for PSPP. - Copyright (C) 2006, 2007 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 - 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, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - 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, see . */ - - -#include - -#include "relocatable.h" - -#include -#include "syntax-editor.h" -#include "data-editor.h" -#include "output-viewer.h" - -#include -#define _(msgid) gettext (msgid) -#define N_(msgid) msgid - - -#include "window-manager.h" - - - -/* A list of struct editor_windows */ -static GSList *window_list = NULL; - - -static void -deregister_window (GtkWindow *w, gpointer data) -{ - struct editor_window *e = data; - - window_list = g_slist_remove (window_list, e); - - if ( g_slist_length (window_list) == 0 ) - gtk_main_quit (); -}; - - -static void -register_window (struct editor_window *e) -{ - window_list = g_slist_prepend (window_list, e); -} - - -static gint -next_window_id (void) -{ - return g_slist_length (window_list); -} - -void -minimise_all_windows (void) -{ - const GSList *i = NULL; - - for (i = window_list; i != NULL ; i = i->next) - { - struct editor_window *e = i->data; - gtk_window_iconify (e->window); - } -} - -static void set_window_name (struct editor_window *e, const gchar *name ); - - -struct editor_window * -window_create (enum window_type type, const gchar *name) -{ - struct editor_window *e; - switch (type) - { - case WINDOW_SYNTAX: - e = (struct editor_window *) new_syntax_editor (); - break; - case WINDOW_DATA: - e = (struct editor_window *) new_data_editor (); - break; - case WINDOW_OUTPUT: - e = (struct editor_window *) new_output_viewer (); - break; - default: - g_assert_not_reached (); - }; - - e->type = type; - e->name = NULL; - - set_window_name (e, name); - - - gtk_window_set_icon_from_file (GTK_WINDOW (e->window), - relocate (PKGDATADIR "/psppicon.png"), 0); - - g_signal_connect (e->window, "destroy", - G_CALLBACK (deregister_window), e); - - register_window (e); - - gtk_widget_show (GTK_WIDGET (e->window)); - - return e; -} - -void -default_window_name (struct editor_window *w) -{ - set_window_name (w, NULL); -} - -static void -set_window_name (struct editor_window *e, - const gchar *name ) -{ - gchar *title ; - g_free (e->name); - - e->name = NULL; - - if ( name ) - { - e->name = g_strdup (name); - return; - } - - switch (e->type ) - { - case WINDOW_SYNTAX: - e->name = g_strdup_printf (_("Syntax%d"), next_window_id () ); - title = g_strdup_printf (_("%s --- PSPP Syntax Editor"), e->name); - break; - case WINDOW_DATA: - e->name = g_strdup_printf (_("Untitled%d"), next_window_id () ); - title = g_strdup_printf (_("%s --- PSPP Data Editor"), e->name); - break; - case WINDOW_OUTPUT: - e->name = g_strdup_printf (_("Output%d"), next_window_id () ); - title = g_strdup_printf (_("%s --- PSPP Output"), e->name); - break; - default: - g_assert_not_reached (); - } - - gtk_window_set_title (GTK_WINDOW (e->window), title); - - g_free (title); -} - - -/* Set the name of this window based on FILENAME. - FILENAME is in "filename encoding" */ -void -window_set_name_from_filename (struct editor_window *e, - const gchar *fn) -{ - gchar *title; - gchar *filename = g_filename_to_utf8 (fn, -1, NULL, NULL, NULL); - gchar *basename = g_path_get_basename (filename); - - set_window_name (e, filename); - - switch (e->type) - { - case WINDOW_SYNTAX: - title = g_strdup_printf (_("%s --- PSPP Syntax Editor"), basename); - break; - case WINDOW_DATA: - title = g_strdup_printf (_("%s --- PSPP Data Editor"), basename); - break; - default: - g_assert_not_reached (); - } - g_free (basename); - - gtk_window_set_title (GTK_WINDOW (e->window), title); - - g_free (title); - g_free (filename); -} - -const gchar * -window_name (const struct editor_window *e) -{ - return e->name; -} diff --git a/src/ui/gui/window-manager.h b/src/ui/gui/window-manager.h deleted file mode 100644 index 2bb2fd7c..00000000 --- a/src/ui/gui/window-manager.h +++ /dev/null @@ -1,53 +0,0 @@ -/* PSPPIRE - a graphical user interface for PSPP. - Copyright (C) 2007 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 - 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, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - 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, see . */ - - -#ifndef WINDOW_MANAGER_H -#define WINDOW_MANAGER_H - -#include - -enum window_type - { - WINDOW_DATA, - WINDOW_SYNTAX, - WINDOW_OUTPUT - }; - - -struct editor_window - { - GtkWindow *window; /* The top level window of the editor */ - gchar *name; /* The name of this editor (UTF-8) */ - enum window_type type; - } ; - -struct editor_window * window_create (enum window_type type, - const gchar *name); - -const gchar * window_name (const struct editor_window *); - -/* Set the name of this window based on FILENAME. - FILENAME is in "filename encoding" */ -void window_set_name_from_filename (struct editor_window *e, - const gchar *filename); - -void default_window_name (struct editor_window *w); - -void minimise_all_windows (void); - - -#endif