Merge commit 'origin/master' into sso
authorJohn Darrington <john@darrington.wattle.id.au>
Sun, 17 Oct 2010 19:04:28 +0000 (21:04 +0200)
committerJohn Darrington <john@darrington.wattle.id.au>
Sun, 17 Oct 2010 19:04:28 +0000 (21:04 +0200)
Conflicts:

src/ui/gui/psppire-syntax-window.c

1  2 
configure.ac
src/ui/gui/automake.mk
src/ui/gui/psppire-data-window.c
src/ui/gui/psppire-syntax-window.c
src/ui/gui/psppire-syntax-window.h

diff --combined configure.ac
index 177ca576a2ab09c9fcd9dde6fe257722bc940322,b06392a58670395c1790406c14b311ab98f0821f..abf7afadedb7f247295e88545270abbaad9dec53
@@@ -2,7 -2,7 +2,7 @@@ dnl Process this file with autoconf to 
  
  dnl Initialize.
  AC_PREREQ(2.63)
- AC_INIT([GNU PSPP], [0.7.5], [bug-gnu-pspp@gnu.org], [pspp])
+ AC_INIT([GNU PSPP], [0.7.6], [bug-gnu-pspp@gnu.org], [pspp])
  AC_CONFIG_AUX_DIR([build-aux])
  AC_CONFIG_HEADERS([config.h])
  AC_CONFIG_TESTDIR([tests])
@@@ -76,9 -76,6 +76,9 @@@ if test "$with_cairo" != no && test "$w
    PKG_CHECK_MODULES([GTK], [gtk+-2.0 >= 2.16], [],
      [PSPP_REQUIRED_PREREQ([gtk+ 2.0 version 2.16 or later (or use --without-gui)])])
  
 +  PKG_CHECK_MODULES([GTKSOURCEVIEW], [gtksourceview-2.0 >= 2.2], [],
 +    [PSPP_REQUIRED_PREREQ([gtksourceview 2.0 version 2.2 or later (or use --without-gui)])])
 +
    AC_ARG_VAR([GLIB_GENMARSHAL])
    AC_CHECK_PROGS([GLIB_GENMARSHAL], [glib-genmarshal])
    if test "x$GLIB_GENMARSHAL" = x; then
@@@ -150,19 -147,22 +150,22 @@@ if test x"$with_libpq" != x"no" && tes
       LDFLAGS=$save_LDFLAGS])
  
    if test $pspp_cv_have_libpq = yes; then
+     PSQL_SUPPORT=yes
      AC_DEFINE([PSQL_SUPPORT], [1],
        [Define to 1 if building in support for reading from postgres
         databases.])
    else
+     PSQL_SUPPORT=no
      PG_CONFIG=
      PG_CFLAGS=
      PG_LDFLAGS=
      PG_LIBS=
    fi
  else
+   PSQL_SUPPORT=no
    pspp_cv_have_libpq=no
  fi
