X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fui%2Fgui%2Fpsppire-data-sheet.c;h=dbc92159777723e87b9a97c0cf67c97fea241b8e;hb=50c7b5b389eb39accf65c8716f6a3f73b5b30aa6;hp=f2cdc5bd5e77ce0b425b9aeaf5c1721b4abc3485;hpb=946019eee800e021b941b5b823b9cf270ec637f8;p=pspp diff --git a/src/ui/gui/psppire-data-sheet.c b/src/ui/gui/psppire-data-sheet.c index f2cdc5bd5e..dbc9215977 100644 --- a/src/ui/gui/psppire-data-sheet.c +++ b/src/ui/gui/psppire-data-sheet.c @@ -124,6 +124,7 @@ on_query_tooltip (GtkWidget *widget, gint wx, gint wy, int width; g_return_val_if_fail (data_store != NULL, FALSE); + g_return_val_if_fail (data_store->datasheet != NULL, FALSE); if (!get_tooltip_location (widget, tooltip, wx, wy, &row, &column)) return FALSE; @@ -176,9 +177,9 @@ render_row_number_cell (PsppSheetViewColumn *tree_column, { PsppireDataStore *store = store_; GValue gvalue = { 0, }; - gint row; + gint row = GPOINTER_TO_INT (iter->user_data); - row = GPOINTER_TO_INT (iter->user_data); + g_return_if_fail (store->datasheet); g_value_init (&gvalue, G_TYPE_INT); g_value_set_int (&gvalue, row + 1); @@ -290,8 +291,9 @@ get_string_width (PsppSheetView *treeview, GtkCellRenderer *renderer, { gint width; g_object_set (G_OBJECT (renderer), "text", string, (void *) NULL); - gtk_cell_renderer_get_size (renderer, GTK_WIDGET (treeview), - NULL, NULL, NULL, &width, NULL); + gtk_cell_renderer_get_preferred_width (renderer, GTK_WIDGET (treeview), + NULL, &width); + return width; } @@ -337,13 +339,15 @@ on_data_column_editing_started (GtkCellRenderer *cell, if (var_has_value_labels (var) && GTK_IS_COMBO_BOX (editable)) { const struct val_labs *labels = var_get_value_labels (var); - const struct val_lab *vl; + const struct val_lab **vls = val_labs_sorted (labels); + size_t n_vls = val_labs_count (labels); GtkListStore *list_store; + int i; list_store = gtk_list_store_new (1, G_TYPE_STRING); - for (vl = val_labs_first (labels); vl != NULL; - vl = val_labs_next (labels, vl)) + for (i = 0; i < n_vls; ++i) { + const struct val_lab *vl = vls[i]; GtkTreeIter iter; gtk_list_store_append (list_store, &iter); @@ -351,6 +355,7 @@ on_data_column_editing_started (GtkCellRenderer *cell, 0, val_lab_get_label (vl), -1); } + free (vls); gtk_combo_box_set_model (GTK_COMBO_BOX (editable), GTK_TREE_MODEL (list_store)); @@ -416,7 +421,7 @@ on_data_column_edited (GtkCellRendererText *cell, { gtk_widget_queue_resize (GTK_WIDGET (data_sheet)); data_sheet->scroll_to_bottom_signal = - g_signal_connect (data_sheet, "size-request", + g_signal_connect (data_sheet, "size-allocate", G_CALLBACK (scroll_to_bottom), NULL); } else @@ -671,7 +676,7 @@ add_data_column_cell_renderer (PsppireDataSheet *data_sheet, var = g_object_get_data (G_OBJECT (column), "variable"); g_return_if_fail (var != NULL); - if (var_has_value_labels (var)) + if (data_sheet->show_value_labels && var_has_value_labels (var)) { cell = gtk_cell_renderer_combo_new (); g_object_set (G_OBJECT (cell), @@ -940,10 +945,11 @@ psppire_data_sheet_set_value_labels (PsppireDataSheet *ds, { ds->show_value_labels = show_value_labels; g_object_notify (G_OBJECT (ds), "value-labels"); - gtk_widget_queue_draw (GTK_WIDGET (ds)); - /* Make the cell being edited refresh too. */ - pspp_sheet_view_stop_editing (PSPP_SHEET_VIEW (ds), TRUE); + /* Pretend the model changed, to force the columns to be rebuilt. + Otherwise cell renderers won't get changed from combo boxes to text + entries or vice versa. */ + g_object_notify (G_OBJECT (ds), "model"); } } @@ -1203,6 +1209,13 @@ psppire_data_sheet_dispose (GObject *object) { PsppireDataSheet *data_sheet = PSPPIRE_DATA_SHEET (object); + if (data_sheet->clip != NULL && data_sheet->on_owner_change_signal != 0) + { + g_signal_handler_disconnect (data_sheet->clip, + data_sheet->on_owner_change_signal); + data_sheet->on_owner_change_signal = 0; + } + if (data_sheet->dispose_has_run) return; @@ -1221,14 +1234,19 @@ psppire_data_sheet_dispose (GObject *object) static void psppire_data_sheet_map (GtkWidget *widget) { - GtkClipboard *clip; + PsppireDataSheet *data_sheet = PSPPIRE_DATA_SHEET (widget); GTK_WIDGET_CLASS (psppire_data_sheet_parent_class)->map (widget); - clip = gtk_widget_get_clipboard (widget, GDK_SELECTION_CLIPBOARD); - g_signal_connect (clip, "owner-change", G_CALLBACK (on_owner_change), - widget); - on_owner_change (clip, NULL, widget); + data_sheet->clip = gtk_widget_get_clipboard (widget, + GDK_SELECTION_CLIPBOARD); + if (data_sheet->on_owner_change_signal) + g_signal_handler_disconnect (data_sheet->clip, + data_sheet->on_owner_change_signal); + data_sheet->on_owner_change_signal + = g_signal_connect (data_sheet->clip, "owner-change", + G_CALLBACK (on_owner_change), widget); + on_owner_change (data_sheet->clip, NULL, widget); } static void @@ -1690,6 +1708,7 @@ psppire_data_sheet_init (PsppireDataSheet *obj) obj->scroll_to_bottom_signal = 0; obj->scroll_to_right_signal = 0; + obj->on_owner_change_signal = 0; obj->new_variable_column = NULL; obj->container = NULL; @@ -1893,6 +1912,7 @@ on_variable_display_width_changed (PsppireDict *dict, int dict_index, static void on_variable_changed (PsppireDict *dict, int dict_index, + guint what, const struct variable *oldvar, PsppireDataSheet *data_sheet) { PsppireDataStore *data_store = psppire_data_sheet_get_data_store (data_sheet); @@ -1905,11 +1925,16 @@ on_variable_changed (PsppireDict *dict, int dict_index, g_return_if_fail (data_sheet->data_store != NULL); g_return_if_fail (dict == data_sheet->data_store->dict); + + if (what & VAR_TRAIT_DISPLAY_WIDTH) + on_variable_display_width_changed (dict, dict_index, data_sheet); + column = psppire_data_sheet_find_column_for_variable (data_sheet, dict_index); if (column == NULL) return; + var = psppire_dict_get_variable (data_store->dict, dict_index); g_return_if_fail (var != NULL); @@ -2029,9 +2054,6 @@ psppire_data_sheet_set_data_store (PsppireDataSheet *data_sheet, g_signal_connect (data_store->dict, "variable-changed", G_CALLBACK (on_variable_changed), data_sheet); - g_signal_connect (data_store->dict, "variable-display-width-changed", - G_CALLBACK (on_variable_display_width_changed), - data_sheet); g_signal_connect (data_store->dict, "variable-inserted", G_CALLBACK (on_variable_inserted), data_sheet); g_signal_connect (data_store->dict, "variable-deleted", @@ -2289,7 +2311,7 @@ psppire_data_sheet_clipboard_set (GtkSelectionData *selection_data, g_assert_not_reached (); } - gtk_selection_data_set (selection_data, selection_data->target, + gtk_selection_data_set (selection_data, gtk_selection_data_get_target (selection_data), 8, (const guchar *) string->str, string->len); @@ -2422,13 +2444,13 @@ psppire_data_sheet_clip_received_cb (GtkClipboard *clipboard, gint first_column; char *c; - if ( sd->length < 0 ) + if ( gtk_selection_data_get_length (sd) < 0 ) return; - if ( sd->type != gdk_atom_intern ("UTF8_STRING", FALSE)) + if ( gtk_selection_data_get_data_type (sd) != gdk_atom_intern ("UTF8_STRING", FALSE)) return; - c = (char *) sd->data; + c = (char *) gtk_selection_data_get_data (sd); /* Get the starting selected position in the data sheet. (Possibly we should only paste into the selected range if it's larger than one cell?) */ @@ -2442,14 +2464,14 @@ psppire_data_sheet_clip_received_cb (GtkClipboard *clipboard, g_return_if_fail (next_row >= 0); g_return_if_fail (next_column >= 0); - while (count < sd->length) + while (count < gtk_selection_data_get_length (sd)) { gint row = next_row; gint column = next_column; struct variable *var; char *s = c; - while (*c != '\t' && *c != '\n' && count < sd->length) + while (*c != '\t' && *c != '\n' && count < gtk_selection_data_get_length (sd)) { c++; count++; @@ -2474,23 +2496,40 @@ psppire_data_sheet_clip_received_cb (GtkClipboard *clipboard, } static void -on_owner_change (GtkClipboard *clip, GdkEventOwnerChange *event, gpointer data) +psppire_data_sheet_targets_received_cb (GtkClipboard *clipboard, + GdkAtom *atoms, + gint n_atoms, + gpointer data) { - PsppireDataSheet *data_sheet = PSPPIRE_DATA_SHEET (data); - gboolean compatible_target = FALSE; - GtkAction *action; + GtkAction *action = GTK_ACTION (data); + gboolean compatible_target; gint i; + compatible_target = FALSE; for (i = 0; i < G_N_ELEMENTS (targets); i++) { - GdkAtom atom = gdk_atom_intern (targets[i].target, TRUE); - if (gtk_clipboard_wait_is_target_available (clip, atom)) - { - compatible_target = TRUE; - break; - } + GdkAtom target = gdk_atom_intern (targets[i].target, TRUE); + gint j; + + for (j = 0; j < n_atoms; j++) + if (target == atoms[j]) + { + compatible_target = TRUE; + break; + } } - action = get_action_assert (data_sheet->builder, "edit_paste"); gtk_action_set_sensitive (action, compatible_target); + g_object_unref (action); +} + +static void +on_owner_change (GtkClipboard *clip, GdkEventOwnerChange *event, gpointer data) +{ + PsppireDataSheet *data_sheet = PSPPIRE_DATA_SHEET (data); + GtkAction *action = get_action_assert (data_sheet->builder, "edit_paste"); + + g_object_ref (action); + gtk_clipboard_request_targets (clip, psppire_data_sheet_targets_received_cb, + action); }