#include <config.h>
+#include <gtk/gtk.h>
+
+
+
#include "checkbox-treeview.h"
#include "descriptives-dialog.h"
#include <errno.h>
-#include <gtk/gtk.h>
+
#include <gtksheet/gtksheet.h>
#include <limits.h>
#include <stdlib.h>
#define _(msgid) gettext (msgid)
#define N_(msgid) msgid
+
+#if !GTK_CHECK_VERSION (2, 10, 0)
+
+void
+text_data_import_assistant (GObject *o, gpointer de_)
+{
+ struct data_editor *de = de_;
+
+ GtkWidget *dialog =
+ gtk_message_dialog_new (de->parent.window,
+ GTK_DIALOG_MODAL,
+ GTK_MESSAGE_WARNING,
+ GTK_BUTTONS_CLOSE,
+ _("The text import assistant has not been "
+ "compiled into this build of PSPPIRE, because "
+ "GTK+ version 2.10.0 or later was not available."));
+
+ gtk_dialog_run (GTK_DIALOG (dialog));
+
+ gtk_widget_destroy (dialog);
+}
+
+#else
+
/* TextImportModel, a GtkTreeModel used by the text data import
dialog. */
enum
GtkWidget *paste_button;
GtkWidget *reset_button;
int response;
+ int watch_cursor;
GtkCellRenderer *prop_renderer;
GtkCellRenderer *fixed_renderer;
static GtkTreeView *create_data_tree_view (bool input, GtkContainer *parent,
struct import_assistant *);
static void escape_underscores (const char *in, char *out);
+static void push_watch_cursor (struct import_assistant *);
+static void pop_watch_cursor (struct import_assistant *);
/* Pops up the Text Data Import assistant. */
void
{
struct data_editor *de = de_;
GtkWindow *parent_window = de->parent.window;
- struct import_assistant ia = { { 0, } };
+ struct import_assistant *ia;
- if (!init_file (&ia, parent_window))
- return;
+ ia = xzalloc (sizeof *ia);
+ if (!init_file (ia, parent_window))
+ {
+ free (ia);
+ return;
+ }
- init_assistant (&ia, parent_window);
- init_intro_page (&ia);
- init_first_line_page (&ia);
- init_separators_page (&ia);
- init_formats_page (&ia);
+ init_assistant (ia, parent_window);
+ init_intro_page (ia);
+ init_first_line_page (ia);
+ init_separators_page (ia);
+ init_formats_page (ia);
- gtk_widget_show_all (GTK_WIDGET (ia.asst.assistant));
+ gtk_widget_show_all (GTK_WIDGET (ia->asst.assistant));
- ia.asst.main_loop = g_main_loop_new (NULL, false);
- g_main_loop_run (ia.asst.main_loop);
+ ia->asst.main_loop = g_main_loop_new (NULL, false);
+ g_main_loop_run (ia->asst.main_loop);
+ g_main_loop_unref (ia->asst.main_loop);
- switch (ia.asst.response)
+ switch (ia->asst.response)
{
case GTK_RESPONSE_APPLY:
{
- char *syntax = generate_syntax (&ia);
+ char *syntax = generate_syntax (ia);
execute_syntax (create_syntax_string_source (syntax));
free (syntax);
}
break;
case PSPPIRE_RESPONSE_PASTE:
{
- char *syntax = generate_syntax (&ia);
+ 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);
break;
}
- destroy_formats_page (&ia);
- destroy_separators_page (&ia);
- destroy_assistant (&ia);
- destroy_file (&ia);
+ destroy_formats_page (ia);
+ destroy_separators_page (ia);
+ destroy_assistant (ia);
+ destroy_file (ia);
+ free (ia);
}
/* Emits PSPP syntax to S that applies the dictionary attributes
gtk_assistant_append_page (ia->asst.assistant, content);
gtk_assistant_set_page_type (ia->asst.assistant, content, type);
gtk_assistant_set_page_title (ia->asst.assistant, content, title_copy);
+ gtk_assistant_set_page_complete (ia->asst.assistant, content, true);
free (title_copy);
gtk_widget_show (ia->asst.paste_button);
else
gtk_widget_hide (ia->asst.paste_button);
-
- /* Make the user visit each page in the assistant once. Seems
- like a reasonable user interface, plus visiting the final
- page is what constructs the dictionary. */
- gtk_assistant_set_page_complete (assistant, page, true);
}
/* Called when the Cancel button in the assistant is clicked. */
revise_fields_preview (struct import_assistant *ia)
{
GtkWidget *w;
+
+ push_watch_cursor (ia);
+
w = GTK_WIDGET (ia->separators.fields_tree_view);
gtk_widget_destroy (w);
get_separators (ia);
true,
GTK_CONTAINER (get_widget_assert (ia->asst.xml, "fields-scroller")),
ia);
+
+ pop_watch_cursor (ia);
}
/* Sets the widgets to match IA's separators substructure. */
unsigned long int number = 0;
size_t column_idx;
+ push_watch_cursor (ia);
+
dict = dict_create ();
fg = fmt_guesser_create ();
for (column_idx = 0; column_idx < s->column_cnt; column_idx++)
false,
GTK_CONTAINER (get_widget_assert (ia->asst.xml, "data-scroller")),
ia);
+
+ pop_watch_cursor (ia);
}
/* Clears the set of user-modified variables from IA's formats
GtkTreeView *tv = ia->formats.data_tree_view;
gint column_idx = dict_idx + 1;
+ push_watch_cursor (ia);
+
/* Remove previous column and replace with new column. */
gtk_tree_view_remove_column (tv, gtk_tree_view_get_column (tv, column_idx));
gtk_tree_view_insert_column (tv, make_data_column (ia, tv, false, dict_idx),
var_destroy (p->modified_vars[dict_idx]);
p->modified_vars[dict_idx]
= var_clone (psppire_dict_get_variable (dict, dict_idx));
+
+ pop_watch_cursor (ia);
}
/* Parses the contents of the field at (ROW,COLUMN) according to
GtkTreeModel *tree_model;
bool ok;
+ /* Check that WIDGET is really visible on the screen before we
+ do anything else. This is a bug fix for a sticky situation:
+ when text_data_import_assistant() returns, it frees the data
+ necessary to compose the tool tip message, but there may be
+ a tool tip under preparation at that point (even if there is
+ no visible tool tip) that will call back into us a little
+ bit later. Perhaps the correct solution to this problem is
+ to make the data related to the tool tips part of a GObject
+ that only gets destroyed when all references are released,
+ but this solution appears to be effective too. */
+ if (!GTK_WIDGET_MAPPED (widget))
+ return FALSE;
+
gtk_tree_view_convert_widget_to_bin_window_coords (tree_view,
wx, wy, &bx, &by);
if (!gtk_tree_view_get_path_at_pos (tree_view, bx, by,
assert (iter->stamp == TREE_MODEL_STAMP);
return GPOINTER_TO_INT (iter->user_data);
}
+
+/* Increments the "watch cursor" level, setting the cursor for
+ the assistant window to a watch face to indicate to the user
+ that the ongoing operation may take some time. */
+static void
+push_watch_cursor (struct import_assistant *ia)
+{
+ if (++ia->asst.watch_cursor == 1)
+ {
+ GtkWidget *widget = GTK_WIDGET (ia->asst.assistant);
+ GdkDisplay *display = gtk_widget_get_display (widget);
+ GdkCursor *cursor = gdk_cursor_new_for_display (display, GDK_WATCH);
+ gdk_window_set_cursor (widget->window, cursor);
+ gdk_cursor_unref (cursor);
+ gdk_display_flush (display);
+ }
+}
+
+/* Decrements the "watch cursor" level. If the level reaches
+ zero, the cursor is reset to its default shape. */
+static void
+pop_watch_cursor (struct import_assistant *ia)
+{
+ if (--ia->asst.watch_cursor == 0)
+ {
+ GtkWidget *widget = GTK_WIDGET (ia->asst.assistant);;
+ gdk_window_set_cursor (widget->window, NULL);
+ }
+}
+
+#endif