- AM_CONDITIONAL(PSQL_SUPPORT, test $pspp_cv_have_libpq = yes)
+ AC_SUBST([PSQL_SUPPORT])
  
  dnl Check for libxml2
  PKG_CHECK_MODULES(
@@@ -204,7 -204,7 +207,7 @@@ if test $HAVE_LIBXML2 = yes && test $HA
  else
    GNM_SUPPORT=no
  fi
- AM_CONDITIONAL([GNM_SUPPORT], [test $GNM_SUPPORT = yes])
+ AC_SUBST([GNM_SUPPORT])
  
  dnl ODT support requires libxml2.
  if test $HAVE_LIBXML2 = yes; then
@@@ -239,7 -239,9 +242,9 @@@ AC_SUBST([WITH_PERL_MODULE]
  AM_CONDITIONAL(WITH_PERL_MODULE, test $WITH_PERL_MODULE = yes)
  
  AC_SEARCH_LIBS([cblas_dsdot], [gslcblas],,[PSPP_REQUIRED_PREREQ([libgslcblas])])
- PKG_CHECK_MODULES([GSL], [gsl >= 1.12], [], [PSPP_REQUIRED_PREREQ([gsl 2.0 version 1.12 or later])])
+ PKG_CHECK_MODULES([GSL], [gsl >= 1.12], [],
+                        AC_SEARCH_LIBS([gsl_linalg_cholesky_invert], [gsl],,[PSPP_REQUIRED_PREREQ([gsl 2.0 version 1.12 or later])]))
  
  PSPP_GSL_NEEDS_FGNU89_INLINE
  
diff --combined src/ui/gui/automake.mk
index f78a7205966c5188f8b6a72cd976d24d8830e109,989677f865a1dd11f961fdf4bf9d820f7f4261d0..fd78196df891d92fa48d2345bb61575db8b714b0
@@@ -19,6 -19,7 +19,7 @@@ UI_FILES = 
        src/ui/gui/psppire.ui \
        src/ui/gui/rank.ui \
        src/ui/gui/sort.ui \
+       src/ui/gui/split-file.ui \
        src/ui/gui/recode.ui \
        src/ui/gui/regression.ui \
        src/ui/gui/reliability.ui \
@@@ -41,7 -42,7 +42,7 @@@ EXTRA_DIST += 
  if HAVE_GUI
  bin_PROGRAMS += src/ui/gui/psppire 
  
 -src_ui_gui_psppire_CFLAGS = $(GTK_CFLAGS) -Wall -DGDK_MULTIHEAD_SAFE=1
 +src_ui_gui_psppire_CFLAGS = $(GTK_CFLAGS) $(GTKSOURCEVIEW_CFLAGS) -Wall -DGDK_MULTIHEAD_SAFE=1
  
  
  src_ui_gui_psppire_LDFLAGS = \
@@@ -63,7 -64,6 +64,7 @@@ src_ui_gui_psppire_LDADD = 
        src/libpspp.la \
        src/libpspp-core.la \
        $(GTK_LIBS) \
 +      $(GTKSOURCEVIEW_LIBS) \
        $(CAIRO_LIBS) \
        $(LIBINTL)
  
@@@ -74,9 -74,6 +75,9 @@@ themedir = $(DESTDIR)$(datadir)/icons/h
  context = apps
  
  
 +install-lang:
 +      $(INSTALL) $(top_srcdir)/src/ui/gui/pspp.lang $(pkgdatadir)
 +      
  install-icons:
        for size in 16x16 ; do \
          $(MKDIR_P) $(themedir)/$$size/$(context) ; \
@@@ -84,7 -81,7 +85,7 @@@
        done 
        gtk-update-icon-cache --ignore-theme-index $(themedir)
  
 -INSTALL_DATA_HOOKS += install-icons
 +INSTALL_DATA_HOOKS += install-icons install-lang
  
  uninstall-icons:
        for size in 16x16 ; do \
@@@ -96,7 -93,6 +97,7 @@@ UNINSTALL_DATA_HOOKS += uninstall-icon
  
  dist_src_ui_gui_psppire_DATA = \
        $(UI_FILES) \
 +      $(top_srcdir)/src/ui/gui/pspp.lang \
        $(top_srcdir)/src/ui/gui/pspplogo.png \
        $(top_srcdir)/src/ui/gui/icons/value-labels.png \
        $(top_srcdir)/src/ui/gui/icons/goto-variable.png\
index a5cd15c0d5ba0dc5021d231b600bc7b8196371e9,63ad9fe1bdc0457644ff5c9865a7c9c7f3acab1e..aace66fa5a5947138087bd3656d6bc5c1741be77
@@@ -365,7 -365,7 +365,7 @@@ load_file (PsppireWindow *de, const gch
  
    g_free (native_file_name);
  
-   sss = create_syntax_string_source ("GET FILE=%s.",
+   sss = create_syntax_format_source ("GET FILE=%s.",
                                     ds_cstr (&filename));
  
    ds_destroy (&filename);
@@@ -465,7 -465,7 +465,7 @@@ open_window (PsppireWindow *de
        if (any_reader_may_open (sysname))
          psppire_window_load (de, name);
        else
 -        open_syntax_window (name);
 +        open_new_syntax_window (name);
  
        g_free (sysname);
        g_free (name);
@@@ -530,12 -530,12 +530,12 @@@ save_file (PsppireWindow *w
  
    if ( de->save_as_portable )
      {
-       sss = create_syntax_string_source ("EXPORT OUTFILE=%s.",
+       sss = create_syntax_format_source ("EXPORT OUTFILE=%s.",
                                         ds_cstr (&filename));
      }
    else
      {
-       sss = create_syntax_string_source ("SAVE OUTFILE=%s.",
+       sss = create_syntax_format_source ("SAVE OUTFILE=%s.",
                                         ds_cstr (&filename));
      }
  
@@@ -589,7 -589,7 +589,7 @@@ sysfile_info (PsppireDataWindow *de
  
        g_free (native_file_name);
  
-       sss = create_syntax_string_source ("SYSFILE INFO %s.",
+       sss = create_syntax_format_source ("SYSFILE INFO %s.",
                                         ds_cstr (&filename));
        execute_syntax (sss);
      }
@@@ -853,6 -853,8 +853,6 @@@ on_recent_files_select (GtkMenuShell *m
  {
    gchar *file;
  
 -  GtkWidget *se ;
 -
    gchar *uri =
      gtk_recent_chooser_get_current_uri (GTK_RECENT_CHOOSER (menushell));
  
  
    g_free (uri);
  
 -  se = psppire_syntax_window_new ();
 -
 -  if ( psppire_window_load (PSPPIRE_WINDOW (se), file) ) 
 -    gtk_widget_show (se);
 -  else
 -    gtk_widget_destroy (se);
 +  open_new_syntax_window (file);
  
    g_free (file);
  }
  
  
 +
  static void
  enable_delete_cases (GtkWidget *w, gint case_num, gpointer data)
  {
@@@ -1261,6 -1267,8 +1261,8 @@@ GtkWidget
  psppire_data_window_new (void)
  {
    return GTK_WIDGET (g_object_new (psppire_data_window_get_type (),
+                                  /* TRANSLATORS: This will form a filename.  Please avoid whitespace. */
+                                  "filename", _("PSPP-data"),
                                   "description", _("Data Editor"),
                                   NULL));
  }
index c162e219d143387a99d28d211a57e6557ace8eb8,ccf94e7bf2f0298b7f38c9ca95b07905f744e07c..c7251a1ab77206c9772df3f377b408708ef67ad3
  
  #include <config.h>
  
 +#include "relocatable.h"
 +
  #include <gtk/gtksignal.h>
  #include <gtk/gtkbox.h>
  #include "executor.h"
  #include "helper.h"
  
 +#include <gtksourceview/gtksourcebuffer.h>
 +#include <gtksourceview/gtksourcelanguage.h>
 +#include <gtksourceview/gtksourcelanguagemanager.h>
 +#include <gtksourceview/gtksourceprintcompositor.h>
 +
  #include <libpspp/message.h>
  #include <stdlib.h>
  
  #include "psppire.h"
 -#include "psppire-syntax-window.h"
  
  #include "psppire-data-window.h"
  #include "psppire-window-register.h"
@@@ -105,30 -99,41 +105,63 @@@ psppire_syntax_window_finalize (GObjec
  }
  
  
+ static void
+ psppire_syntax_window_dispose (GObject *obj)
+ {
+   PsppireSyntaxWindow *sw = (PsppireSyntaxWindow *)obj;
+   GtkClipboard *clip_selection;
+   GtkClipboard *clip_primary;
+   if (sw->dispose_has_run)
+     return;
+   clip_selection = gtk_widget_get_clipboard (GTK_WIDGET (sw), GDK_SELECTION_CLIPBOARD);
+   clip_primary =   gtk_widget_get_clipboard (GTK_WIDGET (sw), GDK_SELECTION_PRIMARY);
+   g_signal_handler_disconnect (clip_primary, sw->sel_handler);
+   g_signal_handler_disconnect (clip_selection, sw->ps_handler);
+   /* Make sure dispose does not run twice. */
+   sw->dispose_has_run = TRUE;
+   /* Chain up to the parent class */
+   G_OBJECT_CLASS (parent_class)->dispose (obj);
+ }
  static void
  psppire_syntax_window_class_init (PsppireSyntaxWindowClass *class)
  {
+   GObjectClass *gobject_class = G_OBJECT_CLASS (class);
 +  GtkSourceLanguageManager *lm = gtk_source_language_manager_get_default ();
 +
 +  const gchar * const *existing_paths =  gtk_source_language_manager_get_search_path (lm);
 +  gchar **new_paths = g_strdupv ((gchar **)existing_paths);
 +  int n = g_strv_length ((gchar **) existing_paths);
 +
 +  new_paths = g_realloc (new_paths, (n + 2) * sizeof (*new_paths));
 +  new_paths[n] = g_strdup (relocate (PKGDATADIR));
 +  new_paths[n+1] = NULL;
 +
 +  lm = gtk_source_language_manager_new ();
 +  gtk_source_language_manager_set_search_path (lm, new_paths);
 +
 +  class->lan = gtk_source_language_manager_get_language (lm, "pspp");
 +
 +  if (class->lan == NULL)
 +    g_warning ("pspp.lang file not found.  Syntax highlighting will not be available.");
 +
 +  parent_class = g_type_class_peek_parent (class);
 +
 +  g_strfreev (new_paths);
++
+   parent_class = g_type_class_peek_parent (class);
+   gobject_class->dispose = psppire_syntax_window_dispose;
  }
  
  
@@@ -136,6 -141,7 +169,6 @@@ static voi
  psppire_syntax_window_base_init (PsppireSyntaxWindowClass *class)
  {
    GObjectClass *object_class = G_OBJECT_CLASS (class);
 -
    object_class->finalize = psppire_syntax_window_finalize;
  }
  
@@@ -154,7 -160,7 +187,7 @@@ editor_execute_syntax (const PsppireSyn
  {
    PsppireWindow *win = PSPPIRE_WINDOW (sw);
    const gchar *name = psppire_window_get_filename (win);
 -  execute_syntax (create_syntax_editor_source (sw->buffer, start, stop, name));
 +  execute_syntax (create_syntax_editor_source (GTK_TEXT_BUFFER (sw->buffer), start, stop, name));
  }
  
  
@@@ -165,13 -171,14 +198,13 @@@ static voi
  on_edit_delete (PsppireSyntaxWindow *sw)
  {
    GtkTextIter begin, end;
 +  GtkTextBuffer *buffer = GTK_TEXT_BUFFER (sw->buffer);
    
 -  if ( gtk_text_buffer_get_selection_bounds (sw->buffer, &begin, &end) )
 -    gtk_text_buffer_delete (sw->buffer, &begin, &end);
 +  if ( gtk_text_buffer_get_selection_bounds (buffer, &begin, &end) )
 +    gtk_text_buffer_delete (buffer, &begin, &end);
  }
  
  
 -
 -
  /* The syntax editor's clipboard deals only with text */
  enum {
    SELECT_FMT_NULL,
  static void
  selection_changed (PsppireSyntaxWindow *sw)
  {
 -  gboolean sel = gtk_text_buffer_get_has_selection (sw->buffer);
 +  gboolean sel = gtk_text_buffer_get_has_selection (GTK_TEXT_BUFFER (sw->buffer));
  
    gtk_action_set_sensitive (sw->edit_copy, sel);
    gtk_action_set_sensitive (sw->edit_cut, sel);
@@@ -235,13 -242,12 +268,13 @@@ static gboolea
  set_clip (PsppireSyntaxWindow *sw, GtkTextIter *begin, GtkTextIter *end)
  {
    GtkClipboard *clipboard ;
 +  GtkTextBuffer *buffer = GTK_TEXT_BUFFER (sw->buffer);
  
 -  if ( ! gtk_text_buffer_get_selection_bounds (sw->buffer, begin, end) )
 +  if ( ! gtk_text_buffer_get_selection_bounds (buffer, begin, end) )
      return FALSE;
  
    g_free (sw->cliptext);
 -  sw->cliptext = gtk_text_buffer_get_text  (sw->buffer, begin, end, FALSE);
 +  sw->cliptext = gtk_text_buffer_get_text  (buffer, begin, end, FALSE);
  
    clipboard =
      gtk_widget_get_clipboard (GTK_WIDGET (sw), GDK_SELECTION_CLIPBOARD);
@@@ -261,7 -267,7 +294,7 @@@ on_edit_cut (PsppireSyntaxWindow *sw
    GtkTextIter begin, end;
    
    if ( set_clip (sw, &begin, &end))
 -    gtk_text_buffer_delete (sw->buffer, &begin, &end);
 +    gtk_text_buffer_delete (GTK_TEXT_BUFFER (sw->buffer), &begin, &end);
  }
  
  static void
@@@ -290,7 -296,7 +323,7 @@@ contents_received_callback (GtkClipboar
  
    c = (gchar *) sd->data;
  
 -  gtk_text_buffer_insert_at_cursor (syntax_window->buffer,
 +  gtk_text_buffer_insert_at_cursor (GTK_TEXT_BUFFER (syntax_window->buffer),
                                    (gchar *) sd->data,
                                    sd->length);
  
@@@ -309,8 -315,12 +342,12 @@@ on_edit_paste (PsppireSyntaxWindow *sw
                                  sw);
  }
  
+ /* Check to see if CLIP holds a target which we know how to paste,
+    and set the sensitivity of the Paste action accordingly.
+  */
  static void
on_owner_change (GtkClipboard *clip, GdkEventOwnerChange *event, gpointer data)
set_paste_sensitivity (GtkClipboard *clip, GdkEventOwnerChange *event, gpointer data)
  {
    gint i;
    gboolean compatible_target = FALSE;
@@@ -339,8 -349,8 +376,8 @@@ on_run_all (GtkMenuItem *menuitem, gpoi
    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);
 +  gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (se->buffer), &begin, 0);
 +  gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (se->buffer), &end, -1);
  
    editor_execute_syntax (se, begin, end);
  }
@@@ -352,7 -362,7 +389,7 @@@ on_run_selection (GtkMenuItem *menuitem
    GtkTextIter begin, end;
    PsppireSyntaxWindow *se = PSPPIRE_SYNTAX_WINDOW (user_data);
  
 -  if ( gtk_text_buffer_get_selection_bounds (se->buffer, &begin, &end) )
 +  if ( gtk_text_buffer_get_selection_bounds (GTK_TEXT_BUFFER (se->buffer), &begin, &end) )
      editor_execute_syntax (se, begin, end);
  }
  
@@@ -369,17 -379,17 +406,17 @@@ on_run_to_end (GtkMenuItem *menuitem, g
    PsppireSyntaxWindow *se = PSPPIRE_SYNTAX_WINDOW (user_data);
  
    /* Get the current line */
 -  gtk_text_buffer_get_iter_at_mark (se->buffer,
 +  gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (se->buffer),
                                    &here,
 -                                  gtk_text_buffer_get_insert (se->buffer)
 +                                  gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (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);
 +  gtk_text_buffer_get_iter_at_line (GTK_TEXT_BUFFER (se->buffer), &begin, line);
 +  gtk_text_buffer_get_iter_at_line (GTK_TEXT_BUFFER (se->buffer), &end, -1);
  
    editor_execute_syntax (se, begin, end);
  }
@@@ -397,17 -407,17 +434,17 @@@ on_run_current_line (GtkMenuItem *menui
    PsppireSyntaxWindow *se = PSPPIRE_SYNTAX_WINDOW (user_data);
  
    /* Get the current line */
 -  gtk_text_buffer_get_iter_at_mark (se->buffer,
 +  gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (se->buffer),
                                    &here,
 -                                  gtk_text_buffer_get_insert (se->buffer)
 +                                  gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (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);
 +  gtk_text_buffer_get_iter_at_line (GTK_TEXT_BUFFER (se->buffer), &begin, line);
 +  gtk_text_buffer_get_iter_at_line (GTK_TEXT_BUFFER (se->buffer), &end, line + 1);
  
    editor_execute_syntax (se, begin, end);
  }
@@@ -439,7 -449,7 +476,7 @@@ save_editor_to_file (PsppireSyntaxWindo
                     const gchar *filename,
                     GError **err)
  {
 -  GtkTextBuffer *buffer = se->buffer;
 +  GtkTextBuffer *buffer = GTK_TEXT_BUFFER (se->buffer);
    gboolean result ;
    GtkTextIter start, stop;
    gchar *text;
    if ( result )
      {
        char *fn = g_filename_display_name (filename);
-       gchar *msg = g_strdup_printf (_("Saved file \"%s\""), fn);
+       gchar *msg = g_strdup_printf (_("Saved file `%s'"), fn);
        g_free (fn);
        gtk_statusbar_push (GTK_STATUSBAR (se->sb), se->text_context, msg);
        gtk_text_buffer_set_modified (buffer, FALSE);
@@@ -552,21 -562,6 +589,21 @@@ on_quit (GtkMenuItem *menuitem, gpointe
  }
  
  
 +static void
 +load_and_show_syntax_window (GtkWidget *se, const gchar *filename)
 +{
 +  gboolean ok;
 +
 +  gtk_source_buffer_begin_not_undoable_action (PSPPIRE_SYNTAX_WINDOW (se)->buffer);
 +  ok = psppire_window_load (PSPPIRE_WINDOW (se), filename);
 +  gtk_source_buffer_end_not_undoable_action (PSPPIRE_SYNTAX_WINDOW (se)->buffer);
 +
 +  if (ok )
 +    gtk_widget_show (se);
 +  else
 +    gtk_widget_destroy (se);
 +}
 +
  void
  create_syntax_window (void)
  {
  }
  
  void
 -open_syntax_window (const char *file_name)
 +open_new_syntax_window (const char *file_name)
  {
    GtkWidget *se = psppire_syntax_window_new ();
  
 -  if ( psppire_window_load (PSPPIRE_WINDOW (se), file_name) )
 -    gtk_widget_show (se);
 -  else
 -    gtk_widget_destroy (se);
 +  if ( file_name)
 +    load_and_show_syntax_window (se, file_name);
  }
  
 -static void
 -on_text_changed (GtkTextBuffer *buffer, PsppireSyntaxWindow *window)
 -{
 -  gtk_statusbar_pop (GTK_STATUSBAR (window->sb), window->text_context);
 -}
 +
 +
 +static void psppire_syntax_window_print (PsppireSyntaxWindow *window);
  
  static void
  on_modified_changed (GtkTextBuffer *buffer, PsppireWindow *window)
  
  extern struct source_stream *the_source_stream ;
  
 +static void undo_redo_update (PsppireSyntaxWindow *window);
 +static void undo_last_edit (PsppireSyntaxWindow *window);
 +static void redo_last_edit (PsppireSyntaxWindow *window);
 +
 +static void
 +on_text_changed (GtkTextBuffer *buffer, PsppireSyntaxWindow *window)
 +{
 +  gtk_statusbar_pop (GTK_STATUSBAR (window->sb), window->text_context);
 +  undo_redo_update (window);
 +}
 +
  static void
  psppire_syntax_window_init (PsppireSyntaxWindow *window)
  {
    GtkWidget *menubar = get_widget_assert (xml, "menubar");
    GtkWidget *sw = get_widget_assert (xml, "scrolledwindow8");
  
 -
    GtkWidget *text_view = get_widget_assert (xml, "syntax_text_view");
  
 +  PsppireSyntaxWindowClass *class
 +    = PSPPIRE_SYNTAX_WINDOW_CLASS (G_OBJECT_GET_CLASS (window));
 +
    GtkClipboard *clip_selection = gtk_widget_get_clipboard (GTK_WIDGET (window), GDK_SELECTION_CLIPBOARD);
    GtkClipboard *clip_primary =   gtk_widget_get_clipboard (GTK_WIDGET (window), GDK_SELECTION_PRIMARY);
  
-   g_signal_connect_swapped (clip_primary, "owner-change", G_CALLBACK (selection_changed), window);
-   g_signal_connect (clip_selection, "owner-change", G_CALLBACK (on_owner_change), window);
++
 +  window->print_settings = NULL;
 +  window->undo_menuitem = get_action_assert (xml, "edit_undo");
 +  window->redo_menuitem = get_action_assert (xml, "edit_redo");
 +
 +  if (class->lan)
 +    window->buffer = gtk_source_buffer_new_with_language (class->lan);
 +  else
 +    window->buffer = gtk_source_buffer_new (NULL);
 +
 +  gtk_text_view_set_buffer (GTK_TEXT_VIEW (text_view), GTK_TEXT_BUFFER (window->buffer));
 +
 +  g_object_set (window->buffer,
 +              "highlight-matching-brackets", TRUE,
 +              NULL);
 +
 +  g_object_set (text_view,
 +              "show-line-numbers", TRUE,
 +              "show-line-marks", TRUE,
 +              "auto-indent", TRUE,
 +              "indent-width", 4,
 +              "highlight-current-line", TRUE,
 +              NULL);
 +
    window->cliptext = NULL;
+   window->dispose_has_run = FALSE;
  
    window->edit_delete = get_action_assert (xml, "edit_delete");
    window->edit_copy = get_action_assert (xml, "edit_copy");
    window->edit_cut = get_action_assert (xml, "edit_cut");
    window->edit_paste = get_action_assert (xml, "edit_paste");
  
 -  window->buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view));
    window->lexer = lex_create (the_source_stream);
  
    window->sb = get_widget_assert (xml, "statusbar2");
    window->text_context = gtk_statusbar_get_context_id (GTK_STATUSBAR (window->sb), "Text Context");
  
-   g_signal_connect (window->buffer, "changed", G_CALLBACK (on_text_changed), window);
+   g_signal_connect (window->buffer, "changed", 
+                   G_CALLBACK (on_text_changed), window);
  
-   g_signal_connect (window->buffer, "modified-changed",
+   g_signal_connect (window->buffer, "modified-changed", 
                    G_CALLBACK (on_modified_changed), window);
  
 +  g_signal_connect_swapped (get_action_assert (xml, "file_print"), "activate",
 +                            G_CALLBACK (psppire_syntax_window_print), window);
 +
 +
 +  g_signal_connect_swapped (window->undo_menuitem,
 +                          "activate",
 +                            G_CALLBACK (undo_last_edit),
 +                          window);
 +
 +  g_signal_connect_swapped (window->redo_menuitem,
 +                          "activate",
 +                            G_CALLBACK (redo_last_edit),
 +                          window);
 +
 +  undo_redo_update (window);
 +
+   window->sel_handler = g_signal_connect_swapped (clip_primary, "owner-change", 
+                                                  G_CALLBACK (selection_changed), window);
+   window->ps_handler = g_signal_connect (clip_selection, "owner-change", 
+                                         G_CALLBACK (set_paste_sensitivity), window);
    connect_help (xml);
  
    gtk_container_add (GTK_CONTAINER (window), box);
  
    g_object_ref (window->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), window->sb, FALSE, TRUE, 0);
                    G_CALLBACK (psppire_window_minimise_all), NULL);
  
  
 +
 +
 +
    {
    GtkUIManager *uim = GTK_UI_MANAGER (get_object_assert (xml, "uimanager1", GTK_TYPE_UI_MANAGER));
  
@@@ -793,7 -741,8 +834,8 @@@ GtkWidget
  psppire_syntax_window_new (void)
  {
    return GTK_WIDGET (g_object_new (psppire_syntax_window_get_type (),
-                                  "filename", "Syntax",
+                                  /* TRANSLATORS: This will form a filename.  Please avoid whitespace. */
+                                  "filename", _("Syntax"),
                                   "description", _("Syntax Editor"),
                                   NULL));
  }
@@@ -808,7 -757,7 +850,7 @@@ error_dialog (GtkWindow *w, const gcha
                            GTK_DIALOG_DESTROY_WITH_PARENT,
                            GTK_MESSAGE_ERROR,
                            GTK_BUTTONS_CLOSE,
-                           _("Cannot load syntax file '%s'"),
+                           _("Cannot load syntax file `%s'"),
                            fn);
  
    g_free (fn);
@@@ -836,7 -785,7 +878,7 @@@ syntax_load (PsppireWindow *window, con
    gsize len_utf8 = -1;
    GtkTextIter iter;
    PsppireSyntaxWindow *sw = PSPPIRE_SYNTAX_WINDOW (window);
 -
 +  GtkTextBuffer *buffer = GTK_TEXT_BUFFER (sw->buffer);
    /* FIXME: What if it's a very big file ? */
    if ( ! g_file_get_contents (filename, &text_locale, &len_locale, &err) )
      {
        return FALSE;
      }
  
 -  gtk_text_buffer_get_iter_at_line (sw->buffer, &iter, 0);
 +  gtk_text_buffer_get_iter_at_line (buffer, &iter, 0);
  
 -  gtk_text_buffer_insert (sw->buffer, &iter, text_utf8, len_utf8);
 +  gtk_text_buffer_insert (buffer, &iter, text_utf8, len_utf8);
  
 -  gtk_text_buffer_set_modified (sw->buffer, FALSE);
 +  gtk_text_buffer_set_modified (buffer, FALSE);
  
    free (text_utf8);
  
@@@ -876,112 -825,3 +918,113 @@@ psppire_syntax_window_iface_init (Psppi
    iface->load = syntax_load;
  }
  
++
 +\f
 +
 +static void
 +undo_redo_update (PsppireSyntaxWindow *window)
 +{
 +  gtk_action_set_sensitive (window->undo_menuitem,
 +                          gtk_source_buffer_can_undo (window->buffer));
 +
 +  gtk_action_set_sensitive (window->redo_menuitem,
 +                          gtk_source_buffer_can_redo (window->buffer));
 +}
 +
 +static void
 +undo_last_edit (PsppireSyntaxWindow *window)
 +{
 +  gtk_source_buffer_undo (window->buffer);
 +  undo_redo_update (window);
 +}
 +
 +static void
 +redo_last_edit (PsppireSyntaxWindow *window)
 +{
 +  gtk_source_buffer_redo (window->buffer);
 +  undo_redo_update (window);
 +}
 +
 +
 +\f
 +/* Printing related stuff */
 +
 +
 +static void
 +begin_print (GtkPrintOperation *operation,
 +          GtkPrintContext   *context,
 +          PsppireSyntaxWindow *window)
 +{
 +  window->compositor =
 +    gtk_source_print_compositor_new (window->buffer);
 +}
 +
 +
 +static void
 +end_print (GtkPrintOperation *operation,
 +          GtkPrintContext   *context,
 +          PsppireSyntaxWindow *window)
 +{
 +  g_object_unref (window->compositor);
 +  window->compositor = NULL;
 +}
 +
 +
 +
 +static gboolean
 +paginate (GtkPrintOperation *operation,
 +          GtkPrintContext   *context,
 +          PsppireSyntaxWindow *window)
 +{
 +  if (gtk_source_print_compositor_paginate (window->compositor, context))
 +    {
 +      gint n_pages = gtk_source_print_compositor_get_n_pages (window->compositor);
 +      gtk_print_operation_set_n_pages (operation, n_pages);
 +        
 +      return TRUE;
 +    }
 +
 +  return FALSE;
 +}
 +
 +static void
 +draw_page (GtkPrintOperation *operation,
 +           GtkPrintContext   *context,
 +           gint               page_nr,
 +          PsppireSyntaxWindow *window)
 +{
 +  gtk_source_print_compositor_draw_page (window->compositor, 
 +                                       context,
 +                                       page_nr);
 +}
 +
 +
 +
 +static void
 +psppire_syntax_window_print (PsppireSyntaxWindow *window)
 +{
 +  GtkPrintOperationResult res;
 +
 +  GtkPrintOperation *print = gtk_print_operation_new ();
 +
 +  if (window->print_settings != NULL) 
 +    gtk_print_operation_set_print_settings (print, window->print_settings);
 +
 +
 +  g_signal_connect (print, "begin_print", G_CALLBACK (begin_print), window);
 +  g_signal_connect (print, "end_print", G_CALLBACK (end_print),     window);
 +  g_signal_connect (print, "draw_page", G_CALLBACK (draw_page),     window);
 +  g_signal_connect (print, "paginate", G_CALLBACK (paginate),       window);
 +
 +  res = gtk_print_operation_run (print, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG,
 +                                 GTK_WINDOW (window), NULL);
 +
 +  if (res == GTK_PRINT_OPERATION_RESULT_APPLY)
 +    {
 +      if (window->print_settings != NULL)
 +        g_object_unref (window->print_settings);
 +      window->print_settings = g_object_ref (gtk_print_operation_get_print_settings (print));
 +    }
 +
 +  g_object_unref (print);
 +}
index 1f97cbc7e0e4814f5fd7d40ca897b78e352c64ee,08f5a7c5b2190246c9691a43b191b25b8f81484a..df16ed3ba62fd650552c8897c01f1b3d48f925f5
  #include "psppire-window.h"
  #include <gtk/gtk.h>
  
 +#include <gtksourceview/gtksourcelanguage.h>
 +#include <gtksourceview/gtksourcelanguagemanager.h>
 +#include <gtksourceview/gtksourcebuffer.h>
 +#include <gtksourceview/gtksourceprintcompositor.h>
 +
  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))
 +    PSPPIRE_SYNTAX_WINDOW_TYPE, PsppireSyntaxWindowClass))
  #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), \
@@@ -52,38 -47,35 +52,43 @@@ struct _PsppireSyntaxWindo
  
    /* <private> */
  
 -  GtkTextBuffer *buffer;  /* The buffer which contains the text */
 +  GtkSourceBuffer *buffer;  /* The buffer which contains the text */
    struct lexer *lexer;    /* Lexer to parse syntax */
    GtkWidget *sb;
    guint text_context;
  
 +  GtkPrintSettings *print_settings;
 +  GtkSourcePrintCompositor *compositor;
 +  GtkAction *undo_menuitem;
 +  GtkAction *redo_menuitem;
 +
    gchar *cliptext;
  
    GtkAction *edit_cut;
    GtkAction *edit_copy;
    GtkAction *edit_delete;
    GtkAction *edit_paste;
+   gulong ps_handler;
+   gulong sel_handler;
+   gboolean dispose_has_run;
  };
  
  struct _PsppireSyntaxWindowClass
  {
    PsppireWindowClass parent_class;
  
 +
 +  GtkSourceLanguage *lan ;
  };
  
  GType      psppire_syntax_window_get_type        (void);
  GtkWidget* psppire_syntax_window_new             (void);
  
  void create_syntax_window (void);
 -void open_syntax_window (const char *file_name);
 +void open_new_syntax_window (const char *file_name);
 +
  
  G_END_DECLS