X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;ds=sidebyside;f=src%2Fui%2Fgui%2Fpsppire-output-view.c;h=4296409120214f545149f0920cb60ea6f2865841;hb=53241f59ac766997bf67870639f70afb82396640;hp=8c14a931250d2b59f6549013012ccc42b647562e;hpb=092c2acd489e88dd99d1f27560d16fc1ba89c88c;p=pspp diff --git a/src/ui/gui/psppire-output-view.c b/src/ui/gui/psppire-output-view.c index 8c14a93125..4296409120 100644 --- a/src/ui/gui/psppire-output-view.c +++ b/src/ui/gui/psppire-output-view.c @@ -67,6 +67,8 @@ struct psppire_output_view GtkWidget *toplevel; + guint buttontime; /* Time of the button event */ + struct output_view_item *items; size_t n_items, allocated_items; struct output_view_item *selected_item; @@ -87,6 +89,12 @@ enum N_COLS }; +static GtkTargetList *build_target_list (const struct output_item *item); +static void clipboard_get_cb (GtkClipboard *clipboard, + GtkSelectionData *selection_data, + guint info, + gpointer data); + /* Draws a white background on the GtkLayout to match the white background of each of the output items. */ static gboolean @@ -264,8 +272,14 @@ off_item_button_press_event_cb (GtkWidget *widget, GdkEventButton *event, struct psppire_output_view *view) { - clear_selection (view); - return FALSE; /* Forward the event */ + /* buttontime is set by button_press_event_cb + If our event->time is equal to the time from the + button_press_event_cb, then we handle the same event. + In that case we must not clear the selection because + it was just set by button_press_event_cb from the item */ + if (event->time != view->buttontime) + clear_selection (view); + return FALSE; /* Forward the event -> DragNDrop */ } static gboolean @@ -273,17 +287,28 @@ button_press_event_cb (GtkWidget *widget, GdkEventButton *event, struct psppire_output_view *view) { + view->buttontime = event->time; clear_selection (view); set_copy_action (view, TRUE); gtk_widget_set_state_flags (widget, GTK_STATE_FLAG_SELECTED, FALSE); gtk_widget_queue_draw (widget); - return TRUE; /* We have handled the event */ + return FALSE; /* Forward Event -> off_item will trigger */ +} + +static void +drag_data_get_cb (GtkWidget *widget, GdkDragContext *context, + GtkSelectionData *selection_data, + guint target_type, guint time, + struct psppire_output_view *view) +{ + view->selected_item = find_selected_item (view); + clipboard_get_cb (NULL, selection_data, target_type, view); } static void create_drawing_area (struct psppire_output_view *view, GtkWidget *drawing_area, struct xr_rendering *r, - int tw, int th) + int tw, int th, const struct output_item *item) { struct string_map options = STRING_MAP_INITIALIZER (options); string_map_insert (&options, "transparent", "true"); @@ -292,10 +317,19 @@ create_drawing_area (struct psppire_output_view *view, g_object_set_data_full (G_OBJECT (drawing_area), "rendering", r, free_rendering); - g_signal_connect (drawing_area, "button-press-event", G_CALLBACK (button_press_event_cb), view); gtk_widget_add_events (drawing_area, GDK_BUTTON_PRESS_MASK); + + { /* Drag and Drop */ + GtkTargetList *tl = build_target_list (item); + g_assert (tl); + gtk_drag_source_set (drawing_area, GDK_BUTTON1_MASK, NULL, 0, GDK_ACTION_COPY); + gtk_drag_source_set_target_list (drawing_area, tl); + gtk_target_list_unref (tl); + g_signal_connect (drawing_area, "drag-data-get", + G_CALLBACK (drag_data_get_cb), view); + } GtkStyleContext *context = gtk_widget_get_style_context (drawing_area); gtk_style_context_add_class (context, GTK_STYLE_CLASS_VIEW); @@ -355,7 +389,7 @@ rerender (struct psppire_output_view *view) if (!item->drawing_area) { item->drawing_area = gtk_drawing_area_new (); - create_drawing_area (view, item->drawing_area, r, tw, th); + create_drawing_area (view, item->drawing_area, r, tw, th, item->item); } else { @@ -459,7 +493,7 @@ psppire_output_view_put (struct psppire_output_view *view, } xr_rendering_measure (r, &tw, &th); - create_drawing_area (view, drawing_area, r, tw, th); + create_drawing_area (view, drawing_area, r, tw, th, item); gdk_window_end_draw_frame (win, ctx); cairo_region_destroy (region); } @@ -767,7 +801,7 @@ CT ( ctn8, "image/svg+xml", 0, SELECT_FMT_SVG ) #define CT(ID, TARGET, FLAGS, INFO) static gchar ID[] = TARGET; CBTARGETS #undef CT -gchar ctnlast[] = "application/vnd.oasis.opendocument.text"; +static gchar ctnlast[] = "application/vnd.oasis.opendocument.text"; static const GtkTargetEntry targets[] = { #define CT(ID, TARGET, FLAGS, INFO) { ID, FLAGS, INFO }, @@ -776,6 +810,17 @@ static const GtkTargetEntry targets[] = { { ctnlast, 0, SELECT_FMT_ODT } }; +static GtkTargetList * +build_target_list (const struct output_item *item) +{ + GtkTargetList *tl = gtk_target_list_new (targets, G_N_ELEMENTS (targets)); + g_return_val_if_fail (tl, NULL); + if (is_table_item (item) || + is_chart_item (item)) + gtk_target_list_add_image_targets (tl, SELECT_FMT_IMG, TRUE); + return tl; +} + static void on_copy (struct psppire_output_view *view) { @@ -786,11 +831,8 @@ on_copy (struct psppire_output_view *view) if (ov_item == NULL) return; view->selected_item = ov_item; - GtkTargetList *tl = gtk_target_list_new (targets, G_N_ELEMENTS (targets)); + GtkTargetList *tl = build_target_list (ov_item->item); g_return_if_fail (tl); - if (is_table_item (ov_item->item) || - is_chart_item (ov_item->item)) - gtk_target_list_add_image_targets (tl, SELECT_FMT_IMG, TRUE); gint no_of_targets = 0; GtkTargetEntry *ta = gtk_target_table_new_from_list (tl, &no_of_targets); g_return_if_fail (ta); @@ -803,23 +845,6 @@ on_copy (struct psppire_output_view *view) gtk_target_table_free (ta,no_of_targets); } -static void -on_selection_change (GtkTreeSelection *sel, GAction *copy_action) -{ - /* The Copy action is available only if there is something selected */ - g_object_set (copy_action, - "enabled", gtk_tree_selection_count_selected_rows (sel) > 0, - NULL); -} - -static void -on_select_all (struct psppire_output_view *view) -{ - GtkTreeSelection *sel = gtk_tree_view_get_selection (view->overview); - gtk_tree_view_expand_all (view->overview); - gtk_tree_selection_select_all (sel); -} - static void on_size_allocate (GtkWidget *widget, GdkRectangle *allocation, @@ -832,9 +857,6 @@ on_size_allocate (GtkWidget *widget, static void on_realize (GtkWidget *overview, GObject *view) { - GtkTreeSelection *sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (overview)); - gtk_tree_selection_set_mode (sel, GTK_SELECTION_MULTIPLE); - GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (overview)); GAction *copy_action = g_action_map_lookup_action (G_ACTION_MAP (toplevel), @@ -844,15 +866,11 @@ on_realize (GtkWidget *overview, GObject *view) "select-all"); g_object_set (copy_action, "enabled", FALSE, NULL); - - g_signal_connect_swapped (select_all_action, "activate", - G_CALLBACK (on_select_all), view); + g_object_set (select_all_action, "enabled", FALSE, NULL); g_signal_connect_swapped (copy_action, "activate", G_CALLBACK (on_copy), view); - g_signal_connect (sel, "changed", G_CALLBACK (on_selection_change), - copy_action); } struct psppire_output_view * @@ -875,6 +893,7 @@ psppire_output_view_new (GtkLayout *output, GtkTreeView *overview) view->overview = overview; view->cur_group = NULL; view->toplevel = gtk_widget_get_toplevel (GTK_WIDGET (output)); + view->buttontime = 0; view->items = NULL; view->n_items = view->allocated_items = 0; view->selected_item = NULL;